refactor: use samples plugin to generate schemas examples (#8728)

Refs #8577
This commit is contained in:
Vladimír Gorej
2023-05-30 15:26:50 +02:00
parent 027f53c302
commit 1ce9ce0cda
8 changed files with 22 additions and 98 deletions

View File

@@ -1,7 +1,6 @@
import React, { PureComponent } from "react" import React, { PureComponent } from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import { fromJS, List } from "immutable" import { fromJS, List } from "immutable"
import { getSampleSchema } from "core/utils"
import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse" import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse"
const NOOP = Function.prototype const NOOP = Function.prototype
@@ -67,10 +66,10 @@ export default class ParamBody extends PureComponent {
} }
sample = (xml) => { sample = (xml) => {
let { param, fn:{inferSchema} } = this.props let { param, fn} = this.props
let schema = inferSchema(param.toJS()) let schema = fn.inferSchema(param.toJS())
return getSampleSchema(schema, xml, { return fn.getSampleSchema(schema, xml, {
includeWriteOnly: true includeWriteOnly: true
}) })
} }

View File

@@ -3,7 +3,7 @@ import { Map, List } from "immutable"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes" import ImPropTypes from "react-immutable-proptypes"
import win from "core/window" import win from "core/window"
import { getSampleSchema, getExtensions, getCommonExtensions, numberToString, stringify, isEmptyValue } from "core/utils" import { getExtensions, getCommonExtensions, numberToString, stringify, isEmptyValue } from "core/utils"
import getParameterSchema from "../../helpers/get-parameter-schema.js" import getParameterSchema from "../../helpers/get-parameter-schema.js"
export default class ParameterRow extends Component { export default class ParameterRow extends Component {
@@ -94,7 +94,7 @@ export default class ParameterRow extends Component {
} }
setDefaultValue = () => { setDefaultValue = () => {
let { specSelectors, pathMethod, rawParam, oas3Selectors } = this.props let { specSelectors, pathMethod, rawParam, oas3Selectors, fn } = this.props
const paramWithMeta = specSelectors.parameterWithMetaByIdentity(pathMethod, rawParam) || Map() const paramWithMeta = specSelectors.parameterWithMetaByIdentity(pathMethod, rawParam) || Map()
const { schema } = getParameterSchema(paramWithMeta, { isOAS3: specSelectors.isOAS3() }) const { schema } = getParameterSchema(paramWithMeta, { isOAS3: specSelectors.isOAS3() })
@@ -104,7 +104,7 @@ export default class ParameterRow extends Component {
.first() .first()
// getSampleSchema could return null // getSampleSchema could return null
const generatedSampleValue = schema ? getSampleSchema(schema.toJS(), parameterMediaType, { const generatedSampleValue = schema ? fn.getSampleSchema(schema.toJS(), parameterMediaType, {
includeWriteOnly: true includeWriteOnly: true
}) : null }) : null

View File

@@ -3,7 +3,7 @@ import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes" import ImPropTypes from "react-immutable-proptypes"
import cx from "classnames" import cx from "classnames"
import { fromJS, Seq, Iterable, List, Map } from "immutable" import { fromJS, Seq, Iterable, List, Map } from "immutable"
import { getExtensions, getSampleSchema, fromJSOrdered, stringify } from "core/utils" import { getExtensions, fromJSOrdered, stringify } from "core/utils"
import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse" import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse"
@@ -93,7 +93,7 @@ export default class Response extends React.Component {
oas3Actions, oas3Actions,
} = this.props } = this.props
let { inferSchema } = fn let { inferSchema, getSampleSchema } = fn
let isOAS3 = specSelectors.isOAS3() let isOAS3 = specSelectors.isOAS3()
const { showExtensions } = getConfigs() const { showExtensions } = getConfigs()

View File

@@ -4,8 +4,7 @@ import { List, fromJS } from "immutable"
import cx from "classnames" import cx from "classnames"
import ImPropTypes from "react-immutable-proptypes" import ImPropTypes from "react-immutable-proptypes"
import DebounceInput from "react-debounce-input" import DebounceInput from "react-debounce-input"
import { stringify, getSampleSchema } from "core/utils" import { stringify } from "core/utils"
//import "less/json-schema-form"
const noop = ()=> {} const noop = ()=> {}
const JsonSchemaPropShape = { const JsonSchemaPropShape = {
@@ -156,9 +155,10 @@ export class JsonSchema_array extends PureComponent {
} }
addItem = () => { addItem = () => {
const { fn } = this.props
let newValue = valueOrEmptyList(this.state.value) let newValue = valueOrEmptyList(this.state.value)
this.setState(() => ({ this.setState(() => ({
value: newValue.push(getSampleSchema(this.state.schema.get("items"), false, { value: newValue.push(fn.getSampleSchema(this.state.schema.get("items"), false, {
includeWriteOnly: true includeWriteOnly: true
})) }))
}), this.onChange) }), this.onChange)

View File

@@ -104,7 +104,6 @@ const JSONSchema202012Plugin = () => ({
}, },
fn: { fn: {
upperFirst, upperFirst,
memoizedSampleFromSchema: null,
jsonSchema202012: { jsonSchema202012: {
isExpandable, isExpandable,
hasKeyword, hasKeyword,

View File

@@ -2,10 +2,10 @@ import React from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes" import ImPropTypes from "react-immutable-proptypes"
import { Map, OrderedMap, List } from "immutable" import { Map, OrderedMap, List } from "immutable"
import { getCommonExtensions, getSampleSchema, stringify, isEmptyValue } from "core/utils" import { getCommonExtensions, stringify, isEmptyValue } from "core/utils"
import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse" import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse"
export const getDefaultRequestBodyValue = (requestBody, mediaType, activeExamplesKey) => { export const getDefaultRequestBodyValue = (requestBody, mediaType, activeExamplesKey, fn) => {
const mediaTypeValue = requestBody.getIn(["content", mediaType]) const mediaTypeValue = requestBody.getIn(["content", mediaType])
const schema = mediaTypeValue.get("schema").toJS() const schema = mediaTypeValue.get("schema").toJS()
@@ -19,7 +19,7 @@ export const getDefaultRequestBodyValue = (requestBody, mediaType, activeExample
]) ])
: exampleSchema : exampleSchema
const exampleValue = getSampleSchema( const exampleValue = fn.getSampleSchema(
schema, schema,
mediaType, mediaType,
{ {
@@ -92,6 +92,7 @@ const RequestBody = ({
requestBody, requestBody,
contentType, contentType,
key, key,
fn,
), val) ), val)
} }
return container return container

View File

@@ -76,7 +76,7 @@ export const shouldRetainRequestBodyValue = onlyOAS3((state, path, method) => {
export const selectDefaultRequestBodyValue = export const selectDefaultRequestBodyValue =
(state, path, method) => (system) => { (state, path, method) => (system) => {
const { oas3Selectors, specSelectors } = system.getSystem() const { oas3Selectors, specSelectors, fn } = system.getSystem()
if (specSelectors.isOAS3()) { if (specSelectors.isOAS3()) {
const currentMediaType = oas3Selectors.requestContentType(path, method) const currentMediaType = oas3Selectors.requestContentType(path, method)
@@ -94,7 +94,8 @@ export const selectDefaultRequestBodyValue =
method, method,
"requestBody", "requestBody",
"requestBody" "requestBody"
) ),
fn
) )
} }
} }

View File

@@ -9,7 +9,6 @@
If you're refactoring something in here, feel free to break it out to a file If you're refactoring something in here, feel free to break it out to a file
in `./helpers` if you have the time. in `./helpers` if you have the time.
*/ */
import Im, { fromJS, Set } from "immutable" import Im, { fromJS, Set } from "immutable"
import { sanitizeUrl as braintreeSanitizeUrl } from "@braintree/sanitize-url" import { sanitizeUrl as braintreeSanitizeUrl } from "@braintree/sanitize-url"
import camelCase from "lodash/camelCase" import camelCase from "lodash/camelCase"
@@ -19,14 +18,11 @@ import find from "lodash/find"
import some from "lodash/some" import some from "lodash/some"
import eq from "lodash/eq" import eq from "lodash/eq"
import isFunction from "lodash/isFunction" import isFunction from "lodash/isFunction"
import { memoizedSampleFromSchema, memoizedCreateXMLExample } from "core/plugins/samples/fn"
import win from "./window" import win from "./window"
import cssEscape from "css.escape" import cssEscape from "css.escape"
import getParameterSchema from "../helpers/get-parameter-schema" import getParameterSchema from "../helpers/get-parameter-schema"
import randomBytes from "randombytes" import randomBytes from "randombytes"
import shaJs from "sha.js" import shaJs from "sha.js"
import YAML, { JSON_SCHEMA } from "js-yaml"
const DEFAULT_RESPONSE_KEY = "default" const DEFAULT_RESPONSE_KEY = "default"
@@ -599,86 +595,14 @@ export const validateParam = (param, value, { isOAS3 = false, bypassRequiredChec
let paramRequired = param.get("required") let paramRequired = param.get("required")
let { schema: paramDetails, parameterContentMediaType } = getParameterSchema(param, { isOAS3 }) let {
schema: paramDetails,
parameterContentMediaType
} = getParameterSchema(param, { isOAS3 })
return validateValueBySchema(value, paramDetails, paramRequired, bypassRequiredCheck, parameterContentMediaType) return validateValueBySchema(value, paramDetails, paramRequired, bypassRequiredCheck, parameterContentMediaType)
} }
const getXmlSampleSchema = (schema, config, exampleOverride) => {
if (schema && !schema.xml) {
schema.xml = {}
}
if (schema && !schema.xml.name) {
if (!schema.$$ref && (schema.type || schema.items || schema.properties || schema.additionalProperties)) {
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- XML example cannot be generated; root element name is undefined -->"
}
if (schema.$$ref) {
let match = schema.$$ref.match(/\S*\/(\S+)$/)
schema.xml.name = match[1]
}
}
return memoizedCreateXMLExample(schema, config, exampleOverride)
}
const shouldStringifyTypesConfig = [
{
when: /json/,
shouldStringifyTypes: ["string"]
}
]
const defaultStringifyTypes = ["object"]
const getStringifiedSampleForSchema = (schema, config, contentType, exampleOverride) => {
const res = memoizedSampleFromSchema(schema, config, exampleOverride)
const resType = typeof res
const typesToStringify = shouldStringifyTypesConfig.reduce(
(types, nextConfig) => nextConfig.when.test(contentType)
? [...types, ...nextConfig.shouldStringifyTypes]
: types,
defaultStringifyTypes)
return some(typesToStringify, x => x === resType)
? JSON.stringify(res, null, 2)
: res
}
const getYamlSampleSchema = (schema, config, contentType, exampleOverride) => {
const jsonExample = getStringifiedSampleForSchema(schema, config, contentType, exampleOverride)
let yamlString
try {
yamlString = YAML.dump(YAML.load(jsonExample), {
lineWidth: -1 // don't generate line folds
}, { schema: JSON_SCHEMA })
if(yamlString[yamlString.length - 1] === "\n") {
yamlString = yamlString.slice(0, yamlString.length - 1)
}
} catch (e) {
console.error(e)
return "error: could not generate yaml example"
}
return yamlString
.replace(/\t/g, " ")
}
export const getSampleSchema = (schema, contentType="", config={}, exampleOverride = undefined) => {
if(schema && isFunc(schema.toJS))
schema = schema.toJS()
if(exampleOverride && isFunc(exampleOverride.toJS))
exampleOverride = exampleOverride.toJS()
if (/xml/.test(contentType)) {
return getXmlSampleSchema(schema, config, exampleOverride)
}
if (/(yaml|yml)/.test(contentType)) {
return getYamlSampleSchema(schema, config, contentType, exampleOverride)
}
return getStringifiedSampleForSchema(schema, config, contentType, exampleOverride)
}
export const parseSearch = () => { export const parseSearch = () => {
let map = {} let map = {}
let search = win.location.search let search = win.location.search