From 6e7759c0c99cbbf58e59a082fe5164f6ec15ec75 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Thu, 11 May 2023 16:19:26 +0200 Subject: [PATCH] feat(oas31): add support for Schema Object xml keyword Refs #8513 --- src/core/plugins/json-schema-2020-12/index.js | 6 +- src/core/plugins/oas31/index.js | 2 + .../components/keywords/Example.jsx | 9 +- .../components/keywords/Xml.jsx | 120 ++++++++++++++++++ .../json-schema-2020-12-extensions/fn.js | 3 +- .../wrap-components/keywords/Default.jsx | 4 +- 6 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 src/core/plugins/oas31/json-schema-2020-12-extensions/components/keywords/Xml.jsx diff --git a/src/core/plugins/json-schema-2020-12/index.js b/src/core/plugins/json-schema-2020-12/index.js index 3392b90df60..fc4f86092ac 100644 --- a/src/core/plugins/json-schema-2020-12/index.js +++ b/src/core/plugins/json-schema-2020-12/index.js @@ -44,7 +44,8 @@ import Accordion from "./components/Accordion/Accordion" import ExpandDeepButton from "./components/ExpandDeepButton/ExpandDeepButton" import ChevronRightIcon from "./components/icons/ChevronRight" import { upperFirst, hasKeyword, isExpandable } from "./fn" -import { useFn } from "./hooks" +import { JSONSchemaDeepExpansionContext } from "./context" +import { useFn, useComponent, useIsExpandedDeeply } from "./hooks" import { withJSONSchemaContext } from "./hoc" const JSONSchema202012Plugin = () => ({ @@ -92,6 +93,7 @@ const JSONSchema202012Plugin = () => ({ JSONSchema202012ExpandDeepButton: ExpandDeepButton, JSONSchema202012ChevronRightIcon: ChevronRightIcon, withJSONSchema202012Context: withJSONSchemaContext, + JSONSchema202012DeepExpansionContext: () => JSONSchemaDeepExpansionContext, }, fn: { upperFirst, @@ -99,6 +101,8 @@ const JSONSchema202012Plugin = () => ({ isExpandable, hasKeyword, useFn, + useComponent, + useIsExpandedDeeply, }, }, }) diff --git a/src/core/plugins/oas31/index.js b/src/core/plugins/oas31/index.js index b98610c1576..90c10d6a631 100644 --- a/src/core/plugins/oas31/index.js +++ b/src/core/plugins/oas31/index.js @@ -51,6 +51,7 @@ import { } from "./spec-extensions/wrap-selectors" import { selectLicenseUrl as selectOAS31LicenseUrl } from "./selectors" import JSONSchema202012KeywordExample from "./json-schema-2020-12-extensions/components/keywords/Example" +import JSONSchema202012KeywordXml from "./json-schema-2020-12-extensions/components/keywords/Xml" 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 { makeIsExpandable } from "./json-schema-2020-12-extensions/fn" @@ -84,6 +85,7 @@ const OAS31Plugin = ({ getSystem }) => { OAS31VersionPragmaFilter: VersionPragmaFilter, OAS31Models: Models, JSONSchema202012KeywordExample, + JSONSchema202012KeywordXml, }, wrapComponents: { InfoContainer: InfoWrapper, diff --git a/src/core/plugins/oas31/json-schema-2020-12-extensions/components/keywords/Example.jsx b/src/core/plugins/oas31/json-schema-2020-12-extensions/components/keywords/Example.jsx index bb5ff8c5824..44c1f5a18e3 100644 --- a/src/core/plugins/oas31/json-schema-2020-12-extensions/components/keywords/Example.jsx +++ b/src/core/plugins/oas31/json-schema-2020-12-extensions/components/keywords/Example.jsx @@ -4,7 +4,8 @@ import React from "react" import PropTypes from "prop-types" -const Example = ({ schema, fn }) => { +const Example = ({ schema, getSystem }) => { + const { fn } = getSystem() const { hasKeyword, stringify } = fn.jsonSchema202012.useFn() if (!hasKeyword(schema, "example")) return null @@ -23,11 +24,7 @@ const Example = ({ schema, fn }) => { Example.propTypes = { schema: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]), - fn: PropTypes.shape({ - jsonSchema202012: PropTypes.shape({ - useFn: PropTypes.func.isRequired, - }).isRequired, - }).isRequired, + getSystem: PropTypes.func.isRequired, } export default Example diff --git a/src/core/plugins/oas31/json-schema-2020-12-extensions/components/keywords/Xml.jsx b/src/core/plugins/oas31/json-schema-2020-12-extensions/components/keywords/Xml.jsx new file mode 100644 index 00000000000..b7398489e0f --- /dev/null +++ b/src/core/plugins/oas31/json-schema-2020-12-extensions/components/keywords/Xml.jsx @@ -0,0 +1,120 @@ +/** + * @prettier + */ +import React, { useCallback, useState } from "react" +import PropTypes from "prop-types" +import classNames from "classnames" + +const Xml = ({ schema, getSystem }) => { + const xml = schema?.xml || {} + 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(xml).length === 0) { + return null + } + + return ( + +
+ + + XML + + + + {xml.attribute === true && ( + + attribute + + )} + {xml.wrapped === true && ( + + wrapped + + )} + + object + +
    + {expanded && ( + <> +
  • + {xml.name && ( +
    + + name + + + {xml.name} + +
    + )} + + {xml.namespace && ( +
    + + namespace + + + {xml.namespace} + +
    + )} + + {xml.prefix && ( +
    + + prefix + + + {xml.prefix} + +
    + )} +
  • + + )} +
+
+
+ ) +} + +Xml.propTypes = { + schema: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]), + fn: PropTypes.shape({ + jsonSchema202012: PropTypes.shape({ + useIsExpandedDeeply: PropTypes.func.isRequired, + useComponent: PropTypes.func.isRequired, + }).isRequired, + }).isRequired, +} + +export default Xml diff --git a/src/core/plugins/oas31/json-schema-2020-12-extensions/fn.js b/src/core/plugins/oas31/json-schema-2020-12-extensions/fn.js index a86fdfd3ae3..3693ada2f59 100644 --- a/src/core/plugins/oas31/json-schema-2020-12-extensions/fn.js +++ b/src/core/plugins/oas31/json-schema-2020-12-extensions/fn.js @@ -8,5 +8,6 @@ export const makeIsExpandable = (original, { fn }) => { const { hasKeyword } = fn.jsonSchema202012 - return (schema) => original(schema) || hasKeyword(schema, "example") + return (schema) => + original(schema) || hasKeyword(schema, "example") || schema?.xml } diff --git a/src/core/plugins/oas31/json-schema-2020-12-extensions/wrap-components/keywords/Default.jsx b/src/core/plugins/oas31/json-schema-2020-12-extensions/wrap-components/keywords/Default.jsx index bd3e3a23b24..1b7feda0f38 100644 --- a/src/core/plugins/oas31/json-schema-2020-12-extensions/wrap-components/keywords/Default.jsx +++ b/src/core/plugins/oas31/json-schema-2020-12-extensions/wrap-components/keywords/Default.jsx @@ -8,11 +8,13 @@ const DefaultWrapper = createOnlyOAS31ComponentWrapper( ({ schema, getSystem, originalComponent: KeywordDefault }) => { const { getComponent, fn } = getSystem() const KeywordExample = getComponent("JSONSchema202012KeywordExample") + const KeywordXml = getComponent("JSONSchema202012KeywordXml") return ( <> - + + ) }