feat(oas31): add support for Schema Object discriminator keyword (#8658)
Refs #8513
This commit is contained in:
@@ -52,6 +52,7 @@ import {
|
|||||||
import { selectLicenseUrl as selectOAS31LicenseUrl } from "./selectors"
|
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 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"
|
||||||
@@ -86,6 +87,7 @@ const OAS31Plugin = ({ getSystem }) => {
|
|||||||
OAS31Models: Models,
|
OAS31Models: Models,
|
||||||
JSONSchema202012KeywordExample,
|
JSONSchema202012KeywordExample,
|
||||||
JSONSchema202012KeywordXml,
|
JSONSchema202012KeywordXml,
|
||||||
|
JSONSchema202012KeywordDiscriminator,
|
||||||
},
|
},
|
||||||
wrapComponents: {
|
wrapComponents: {
|
||||||
InfoContainer: InfoWrapper,
|
InfoContainer: InfoWrapper,
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import React, { useCallback, useState } from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
import classNames from "classnames"
|
||||||
|
|
||||||
|
import DiscriminatorMapping from "./DiscriminatorMapping"
|
||||||
|
|
||||||
|
const Discriminator = ({ schema, getSystem }) => {
|
||||||
|
const discriminator = schema?.discriminator || {}
|
||||||
|
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 JSONSchemaDeepExpansionContext = getComponent(
|
||||||
|
"JSONSchema202012DeepExpansionContext"
|
||||||
|
)()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handlers.
|
||||||
|
*/
|
||||||
|
const handleExpansion = useCallback(() => {
|
||||||
|
setExpanded((prev) => !prev)
|
||||||
|
}, [])
|
||||||
|
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||||
|
setExpanded(expandedDeepNew)
|
||||||
|
setExpandedDeeply(expandedDeepNew)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rendering.
|
||||||
|
*/
|
||||||
|
if (Object.keys(discriminator).length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||||
|
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--discriminator">
|
||||||
|
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||||
|
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||||
|
Discriminator
|
||||||
|
</span>
|
||||||
|
</Accordion>
|
||||||
|
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
|
||||||
|
{discriminator.propertyName && (
|
||||||
|
<span className="json-schema-2020-12__attribute json-schema-2020-12__attribute--muted">
|
||||||
|
{discriminator.propertyName}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<ul
|
||||||
|
className={classNames("json-schema-2020-12-keyword__children", {
|
||||||
|
"json-schema-2020-12-keyword__children--collapsed": !expanded,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{expanded && (
|
||||||
|
<li className="json-schema-2020-12-property">
|
||||||
|
<DiscriminatorMapping discriminator={discriminator} />
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</JSONSchemaDeepExpansionContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Discriminator.propTypes = {
|
||||||
|
schema: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
|
||||||
|
getSystem: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Discriminator
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import React from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
|
const DiscriminatorMapping = ({ discriminator }) => {
|
||||||
|
const mapping = discriminator?.mapping || {}
|
||||||
|
|
||||||
|
if (Object.keys(mapping).length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.entries(mapping).map(([key, value]) => (
|
||||||
|
<div key={`${key}-${value}`} className="json-schema-2020-12-keyword">
|
||||||
|
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||||
|
{key}
|
||||||
|
</span>
|
||||||
|
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||||
|
{value}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscriminatorMapping.propTypes = {
|
||||||
|
discriminator: PropTypes.shape({
|
||||||
|
mapping: PropTypes.any,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscriminatorMapping.defaultProps = {
|
||||||
|
mapping: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DiscriminatorMapping
|
||||||
@@ -12,7 +12,7 @@ const Example = ({ schema, getSystem }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--example">
|
<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">
|
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||||
Example
|
Example
|
||||||
</span>
|
</span>
|
||||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const">
|
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const">
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ const Xml = ({ schema, getSystem }) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</li>
|
||||||
|
<li className="json-schema-2020-12-property">
|
||||||
{xml.namespace && (
|
{xml.namespace && (
|
||||||
<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">
|
||||||
@@ -87,7 +88,8 @@ const Xml = ({ schema, getSystem }) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</li>
|
||||||
|
<li className="json-schema-2020-12-property">
|
||||||
{xml.prefix && (
|
{xml.prefix && (
|
||||||
<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">
|
||||||
|
|||||||
@@ -7,14 +7,18 @@ import { createOnlyOAS31ComponentWrapper } from "../../../fn"
|
|||||||
const DefaultWrapper = createOnlyOAS31ComponentWrapper(
|
const DefaultWrapper = createOnlyOAS31ComponentWrapper(
|
||||||
({ schema, getSystem, originalComponent: KeywordDefault }) => {
|
({ schema, getSystem, originalComponent: KeywordDefault }) => {
|
||||||
const { getComponent } = getSystem()
|
const { getComponent } = getSystem()
|
||||||
const KeywordExample = getComponent("JSONSchema202012KeywordExample")
|
const KeywordDiscriminator = getComponent(
|
||||||
|
"JSONSchema202012KeywordDiscriminator"
|
||||||
|
)
|
||||||
const KeywordXml = getComponent("JSONSchema202012KeywordXml")
|
const KeywordXml = getComponent("JSONSchema202012KeywordXml")
|
||||||
|
const KeywordExample = getComponent("JSONSchema202012KeywordExample")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<KeywordDefault schema={schema} />
|
<KeywordDefault schema={schema} />
|
||||||
<KeywordExample schema={schema} getSystem={getSystem} />
|
<KeywordDiscriminator schema={schema} getSystem={getSystem} />
|
||||||
<KeywordXml schema={schema} getSystem={getSystem} />
|
<KeywordXml schema={schema} getSystem={getSystem} />
|
||||||
|
<KeywordExample schema={schema} getSystem={getSystem} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user