Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add 'yapi.no_update.description' to stop api description updates #1170

Merged
merged 1 commit into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ open class DefaultYapiApiHelper : AbstractYapiApiHelper(), YapiApiHelper {
}

override fun saveApiInfo(apiInfo: HashMap<String, Any?>): Boolean {
if (!saveInterceptor.beforeSaveApi(this, apiInfo)) {
if (saveInterceptor.beforeSaveApi(this, apiInfo) == false) {
return false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,29 @@ fun YapiApiHelper.listApis(token: String, catId: String): JsonArray? {
}

fun YapiApiHelper.existed(apiInfo: HashMap<String, Any?>): Boolean {
val path = apiInfo["path"] ?: return false
val method = apiInfo["method"] ?: return false
val token = apiInfo["token"] as? String ?: return false
val projectId: String = this.getProjectIdByToken(token) ?: return false
val carts = this.findCarts(projectId, token) ?: return false
return this.findExistApi(apiInfo) != null
}

fun YapiApiHelper.findExistApi(apiInfo: HashMap<String, Any?>): JsonObject? {
val path = apiInfo["path"] as? String ?: return null
val method = apiInfo["method"] as? String ?: return null
val token = apiInfo["token"] as? String ?: return null
return this.findExistApi(token, path, method)
}

fun YapiApiHelper.findExistApi(token: String, path: String, method: String): JsonObject? {
val projectId: String = this.getProjectIdByToken(token) ?: return null
val carts = this.findCarts(projectId, token) ?: return null
for (cart in carts) {
val cart_id = (cart as? Map<*, *>)?.get("_id")?.toString() ?: continue
if (this.listApis(token, cart_id, null)?.any { api ->
api.sub("path")?.asString == path && api.sub("method")?.asString == method
} == true) {
return true
val catId = (cart as? Map<*, *>)?.get("_id")?.toString() ?: continue
val api = this.listApis(token, catId, null)?.find { api ->
api.sub("path")?.asString == path && api.sub("method")?.asString == method
}
if (api != null) {
return api as JsonObject
}
}
return false
return null
}

fun YapiApiHelper.getCartForFolder(folder: Folder, privateToken: String): CartInfo? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package com.itangcent.idea.plugin.api.export.yapi

import com.intellij.openapi.ui.Messages
import com.itangcent.common.concurrent.ValueHolder
import com.itangcent.common.utils.toBool
import com.itangcent.idea.plugin.condition.ConditionOnSetting
import com.itangcent.idea.swing.MessagesHelper
import com.itangcent.intellij.config.ConfigReader
import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.extend.sub

/**
* Workflow interface that allows for customized yapi save action.
Expand All @@ -13,10 +16,10 @@ internal interface YapiSaveInterceptor {
/**
* Called before [YapiApiHelper] save an apiInfo to yapi server.
*
* @return @return {@code true} if the apiInfo should be saved.
* Else, [YapiApiHelper] will discard this apiInfo.
* @return return {@code false} [YapiApiHelper] will discard this apiInfo.
* else [YapiApiHelper] will save this apiInfo to yapi server.
*/
fun beforeSaveApi(apiHelper: YapiApiHelper, apiInfo: HashMap<String, Any?>): Boolean
fun beforeSaveApi(apiHelper: YapiApiHelper, apiInfo: HashMap<String, Any?>): Boolean?
}

/**
Expand Down Expand Up @@ -57,7 +60,7 @@ class AlwaysAskYapiSaveInterceptor : YapiSaveInterceptor {
private var selectedYapiSaveInterceptor: YapiSaveInterceptor? = null

@Synchronized
override fun beforeSaveApi(apiHelper: YapiApiHelper, apiInfo: HashMap<String, Any?>): Boolean {
override fun beforeSaveApi(apiHelper: YapiApiHelper, apiInfo: HashMap<String, Any?>): Boolean? {
if (selectedYapiSaveInterceptor != null) {
return selectedYapiSaveInterceptor!!.beforeSaveApi(apiHelper, apiInfo)
}
Expand All @@ -68,7 +71,8 @@ class AlwaysAskYapiSaveInterceptor : YapiSaveInterceptor {
val context = ActionContext.getContext() ?: return true
context.instance(MessagesHelper::class).showAskWithApplyAllDialog(
"The api [${apiInfo["title"]}] already existed in the project.\n" +
"Do you want update it?", arrayOf("Update", "Skip", "Cancel")) { ret, applyAll ->
"Do you want update it?", arrayOf("Update", "Skip", "Cancel")
) { ret, applyAll ->
if (ret == Messages.CANCEL) {
context.stop()
valueHolder.success(false)
Expand All @@ -91,3 +95,36 @@ class AlwaysAskYapiSaveInterceptor : YapiSaveInterceptor {
return valueHolder.value() ?: false
}
}

/**
* A [YapiSaveInterceptor] that prevents overwriting the existing description and markdown fields in YAPI when saving API details.
* Only works when the configuration "yapi.no_update.description" is set to true.
*/
class NoUpdateDescriptionYapiSaveInterceptor : YapiSaveInterceptor {
override fun beforeSaveApi(apiHelper: YapiApiHelper, apiInfo: HashMap<String, Any?>): Boolean? {
recoverDescription(apiHelper, apiInfo)
return null
}

/**
* Retrieves the existing API information from YAPI and copies the description and markdown
* fields to the new API information to prevent them from being overwritten.
*/
private fun recoverDescription(apiHelper: YapiApiHelper, apiInfo: HashMap<String, Any?>) {
val disable = ActionContext.getContext()
?.instance(ConfigReader::class)
?.first("yapi.no_update.description")
?.toBool(false) ?: false
if (!disable) return

val existedApi = apiHelper.findExistApi(apiInfo) ?: return
val apiId = existedApi.sub("_id")?.asString ?: return
val existedApiInfo = apiHelper.getApiInfo(apiInfo["token"] as String, apiId)

val existedDescription = existedApiInfo.sub("desc")?.asString ?: ""
apiInfo["desc"] = existedDescription

val existedMarkdown = existedApiInfo.sub("markdown")?.asString ?: ""
apiInfo["markdown"] = existedMarkdown
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
com.itangcent.idea.plugin.api.export.yapi.AlwaysUpdateYapiSaveInterceptor
com.itangcent.idea.plugin.api.export.yapi.NeverUpdateYapiSaveInterceptor
com.itangcent.idea.plugin.api.export.yapi.AlwaysAskYapiSaveInterceptor
com.itangcent.idea.plugin.api.export.yapi.NoUpdateDescriptionYapiSaveInterceptor
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.itangcent.idea.plugin.api.export.condition

import com.itangcent.idea.plugin.api.export.ExportDoc
import com.itangcent.idea.plugin.api.export.condition.ConditionOnChannel
import com.itangcent.intellij.context.ActionContext
import com.itangcent.mock.AdvancedContextTest
import org.junit.jupiter.api.Test
Expand Down
Loading
Loading