feat(oas31): add support for JSON Schema 2020-12 example keyword (#8652)

Refs #8513
This commit is contained in:
Vladimír Gorej
2023-05-11 13:26:21 +02:00
committed by GitHub
parent 091d6cbdad
commit 7d14577523
8 changed files with 134 additions and 34 deletions

View File

@@ -43,7 +43,8 @@ import KeywordWriteOnly from "./components/keywords/WriteOnly/WriteOnly"
import Accordion from "./components/Accordion/Accordion" import Accordion from "./components/Accordion/Accordion"
import ExpandDeepButton from "./components/ExpandDeepButton/ExpandDeepButton" import ExpandDeepButton from "./components/ExpandDeepButton/ExpandDeepButton"
import ChevronRightIcon from "./components/icons/ChevronRight" import ChevronRightIcon from "./components/icons/ChevronRight"
import { upperFirst } from "./fn" import { upperFirst, hasKeyword, isExpandable } from "./fn"
import { useFn } from "./hooks"
import { withJSONSchemaContext } from "./hoc" import { withJSONSchemaContext } from "./hoc"
const JSONSchema202012Plugin = () => ({ const JSONSchema202012Plugin = () => ({
@@ -94,6 +95,11 @@ const JSONSchema202012Plugin = () => ({
}, },
fn: { fn: {
upperFirst, upperFirst,
jsonSchema202012: {
isExpandable,
hasKeyword,
useFn,
},
}, },
}) })

View File

@@ -14,7 +14,11 @@ import InfoWrapper from "./wrap-components/info"
import ModelsWrapper from "./wrap-components/models" import ModelsWrapper from "./wrap-components/models"
import VersionPragmaFilterWrapper from "./wrap-components/version-pragma-filter" import VersionPragmaFilterWrapper from "./wrap-components/version-pragma-filter"
import VersionStampWrapper from "./wrap-components/version-stamp" import VersionStampWrapper from "./wrap-components/version-stamp"
import JSONSchema202012KeywordDescriptionWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Description" import {
isOAS31 as isOAS31Fn,
createOnlyOAS31Selector as createOnlyOAS31SelectorFn,
createSystemSelector as createSystemSelectorFn,
} from "./fn"
import { import {
license as selectLicense, license as selectLicense,
contact as selectContact, contact as selectContact,
@@ -46,22 +50,31 @@ import {
selectLicenseUrl as selectLicenseUrlWrapper, selectLicenseUrl as selectLicenseUrlWrapper,
} from "./spec-extensions/wrap-selectors" } from "./spec-extensions/wrap-selectors"
import { selectLicenseUrl as selectOAS31LicenseUrl } from "./selectors" import { selectLicenseUrl as selectOAS31LicenseUrl } from "./selectors"
import { import JSONSchema202012KeywordExample from "./json-schema-2020-12-extensions/components/keywords/Example"
isOAS31 as isOAS31Fn, import JSONSchema202012KeywordDescriptionWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Description"
createOnlyOAS31Selector as createOnlyOAS31SelectorFn, import JSONSchema202012KeywordDefaultWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Default"
createSystemSelector as createSystemSelectorFn, import { makeIsExpandable } from "./json-schema-2020-12-extensions/fn"
} from "./fn"
const OAS31Plugin = ({ fn }) => { const OAS31Plugin = ({ getSystem }) => {
const system = getSystem()
const { fn } = system
const createSystemSelector = fn.createSystemSelector || createSystemSelectorFn const createSystemSelector = fn.createSystemSelector || createSystemSelectorFn
const createOnlyOAS31Selector = fn.createOnlyOAS31Selector || createOnlyOAS31SelectorFn // prettier-ignore const createOnlyOAS31Selector = fn.createOnlyOAS31Selector || createOnlyOAS31SelectorFn // prettier-ignore
const pluginFn = {
isOAs31: isOAS31Fn,
createSystemSelector: createSystemSelectorFn,
createOnlyOAS31Selector: createOnlyOAS31SelectorFn,
}
if (typeof fn.jsonSchema202012?.isExpandable === "function") {
pluginFn.jsonSchema202012 = {
...fn.jsonSchema202012,
isExpandable: makeIsExpandable(fn.jsonSchema202012.isExpandable, system),
}
}
return { return {
fn: { fn: pluginFn,
isOAs31: isOAS31Fn,
createSystemSelector: createSystemSelectorFn,
createOnlyOAS31Selector: createOnlyOAS31SelectorFn,
},
components: { components: {
Webhooks, Webhooks,
JsonSchemaDialect, JsonSchemaDialect,
@@ -70,6 +83,7 @@ const OAS31Plugin = ({ fn }) => {
OAS31Contact: Contact, OAS31Contact: Contact,
OAS31VersionPragmaFilter: VersionPragmaFilter, OAS31VersionPragmaFilter: VersionPragmaFilter,
OAS31Models: Models, OAS31Models: Models,
JSONSchema202012KeywordExample,
}, },
wrapComponents: { wrapComponents: {
InfoContainer: InfoWrapper, InfoContainer: InfoWrapper,
@@ -80,6 +94,7 @@ const OAS31Plugin = ({ fn }) => {
Models: ModelsWrapper, Models: ModelsWrapper,
JSONSchema202012KeywordDescription: JSONSchema202012KeywordDescription:
JSONSchema202012KeywordDescriptionWrapper, JSONSchema202012KeywordDescriptionWrapper,
JSONSchema202012KeywordDefault: JSONSchema202012KeywordDefaultWrapper,
}, },
statePlugins: { statePlugins: {
spec: { spec: {

View File

@@ -0,0 +1,27 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
const Description = ({ schema, getSystem }) => {
if (!schema?.description) return null
const { getComponent } = getSystem()
const MarkDown = getComponent("Markdown")
return (
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--description">
<div className="json-schema-2020-12-core-keyword__value json-schema-2020-12-core-keyword__value--secondary">
<MarkDown source={schema.description} />
</div>
</div>
)
}
Description.propTypes = {
schema: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
getSystem: PropTypes.func.isRequired,
}
export default Description

View File

@@ -0,0 +1,33 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
const Example = ({ schema, fn }) => {
const { hasKeyword, stringify } = fn.jsonSchema202012.useFn()
if (!hasKeyword(schema, "example")) return null
return (
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--example">
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
Example
</span>
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const">
{stringify(schema.example)}
</span>
</div>
)
}
Example.propTypes = {
schema: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
fn: PropTypes.shape({
jsonSchema202012: PropTypes.shape({
useFn: PropTypes.func.isRequired,
}).isRequired,
}).isRequired,
}
export default Example

View File

@@ -0,0 +1,12 @@
/**
* @prettier
*/
export const makeIsExpandable = (original, { fn }) => {
if (typeof original !== "function") {
return null
}
const { hasKeyword } = fn.jsonSchema202012
return (schema) => original(schema) || hasKeyword(schema, "example")
}

View File

@@ -0,0 +1,21 @@
/**
* @prettier
*/
import React from "react"
import { createOnlyOAS31ComponentWrapper } from "../../../fn"
const DefaultWrapper = createOnlyOAS31ComponentWrapper(
({ schema, getSystem, originalComponent: KeywordDefault }) => {
const { getComponent, fn } = getSystem()
const KeywordExample = getComponent("JSONSchema202012KeywordExample")
return (
<>
<KeywordDefault schema={schema} />
<KeywordExample schema={schema} fn={fn} />
</>
)
}
)
export default DefaultWrapper

View File

@@ -1,23 +1,9 @@
/** /**
* @prettier * @prettier
*/ */
import React from "react" import DescriptionKeyword from "../../components/keywords/Description"
import { createOnlyOAS31ComponentWrapper } from "../../../fn" import { createOnlyOAS31ComponentWrapper } from "../../../fn"
const DescriptionWrapper = createOnlyOAS31ComponentWrapper( const DescriptionWrapper = createOnlyOAS31ComponentWrapper(DescriptionKeyword)
({ schema, getComponent }) => {
if (!schema?.description) return null
const MarkDown = getComponent("Markdown")
return (
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--description">
<div className="json-schema-2020-12-core-keyword__value json-schema-2020-12-core-keyword__value--secondary">
<MarkDown source={schema.description} />
</div>
</div>
)
}
)
export default DescriptionWrapper export default DescriptionWrapper

View File

@@ -4,9 +4,11 @@
import React from "react" import React from "react"
import { createOnlyOAS31ComponentWrapper } from "../fn" import { createOnlyOAS31ComponentWrapper } from "../fn"
import { makeIsExpandable } from "../json-schema-2020-12-extensions/fn"
const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => { const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
const { getComponent, fn, getConfigs } = getSystem() const system = getSystem()
const { getComponent, fn, getConfigs } = system
const configs = getConfigs() const configs = getConfigs()
if (ModelsWrapper.ModelsWithJSONContext) { if (ModelsWrapper.ModelsWithJSONContext) {
@@ -66,10 +68,7 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
"JSONSchema202012KeywordContentSchema" "JSONSchema202012KeywordContentSchema"
) )
const KeywordTitle = getComponent("JSONSchema202012KeywordTitle") const KeywordTitle = getComponent("JSONSchema202012KeywordTitle")
const KeywordDescription = getComponent( const KeywordDescription = getComponent("JSONSchema202012KeywordDescription")
"JSONSchema202012KeywordDescription",
true
)
const KeywordDefault = getComponent("JSONSchema202012KeywordDefault") const KeywordDefault = getComponent("JSONSchema202012KeywordDefault")
const KeywordDeprecated = getComponent("JSONSchema202012KeywordDeprecated") const KeywordDeprecated = getComponent("JSONSchema202012KeywordDeprecated")
const KeywordReadOnly = getComponent("JSONSchema202012KeywordReadOnly") const KeywordReadOnly = getComponent("JSONSchema202012KeywordReadOnly")
@@ -130,6 +129,7 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
}, },
fn: { fn: {
upperFirst: fn.upperFirst, upperFirst: fn.upperFirst,
isExpandable: makeIsExpandable(fn.jsonSchema202012.isExpandable, system),
}, },
}) })