Skip to content

Commit

Permalink
feat: support json5 for postman
Browse files Browse the repository at this point in the history
  • Loading branch information
tangcent committed Nov 21, 2020
1 parent 9b7b2da commit ab68506
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.extend.toPrettyString
import com.itangcent.intellij.util.ActionUtils
import com.itangcent.intellij.util.forEachValid
import java.util.*

/**
* format [com.itangcent.common.model.Doc] to `markdown`.
Expand Down Expand Up @@ -465,24 +464,28 @@ private class SimpleObjectFormatter(handle: (String) -> Unit) : AbstractObjectFo
addBodyProperty(deep, name, "array", desc)

if (obj.size > 0) {
writeBody(obj[0], "", "", deep + 1)
obj.forEach {
writeBody(it, "", "", deep + 1)
}
} else {
writeBody(null, "", "", deep + 1)
}
} else if (obj is List<*>) {
} else if (obj is Collection<*>) {
addBodyProperty(deep, name, "array", desc)
if (obj.size > 0) {
writeBody(obj[0], "", "", deep + 1)
obj.forEach {
writeBody(it, "", "", deep + 1)
}
} else {
writeBody(null, "", "", deep + 1)
}
} else if (obj is Map<*, *>) {
if (deep > 0) {
addBodyProperty(deep, name, "object", desc)
}
var comment: HashMap<String, Any?>? = null
var comment: Map<String, Any?>? = null
try {
comment = obj[Attrs.COMMENT_ATTR] as HashMap<String, Any?>?
comment = obj[Attrs.COMMENT_ATTR] as Map<String, Any?>?
} catch (e: Throwable) {
}
obj.forEachValid { k, v ->
Expand Down Expand Up @@ -528,14 +531,18 @@ private class UltimateObjectFormatter(handle: (String) -> Unit) : AbstractObject
if (obj is Array<*>) {
addBodyProperty(deep, name, "array", required, default, desc)
if (obj.size > 0) {
writeBody(obj[0], "", null, null, "", deep + 1)
obj.forEach {
writeBody(it, "", null, null, "", deep + 1)
}
} else {
writeBody(null, "", null, null, "", deep + 1)
}
} else if (obj is List<*>) {
} else if (obj is Collection<*>) {
addBodyProperty(deep, name, "array", desc)
if (obj.size > 0) {
writeBody(obj[0], "", null, null, "", deep + 1)
obj.forEach {
writeBody(it, "", null, null, "", deep + 1)
}
} else {
writeBody(null, "", null, null, "", deep + 1)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.itangcent.idea.plugin.api.export.postman
import com.google.inject.Inject
import com.google.inject.Singleton
import com.intellij.psi.PsiClass
import com.itangcent.common.constant.Attrs
import com.itangcent.common.kit.KVUtils
import com.itangcent.common.model.Request
import com.itangcent.common.model.URL
import com.itangcent.common.model.getContentType
Expand All @@ -21,6 +23,8 @@ import com.itangcent.idea.utils.ModuleHelper
import com.itangcent.intellij.config.rule.RuleComputer
import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.util.ActionUtils
import com.itangcent.intellij.util.forEachValid
import com.itangcent.intellij.util.validSize
import org.apache.commons.lang3.RandomUtils
import java.util.*
import kotlin.collections.ArrayList
Expand Down Expand Up @@ -215,7 +219,7 @@ open class PostmanFormatter {

if (request.body != null) {
body[MODE] = "raw"
body["raw"] = RequestUtils.parseRawBody(request.body!!)
body["raw"] = getBodyFormatter().format(request.body)
body["options"] = KV.by("raw", KV.by("language", "json"))
}

Expand Down Expand Up @@ -293,7 +297,7 @@ open class PostmanFormatter {

responseInfo["responseTime"] = RandomUtils.nextInt(10, 100)

responseInfo["body"] = response.body?.let { RequestUtils.parseRawBody(it) }
responseInfo["body"] = getBodyFormatter().format(response.body)

responses.add(responseInfo)
}
Expand Down Expand Up @@ -591,13 +595,191 @@ open class PostmanFormatter {
}
}

private fun getBodyFormatter(): BodyFormatter {
val useJson5 = settingBinder!!.read().useJson5
return if (useJson5) {
Json5BodyFormatter()
} else {
SimpleJsonBodyFormatter()
}
}

companion object {
const val NULL_RESOURCE = "unknown"

const val POSTMAN_SCHEMA_V2_1_0 = "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
}
}

private interface BodyFormatter {
fun format(obj: Any?): String
}

private class SimpleJsonBodyFormatter : BodyFormatter {
override fun format(obj: Any?): String {
return obj?.let { RequestUtils.parseRawBody(it) } ?: ""
}
}

/**
* @see {@link https://github.com/json5/json5}
* @see {@link https://json5.org/}
*/
@Suppress("UNCHECKED_CAST")
private class Json5BodyFormatter : BodyFormatter {
override fun format(obj: Any?): String {
val sb = StringBuilder()
format(obj, 0, true, null, sb)
return sb.toString()
}

fun format(obj: Any?, deep: Int, end: Boolean, desc: String?, sb: StringBuilder) {
when (obj) {
null -> {
sb.append("null")
sb.appendEnd(end)
sb.appendEndLineComment(desc)
}
is Array<*> -> {
if (obj.isEmpty()) {
sb.append("[]")
sb.appendEnd(end)
sb.appendEndLineComment(desc)
return
}
sb.append("[")
sb.appendEndLineComment(desc)
val endCounter = EndCounter(obj.size)
obj.forEach {
sb.nextLine(deep + 1)
format(it, deep + 1, endCounter.end(), null, sb)
}
sb.nextLine(deep)
sb.append("]")
sb.appendEnd(end)
}
is Collection<*> -> {
if (obj.isEmpty()) {
sb.append("[]")
sb.appendEnd(end)
sb.appendEndLineComment(desc)
return
}
sb.append("[")
sb.appendEndLineComment(desc)
val endCounter = EndCounter(obj.size)
obj.forEach {
sb.nextLine(deep + 1)
format(it, deep + 1, endCounter.end(), null, sb)
}
sb.nextLine(deep)
sb.append("]")
sb.appendEnd(end)
}
is Map<*, *> -> {
if (obj.isEmpty()) {
sb.append("{}")
sb.appendEnd(end)
sb.appendEndLineComment(desc)
return
}
var comment: Map<String, Any?>? = null
try {
comment = obj[Attrs.COMMENT_ATTR] as Map<String, Any?>?
} catch (e: Throwable) {
}
sb.append("{")
sb.appendEndLineComment(desc)
val endCounter = EndCounter(obj.validSize())
obj.forEachValid { k, v ->
val propertyDesc: String? = KVUtils.getUltimateComment(comment, k)
sb.nextLine(deep + 1)
format(k.toString(), v, deep + 1, propertyDesc ?: "", endCounter.end(), sb)
}
sb.nextLine(deep)
sb.append("}")
sb.appendEnd(end)
}
is String -> {
sb.appendString(obj)
sb.appendEnd(end)
sb.appendEndLineComment(desc)
}
else -> {
sb.append(obj)
sb.appendEnd(end)
sb.appendEndLineComment(desc)
}
}
}

fun format(name: String, obj: Any?, deep: Int, desc: String?, end: Boolean, sb: StringBuilder) {
if (desc.isNullOrBlank()) {
sb.appendString(name)
sb.append(": ")
format(obj, deep, end, desc, sb)
return
}
val lines = desc.lines()
if (lines.size == 1) {
sb.appendString(name)
sb.append(": ")
format(obj, deep, end, desc, sb)
return
} else {
sb.appendBlockComment(lines, deep)
sb.appendString(name)
sb.append(": ")
format(obj, deep, end, null, sb)
return
}
}

private fun StringBuilder.appendString(key: String) {
this.append('"')
this.append(key)
this.append('"')
}

private fun StringBuilder.appendEnd(end: Boolean) {
if (!end) {
this.append(',')
}
}

private fun StringBuilder.appendBlockComment(descs: List<String>, deep: Int) {
this.append("/**")
this.appendln()
descs.forEach {
this.append(TAB.repeat(deep))
this.append(" * ")
this.appendln(it)
}
this.append(TAB.repeat(deep))
this.append(" */")
this.appendln()
this.append(TAB.repeat(deep))
}

private fun StringBuilder.appendEndLineComment(desc: String?) {
if (desc.notNullOrBlank()) {
this.append("//")
this.append(desc)
}
}

private fun StringBuilder.nextLine(deep: Int) {
this.appendln()
this.append(TAB.repeat(deep))
}
}

private class EndCounter(val size: Int) {
private var i = 0
fun end(): Boolean {
return ++i == size
}
}

private const val NAME = "name"
private const val KEY = "key"
Expand All @@ -607,3 +789,19 @@ private const val MODE = "mode"
private const val DESCRIPTION = "description"
private const val EVENT = "event"
private const val ITEM = "item"
private const val TAB = " "


fun main() {
val json5BodyFormatter = Json5BodyFormatter()
println(json5BodyFormatter.format("aa"))
println(json5BodyFormatter.format(KV.by("aa", "bb")))
println(json5BodyFormatter.format(KV.by("aa", listOf("bb", KV.by("aa", "bb")))))
println(json5BodyFormatter.format(
KV.by<String, Any?>("aa", listOf("bb", KV.by("aa", "bb")))
.set("bb", listOf("cc", KV.by("aa", "bb")))
.set(Attrs.COMMENT_ATTR, KV.by("aa", "string - a")
.set("bb", "bbb\nbbb\nbbb")
)
))
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<grid id="b08f8" binding="rootPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="504" height="1028"/>
<xy x="20" y="20" width="504" height="1062"/>
</constraints>
<properties/>
<border type="none"/>
Expand Down Expand Up @@ -190,7 +190,7 @@
</grid>
</children>
</grid>
<grid id="5c34a" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="5c34a" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false">
Expand Down Expand Up @@ -289,6 +289,39 @@
</grid>
</children>
</grid>
<grid id="4a8c1" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="1a00d" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="5a58b" class="javax.swing.JCheckBox" binding="useJson5CheckBox">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="json5"/>
</properties>
</component>
</children>
</grid>
<hspacer id="40904">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</children>
</grid>
<grid id="5f37" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class EasyApiSettingGUI {

private var autoMergeScriptCheckBox: JCheckBox? = null

private var useJson5CheckBox: JCheckBox? = null

//endregion

//region general-----------------------------------------------------
Expand Down Expand Up @@ -144,6 +146,9 @@ class EasyApiSettingGUI {
autoComputer.bind(autoMergeScriptCheckBox!!)
.mutual(this, "settings.autoMergeScript")

autoComputer.bind(useJson5CheckBox!!)
.mutual(this, "settings.useJson5")

autoComputer.bind(this.globalCacheSizeLabel!!)
.with(this::globalCacheSize)
.eval { it }
Expand Down
Loading

0 comments on commit ab68506

Please sign in to comment.