feat(oas31): add support for Schema Object externalDocs keyword (#8659)

Refs #8513
This commit is contained in:
Vladimír Gorej
2023-05-11 17:50:17 +02:00
committed by GitHub
parent 11bb4f9b30
commit 01d2376b5f
6 changed files with 129 additions and 13 deletions

View File

@@ -53,6 +53,7 @@ import { selectLicenseUrl as selectOAS31LicenseUrl } from "./selectors"
import JSONSchema202012KeywordExample from "./json-schema-2020-12-extensions/components/keywords/Example" import JSONSchema202012KeywordExample from "./json-schema-2020-12-extensions/components/keywords/Example"
import JSONSchema202012KeywordXml from "./json-schema-2020-12-extensions/components/keywords/Xml" import JSONSchema202012KeywordXml from "./json-schema-2020-12-extensions/components/keywords/Xml"
import JSONSchema202012KeywordDiscriminator from "./json-schema-2020-12-extensions/components/keywords/Discriminator/Discriminator" import JSONSchema202012KeywordDiscriminator from "./json-schema-2020-12-extensions/components/keywords/Discriminator/Discriminator"
import JSONSchema202012KeywordExternalDocs from "./json-schema-2020-12-extensions/components/keywords/ExternalDocs"
import JSONSchema202012KeywordDescriptionWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Description" import JSONSchema202012KeywordDescriptionWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Description"
import JSONSchema202012KeywordDefaultWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Default" import JSONSchema202012KeywordDefaultWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Default"
import { makeIsExpandable } from "./json-schema-2020-12-extensions/fn" import { makeIsExpandable } from "./json-schema-2020-12-extensions/fn"
@@ -88,6 +89,7 @@ const OAS31Plugin = ({ getSystem }) => {
JSONSchema202012KeywordExample, JSONSchema202012KeywordExample,
JSONSchema202012KeywordXml, JSONSchema202012KeywordXml,
JSONSchema202012KeywordDiscriminator, JSONSchema202012KeywordDiscriminator,
JSONSchema202012KeywordExternalDocs,
}, },
wrapComponents: { wrapComponents: {
InfoContainer: InfoWrapper, InfoContainer: InfoWrapper,

View File

@@ -52,6 +52,9 @@ const Discriminator = ({ schema, getSystem }) => {
{discriminator.propertyName} {discriminator.propertyName}
</span> </span>
)} )}
<strong className="json-schema-2020-12__attribute json-schema-2020-12__attribute--primary">
object
</strong>
<ul <ul
className={classNames("json-schema-2020-12-keyword__children", { className={classNames("json-schema-2020-12-keyword__children", {
"json-schema-2020-12-keyword__children--collapsed": !expanded, "json-schema-2020-12-keyword__children--collapsed": !expanded,

View File

@@ -0,0 +1,101 @@
/**
* @prettier
*/
import React, { useCallback, useState } from "react"
import PropTypes from "prop-types"
import classNames from "classnames"
import { sanitizeUrl } from "core/utils"
const ExternalDocs = ({ schema, getSystem }) => {
const externalDocs = schema?.externalDocs || {}
const { fn, getComponent } = getSystem()
const { useIsExpandedDeeply, useComponent } = fn.jsonSchema202012
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const [expandedDeeply, setExpandedDeeply] = useState(false)
const Accordion = useComponent("Accordion")
const ExpandDeepButton = useComponent("ExpandDeepButton")
const KeywordDescription = getComponent("JSONSchema202012KeywordDescription")
const Link = getComponent("Link")
const JSONSchemaDeepExpansionContext = getComponent(
"JSONSchema202012DeepExpansionContext"
)()
/**
* Event handlers.
*/
const handleExpansion = useCallback(() => {
setExpanded((prev) => !prev)
}, [])
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
setExpanded(expandedDeepNew)
setExpandedDeeply(expandedDeepNew)
}, [])
/**
* Rendering.
*/
if (Object.keys(externalDocs).length === 0) {
return null
}
return (
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--externalDocs">
<Accordion expanded={expanded} onChange={handleExpansion}>
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
External documentation
</span>
</Accordion>
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
<strong className="json-schema-2020-12__attribute json-schema-2020-12__attribute--primary">
object
</strong>
<ul
className={classNames("json-schema-2020-12-keyword__children", {
"json-schema-2020-12-keyword__children--collapsed": !expanded,
})}
>
{expanded && (
<>
{externalDocs.description && (
<li className="json-schema-2020-12-property">
<KeywordDescription
schema={externalDocs}
getSystem={getSystem}
/>
</li>
)}
{externalDocs.url && (
<li className="json-schema-2020-12-property">
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword">
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
url
</span>
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
<Link
target="_blank"
href={sanitizeUrl(externalDocs.url)}
>
{externalDocs.url}
</Link>
</span>
</div>
</li>
)}
</>
)}
</ul>
</div>
</JSONSchemaDeepExpansionContext.Provider>
)
}
ExternalDocs.propTypes = {
schema: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
getSystem: PropTypes.func.isRequired,
}
export default ExternalDocs

View File

@@ -65,8 +65,8 @@ const Xml = ({ schema, getSystem }) => {
> >
{expanded && ( {expanded && (
<> <>
<li className="json-schema-2020-12-property"> {xml.name && (
{xml.name && ( <li className="json-schema-2020-12-property">
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword"> <div className="json-schema-2020-12-keyword json-schema-2020-12-keyword">
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary"> <span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
name name
@@ -75,10 +75,11 @@ const Xml = ({ schema, getSystem }) => {
{xml.name} {xml.name}
</span> </span>
</div> </div>
)} </li>
</li> )}
<li className="json-schema-2020-12-property">
{xml.namespace && ( {xml.namespace && (
<li className="json-schema-2020-12-property">
<div className="json-schema-2020-12-keyword"> <div className="json-schema-2020-12-keyword">
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary"> <span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
namespace namespace
@@ -87,10 +88,11 @@ const Xml = ({ schema, getSystem }) => {
{xml.namespace} {xml.namespace}
</span> </span>
</div> </div>
)} </li>
</li> )}
<li className="json-schema-2020-12-property">
{xml.prefix && ( {xml.prefix && (
<li className="json-schema-2020-12-property">
<div className="json-schema-2020-12-keyword"> <div className="json-schema-2020-12-keyword">
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary"> <span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
prefix prefix
@@ -99,8 +101,8 @@ const Xml = ({ schema, getSystem }) => {
{xml.prefix} {xml.prefix}
</span> </span>
</div> </div>
)} </li>
</li> )}
</> </>
)} )}
</ul> </ul>

View File

@@ -9,5 +9,9 @@ export const makeIsExpandable = (original, { fn }) => {
const { hasKeyword } = fn.jsonSchema202012 const { hasKeyword } = fn.jsonSchema202012
return (schema) => return (schema) =>
original(schema) || hasKeyword(schema, "example") || schema?.xml original(schema) ||
hasKeyword(schema, "example") ||
schema?.xml ||
schema?.discriminator ||
schema?.externalDocs
} }

View File

@@ -12,12 +12,16 @@ const DefaultWrapper = createOnlyOAS31ComponentWrapper(
) )
const KeywordXml = getComponent("JSONSchema202012KeywordXml") const KeywordXml = getComponent("JSONSchema202012KeywordXml")
const KeywordExample = getComponent("JSONSchema202012KeywordExample") const KeywordExample = getComponent("JSONSchema202012KeywordExample")
const KeywordExternalDocs = getComponent(
"JSONSchema202012KeywordExternalDocs"
)
return ( return (
<> <>
<KeywordDefault schema={schema} /> <KeywordDefault schema={schema} />
<KeywordDiscriminator schema={schema} getSystem={getSystem} /> <KeywordDiscriminator schema={schema} getSystem={getSystem} />
<KeywordXml schema={schema} getSystem={getSystem} /> <KeywordXml schema={schema} getSystem={getSystem} />
<KeywordExternalDocs schema={schema} getSystem={getSystem} />
<KeywordExample schema={schema} getSystem={getSystem} /> <KeywordExample schema={schema} getSystem={getSystem} />
</> </>
) )