feat: apply cumulative update to address various issues (#10324)
This commit is contained in:
@@ -5,9 +5,7 @@ import { btoa, buildFormData } from "core/utils"
|
||||
export const SHOW_AUTH_POPUP = "show_popup"
|
||||
export const AUTHORIZE = "authorize"
|
||||
export const LOGOUT = "logout"
|
||||
export const PRE_AUTHORIZE_OAUTH2 = "pre_authorize_oauth2"
|
||||
export const AUTHORIZE_OAUTH2 = "authorize_oauth2"
|
||||
export const VALIDATE = "validate"
|
||||
export const CONFIGURE_AUTH = "configure_auth"
|
||||
export const RESTORE_AUTHORIZATION = "restore_authorization"
|
||||
|
||||
|
||||
@@ -26,7 +26,15 @@ export const definitionsToAuthorize = createSelector(
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
export const selectAuthPath =
|
||||
(state, name) =>
|
||||
({ specSelectors }) =>
|
||||
List(
|
||||
specSelectors.isOAS3()
|
||||
? ["components", "securitySchemes", name]
|
||||
: ["securityDefinitions", name]
|
||||
)
|
||||
|
||||
export const getDefinitionsByNames = ( state, securities ) => ( { specSelectors } ) => {
|
||||
console.warn("WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.")
|
||||
let securityDefinitions = specSelectors.securityDefinitions()
|
||||
|
||||
@@ -10,15 +10,15 @@ import LockIcon from "./components/lock"
|
||||
import UnlockIcon from "./components/unlock"
|
||||
|
||||
const IconsPlugin = () => ({
|
||||
components: {
|
||||
ArrowUpIcon,
|
||||
ArrowDownIcon,
|
||||
ArrowIcon,
|
||||
CloseIcon,
|
||||
CopyIcon,
|
||||
LockIcon,
|
||||
UnlockIcon,
|
||||
}
|
||||
components: {
|
||||
ArrowUpIcon,
|
||||
ArrowDownIcon,
|
||||
ArrowIcon,
|
||||
CloseIcon,
|
||||
CopyIcon,
|
||||
LockIcon,
|
||||
UnlockIcon,
|
||||
},
|
||||
})
|
||||
|
||||
export default IconsPlugin
|
||||
export default IconsPlugin
|
||||
|
||||
@@ -13,3 +13,4 @@ export { default as encoderAPI } from "./api/encoderAPI"
|
||||
export { default as formatAPI } from "./api/formatAPI"
|
||||
export { default as mediaTypeAPI } from "./api/mediaTypeAPI"
|
||||
export { default as mergeJsonSchema } from "./core/merge"
|
||||
export { foldType } from "./core/type"
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
mediaTypeAPI,
|
||||
formatAPI,
|
||||
mergeJsonSchema,
|
||||
foldType,
|
||||
} from "./fn/index"
|
||||
import makeGetJsonSampleSchema from "./fn/get-json-sample-schema"
|
||||
import makeGetYamlSampleSchema from "./fn/get-yaml-sample-schema"
|
||||
@@ -41,6 +42,7 @@ const JSONSchema202012SamplesPlugin = ({ getSystem }) => {
|
||||
getXmlSampleSchema,
|
||||
getSampleSchema,
|
||||
mergeJsonSchema,
|
||||
foldType,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
vertical-align: bottom;
|
||||
|
||||
&--expanded {
|
||||
transition: transform .15s ease-in;
|
||||
transition: transform 0.15s ease-in;
|
||||
transform: rotate(-90deg);
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
&--collapsed {
|
||||
transition: transform .15s ease-in;
|
||||
transition: transform 0.15s ease-in;
|
||||
transform: rotate(0deg);
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
@@ -31,4 +31,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
@use "./../../../../../style/variables" as *;
|
||||
@use "./../../../../../style/type";
|
||||
|
||||
.json-schema-2020-12-expand-deep-button {
|
||||
@include text_headline($section-models-model-title-font-color);
|
||||
@include type.text_headline($section-models-model-title-font-color);
|
||||
font-size: 12px;
|
||||
color: rgb(175, 174, 174);
|
||||
border: none;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { forwardRef, useState, useCallback, useEffect } from "react"
|
||||
import React, { forwardRef, useCallback } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import classNames from "classnames"
|
||||
|
||||
@@ -12,23 +12,32 @@ import {
|
||||
useFn,
|
||||
useIsEmbedded,
|
||||
useIsExpanded,
|
||||
useIsExpandedDeeply,
|
||||
useIsCircular,
|
||||
useRenderedSchemas,
|
||||
usePath,
|
||||
} from "../../hooks"
|
||||
import {
|
||||
JSONSchemaLevelContext,
|
||||
JSONSchemaDeepExpansionContext,
|
||||
JSONSchemaCyclesContext,
|
||||
JSONSchemaPathContext,
|
||||
} from "../../context"
|
||||
|
||||
const JSONSchema = forwardRef(
|
||||
({ schema, name = "", dependentRequired = [], onExpand = () => {} }, ref) => {
|
||||
(
|
||||
{
|
||||
schema,
|
||||
name = "",
|
||||
dependentRequired = [],
|
||||
onExpand = () => {},
|
||||
identifier = "",
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const fn = useFn()
|
||||
const isExpanded = useIsExpanded()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpanded || isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(isExpandedDeeply)
|
||||
// this implementation assumes that $id is always non-relative URI
|
||||
const pathToken = identifier || schema.$id || name
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const isEmbedded = useIsEmbedded()
|
||||
const isExpandable = fn.isExpandable(schema) || dependentRequired.length > 0
|
||||
@@ -78,42 +87,39 @@ const JSONSchema = forwardRef(
|
||||
const KeywordDeprecated = useComponent("KeywordDeprecated")
|
||||
const KeywordReadOnly = useComponent("KeywordReadOnly")
|
||||
const KeywordWriteOnly = useComponent("KeywordWriteOnly")
|
||||
const KeywordExamples = useComponent("KeywordExamples")
|
||||
const ExtensionKeywords = useComponent("ExtensionKeywords")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
|
||||
/**
|
||||
* Effects handlers.
|
||||
*/
|
||||
useEffect(() => {
|
||||
setExpandedDeeply(isExpandedDeeply)
|
||||
}, [isExpandedDeeply])
|
||||
|
||||
useEffect(() => {
|
||||
setExpandedDeeply(expandedDeeply)
|
||||
}, [expandedDeeply])
|
||||
|
||||
/**
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(
|
||||
(e, expandedNew) => {
|
||||
setExpanded(expandedNew)
|
||||
!expandedNew && setExpandedDeeply(false)
|
||||
if (expandedNew) {
|
||||
setExpanded()
|
||||
} else {
|
||||
setCollapsed()
|
||||
}
|
||||
onExpand(e, expandedNew, false)
|
||||
},
|
||||
[onExpand]
|
||||
[onExpand, setExpanded, setCollapsed]
|
||||
)
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
onExpand(e, expandedDeepNew, true)
|
||||
},
|
||||
[onExpand]
|
||||
[onExpand, setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
return (
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<JSONSchemaCyclesContext.Provider value={renderedSchemas}>
|
||||
<article
|
||||
ref={ref}
|
||||
@@ -126,11 +132,11 @@ const JSONSchema = forwardRef(
|
||||
<div className="json-schema-2020-12-head">
|
||||
{isExpandable && !isCircular ? (
|
||||
<>
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<KeywordTitle title={name} schema={schema} />
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={expanded}
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
</>
|
||||
@@ -151,10 +157,10 @@ const JSONSchema = forwardRef(
|
||||
</div>
|
||||
<div
|
||||
className={classNames("json-schema-2020-12-body", {
|
||||
"json-schema-2020-12-body--collapsed": !expanded,
|
||||
"json-schema-2020-12-body--collapsed": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{expanded && (
|
||||
{isExpanded && (
|
||||
<>
|
||||
<KeywordDescription schema={schema} />
|
||||
{!isCircular && isExpandable && (
|
||||
@@ -186,6 +192,7 @@ const JSONSchema = forwardRef(
|
||||
dependentRequired={dependentRequired}
|
||||
/>
|
||||
<KeywordDefault schema={schema} />
|
||||
<KeywordExamples schema={schema} />
|
||||
<Keyword$schema schema={schema} />
|
||||
<Keyword$vocabulary schema={schema} />
|
||||
<Keyword$id schema={schema} />
|
||||
@@ -197,13 +204,14 @@ const JSONSchema = forwardRef(
|
||||
)}
|
||||
<Keyword$dynamicRef schema={schema} />
|
||||
<Keyword$comment schema={schema} />
|
||||
<ExtensionKeywords schema={schema} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</article>
|
||||
</JSONSchemaCyclesContext.Provider>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -213,6 +221,7 @@ JSONSchema.propTypes = {
|
||||
schema: propTypes.schema.isRequired,
|
||||
dependentRequired: PropTypes.arrayOf(PropTypes.string),
|
||||
onExpand: PropTypes.func,
|
||||
identifier: PropTypes.string,
|
||||
}
|
||||
|
||||
export default JSONSchema
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
@use "./../../../../../style/variables" as *;
|
||||
@use "./../../components/mixins";
|
||||
|
||||
.json-schema-2020-12 {
|
||||
margin: 0 20px 15px 20px;
|
||||
border-radius: 4px;
|
||||
padding: 12px 0 12px 20px;
|
||||
background-color: rgba($section-models-model-container-background-color, .05);
|
||||
background-color: rgba(
|
||||
$section-models-model-container-background-color,
|
||||
0.05
|
||||
);
|
||||
|
||||
&:first-of-type {
|
||||
margin: 20px;
|
||||
@@ -18,7 +24,7 @@
|
||||
}
|
||||
|
||||
&-body {
|
||||
@include expansion-border;
|
||||
@include mixins.expansion-border;
|
||||
margin: 2px 0;
|
||||
|
||||
&--collapsed {
|
||||
@@ -26,5 +32,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import classNames from "classnames"
|
||||
|
||||
import {
|
||||
useComponent,
|
||||
useIsExpanded,
|
||||
useFn,
|
||||
usePath,
|
||||
useLevel,
|
||||
} from "../../hooks"
|
||||
import { JSONSchemaLevelContext, JSONSchemaPathContext } from "../../context"
|
||||
import { isEmptyObject, isEmptyArray } from "../../fn"
|
||||
|
||||
const JSONViewer = ({ name, value, className }) => {
|
||||
const fn = useFn()
|
||||
const { path } = usePath(name)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(name)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const isPrimitive =
|
||||
typeof value === "string" ||
|
||||
typeof value === "number" ||
|
||||
typeof value === "bigint" ||
|
||||
typeof value === "boolean" ||
|
||||
typeof value === "symbol" ||
|
||||
value == null
|
||||
const isEmpty = isEmptyObject(value) || isEmptyArray(value)
|
||||
|
||||
/**
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
*/
|
||||
if (isPrimitive) {
|
||||
return (
|
||||
<div className={classNames("json-schema-2020-12-json-viewer", className)}>
|
||||
<span className="json-schema-2020-12-json-viewer__name json-schema-2020-12-json-viewer__name--secondary">
|
||||
{name}
|
||||
</span>
|
||||
<span className="json-schema-2020-12-json-viewer__value json-schema-2020-12-json-viewer__value--secondary">
|
||||
{fn.stringify(value)}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (isEmpty) {
|
||||
return (
|
||||
<div className={classNames("json-schema-2020-12-json-viewer", className)}>
|
||||
<span className="json-schema-2020-12-json-viewer__name json-schema-2020-12-json-viewer__name--secondary">
|
||||
{name}
|
||||
</span>
|
||||
<strong className="json-schema-2020-12__attribute json-schema-2020-12__attribute--primary">
|
||||
{Array.isArray(value) ? "empty array" : "empty object"}
|
||||
</strong>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className={classNames("json-schema-2020-12-json-viewer", className)}
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-json-viewer__name json-schema-2020-12-json-viewer__name--secondary">
|
||||
{name}
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
<strong className="json-schema-2020-12__attribute json-schema-2020-12__attribute--primary">
|
||||
{Array.isArray(value) ? "array" : "object"}
|
||||
</strong>
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-json-viewer__children", {
|
||||
"json-schema-2020-12-json-viewer__children--collapsed":
|
||||
!isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{Array.isArray(value)
|
||||
? value.map((item, index) => (
|
||||
<li
|
||||
key={`#${index}`}
|
||||
className="json-schema-2020-12-property"
|
||||
>
|
||||
<JSONViewer
|
||||
name={`#${index}`}
|
||||
value={item}
|
||||
className={className}
|
||||
/>
|
||||
</li>
|
||||
))
|
||||
: Object.entries(value).map(
|
||||
([propertyName, propertyValue]) => (
|
||||
<li
|
||||
key={propertyName}
|
||||
className="json-schema-2020-12-property"
|
||||
>
|
||||
<JSONViewer
|
||||
name={propertyName}
|
||||
value={propertyValue}
|
||||
className={className}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
JSONViewer.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.any.isRequired,
|
||||
className: PropTypes.string,
|
||||
}
|
||||
|
||||
export default JSONViewer
|
||||
@@ -0,0 +1,11 @@
|
||||
@use "./../mixins";
|
||||
@use "./../keywords/all";
|
||||
|
||||
.json-schema-2020-12-json-viewer {
|
||||
@include mixins.json-schema-2020-12-keyword;
|
||||
}
|
||||
|
||||
.json-schema-2020-12-json-viewer__name--secondary
|
||||
+ .json-schema-2020-12-json-viewer__value--secondary::before {
|
||||
content: "=";
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
@mixin expansion-border {
|
||||
margin: 0 0 0 20px;
|
||||
border-left: 1px dashed rgba($section-models-model-container-background-color, 0.1);
|
||||
}
|
||||
|
||||
@import './JSONSchema/json-schema';
|
||||
@import './Accordion/accordion';
|
||||
@import './ExpandDeepButton/expand-deep-button';
|
||||
@import './keywords/all';
|
||||
@use "./JSONViewer/json-viewer";
|
||||
@use "./JSONSchema/json-schema";
|
||||
@use "./Accordion/accordion";
|
||||
@use "./ExpandDeepButton/expand-deep-button";
|
||||
|
||||
82
src/core/plugins/json-schema-2020-12/components/_mixins.scss
Normal file
82
src/core/plugins/json-schema-2020-12/components/_mixins.scss
Normal file
@@ -0,0 +1,82 @@
|
||||
@use "./../../../../style/variables" as *;
|
||||
@use "./../../../../style/type";
|
||||
|
||||
@mixin expansion-border {
|
||||
margin: 0 0 0 20px;
|
||||
border-left: 1px dashed
|
||||
rgba($section-models-model-container-background-color, 0.1);
|
||||
}
|
||||
|
||||
@mixin json-schema-2020-12-keyword--primary {
|
||||
color: $text-code-default-font-color;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@mixin json-schema-2020-12-keyword--extension {
|
||||
color: #929292;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@mixin json-schema-2020-12-keyword {
|
||||
margin: 5px 0 5px 0;
|
||||
|
||||
&__children {
|
||||
@include expansion-border;
|
||||
padding: 0;
|
||||
|
||||
&--collapsed {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 12px;
|
||||
margin-left: 20px;
|
||||
font-weight: bold;
|
||||
|
||||
&--primary {
|
||||
@include json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
color: #6b6b6b;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&--extension {
|
||||
@include json-schema-2020-12-keyword--extension;
|
||||
}
|
||||
}
|
||||
|
||||
&__value {
|
||||
color: #6b6b6b;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
|
||||
&--primary {
|
||||
@include json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
color: #6b6b6b;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&--extension {
|
||||
@include json-schema-2020-12-keyword--extension;
|
||||
}
|
||||
|
||||
&--warning {
|
||||
@include type.text_code();
|
||||
font-style: normal;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
line-height: 1.5;
|
||||
padding: 1px 4px 1px 4px;
|
||||
border-radius: 4px;
|
||||
color: red;
|
||||
border: 1px dashed red;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../prop-types"
|
||||
import { useComponent, useIsExpanded, useIsExpandedDeeply } from "../../hooks"
|
||||
import { JSONSchemaDeepExpansionContext } from "../../context"
|
||||
import { useComponent, useIsExpanded, usePath, useLevel } from "../../hooks"
|
||||
import { JSONSchemaLevelContext, JSONSchemaPathContext } from "../../context"
|
||||
|
||||
const $defs = ({ schema }) => {
|
||||
const $defs = schema?.$defs || {}
|
||||
const isExpanded = useIsExpanded()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpanded || isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const pathToken = "$defs"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
@@ -22,12 +22,22 @@ const $defs = ({ schema }) => {
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -37,34 +47,42 @@ const $defs = ({ schema }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--$defs">
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
$defs
|
||||
</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,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--$defs"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
<>
|
||||
{Object.entries($defs).map(([schemaName, schema]) => (
|
||||
<li key={schemaName} className="json-schema-2020-12-property">
|
||||
<JSONSchema name={schemaName} schema={schema} />
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
$defs
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
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": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{Object.entries($defs).map(([schemaName, schema]) => (
|
||||
<li key={schemaName} className="json-schema-2020-12-property">
|
||||
<JSONSchema name={schemaName} schema={schema} />
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../../prop-types"
|
||||
import {
|
||||
useComponent,
|
||||
useIsExpanded,
|
||||
useIsExpandedDeeply,
|
||||
} from "../../../hooks"
|
||||
import { useComponent, useIsExpanded, usePath } from "../../../hooks"
|
||||
import { JSONSchemaPathContext } from "../../../context"
|
||||
|
||||
const $vocabulary = ({ schema }) => {
|
||||
const isExpanded = useIsExpanded()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpanded || isExpandedDeeply)
|
||||
const pathToken = "$vocabulary"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const Accordion = useComponent("Accordion")
|
||||
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -28,31 +29,33 @@ const $vocabulary = ({ schema }) => {
|
||||
if (typeof schema.$vocabulary !== "object") return null
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--$vocabulary">
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
$vocabulary
|
||||
</span>
|
||||
</Accordion>
|
||||
<strong className="json-schema-2020-12__attribute json-schema-2020-12__attribute--primary">
|
||||
object
|
||||
</strong>
|
||||
<ul>
|
||||
{expanded &&
|
||||
Object.entries(schema.$vocabulary).map(([uri, enabled]) => (
|
||||
<li
|
||||
key={uri}
|
||||
className={classNames("json-schema-2020-12-$vocabulary-uri", {
|
||||
"json-schema-2020-12-$vocabulary-uri--disabled": !enabled,
|
||||
})}
|
||||
>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||
{uri}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--$vocabulary">
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
$vocabulary
|
||||
</span>
|
||||
</Accordion>
|
||||
<strong className="json-schema-2020-12__attribute json-schema-2020-12__attribute--primary">
|
||||
object
|
||||
</strong>
|
||||
<ul>
|
||||
{isExpanded &&
|
||||
Object.entries(schema.$vocabulary).map(([uri, enabled]) => (
|
||||
<li
|
||||
key={uri}
|
||||
className={classNames("json-schema-2020-12-$vocabulary-uri", {
|
||||
"json-schema-2020-12-$vocabulary-uri--disabled": !enabled,
|
||||
})}
|
||||
>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||
{uri}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
@use "./../../../components/mixins";
|
||||
|
||||
.json-schema-2020-12 {
|
||||
&-keyword--\$vocabulary {
|
||||
ul {
|
||||
@include expansion-border;
|
||||
@include mixins.expansion-border;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,11 @@ const AdditionalProperties = ({ schema }) => {
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<JSONSchema name={name} schema={additionalProperties} />
|
||||
<JSONSchema
|
||||
name={name}
|
||||
schema={additionalProperties}
|
||||
identifier="additionalProperties"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../prop-types"
|
||||
@@ -9,17 +9,18 @@ import {
|
||||
useFn,
|
||||
useComponent,
|
||||
useIsExpanded,
|
||||
useIsExpandedDeeply,
|
||||
usePath,
|
||||
useLevel,
|
||||
} from "../../hooks"
|
||||
import { JSONSchemaDeepExpansionContext } from "../../context"
|
||||
import { JSONSchemaLevelContext, JSONSchemaPathContext } from "../../context"
|
||||
|
||||
const AllOf = ({ schema }) => {
|
||||
const allOf = schema?.allOf || []
|
||||
const fn = useFn()
|
||||
const isExpanded = useIsExpanded()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpanded || isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const pathToken = "allOf"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
@@ -29,12 +30,22 @@ const AllOf = ({ schema }) => {
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -44,35 +55,46 @@ const AllOf = ({ schema }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--allOf">
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
All of
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
|
||||
<KeywordType schema={{ allOf }} />
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !expanded,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--allOf"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
<>
|
||||
{allOf.map((schema, index) => (
|
||||
<li key={`#${index}`} className="json-schema-2020-12-property">
|
||||
<JSONSchema
|
||||
name={`#${index} ${fn.getTitle(schema)}`}
|
||||
schema={schema}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
All of
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
<KeywordType schema={{ allOf }} />
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{allOf.map((schema, index) => (
|
||||
<li
|
||||
key={`#${index}`}
|
||||
className="json-schema-2020-12-property"
|
||||
>
|
||||
<JSONSchema
|
||||
name={`#${index} ${fn.getTitle(schema)}`}
|
||||
schema={schema}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../prop-types"
|
||||
@@ -9,17 +9,18 @@ import {
|
||||
useFn,
|
||||
useComponent,
|
||||
useIsExpanded,
|
||||
useIsExpandedDeeply,
|
||||
usePath,
|
||||
useLevel,
|
||||
} from "../../hooks"
|
||||
import { JSONSchemaDeepExpansionContext } from "../../context"
|
||||
import { JSONSchemaLevelContext, JSONSchemaPathContext } from "../../context"
|
||||
|
||||
const AnyOf = ({ schema }) => {
|
||||
const anyOf = schema?.anyOf || []
|
||||
const fn = useFn()
|
||||
const isExpanded = useIsExpanded()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpanded || isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const pathToken = "anyOf"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
@@ -29,12 +30,22 @@ const AnyOf = ({ schema }) => {
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -44,35 +55,46 @@ const AnyOf = ({ schema }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--anyOf">
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Any of
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
|
||||
<KeywordType schema={{ anyOf }} />
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !expanded,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--anyOf"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
<>
|
||||
{anyOf.map((schema, index) => (
|
||||
<li key={`#${index}`} className="json-schema-2020-12-property">
|
||||
<JSONSchema
|
||||
name={`#${index} ${fn.getTitle(schema)}`}
|
||||
schema={schema}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Any of
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
<KeywordType schema={{ anyOf }} />
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{anyOf.map((schema, index) => (
|
||||
<li
|
||||
key={`#${index}`}
|
||||
className="json-schema-2020-12-property"
|
||||
>
|
||||
<JSONSchema
|
||||
name={`#${index} ${fn.getTitle(schema)}`}
|
||||
schema={schema}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React from "react"
|
||||
|
||||
import { schema } from "../../prop-types"
|
||||
import { useFn } from "../../hooks"
|
||||
|
||||
const Const = ({ schema }) => {
|
||||
const fn = useFn()
|
||||
|
||||
if (!fn.hasKeyword(schema, "const")) return null
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--const">
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Const
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const">
|
||||
{fn.stringify(schema.const)}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Const.propTypes = {
|
||||
schema: schema.isRequired,
|
||||
}
|
||||
|
||||
export default Const
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React from "react"
|
||||
|
||||
import { schema } from "../../../prop-types"
|
||||
import { useComponent, useFn } from "../../../hooks"
|
||||
|
||||
const Const = ({ schema }) => {
|
||||
const fn = useFn()
|
||||
const JSONViewer = useComponent("JSONViewer")
|
||||
|
||||
if (!fn.hasKeyword(schema, "const")) return null
|
||||
|
||||
return (
|
||||
<JSONViewer
|
||||
name="Const"
|
||||
value={schema.const}
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--const"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Const.propTypes = {
|
||||
schema: schema.isRequired,
|
||||
}
|
||||
|
||||
export default Const
|
||||
@@ -0,0 +1,11 @@
|
||||
@use "./../../mixins";
|
||||
|
||||
.json-schema-2020-12-keyword--const {
|
||||
.json-schema-2020-12-json-viewer__name {
|
||||
@include mixins.json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
|
||||
.json-schema-2020-12-json-viewer__value {
|
||||
@include mixins.json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,16 @@
|
||||
@use "./../../../../../../style/type";
|
||||
|
||||
.json-schema-2020-12__constraint {
|
||||
@include text_code();
|
||||
@include type.text_code();
|
||||
margin-left: 10px;
|
||||
line-height: 1.5;
|
||||
padding: 1px 3px;
|
||||
color: white;
|
||||
background-color: #805AD5;
|
||||
background-color: #805ad5;
|
||||
border-radius: 4px;
|
||||
|
||||
&--string {
|
||||
color: white;
|
||||
background-color: #D69E2E;
|
||||
background-color: #d69e2e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const Contains = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--contains">
|
||||
<JSONSchema name={name} schema={schema.contains} />
|
||||
<JSONSchema name={name} schema={schema.contains} identifier="contains" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,11 @@ const ContentSchema = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--contentSchema">
|
||||
<JSONSchema name={name} schema={schema.contentSchema} />
|
||||
<JSONSchema
|
||||
name={name}
|
||||
schema={schema.contentSchema}
|
||||
identifier="contentSchema"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React from "react"
|
||||
|
||||
import { schema } from "../../prop-types"
|
||||
import { useFn } from "../../hooks"
|
||||
|
||||
const Default = ({ schema }) => {
|
||||
const fn = useFn()
|
||||
|
||||
if (!fn.hasKeyword(schema, "default")) return null
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--default">
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Default
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const">
|
||||
{fn.stringify(schema.default)}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Default.propTypes = {
|
||||
schema: schema.isRequired,
|
||||
}
|
||||
|
||||
export default Default
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React from "react"
|
||||
|
||||
import { schema } from "../../../prop-types"
|
||||
import { useComponent, useFn } from "../../../hooks"
|
||||
|
||||
const Default = ({ schema }) => {
|
||||
const fn = useFn()
|
||||
const JSONViewer = useComponent("JSONViewer")
|
||||
|
||||
if (!fn.hasKeyword(schema, "default")) return null
|
||||
|
||||
return (
|
||||
<JSONViewer
|
||||
name="Default"
|
||||
value={schema.default}
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--default"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Default.propTypes = {
|
||||
schema: schema.isRequired,
|
||||
}
|
||||
|
||||
export default Default
|
||||
@@ -0,0 +1,11 @@
|
||||
@use "./../../mixins";
|
||||
|
||||
.json-schema-2020-12-keyword--default {
|
||||
.json-schema-2020-12-json-viewer__name {
|
||||
@include mixins.json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
|
||||
.json-schema-2020-12-json-viewer__value {
|
||||
@include mixins.json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../prop-types"
|
||||
import { useComponent, useIsExpanded, useIsExpandedDeeply } from "../../hooks"
|
||||
import { JSONSchemaDeepExpansionContext } from "../../context"
|
||||
import { useComponent, useIsExpanded, useLevel, usePath } from "../../hooks"
|
||||
import { JSONSchemaLevelContext, JSONSchemaPathContext } from "../../context"
|
||||
|
||||
const DependentSchemas = ({ schema }) => {
|
||||
const dependentSchemas = schema?.dependentSchemas || []
|
||||
const isExpanded = useIsExpanded()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpanded || isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const pathToken = "dependentSchemas"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
@@ -22,12 +22,22 @@ const DependentSchemas = ({ schema }) => {
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -36,34 +46,47 @@ const DependentSchemas = ({ schema }) => {
|
||||
if (Object.keys(dependentSchemas).length === 0) return null
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--dependentSchemas">
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Dependent schemas
|
||||
</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,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--dependentSchemas"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
<>
|
||||
{Object.entries(dependentSchemas).map(([schemaName, schema]) => (
|
||||
<li key={schemaName} className="json-schema-2020-12-property">
|
||||
<JSONSchema name={schemaName} schema={schema} />
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Dependent schemas
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
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": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{Object.entries(dependentSchemas).map(
|
||||
([schemaName, schema]) => (
|
||||
<li
|
||||
key={schemaName}
|
||||
className="json-schema-2020-12-property"
|
||||
>
|
||||
<JSONSchema name={schemaName} schema={schema} />
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const Else = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--if">
|
||||
<JSONSchema name={name} schema={schema.else} />
|
||||
<JSONSchema name={name} schema={schema.else} identifier="else" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,32 +4,19 @@
|
||||
import React from "react"
|
||||
|
||||
import { schema } from "../../../prop-types"
|
||||
import { useFn } from "../../../hooks"
|
||||
import { useComponent } from "../../../hooks"
|
||||
|
||||
const Enum = ({ schema }) => {
|
||||
const fn = useFn()
|
||||
const JSONViewer = useComponent("JSONViewer")
|
||||
|
||||
if (!Array.isArray(schema?.enum)) return null
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--enum">
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Allowed values
|
||||
</span>
|
||||
<ul>
|
||||
{schema.enum.map((element) => {
|
||||
const strigifiedElement = fn.stringify(element)
|
||||
|
||||
return (
|
||||
<li key={strigifiedElement}>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const">
|
||||
{strigifiedElement}
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
<JSONViewer
|
||||
name="Enum"
|
||||
value={schema.enum}
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--enum"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
.json-schema-2020-12-keyword--enum {
|
||||
& > ul {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
@use "./../../mixins";
|
||||
|
||||
li {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
}
|
||||
.json-schema-2020-12-keyword--enum {
|
||||
.json-schema-2020-12-json-viewer__name {
|
||||
@include mixins.json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
|
||||
.json-schema-2020-12-json-viewer__value {
|
||||
@include mixins.json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React from "react"
|
||||
|
||||
import { schema } from "../../../prop-types"
|
||||
import { useComponent } from "../../../hooks"
|
||||
|
||||
const Examples = ({ schema }) => {
|
||||
const examples = schema?.examples || []
|
||||
const JSONViewer = useComponent("JSONViewer")
|
||||
|
||||
if (!Array.isArray(examples) || examples.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONViewer
|
||||
name="Examples"
|
||||
value={schema.examples}
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--examples"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Examples.propTypes = {
|
||||
schema: schema.isRequired,
|
||||
}
|
||||
|
||||
export default Examples
|
||||
@@ -0,0 +1,11 @@
|
||||
@use "./../../mixins";
|
||||
|
||||
.json-schema-2020-12-keyword--examples {
|
||||
.json-schema-2020-12-json-viewer__name {
|
||||
@include mixins.json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
|
||||
.json-schema-2020-12-json-viewer__value {
|
||||
@include mixins.json-schema-2020-12-keyword--primary;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback } from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../../prop-types"
|
||||
|
||||
import {
|
||||
useComponent,
|
||||
useIsExpanded,
|
||||
useFn,
|
||||
usePath,
|
||||
useLevel,
|
||||
useConfig,
|
||||
} from "../../../hooks"
|
||||
import { JSONSchemaLevelContext, JSONSchemaPathContext } from "../../../context"
|
||||
|
||||
const ExtensionKeywords = ({ schema }) => {
|
||||
const fn = useFn()
|
||||
const pathToken = "ExtensionKeywords"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONViewer = useComponent("JSONViewer")
|
||||
const { showExtensionKeywords } = useConfig("showExtensionKeywords")
|
||||
const extensionKeywords = fn.getExtensionKeywords(schema)
|
||||
|
||||
/**
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
*/
|
||||
if (!showExtensionKeywords || extensionKeywords.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--extension-keywords"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--extension">
|
||||
Extension Keywords
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{extensionKeywords.map((keyword) => (
|
||||
<JSONViewer
|
||||
key={keyword}
|
||||
name={keyword}
|
||||
value={schema[keyword]}
|
||||
className="json-schema-2020-12-json-viewer-extension-keyword"
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
ExtensionKeywords.propTypes = {
|
||||
schema: schema.isRequired,
|
||||
}
|
||||
|
||||
export default ExtensionKeywords
|
||||
@@ -0,0 +1,11 @@
|
||||
@use "./../../mixins";
|
||||
|
||||
.json-schema-2020-12-json-viewer-extension-keyword {
|
||||
.json-schema-2020-12-json-viewer__name {
|
||||
@include mixins.json-schema-2020-12-keyword--extension;
|
||||
}
|
||||
|
||||
.json-schema-2020-12-json-viewer__value {
|
||||
@include mixins.json-schema-2020-12-keyword--extension;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ const If = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--if">
|
||||
<JSONSchema name={name} schema={schema.if} />
|
||||
<JSONSchema name={name} schema={schema.if} identifier="if" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const Items = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--items">
|
||||
<JSONSchema name={name} schema={schema.items} />
|
||||
<JSONSchema name={name} schema={schema.items} identifier="items" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const Not = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--not">
|
||||
<JSONSchema name={name} schema={schema.not} />
|
||||
<JSONSchema name={name} schema={schema.not} identifier="not" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../prop-types"
|
||||
@@ -9,17 +9,18 @@ import {
|
||||
useFn,
|
||||
useComponent,
|
||||
useIsExpanded,
|
||||
useIsExpandedDeeply,
|
||||
usePath,
|
||||
useLevel,
|
||||
} from "../../hooks"
|
||||
import { JSONSchemaDeepExpansionContext } from "../../context"
|
||||
import { JSONSchemaLevelContext, JSONSchemaPathContext } from "../../context"
|
||||
|
||||
const OneOf = ({ schema }) => {
|
||||
const oneOf = schema?.oneOf || []
|
||||
const fn = useFn()
|
||||
const isExpanded = useIsExpanded()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpanded || isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const pathToken = "oneOf"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
@@ -29,12 +30,22 @@ const OneOf = ({ schema }) => {
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -44,35 +55,46 @@ const OneOf = ({ schema }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--oneOf">
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
One of
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
|
||||
<KeywordType schema={{ oneOf }} />
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !expanded,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--oneOf"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
<>
|
||||
{oneOf.map((schema, index) => (
|
||||
<li key={`#${index}`} className="json-schema-2020-12-property">
|
||||
<JSONSchema
|
||||
name={`#${index} ${fn.getTitle(schema)}`}
|
||||
schema={schema}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
One of
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
<KeywordType schema={{ oneOf }} />
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{oneOf.map((schema, index) => (
|
||||
<li
|
||||
key={`#${index}`}
|
||||
className="json-schema-2020-12-property"
|
||||
>
|
||||
<JSONSchema
|
||||
name={`#${index} ${fn.getTitle(schema)}`}
|
||||
schema={schema}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
import React from "react"
|
||||
|
||||
import { schema } from "../../../prop-types"
|
||||
import { useComponent } from "../../../hooks"
|
||||
import { useComponent, usePath } from "../../../hooks"
|
||||
import { JSONSchemaPathContext } from "../../../context"
|
||||
|
||||
const PatternProperties = ({ schema }) => {
|
||||
const patternProperties = schema?.patternProperties || {}
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
const { path } = usePath("patternProperties")
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -18,15 +20,17 @@ const PatternProperties = ({ schema }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--patternProperties">
|
||||
<ul>
|
||||
{Object.entries(patternProperties).map(([propertyName, schema]) => (
|
||||
<li key={propertyName} className="json-schema-2020-12-property">
|
||||
<JSONSchema name={propertyName} schema={schema} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--patternProperties">
|
||||
<ul>
|
||||
{Object.entries(patternProperties).map(([propertyName, schema]) => (
|
||||
<li key={propertyName} className="json-schema-2020-12-property">
|
||||
<JSONSchema name={propertyName} schema={schema} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@use "./../../../../../../style/variables" as *;
|
||||
|
||||
.json-schema-2020-12 {
|
||||
&-keyword--patternProperties {
|
||||
ul {
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../prop-types"
|
||||
import {
|
||||
useFn,
|
||||
useComponent,
|
||||
useIsExpandedDeeply,
|
||||
useIsExpanded,
|
||||
usePath,
|
||||
useLevel,
|
||||
} from "../../hooks"
|
||||
import { JSONSchemaDeepExpansionContext } from "../../context"
|
||||
import { JSONSchemaLevelContext, JSONSchemaPathContext } from "../../context"
|
||||
|
||||
const PrefixItems = ({ schema }) => {
|
||||
const prefixItems = schema?.prefixItems || []
|
||||
const fn = useFn()
|
||||
const isExpanded = useIsExpanded()
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const [expanded, setExpanded] = useState(isExpanded || isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const pathToken = "prefixItems"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
@@ -29,12 +30,22 @@ const PrefixItems = ({ schema }) => {
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -44,35 +55,46 @@ const PrefixItems = ({ schema }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--prefixItems">
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Prefix items
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
|
||||
<KeywordType schema={{ prefixItems }} />
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !expanded,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--prefixItems"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
<>
|
||||
{prefixItems.map((schema, index) => (
|
||||
<li key={`#${index}`} className="json-schema-2020-12-property">
|
||||
<JSONSchema
|
||||
name={`#${index} ${fn.getTitle(schema)}`}
|
||||
schema={schema}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
|
||||
Prefix items
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
<KeywordType schema={{ prefixItems }} />
|
||||
<ul
|
||||
className={classNames("json-schema-2020-12-keyword__children", {
|
||||
"json-schema-2020-12-keyword__children--collapsed": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{prefixItems.map((schema, index) => (
|
||||
<li
|
||||
key={`#${index}`}
|
||||
className="json-schema-2020-12-property"
|
||||
>
|
||||
<JSONSchema
|
||||
name={`#${index} ${fn.getTitle(schema)}`}
|
||||
schema={schema}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,15 @@ import React from "react"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { schema } from "../../../prop-types"
|
||||
import { useFn, useComponent } from "../../../hooks"
|
||||
import { useFn, useComponent, usePath } from "../../../hooks"
|
||||
import { JSONSchemaPathContext } from "../../../context"
|
||||
|
||||
const Properties = ({ schema }) => {
|
||||
const fn = useFn()
|
||||
const properties = schema?.properties || {}
|
||||
const required = Array.isArray(schema?.required) ? schema.required : []
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
const { path } = usePath("properties")
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -21,32 +23,34 @@ const Properties = ({ schema }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--properties">
|
||||
<ul>
|
||||
{Object.entries(properties).map(([propertyName, propertySchema]) => {
|
||||
const isRequired = required.includes(propertyName)
|
||||
const dependentRequired = fn.getDependentRequired(
|
||||
propertyName,
|
||||
schema
|
||||
)
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--properties">
|
||||
<ul>
|
||||
{Object.entries(properties).map(([propertyName, propertySchema]) => {
|
||||
const isRequired = required.includes(propertyName)
|
||||
const dependentRequired = fn.getDependentRequired(
|
||||
propertyName,
|
||||
schema
|
||||
)
|
||||
|
||||
return (
|
||||
<li
|
||||
key={propertyName}
|
||||
className={classNames("json-schema-2020-12-property", {
|
||||
"json-schema-2020-12-property--required": isRequired,
|
||||
})}
|
||||
>
|
||||
<JSONSchema
|
||||
name={propertyName}
|
||||
schema={propertySchema}
|
||||
dependentRequired={dependentRequired}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
return (
|
||||
<li
|
||||
key={propertyName}
|
||||
className={classNames("json-schema-2020-12-property", {
|
||||
"json-schema-2020-12-property--required": isRequired,
|
||||
})}
|
||||
>
|
||||
<JSONSchema
|
||||
name={propertyName}
|
||||
schema={propertySchema}
|
||||
dependentRequired={dependentRequired}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,11 @@
|
||||
list-style-type: none;
|
||||
|
||||
&--required {
|
||||
& > .json-schema-2020-12:first-of-type > .json-schema-2020-12-head .json-schema-2020-12__title:after {
|
||||
content: '*';
|
||||
&
|
||||
> .json-schema-2020-12:first-of-type
|
||||
> .json-schema-2020-12-head
|
||||
.json-schema-2020-12__title:after {
|
||||
content: "*";
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,11 @@ const PropertyNames = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--propertyNames">
|
||||
<JSONSchema name={name} schema={propertyNames} />
|
||||
<JSONSchema
|
||||
name={name}
|
||||
schema={propertyNames}
|
||||
identifier="propertyNames"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const Then = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--then">
|
||||
<JSONSchema name={name} schema={schema.then} />
|
||||
<JSONSchema name={name} schema={schema.then} identifier="then" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
@use "./../../../../../../style/variables" as *;
|
||||
@use "./../../../../../../style/type";
|
||||
|
||||
.json-schema-2020-12 {
|
||||
&__title {
|
||||
@include text_headline($section-models-model-title-font-color);
|
||||
@include type.text_headline($section-models-model-title-font-color);
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
@@ -15,7 +18,7 @@
|
||||
margin: 7px 0;
|
||||
|
||||
.json-schema-2020-12__title {
|
||||
@include text_code();
|
||||
@include type.text_code();
|
||||
font-size: 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,11 @@ const UnevaluatedItems = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--unevaluatedItems">
|
||||
<JSONSchema name={name} schema={unevaluatedItems} />
|
||||
<JSONSchema
|
||||
name={name}
|
||||
schema={unevaluatedItems}
|
||||
identifier="unevaluatedItems"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,11 @@ const UnevaluatedProperties = ({ schema }) => {
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--unevaluatedProperties">
|
||||
<JSONSchema name={name} schema={unevaluatedProperties} />
|
||||
<JSONSchema
|
||||
name={name}
|
||||
schema={unevaluatedProperties}
|
||||
identifier="unevaluatedProperties"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,68 +1,25 @@
|
||||
@use "./../../../../../style/variables" as *;
|
||||
@use "./../mixins";
|
||||
@use "./$vocabulary/$vocabulary" as vocabulary;
|
||||
@use "./Const/const";
|
||||
@use "./Constraint/constraint";
|
||||
@use "./Default/default";
|
||||
@use "./DependentRequired/dependent-required";
|
||||
@use "./Description/description";
|
||||
@use "./Enum/enum";
|
||||
@use "./Examples/examples";
|
||||
@use "./ExtensionKeywords/extension-keywords";
|
||||
@use "./PatternProperties/pattern-properties";
|
||||
@use "./Properties/properties";
|
||||
@use "./Title/title";
|
||||
|
||||
.json-schema-2020-12-keyword {
|
||||
margin: 5px 0 5px 0;
|
||||
|
||||
&__children {
|
||||
@include expansion-border;
|
||||
padding: 0;
|
||||
|
||||
&--collapsed {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 12px;
|
||||
margin-left: 20px;
|
||||
font-weight: bold;
|
||||
|
||||
&--primary {
|
||||
color: $text-code-default-font-color;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
color: #6b6b6b;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
&__value {
|
||||
color: #6b6b6b;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
|
||||
&--primary {
|
||||
color: $text-code-default-font-color;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
color: #6b6b6b;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&--const {
|
||||
@include text_code();
|
||||
color: #6b6b6b;
|
||||
font-style: normal;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
line-height: 1.5;
|
||||
padding: 1px 4px 1px 4px;
|
||||
border: 1px dashed #6b6b6b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&--warning {
|
||||
@extend .json-schema-2020-12-keyword__value--const;
|
||||
color: red;
|
||||
border: 1px dashed red;
|
||||
}
|
||||
}
|
||||
@include mixins.json-schema-2020-12-keyword;
|
||||
}
|
||||
.json-schema-2020-12-keyword__name--secondary + .json-schema-2020-12-keyword__value--secondary::before {
|
||||
content: '='
|
||||
|
||||
.json-schema-2020-12-keyword__name--secondary
|
||||
+ .json-schema-2020-12-keyword__value--secondary::before {
|
||||
content: "=";
|
||||
}
|
||||
|
||||
.json-schema-2020-12__attribute {
|
||||
@@ -72,7 +29,7 @@
|
||||
text-transform: lowercase;
|
||||
padding-left: 10px;
|
||||
|
||||
&--primary {
|
||||
&--primary {
|
||||
color: $prop-type-font-color;
|
||||
}
|
||||
|
||||
@@ -84,12 +41,3 @@
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
||||
@import './$vocabulary/$vocabulary';
|
||||
@import './Description/description';
|
||||
@import './Title/title';
|
||||
@import './Properties/properties';
|
||||
@import './PatternProperties/pattern-properties';
|
||||
@import './Enum/enum';
|
||||
@import './Constraint/constraint';
|
||||
@import './DependentRequired/dependent-required';
|
||||
|
||||
@@ -9,7 +9,6 @@ JSONSchemaContext.displayName = "JSONSchemaContext"
|
||||
export const JSONSchemaLevelContext = createContext(0)
|
||||
JSONSchemaLevelContext.displayName = "JSONSchemaLevelContext"
|
||||
|
||||
export const JSONSchemaDeepExpansionContext = createContext(false)
|
||||
JSONSchemaDeepExpansionContext.displayName = "JSONSchemaDeepExpansionContext"
|
||||
|
||||
export const JSONSchemaCyclesContext = createContext(new Set())
|
||||
|
||||
export const JSONSchemaPathContext = createContext([])
|
||||
|
||||
10
src/core/plugins/json-schema-2020-12/enum.js
Normal file
10
src/core/plugins/json-schema-2020-12/enum.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
export class JSONSchemaIsExpandedState {
|
||||
static Collapsed = "collapsed"
|
||||
|
||||
static Expanded = "expanded"
|
||||
|
||||
static DeeplyExpanded = "deeply-expanded"
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import { useFn } from "./hooks"
|
||||
|
||||
export const upperFirst = (value) => {
|
||||
if (typeof value === "string") {
|
||||
return `${value.charAt(0).toUpperCase()}${value.slice(1)}`
|
||||
@@ -13,148 +11,156 @@ export const upperFirst = (value) => {
|
||||
/**
|
||||
* Lookup can be `basic` or `extended`. By default the lookup is `extended`.
|
||||
*/
|
||||
export const getTitle = (schema, { lookup = "extended" } = {}) => {
|
||||
const fn = useFn()
|
||||
export const makeGetTitle = (fnAccessor) => {
|
||||
const getTitle = (schema, { lookup = "extended" } = {}) => {
|
||||
const fn = fnAccessor()
|
||||
|
||||
if (schema?.title != null) return fn.upperFirst(String(schema.title))
|
||||
if (lookup === "extended") {
|
||||
if (schema?.$anchor != null) return fn.upperFirst(String(schema.$anchor))
|
||||
if (schema?.$id != null) return String(schema.$id)
|
||||
if (schema?.title != null) return fn.upperFirst(String(schema.title))
|
||||
if (lookup === "extended") {
|
||||
if (schema?.$anchor != null) return fn.upperFirst(String(schema.$anchor))
|
||||
if (schema?.$id != null) return String(schema.$id)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
return ""
|
||||
return getTitle
|
||||
}
|
||||
|
||||
export const getType = (schema, processedSchemas = new WeakSet()) => {
|
||||
const fn = useFn()
|
||||
export const makeGetType = (fnAccessor) => {
|
||||
const getType = (schema, processedSchemas = new WeakSet()) => {
|
||||
const fn = fnAccessor()
|
||||
|
||||
if (schema == null) {
|
||||
return "any"
|
||||
}
|
||||
|
||||
if (fn.isBooleanJSONSchema(schema)) {
|
||||
return schema ? "any" : "never"
|
||||
}
|
||||
|
||||
if (typeof schema !== "object") {
|
||||
return "any"
|
||||
}
|
||||
|
||||
if (processedSchemas.has(schema)) {
|
||||
return "any" // detect a cycle
|
||||
}
|
||||
processedSchemas.add(schema)
|
||||
|
||||
const { type, prefixItems, items } = schema
|
||||
|
||||
const getArrayType = () => {
|
||||
if (Array.isArray(prefixItems)) {
|
||||
const prefixItemsTypes = prefixItems.map((itemSchema) =>
|
||||
getType(itemSchema, processedSchemas)
|
||||
)
|
||||
const itemsType = items ? getType(items, processedSchemas) : "any"
|
||||
return `array<[${prefixItemsTypes.join(", ")}], ${itemsType}>`
|
||||
} else if (items) {
|
||||
const itemsType = getType(items, processedSchemas)
|
||||
return `array<${itemsType}>`
|
||||
} else {
|
||||
return "array<any>"
|
||||
if (schema == null) {
|
||||
return "any"
|
||||
}
|
||||
}
|
||||
|
||||
const inferType = () => {
|
||||
if (
|
||||
Object.hasOwn(schema, "prefixItems") ||
|
||||
Object.hasOwn(schema, "items") ||
|
||||
Object.hasOwn(schema, "contains")
|
||||
) {
|
||||
return getArrayType()
|
||||
} else if (
|
||||
Object.hasOwn(schema, "properties") ||
|
||||
Object.hasOwn(schema, "additionalProperties") ||
|
||||
Object.hasOwn(schema, "patternProperties")
|
||||
) {
|
||||
return "object"
|
||||
} else if (["int32", "int64"].includes(schema.format)) {
|
||||
// OpenAPI 3.1.0 integer custom formats
|
||||
return "integer"
|
||||
} else if (["float", "double"].includes(schema.format)) {
|
||||
// OpenAPI 3.1.0 number custom formats
|
||||
return "number"
|
||||
} else if (
|
||||
Object.hasOwn(schema, "minimum") ||
|
||||
Object.hasOwn(schema, "maximum") ||
|
||||
Object.hasOwn(schema, "exclusiveMinimum") ||
|
||||
Object.hasOwn(schema, "exclusiveMaximum") ||
|
||||
Object.hasOwn(schema, "multipleOf")
|
||||
) {
|
||||
return "number | integer"
|
||||
} else if (
|
||||
Object.hasOwn(schema, "pattern") ||
|
||||
Object.hasOwn(schema, "format") ||
|
||||
Object.hasOwn(schema, "minLength") ||
|
||||
Object.hasOwn(schema, "maxLength")
|
||||
) {
|
||||
return "string"
|
||||
} else if (typeof schema.const !== "undefined") {
|
||||
if (schema.const === null) {
|
||||
return "null"
|
||||
} else if (typeof schema.const === "boolean") {
|
||||
return "boolean"
|
||||
} else if (typeof schema.const === "number") {
|
||||
return Number.isInteger(schema.const) ? "integer" : "number"
|
||||
} else if (typeof schema.const === "string") {
|
||||
return "string"
|
||||
} else if (Array.isArray(schema.const)) {
|
||||
if (fn.isBooleanJSONSchema(schema)) {
|
||||
return schema ? "any" : "never"
|
||||
}
|
||||
|
||||
if (typeof schema !== "object") {
|
||||
return "any"
|
||||
}
|
||||
|
||||
if (processedSchemas.has(schema)) {
|
||||
return "any" // detect a cycle
|
||||
}
|
||||
processedSchemas.add(schema)
|
||||
|
||||
const { type, prefixItems, items } = schema
|
||||
|
||||
const getArrayType = () => {
|
||||
if (Array.isArray(prefixItems)) {
|
||||
const prefixItemsTypes = prefixItems.map((itemSchema) =>
|
||||
getType(itemSchema, processedSchemas)
|
||||
)
|
||||
const itemsType = items ? getType(items, processedSchemas) : "any"
|
||||
return `array<[${prefixItemsTypes.join(", ")}], ${itemsType}>`
|
||||
} else if (items) {
|
||||
const itemsType = getType(items, processedSchemas)
|
||||
return `array<${itemsType}>`
|
||||
} else {
|
||||
return "array<any>"
|
||||
} else if (typeof schema.const === "object") {
|
||||
return "object"
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
if (schema.not && getType(schema.not) === "any") {
|
||||
return "never"
|
||||
}
|
||||
|
||||
const typeString = Array.isArray(type)
|
||||
? type.map((t) => (t === "array" ? getArrayType() : t)).join(" | ")
|
||||
: type === "array"
|
||||
? getArrayType()
|
||||
: [
|
||||
"null",
|
||||
"boolean",
|
||||
"object",
|
||||
"array",
|
||||
"number",
|
||||
"integer",
|
||||
"string",
|
||||
].includes(type)
|
||||
? type
|
||||
: inferType()
|
||||
|
||||
const handleCombiningKeywords = (keyword, separator) => {
|
||||
if (Array.isArray(schema[keyword])) {
|
||||
const combinedTypes = schema[keyword].map((subSchema) =>
|
||||
getType(subSchema, processedSchemas)
|
||||
)
|
||||
return `(${combinedTypes.join(separator)})`
|
||||
const inferType = () => {
|
||||
if (
|
||||
Object.hasOwn(schema, "prefixItems") ||
|
||||
Object.hasOwn(schema, "items") ||
|
||||
Object.hasOwn(schema, "contains")
|
||||
) {
|
||||
return getArrayType()
|
||||
} else if (
|
||||
Object.hasOwn(schema, "properties") ||
|
||||
Object.hasOwn(schema, "additionalProperties") ||
|
||||
Object.hasOwn(schema, "patternProperties")
|
||||
) {
|
||||
return "object"
|
||||
} else if (["int32", "int64"].includes(schema.format)) {
|
||||
// OpenAPI 3.1.0 integer custom formats
|
||||
return "integer"
|
||||
} else if (["float", "double"].includes(schema.format)) {
|
||||
// OpenAPI 3.1.0 number custom formats
|
||||
return "number"
|
||||
} else if (
|
||||
Object.hasOwn(schema, "minimum") ||
|
||||
Object.hasOwn(schema, "maximum") ||
|
||||
Object.hasOwn(schema, "exclusiveMinimum") ||
|
||||
Object.hasOwn(schema, "exclusiveMaximum") ||
|
||||
Object.hasOwn(schema, "multipleOf")
|
||||
) {
|
||||
return "number | integer"
|
||||
} else if (
|
||||
Object.hasOwn(schema, "pattern") ||
|
||||
Object.hasOwn(schema, "format") ||
|
||||
Object.hasOwn(schema, "minLength") ||
|
||||
Object.hasOwn(schema, "maxLength")
|
||||
) {
|
||||
return "string"
|
||||
} else if (typeof schema.const !== "undefined") {
|
||||
if (schema.const === null) {
|
||||
return "null"
|
||||
} else if (typeof schema.const === "boolean") {
|
||||
return "boolean"
|
||||
} else if (typeof schema.const === "number") {
|
||||
return Number.isInteger(schema.const) ? "integer" : "number"
|
||||
} else if (typeof schema.const === "string") {
|
||||
return "string"
|
||||
} else if (Array.isArray(schema.const)) {
|
||||
return "array<any>"
|
||||
} else if (typeof schema.const === "object") {
|
||||
return "object"
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
return null
|
||||
|
||||
if (schema.not && getType(schema.not) === "any") {
|
||||
return "never"
|
||||
}
|
||||
|
||||
const typeString = Array.isArray(type)
|
||||
? type.map((t) => (t === "array" ? getArrayType() : t)).join(" | ")
|
||||
: type === "array"
|
||||
? getArrayType()
|
||||
: [
|
||||
"null",
|
||||
"boolean",
|
||||
"object",
|
||||
"array",
|
||||
"number",
|
||||
"integer",
|
||||
"string",
|
||||
].includes(type)
|
||||
? type
|
||||
: inferType()
|
||||
|
||||
const handleCombiningKeywords = (keyword, separator) => {
|
||||
if (Array.isArray(schema[keyword])) {
|
||||
const combinedTypes = schema[keyword].map((subSchema) =>
|
||||
getType(subSchema, processedSchemas)
|
||||
)
|
||||
return `(${combinedTypes.join(separator)})`
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const oneOfString = handleCombiningKeywords("oneOf", " | ")
|
||||
const anyOfString = handleCombiningKeywords("anyOf", " | ")
|
||||
const allOfString = handleCombiningKeywords("allOf", " & ")
|
||||
|
||||
const combinedStrings = [typeString, oneOfString, anyOfString, allOfString]
|
||||
.filter(Boolean)
|
||||
.join(" | ")
|
||||
|
||||
processedSchemas.delete(schema)
|
||||
|
||||
return combinedStrings || "any"
|
||||
}
|
||||
|
||||
const oneOfString = handleCombiningKeywords("oneOf", " | ")
|
||||
const anyOfString = handleCombiningKeywords("anyOf", " | ")
|
||||
const allOfString = handleCombiningKeywords("allOf", " & ")
|
||||
|
||||
const combinedStrings = [typeString, oneOfString, anyOfString, allOfString]
|
||||
.filter(Boolean)
|
||||
.join(" | ")
|
||||
|
||||
processedSchemas.delete(schema)
|
||||
|
||||
return combinedStrings || "any"
|
||||
return getType
|
||||
}
|
||||
|
||||
export const isBooleanJSONSchema = (schema) => typeof schema === "boolean"
|
||||
@@ -164,42 +170,48 @@ export const hasKeyword = (schema, keyword) =>
|
||||
typeof schema === "object" &&
|
||||
Object.hasOwn(schema, keyword)
|
||||
|
||||
export const isExpandable = (schema) => {
|
||||
const fn = useFn()
|
||||
export const makeIsExpandable = (fnAccessor) => {
|
||||
const isExpandable = (schema) => {
|
||||
const fn = fnAccessor()
|
||||
|
||||
return (
|
||||
schema?.$schema ||
|
||||
schema?.$vocabulary ||
|
||||
schema?.$id ||
|
||||
schema?.$anchor ||
|
||||
schema?.$dynamicAnchor ||
|
||||
schema?.$ref ||
|
||||
schema?.$dynamicRef ||
|
||||
schema?.$defs ||
|
||||
schema?.$comment ||
|
||||
schema?.allOf ||
|
||||
schema?.anyOf ||
|
||||
schema?.oneOf ||
|
||||
fn.hasKeyword(schema, "not") ||
|
||||
fn.hasKeyword(schema, "if") ||
|
||||
fn.hasKeyword(schema, "then") ||
|
||||
fn.hasKeyword(schema, "else") ||
|
||||
schema?.dependentSchemas ||
|
||||
schema?.prefixItems ||
|
||||
fn.hasKeyword(schema, "items") ||
|
||||
fn.hasKeyword(schema, "contains") ||
|
||||
schema?.properties ||
|
||||
schema?.patternProperties ||
|
||||
fn.hasKeyword(schema, "additionalProperties") ||
|
||||
fn.hasKeyword(schema, "propertyNames") ||
|
||||
fn.hasKeyword(schema, "unevaluatedItems") ||
|
||||
fn.hasKeyword(schema, "unevaluatedProperties") ||
|
||||
schema?.description ||
|
||||
schema?.enum ||
|
||||
fn.hasKeyword(schema, "const") ||
|
||||
fn.hasKeyword(schema, "contentSchema") ||
|
||||
fn.hasKeyword(schema, "default")
|
||||
)
|
||||
return (
|
||||
schema?.$schema ||
|
||||
schema?.$vocabulary ||
|
||||
schema?.$id ||
|
||||
schema?.$anchor ||
|
||||
schema?.$dynamicAnchor ||
|
||||
schema?.$ref ||
|
||||
schema?.$dynamicRef ||
|
||||
schema?.$defs ||
|
||||
schema?.$comment ||
|
||||
schema?.allOf ||
|
||||
schema?.anyOf ||
|
||||
schema?.oneOf ||
|
||||
fn.hasKeyword(schema, "not") ||
|
||||
fn.hasKeyword(schema, "if") ||
|
||||
fn.hasKeyword(schema, "then") ||
|
||||
fn.hasKeyword(schema, "else") ||
|
||||
schema?.dependentSchemas ||
|
||||
schema?.prefixItems ||
|
||||
fn.hasKeyword(schema, "items") ||
|
||||
fn.hasKeyword(schema, "contains") ||
|
||||
schema?.properties ||
|
||||
schema?.patternProperties ||
|
||||
fn.hasKeyword(schema, "additionalProperties") ||
|
||||
fn.hasKeyword(schema, "propertyNames") ||
|
||||
fn.hasKeyword(schema, "unevaluatedItems") ||
|
||||
fn.hasKeyword(schema, "unevaluatedProperties") ||
|
||||
schema?.description ||
|
||||
schema?.enum ||
|
||||
fn.hasKeyword(schema, "const") ||
|
||||
fn.hasKeyword(schema, "contentSchema") ||
|
||||
fn.hasKeyword(schema, "default") ||
|
||||
schema?.examples ||
|
||||
fn.getExtensionKeywords(schema).length > 0
|
||||
)
|
||||
}
|
||||
|
||||
return isExpandable
|
||||
}
|
||||
|
||||
export const stringify = (value) => {
|
||||
@@ -339,13 +351,16 @@ export const stringifyConstraints = (schema) => {
|
||||
|
||||
// validation Keywords for Arrays
|
||||
const arrayRange = stringifyConstraintRange(
|
||||
schema?.hasUniqueItems ? "unique items" : "items",
|
||||
schema?.uniqueItems ? "unique items" : "items",
|
||||
schema?.minItems,
|
||||
schema?.maxItems
|
||||
)
|
||||
if (arrayRange !== null) {
|
||||
constraints.push({ scope: "array", value: arrayRange })
|
||||
}
|
||||
if (schema?.uniqueItems && !arrayRange) {
|
||||
constraints.push({ scope: "array", value: "unique" })
|
||||
}
|
||||
const containsRange = stringifyConstraintRange(
|
||||
"contained items",
|
||||
schema?.minContains,
|
||||
@@ -382,3 +397,108 @@ export const getDependentRequired = (propertyName, schema) => {
|
||||
}, new Set())
|
||||
)
|
||||
}
|
||||
|
||||
export const isPlainObject = (value) =>
|
||||
typeof value === "object" &&
|
||||
value !== null &&
|
||||
!Array.isArray(value) &&
|
||||
(Object.getPrototypeOf(value) === null ||
|
||||
Object.getPrototypeOf(value) === Object.prototype)
|
||||
|
||||
export const isEmptyObject = (value) =>
|
||||
isPlainObject(value) && Object.keys(value).length === 0
|
||||
|
||||
export const isEmptyArray = (value) =>
|
||||
Array.isArray(value) && value.length === 0
|
||||
|
||||
export const difference = (value, comparisonValue) => {
|
||||
const comparisonSet = new Set(comparisonValue)
|
||||
return value.filter((item) => !comparisonSet.has(item))
|
||||
}
|
||||
|
||||
export const getSchemaKeywords = () => {
|
||||
return [
|
||||
// core vocabulary
|
||||
"$schema",
|
||||
"$vocabulary",
|
||||
"$id",
|
||||
"$anchor",
|
||||
"$dynamicAnchor",
|
||||
"$dynamicRef",
|
||||
"$ref",
|
||||
"$defs",
|
||||
"$comment",
|
||||
// applicator vocabulary
|
||||
"allOf",
|
||||
"anyOf",
|
||||
"oneOf",
|
||||
"not",
|
||||
"if",
|
||||
"then",
|
||||
"else",
|
||||
"dependentSchemas",
|
||||
"prefixItems",
|
||||
"items",
|
||||
"contains",
|
||||
"properties",
|
||||
"patternProperties",
|
||||
"additionalProperties",
|
||||
"propertyNames",
|
||||
// unevaluated Locations vocabulary
|
||||
"unevaluatedItems",
|
||||
"unevaluatedProperties",
|
||||
// validation vocabulary
|
||||
// validation Keywords for Any Instance Type
|
||||
"type",
|
||||
"enum",
|
||||
"const",
|
||||
// validation Keywords for Numeric Instances (number and integer)
|
||||
"multipleOf",
|
||||
"maximum",
|
||||
"exclusiveMaximum",
|
||||
"minimum",
|
||||
"exclusiveMinimum",
|
||||
// validation Keywords for Strings
|
||||
"maxLength",
|
||||
"minLength",
|
||||
"pattern",
|
||||
// validation Keywords for Arrays
|
||||
"maxItems",
|
||||
"minItems",
|
||||
"uniqueItems",
|
||||
"maxContains",
|
||||
"minContains",
|
||||
// validation Keywords for Objects
|
||||
"maxProperties",
|
||||
"minProperties",
|
||||
"required",
|
||||
"dependentRequired",
|
||||
// basic Meta-Data Annotations vocabulary
|
||||
"title",
|
||||
"description",
|
||||
"default",
|
||||
"deprecated",
|
||||
"readOnly",
|
||||
"writeOnly",
|
||||
"examples",
|
||||
// semantic Content With "format" vocabulary
|
||||
"format",
|
||||
// contents of String-Encoded Data vocabulary
|
||||
"contentEncoding",
|
||||
"contentMediaType",
|
||||
"contentSchema",
|
||||
]
|
||||
}
|
||||
|
||||
export const makeGetExtensionKeywords = (fnAccessor) => {
|
||||
const getExtensionKeywords = (schema) => {
|
||||
const fn = fnAccessor()
|
||||
const keywords = fn.getSchemaKeywords()
|
||||
|
||||
return isPlainObject(schema)
|
||||
? difference(Object.keys(schema), keywords)
|
||||
: []
|
||||
}
|
||||
|
||||
return getExtensionKeywords
|
||||
}
|
||||
|
||||
@@ -32,30 +32,36 @@ import KeywordUnevaluatedItems from "./components/keywords/UnevaluatedItems"
|
||||
import KeywordUnevaluatedProperties from "./components/keywords/UnevaluatedProperties"
|
||||
import KeywordType from "./components/keywords/Type"
|
||||
import KeywordEnum from "./components/keywords/Enum/Enum"
|
||||
import KeywordConst from "./components/keywords/Const"
|
||||
import KeywordConst from "./components/keywords/Const/Const"
|
||||
import KeywordConstraint from "./components/keywords/Constraint/Constraint"
|
||||
import KeywordDependentRequired from "./components/keywords/DependentRequired/DependentRequired"
|
||||
import KeywordContentSchema from "./components/keywords/ContentSchema"
|
||||
import KeywordTitle from "./components/keywords/Title/Title"
|
||||
import KeywordDescription from "./components/keywords/Description/Description"
|
||||
import KeywordDefault from "./components/keywords/Default"
|
||||
import KeywordDefault from "./components/keywords/Default/Default"
|
||||
import KeywordDeprecated from "./components/keywords/Deprecated"
|
||||
import KeywordReadOnly from "./components/keywords/ReadOnly"
|
||||
import KeywordWriteOnly from "./components/keywords/WriteOnly"
|
||||
import KeywordExamples from "./components/keywords/Examples/Examples"
|
||||
import ExtensionKeywords from "./components/keywords/ExtensionKeywords/ExtensionKeywords"
|
||||
import JSONViewer from "./components/JSONViewer/JSONViewer"
|
||||
import Accordion from "./components/Accordion/Accordion"
|
||||
import ExpandDeepButton from "./components/ExpandDeepButton/ExpandDeepButton"
|
||||
import ChevronRightIcon from "./components/icons/ChevronRight"
|
||||
import { JSONSchemaContext } from "./context"
|
||||
import { useFn } from "./hooks"
|
||||
import {
|
||||
getTitle,
|
||||
makeGetTitle,
|
||||
isBooleanJSONSchema,
|
||||
upperFirst,
|
||||
getType,
|
||||
makeGetType,
|
||||
hasKeyword,
|
||||
isExpandable,
|
||||
makeIsExpandable,
|
||||
stringify,
|
||||
stringifyConstraints,
|
||||
getDependentRequired,
|
||||
getSchemaKeywords,
|
||||
makeGetExtensionKeywords,
|
||||
} from "./fn"
|
||||
|
||||
export const withJSONSchemaContext = (Component, overrides = {}) => {
|
||||
@@ -100,6 +106,9 @@ export const withJSONSchemaContext = (Component, overrides = {}) => {
|
||||
KeywordDeprecated,
|
||||
KeywordReadOnly,
|
||||
KeywordWriteOnly,
|
||||
KeywordExamples,
|
||||
ExtensionKeywords,
|
||||
JSONViewer,
|
||||
Accordion,
|
||||
ExpandDeepButton,
|
||||
ChevronRightIcon,
|
||||
@@ -116,20 +125,24 @@ export const withJSONSchemaContext = (Component, overrides = {}) => {
|
||||
* 3 -> [0]...(3)
|
||||
*/
|
||||
defaultExpandedLevels: 0, // 2 = 0...2
|
||||
showExtensionKeywords: true,
|
||||
...overrides.config,
|
||||
},
|
||||
fn: {
|
||||
upperFirst,
|
||||
getTitle,
|
||||
getType,
|
||||
getTitle: makeGetTitle(useFn),
|
||||
getType: makeGetType(useFn),
|
||||
isBooleanJSONSchema,
|
||||
hasKeyword,
|
||||
isExpandable,
|
||||
isExpandable: makeIsExpandable(useFn),
|
||||
stringify,
|
||||
stringifyConstraints,
|
||||
getDependentRequired,
|
||||
getSchemaKeywords,
|
||||
getExtensionKeywords: makeGetExtensionKeywords(useFn),
|
||||
...overrides.fn,
|
||||
},
|
||||
state: { paths: {} },
|
||||
}
|
||||
|
||||
const HOC = (props) => (
|
||||
@@ -144,3 +157,140 @@ export const withJSONSchemaContext = (Component, overrides = {}) => {
|
||||
|
||||
return HOC
|
||||
}
|
||||
|
||||
export const makeWithJSONSchemaSystemContext =
|
||||
({ getSystem }) =>
|
||||
(Component, overrides = {}) => {
|
||||
const { getComponent, getConfigs } = getSystem()
|
||||
const configs = getConfigs()
|
||||
|
||||
const JSONSchema = getComponent("JSONSchema202012")
|
||||
const Keyword$schema = getComponent("JSONSchema202012Keyword$schema")
|
||||
const Keyword$vocabulary = getComponent(
|
||||
"JSONSchema202012Keyword$vocabulary"
|
||||
)
|
||||
const Keyword$id = getComponent("JSONSchema202012Keyword$id")
|
||||
const Keyword$anchor = getComponent("JSONSchema202012Keyword$anchor")
|
||||
const Keyword$dynamicAnchor = getComponent(
|
||||
"JSONSchema202012Keyword$dynamicAnchor"
|
||||
)
|
||||
const Keyword$ref = getComponent("JSONSchema202012Keyword$ref")
|
||||
const Keyword$dynamicRef = getComponent(
|
||||
"JSONSchema202012Keyword$dynamicRef"
|
||||
)
|
||||
const Keyword$defs = getComponent("JSONSchema202012Keyword$defs")
|
||||
const Keyword$comment = getComponent("JSONSchema202012Keyword$comment")
|
||||
const KeywordAllOf = getComponent("JSONSchema202012KeywordAllOf")
|
||||
const KeywordAnyOf = getComponent("JSONSchema202012KeywordAnyOf")
|
||||
const KeywordOneOf = getComponent("JSONSchema202012KeywordOneOf")
|
||||
const KeywordNot = getComponent("JSONSchema202012KeywordNot")
|
||||
const KeywordIf = getComponent("JSONSchema202012KeywordIf")
|
||||
const KeywordThen = getComponent("JSONSchema202012KeywordThen")
|
||||
const KeywordElse = getComponent("JSONSchema202012KeywordElse")
|
||||
const KeywordDependentSchemas = getComponent(
|
||||
"JSONSchema202012KeywordDependentSchemas"
|
||||
)
|
||||
const KeywordPrefixItems = getComponent(
|
||||
"JSONSchema202012KeywordPrefixItems"
|
||||
)
|
||||
const KeywordItems = getComponent("JSONSchema202012KeywordItems")
|
||||
const KeywordContains = getComponent("JSONSchema202012KeywordContains")
|
||||
const KeywordProperties = getComponent("JSONSchema202012KeywordProperties")
|
||||
const KeywordPatternProperties = getComponent(
|
||||
"JSONSchema202012KeywordPatternProperties"
|
||||
)
|
||||
const KeywordAdditionalProperties = getComponent(
|
||||
"JSONSchema202012KeywordAdditionalProperties"
|
||||
)
|
||||
const KeywordPropertyNames = getComponent(
|
||||
"JSONSchema202012KeywordPropertyNames"
|
||||
)
|
||||
const KeywordUnevaluatedItems = getComponent(
|
||||
"JSONSchema202012KeywordUnevaluatedItems"
|
||||
)
|
||||
const KeywordUnevaluatedProperties = getComponent(
|
||||
"JSONSchema202012KeywordUnevaluatedProperties"
|
||||
)
|
||||
const KeywordType = getComponent("JSONSchema202012KeywordType")
|
||||
const KeywordEnum = getComponent("JSONSchema202012KeywordEnum")
|
||||
const KeywordConst = getComponent("JSONSchema202012KeywordConst")
|
||||
const KeywordConstraint = getComponent("JSONSchema202012KeywordConstraint")
|
||||
const KeywordDependentRequired = getComponent(
|
||||
"JSONSchema202012KeywordDependentRequired"
|
||||
)
|
||||
const KeywordContentSchema = getComponent(
|
||||
"JSONSchema202012KeywordContentSchema"
|
||||
)
|
||||
const KeywordTitle = getComponent("JSONSchema202012KeywordTitle")
|
||||
const KeywordDescription = getComponent(
|
||||
"JSONSchema202012KeywordDescription"
|
||||
)
|
||||
const KeywordDefault = getComponent("JSONSchema202012KeywordDefault")
|
||||
const KeywordDeprecated = getComponent("JSONSchema202012KeywordDeprecated")
|
||||
const KeywordReadOnly = getComponent("JSONSchema202012KeywordReadOnly")
|
||||
const KeywordWriteOnly = getComponent("JSONSchema202012KeywordWriteOnly")
|
||||
const KeywordExamples = getComponent("JSONSchema202012KeywordExamples")
|
||||
const ExtensionKeywords = getComponent("JSONSchema202012ExtensionKeywords")
|
||||
const JSONViewer = getComponent("JSONSchema202012JSONViewer")
|
||||
const Accordion = getComponent("JSONSchema202012Accordion")
|
||||
const ExpandDeepButton = getComponent("JSONSchema202012ExpandDeepButton")
|
||||
const ChevronRightIcon = getComponent("JSONSchema202012ChevronRightIcon")
|
||||
|
||||
return withJSONSchemaContext(Component, {
|
||||
components: {
|
||||
JSONSchema,
|
||||
Keyword$schema,
|
||||
Keyword$vocabulary,
|
||||
Keyword$id,
|
||||
Keyword$anchor,
|
||||
Keyword$dynamicAnchor,
|
||||
Keyword$ref,
|
||||
Keyword$dynamicRef,
|
||||
Keyword$defs,
|
||||
Keyword$comment,
|
||||
KeywordAllOf,
|
||||
KeywordAnyOf,
|
||||
KeywordOneOf,
|
||||
KeywordNot,
|
||||
KeywordIf,
|
||||
KeywordThen,
|
||||
KeywordElse,
|
||||
KeywordDependentSchemas,
|
||||
KeywordPrefixItems,
|
||||
KeywordItems,
|
||||
KeywordContains,
|
||||
KeywordProperties,
|
||||
KeywordPatternProperties,
|
||||
KeywordAdditionalProperties,
|
||||
KeywordPropertyNames,
|
||||
KeywordUnevaluatedItems,
|
||||
KeywordUnevaluatedProperties,
|
||||
KeywordType,
|
||||
KeywordEnum,
|
||||
KeywordConst,
|
||||
KeywordConstraint,
|
||||
KeywordDependentRequired,
|
||||
KeywordContentSchema,
|
||||
KeywordTitle,
|
||||
KeywordDescription,
|
||||
KeywordDefault,
|
||||
KeywordDeprecated,
|
||||
KeywordReadOnly,
|
||||
KeywordWriteOnly,
|
||||
KeywordExamples,
|
||||
ExtensionKeywords,
|
||||
JSONViewer,
|
||||
Accordion,
|
||||
ExpandDeepButton,
|
||||
ChevronRightIcon,
|
||||
...overrides.components,
|
||||
},
|
||||
config: {
|
||||
showExtensionKeywords: configs.showExtensions,
|
||||
...overrides.config,
|
||||
},
|
||||
fn: {
|
||||
...overrides.fn,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import { useContext } from "react"
|
||||
import { useCallback, useContext, useEffect, useState } from "react"
|
||||
|
||||
import {
|
||||
JSONSchemaContext,
|
||||
JSONSchemaLevelContext,
|
||||
JSONSchemaDeepExpansionContext,
|
||||
JSONSchemaCyclesContext,
|
||||
JSONSchemaPathContext,
|
||||
} from "./context"
|
||||
import { JSONSchemaIsExpandedState } from "./enum"
|
||||
|
||||
export const useConfig = () => {
|
||||
const { config } = useContext(JSONSchemaContext)
|
||||
@@ -26,6 +27,17 @@ export const useFn = (fnName = undefined) => {
|
||||
return typeof fnName !== "undefined" ? fn[fnName] : fn
|
||||
}
|
||||
|
||||
export const useJSONSchemaContextState = () => {
|
||||
const [, setFakeState] = useState(null)
|
||||
const { state } = useContext(JSONSchemaContext)
|
||||
const setState = (updateFn) => {
|
||||
updateFn(state)
|
||||
setFakeState({})
|
||||
}
|
||||
|
||||
return { state, setState }
|
||||
}
|
||||
|
||||
export const useLevel = () => {
|
||||
const level = useContext(JSONSchemaLevelContext)
|
||||
|
||||
@@ -38,15 +50,84 @@ export const useIsEmbedded = () => {
|
||||
return level > 0
|
||||
}
|
||||
|
||||
export const useIsExpanded = () => {
|
||||
const [level] = useLevel()
|
||||
const { defaultExpandedLevels } = useConfig()
|
||||
export const usePath = (pathToken) => {
|
||||
const path = useContext(JSONSchemaPathContext)
|
||||
const { setState } = useJSONSchemaContextState()
|
||||
const currentPath =
|
||||
typeof pathToken === "string" ? [...path, pathToken] : path
|
||||
|
||||
return defaultExpandedLevels - level > 0
|
||||
const pathMutator = (value, options = { deep: false }) => {
|
||||
const startPath = currentPath.toString()
|
||||
const updateFn = (state) => {
|
||||
state.paths[startPath] = value
|
||||
|
||||
if (value === JSONSchemaIsExpandedState.Collapsed) {
|
||||
Object.keys(state.paths).forEach((key) => {
|
||||
if (
|
||||
key.startsWith(startPath) &&
|
||||
state.paths[key] === JSONSchemaIsExpandedState.DeeplyExpanded
|
||||
) {
|
||||
state.paths[key] = JSONSchemaIsExpandedState.Expanded
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const updateDeepFn = (state) => {
|
||||
Object.keys(state.paths).forEach((key) => {
|
||||
if (key.startsWith(startPath)) {
|
||||
state.paths[key] = value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (options.deep) {
|
||||
setState(updateDeepFn)
|
||||
} else {
|
||||
setState(updateFn)
|
||||
}
|
||||
}
|
||||
|
||||
return { path: currentPath, pathMutator }
|
||||
}
|
||||
|
||||
export const useIsExpandedDeeply = () => {
|
||||
return useContext(JSONSchemaDeepExpansionContext)
|
||||
export const useIsExpanded = (name) => {
|
||||
const [level] = useLevel()
|
||||
const { defaultExpandedLevels } = useConfig()
|
||||
const { path, pathMutator } = usePath(name)
|
||||
const { path: parentPath } = usePath()
|
||||
const { state } = useJSONSchemaContextState()
|
||||
const currentState = state.paths[path.toString()]
|
||||
const parentState =
|
||||
state.paths[parentPath.toString()] ??
|
||||
state.paths[parentPath.slice(0, -1).toString()]
|
||||
const isExpandedState =
|
||||
currentState ??
|
||||
(defaultExpandedLevels - level > 0
|
||||
? JSONSchemaIsExpandedState.Expanded
|
||||
: JSONSchemaIsExpandedState.Collapsed)
|
||||
const isExpanded = isExpandedState !== JSONSchemaIsExpandedState.Collapsed
|
||||
|
||||
useEffect(() => {
|
||||
pathMutator(
|
||||
parentState === JSONSchemaIsExpandedState.DeeplyExpanded
|
||||
? JSONSchemaIsExpandedState.DeeplyExpanded
|
||||
: isExpandedState
|
||||
)
|
||||
}, [parentState])
|
||||
|
||||
const setExpanded = useCallback((options = { deep: false }) => {
|
||||
pathMutator(
|
||||
options.deep
|
||||
? JSONSchemaIsExpandedState.DeeplyExpanded
|
||||
: JSONSchemaIsExpandedState.Expanded
|
||||
)
|
||||
}, [])
|
||||
|
||||
const setCollapsed = useCallback((options = { deep: false }) => {
|
||||
pathMutator(JSONSchemaIsExpandedState.Collapsed, options)
|
||||
}, [])
|
||||
|
||||
return { isExpanded, setExpanded, setCollapsed }
|
||||
}
|
||||
|
||||
export const useRenderedSchemas = (schema = undefined) => {
|
||||
|
||||
@@ -30,82 +30,122 @@ import KeywordUnevaluatedItems from "./components/keywords/UnevaluatedItems"
|
||||
import KeywordUnevaluatedProperties from "./components/keywords/UnevaluatedProperties"
|
||||
import KeywordType from "./components/keywords/Type"
|
||||
import KeywordEnum from "./components/keywords/Enum/Enum"
|
||||
import KeywordConst from "./components/keywords/Const"
|
||||
import KeywordConst from "./components/keywords/Const/Const"
|
||||
import KeywordConstraint from "./components/keywords/Constraint/Constraint"
|
||||
import KeywordDependentRequired from "./components/keywords/DependentRequired/DependentRequired"
|
||||
import KeywordContentSchema from "./components/keywords/ContentSchema"
|
||||
import KeywordTitle from "./components/keywords/Title/Title"
|
||||
import KeywordDescription from "./components/keywords/Description/Description"
|
||||
import KeywordDefault from "./components/keywords/Default"
|
||||
import KeywordDefault from "./components/keywords/Default/Default"
|
||||
import KeywordDeprecated from "./components/keywords/Deprecated"
|
||||
import KeywordReadOnly from "./components/keywords/ReadOnly"
|
||||
import KeywordWriteOnly from "./components/keywords/WriteOnly"
|
||||
import KeywordExamples from "./components/keywords/Examples/Examples"
|
||||
import ExtensionKeywords from "./components/keywords/ExtensionKeywords/ExtensionKeywords"
|
||||
import JSONViewer from "./components/JSONViewer/JSONViewer"
|
||||
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 { JSONSchemaDeepExpansionContext } from "./context"
|
||||
import { useFn, useConfig, useComponent, useIsExpandedDeeply } from "./hooks"
|
||||
import { withJSONSchemaContext } from "./hoc"
|
||||
import {
|
||||
upperFirst,
|
||||
hasKeyword,
|
||||
makeGetTitle,
|
||||
makeGetType,
|
||||
makeIsExpandable,
|
||||
isBooleanJSONSchema,
|
||||
getSchemaKeywords,
|
||||
makeGetExtensionKeywords,
|
||||
} from "./fn"
|
||||
import { JSONSchemaPathContext, JSONSchemaLevelContext } from "./context"
|
||||
import {
|
||||
useFn,
|
||||
useConfig,
|
||||
useComponent,
|
||||
useIsExpanded,
|
||||
usePath,
|
||||
useLevel,
|
||||
} from "./hooks"
|
||||
import { withJSONSchemaContext, makeWithJSONSchemaSystemContext } from "./hoc"
|
||||
|
||||
const JSONSchema202012Plugin = () => ({
|
||||
components: {
|
||||
JSONSchema202012: JSONSchema,
|
||||
JSONSchema202012Keyword$schema: Keyword$schema,
|
||||
JSONSchema202012Keyword$vocabulary: Keyword$vocabulary,
|
||||
JSONSchema202012Keyword$id: Keyword$id,
|
||||
JSONSchema202012Keyword$anchor: Keyword$anchor,
|
||||
JSONSchema202012Keyword$dynamicAnchor: Keyword$dynamicAnchor,
|
||||
JSONSchema202012Keyword$ref: Keyword$ref,
|
||||
JSONSchema202012Keyword$dynamicRef: Keyword$dynamicRef,
|
||||
JSONSchema202012Keyword$defs: Keyword$defs,
|
||||
JSONSchema202012Keyword$comment: Keyword$comment,
|
||||
JSONSchema202012KeywordAllOf: KeywordAllOf,
|
||||
JSONSchema202012KeywordAnyOf: KeywordAnyOf,
|
||||
JSONSchema202012KeywordOneOf: KeywordOneOf,
|
||||
JSONSchema202012KeywordNot: KeywordNot,
|
||||
JSONSchema202012KeywordIf: KeywordIf,
|
||||
JSONSchema202012KeywordThen: KeywordThen,
|
||||
JSONSchema202012KeywordElse: KeywordElse,
|
||||
JSONSchema202012KeywordDependentSchemas: KeywordDependentSchemas,
|
||||
JSONSchema202012KeywordPrefixItems: KeywordPrefixItems,
|
||||
JSONSchema202012KeywordItems: KeywordItems,
|
||||
JSONSchema202012KeywordContains: KeywordContains,
|
||||
JSONSchema202012KeywordProperties: KeywordProperties,
|
||||
JSONSchema202012KeywordPatternProperties: KeywordPatternProperties,
|
||||
JSONSchema202012KeywordAdditionalProperties: KeywordAdditionalProperties,
|
||||
JSONSchema202012KeywordPropertyNames: KeywordPropertyNames,
|
||||
JSONSchema202012KeywordUnevaluatedItems: KeywordUnevaluatedItems,
|
||||
JSONSchema202012KeywordUnevaluatedProperties: KeywordUnevaluatedProperties,
|
||||
JSONSchema202012KeywordType: KeywordType,
|
||||
JSONSchema202012KeywordEnum: KeywordEnum,
|
||||
JSONSchema202012KeywordConst: KeywordConst,
|
||||
JSONSchema202012KeywordConstraint: KeywordConstraint,
|
||||
JSONSchema202012KeywordDependentRequired: KeywordDependentRequired,
|
||||
JSONSchema202012KeywordContentSchema: KeywordContentSchema,
|
||||
JSONSchema202012KeywordTitle: KeywordTitle,
|
||||
JSONSchema202012KeywordDescription: KeywordDescription,
|
||||
JSONSchema202012KeywordDefault: KeywordDefault,
|
||||
JSONSchema202012KeywordDeprecated: KeywordDeprecated,
|
||||
JSONSchema202012KeywordReadOnly: KeywordReadOnly,
|
||||
JSONSchema202012KeywordWriteOnly: KeywordWriteOnly,
|
||||
JSONSchema202012Accordion: Accordion,
|
||||
JSONSchema202012ExpandDeepButton: ExpandDeepButton,
|
||||
JSONSchema202012ChevronRightIcon: ChevronRightIcon,
|
||||
withJSONSchema202012Context: withJSONSchemaContext,
|
||||
JSONSchema202012DeepExpansionContext: () => JSONSchemaDeepExpansionContext,
|
||||
},
|
||||
fn: {
|
||||
upperFirst,
|
||||
jsonSchema202012: {
|
||||
isExpandable,
|
||||
hasKeyword,
|
||||
useFn,
|
||||
useConfig,
|
||||
useComponent,
|
||||
useIsExpandedDeeply,
|
||||
const JSONSchema202012Plugin = ({ getSystem, fn }) => {
|
||||
const fnAccessor = () => ({
|
||||
upperFirst: fn.upperFirst,
|
||||
...fn.jsonSchema202012,
|
||||
})
|
||||
|
||||
return {
|
||||
components: {
|
||||
JSONSchema202012: JSONSchema,
|
||||
JSONSchema202012Keyword$schema: Keyword$schema,
|
||||
JSONSchema202012Keyword$vocabulary: Keyword$vocabulary,
|
||||
JSONSchema202012Keyword$id: Keyword$id,
|
||||
JSONSchema202012Keyword$anchor: Keyword$anchor,
|
||||
JSONSchema202012Keyword$dynamicAnchor: Keyword$dynamicAnchor,
|
||||
JSONSchema202012Keyword$ref: Keyword$ref,
|
||||
JSONSchema202012Keyword$dynamicRef: Keyword$dynamicRef,
|
||||
JSONSchema202012Keyword$defs: Keyword$defs,
|
||||
JSONSchema202012Keyword$comment: Keyword$comment,
|
||||
JSONSchema202012KeywordAllOf: KeywordAllOf,
|
||||
JSONSchema202012KeywordAnyOf: KeywordAnyOf,
|
||||
JSONSchema202012KeywordOneOf: KeywordOneOf,
|
||||
JSONSchema202012KeywordNot: KeywordNot,
|
||||
JSONSchema202012KeywordIf: KeywordIf,
|
||||
JSONSchema202012KeywordThen: KeywordThen,
|
||||
JSONSchema202012KeywordElse: KeywordElse,
|
||||
JSONSchema202012KeywordDependentSchemas: KeywordDependentSchemas,
|
||||
JSONSchema202012KeywordPrefixItems: KeywordPrefixItems,
|
||||
JSONSchema202012KeywordItems: KeywordItems,
|
||||
JSONSchema202012KeywordContains: KeywordContains,
|
||||
JSONSchema202012KeywordProperties: KeywordProperties,
|
||||
JSONSchema202012KeywordPatternProperties: KeywordPatternProperties,
|
||||
JSONSchema202012KeywordAdditionalProperties: KeywordAdditionalProperties,
|
||||
JSONSchema202012KeywordPropertyNames: KeywordPropertyNames,
|
||||
JSONSchema202012KeywordUnevaluatedItems: KeywordUnevaluatedItems,
|
||||
JSONSchema202012KeywordUnevaluatedProperties:
|
||||
KeywordUnevaluatedProperties,
|
||||
JSONSchema202012KeywordType: KeywordType,
|
||||
JSONSchema202012KeywordEnum: KeywordEnum,
|
||||
JSONSchema202012KeywordConst: KeywordConst,
|
||||
JSONSchema202012KeywordConstraint: KeywordConstraint,
|
||||
JSONSchema202012KeywordDependentRequired: KeywordDependentRequired,
|
||||
JSONSchema202012KeywordContentSchema: KeywordContentSchema,
|
||||
JSONSchema202012KeywordTitle: KeywordTitle,
|
||||
JSONSchema202012KeywordDescription: KeywordDescription,
|
||||
JSONSchema202012KeywordDefault: KeywordDefault,
|
||||
JSONSchema202012KeywordDeprecated: KeywordDeprecated,
|
||||
JSONSchema202012KeywordReadOnly: KeywordReadOnly,
|
||||
JSONSchema202012KeywordWriteOnly: KeywordWriteOnly,
|
||||
JSONSchema202012KeywordExamples: KeywordExamples,
|
||||
JSONSchema202012ExtensionKeywords: ExtensionKeywords,
|
||||
JSONSchema202012JSONViewer: JSONViewer,
|
||||
JSONSchema202012Accordion: Accordion,
|
||||
JSONSchema202012ExpandDeepButton: ExpandDeepButton,
|
||||
JSONSchema202012ChevronRightIcon: ChevronRightIcon,
|
||||
withJSONSchema202012Context: withJSONSchemaContext,
|
||||
withJSONSchema202012SystemContext:
|
||||
makeWithJSONSchemaSystemContext(getSystem()),
|
||||
JSONSchema202012PathContext: () => JSONSchemaPathContext,
|
||||
JSONSchema202012LevelContext: () => JSONSchemaLevelContext,
|
||||
},
|
||||
},
|
||||
})
|
||||
fn: {
|
||||
upperFirst,
|
||||
jsonSchema202012: {
|
||||
getTitle: makeGetTitle(fnAccessor),
|
||||
getType: makeGetType(fnAccessor),
|
||||
isExpandable: makeIsExpandable(fnAccessor),
|
||||
isBooleanJSONSchema,
|
||||
hasKeyword,
|
||||
useFn,
|
||||
useConfig,
|
||||
useComponent,
|
||||
useIsExpanded,
|
||||
usePath,
|
||||
useLevel,
|
||||
getSchemaKeywords,
|
||||
getExtensionKeywords: makeGetExtensionKeywords(fnAccessor),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default JSONSchema202012Plugin
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import { sanitizeUrl } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
|
||||
const propClass = "property"
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import { List, fromJS } from "immutable"
|
||||
import cx from "classnames"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import DebounceInput from "react-debounce-input"
|
||||
import { stringify } from "core/utils"
|
||||
import { stringify, isImmutable, immutableToJS } from "core/utils"
|
||||
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
|
||||
const noop = ()=> {}
|
||||
const JsonSchemaPropShape = {
|
||||
@@ -48,15 +50,22 @@ export class JsonSchemaForm extends Component {
|
||||
let { schema, errors, value, onChange, getComponent, fn, disabled } = this.props
|
||||
const format = schema && schema.get ? schema.get("format") : null
|
||||
const type = schema && schema.get ? schema.get("type") : null
|
||||
const foldedType = fn.jsonSchema202012.foldType(immutableToJS(type))
|
||||
|
||||
let getComponentSilently = (name) => getComponent(name, false, { failSilently: true })
|
||||
let Comp = type ? format ?
|
||||
getComponentSilently(`JsonSchema_${type}_${format}`) :
|
||||
getComponentSilently(`JsonSchema_${type}`) :
|
||||
getComponent("JsonSchema_string")
|
||||
|
||||
if (List.isList(type) && (foldedType === "array" || foldedType === "object")) {
|
||||
Comp = getComponent("JsonSchema_object")
|
||||
}
|
||||
|
||||
if (!Comp) {
|
||||
Comp = getComponent("JsonSchema_string")
|
||||
}
|
||||
|
||||
return <Comp { ...this.props } errors={errors} fn={fn} getComponent={getComponent} value={value} onChange={onChange} schema={schema} disabled={disabled}/>
|
||||
}
|
||||
}
|
||||
@@ -77,7 +86,10 @@ export class JsonSchema_string extends Component {
|
||||
const schemaIn = schema && schema.get ? schema.get("in") : null
|
||||
if (!value) {
|
||||
value = "" // value should not be null; this fixes a Debounce error
|
||||
} else if (isImmutable(value) || typeof value === "object") {
|
||||
value = stringify(value)
|
||||
}
|
||||
|
||||
errors = errors.toJS ? errors.toJS() : []
|
||||
|
||||
if ( enumValue ) {
|
||||
@@ -182,6 +194,8 @@ export class JsonSchema_array extends PureComponent {
|
||||
value && value.count && value.count() > 0 ? true : false
|
||||
const schemaItemsEnum = schema.getIn(["items", "enum"])
|
||||
const schemaItemsType = schema.getIn(["items", "type"])
|
||||
const foldedSchemaItemsType = fn.jsonSchema202012.foldType(immutableToJS(schemaItemsType))
|
||||
const schemaItemsTypeLabel = fn.jsonSchema202012.getType(immutableToJS(schema.get("items")))
|
||||
const schemaItemsFormat = schema.getIn(["items", "format"])
|
||||
const schemaItemsSchema = schema.get("items")
|
||||
let ArrayItemsComponent
|
||||
@@ -192,6 +206,11 @@ export class JsonSchema_array extends PureComponent {
|
||||
} else if (schemaItemsType === "boolean" || schemaItemsType === "array" || schemaItemsType === "object") {
|
||||
ArrayItemsComponent = getComponent(`JsonSchema_${schemaItemsType}`)
|
||||
}
|
||||
|
||||
if (List.isList(schemaItemsType) && (foldedSchemaItemsType === "array" || foldedSchemaItemsType === "object")) {
|
||||
ArrayItemsComponent = getComponent(`JsonSchema_object`)
|
||||
}
|
||||
|
||||
// if ArrayItemsComponent not assigned or does not exist,
|
||||
// use default schemaItemsType === "string" & JsonSchemaArrayItemText component
|
||||
if (!ArrayItemsComponent && !isArrayItemFile) {
|
||||
@@ -266,7 +285,7 @@ export class JsonSchema_array extends PureComponent {
|
||||
title={arrayErrors.length ? arrayErrors : ""}
|
||||
onClick={this.addItem}
|
||||
>
|
||||
Add {schemaItemsType ? `${schemaItemsType} ` : ""}item
|
||||
Add {schemaItemsTypeLabel} item
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -287,7 +306,10 @@ export class JsonSchemaArrayItemText extends Component {
|
||||
let { value, errors, description, disabled } = this.props
|
||||
if (!value) {
|
||||
value = "" // value should not be null
|
||||
} else if (isImmutable(value) || typeof value === "object") {
|
||||
value = stringify(value)
|
||||
}
|
||||
|
||||
errors = errors.toJS ? errors.toJS() : []
|
||||
|
||||
return (<DebounceInput
|
||||
|
||||
@@ -120,6 +120,7 @@ const ModelExample = ({
|
||||
|
||||
{activeTab === tabs.model && (
|
||||
<div
|
||||
className="model-container"
|
||||
aria-hidden={activeTab === tabs.example}
|
||||
aria-labelledby={modelTabId}
|
||||
data-name="modelPanel"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { immutableToJS } from "core/utils"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
|
||||
export const ModelExtensions = ({ extensions, propClass = "" }) => {
|
||||
return extensions
|
||||
.entrySeq()
|
||||
.map(([key, value]) => {
|
||||
const normalizedValue = immutableToJS(value) ?? null
|
||||
|
||||
return (
|
||||
<tr key={key} className={propClass}>
|
||||
<td>{key}</td>
|
||||
<td>{JSON.stringify(normalizedValue)}</td>
|
||||
</tr>
|
||||
)
|
||||
})
|
||||
.toArray()
|
||||
}
|
||||
|
||||
ModelExtensions.propTypes = {
|
||||
extensions: ImPropTypes.map.isRequired,
|
||||
propClass: PropTypes.string,
|
||||
}
|
||||
@@ -66,7 +66,7 @@ export default class Model extends ImmutablePureComponent {
|
||||
/*
|
||||
* If we have an unresolved ref, get the schema and name from the ref.
|
||||
* If the ref is external, we can't resolve it, so we just display the ref location.
|
||||
* This is for situations where:
|
||||
* This is for situations where:
|
||||
* - the ref was not resolved by Swagger Client because we reached the traversal depth limit
|
||||
* - we had a circular ref inside the allOf keyword
|
||||
*/
|
||||
@@ -74,9 +74,9 @@ export default class Model extends ImmutablePureComponent {
|
||||
const refName = this.getModelName($ref)
|
||||
const refSchema = this.getRefSchema(refName)
|
||||
if (Map.isMap(refSchema)) {
|
||||
schema = refSchema.mergeDeep(schema)
|
||||
schema = refSchema.mergeDeep(schema)
|
||||
if (!$$ref) {
|
||||
schema = schema.set("$$ref", $ref)
|
||||
schema = schema.set("$$ref", $ref)
|
||||
$$ref = $ref
|
||||
}
|
||||
} else if (Map.isMap(schema) && schema.size === 1) {
|
||||
|
||||
@@ -2,6 +2,8 @@ import React, { Component } from "react"
|
||||
import Im, { Map } from "immutable"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
|
||||
export default class Models extends Component {
|
||||
static propTypes = {
|
||||
getComponent: PropTypes.func,
|
||||
@@ -114,7 +116,7 @@ export default class Models extends Component {
|
||||
|
||||
return <div id={ `model-${name}` } className="model-container" key={ `models-section-${name}` }
|
||||
data-name={name} ref={this.onLoadModel} >
|
||||
<span className="models-jump-to-path"><JumpToPath specPath={specPath} /></span>
|
||||
<span className="models-jump-to-path"><JumpToPath path={specPath} /></span>
|
||||
<ModelCollapse
|
||||
classes="model-box"
|
||||
collapsedContent={this.getCollapsedContent(name)}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import React, { Component, } from "react"
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { Component } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { List } from "immutable"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import { sanitizeUrl } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
import classNames from "classnames"
|
||||
import { getExtensions } from "../../../utils"
|
||||
|
||||
const braceOpen = "{"
|
||||
const braceClose = "}"
|
||||
@@ -26,24 +31,43 @@ export default class ObjectModel extends Component {
|
||||
includeWriteOnly: PropTypes.bool,
|
||||
}
|
||||
|
||||
render(){
|
||||
let { schema, name, displayName, isRef, getComponent, getConfigs, depth, onToggle, expanded, specPath, ...otherProps } = this.props
|
||||
let { specSelectors,expandDepth, includeReadOnly, includeWriteOnly} = otherProps
|
||||
render() {
|
||||
let {
|
||||
schema,
|
||||
name,
|
||||
displayName,
|
||||
isRef,
|
||||
getComponent,
|
||||
getConfigs,
|
||||
depth,
|
||||
onToggle,
|
||||
expanded,
|
||||
specPath,
|
||||
...otherProps
|
||||
} = this.props
|
||||
let { specSelectors, expandDepth, includeReadOnly, includeWriteOnly } =
|
||||
otherProps
|
||||
const { isOAS3 } = specSelectors
|
||||
const isEmbedded = depth > 2 || (depth === 2 && specPath.last() !== "items")
|
||||
|
||||
if(!schema) {
|
||||
if (!schema) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { showExtensions } = getConfigs()
|
||||
const extensions = showExtensions ? getExtensions(schema) : List()
|
||||
|
||||
let description = schema.get("description")
|
||||
let properties = schema.get("properties")
|
||||
let additionalProperties = schema.get("additionalProperties")
|
||||
let title = schema.get("title") || displayName || name
|
||||
let requiredProperties = schema.get("required")
|
||||
let infoProperties = schema
|
||||
.filter( ( v, key) => ["maxProperties", "minProperties", "nullable", "example"].indexOf(key) !== -1 )
|
||||
let infoProperties = schema.filter(
|
||||
(v, key) =>
|
||||
["maxProperties", "minProperties", "nullable", "example"].indexOf(
|
||||
key
|
||||
) !== -1
|
||||
)
|
||||
let deprecated = schema.get("deprecated")
|
||||
let externalDocsUrl = schema.getIn(["externalDocs", "url"])
|
||||
let externalDocsDescription = schema.getIn(["externalDocs", "description"])
|
||||
@@ -54,220 +78,263 @@ export default class ObjectModel extends Component {
|
||||
const ModelCollapse = getComponent("ModelCollapse")
|
||||
const Property = getComponent("Property")
|
||||
const Link = getComponent("Link")
|
||||
const ModelExtensions = getComponent("ModelExtensions")
|
||||
|
||||
const JumpToPathSection = () => {
|
||||
return <span className="model-jump-to-path"><JumpToPath specPath={specPath} /></span>
|
||||
return (
|
||||
<span className="model-jump-to-path">
|
||||
<JumpToPath path={specPath} />
|
||||
</span>
|
||||
)
|
||||
}
|
||||
const collapsedContent = (<span>
|
||||
<span>{ braceOpen }</span>...<span>{ braceClose }</span>
|
||||
{
|
||||
isRef ? <JumpToPathSection /> : ""
|
||||
}
|
||||
</span>)
|
||||
const collapsedContent = (
|
||||
<span>
|
||||
<span>{braceOpen}</span>...<span>{braceClose}</span>
|
||||
{isRef ? <JumpToPathSection /> : ""}
|
||||
</span>
|
||||
)
|
||||
|
||||
const allOf = specSelectors.isOAS3() ? schema.get("allOf") : null
|
||||
const anyOf = specSelectors.isOAS3() ? schema.get("anyOf") : null
|
||||
const oneOf = specSelectors.isOAS3() ? schema.get("oneOf") : null
|
||||
const not = specSelectors.isOAS3() ? schema.get("not") : null
|
||||
|
||||
const titleEl = title && <span className="model-title">
|
||||
{ isRef && schema.get("$$ref") && <span className="model-hint">{ schema.get("$$ref") }</span> }
|
||||
<span className="model-title__text">{ title }</span>
|
||||
</span>
|
||||
const titleEl = title && (
|
||||
<span className="model-title">
|
||||
{isRef && schema.get("$$ref") && (
|
||||
<span
|
||||
className={classNames("model-hint", {
|
||||
"model-hint--embedded": isEmbedded,
|
||||
})}
|
||||
>
|
||||
{schema.get("$$ref")}
|
||||
</span>
|
||||
)}
|
||||
<span className="model-title__text">{title}</span>
|
||||
</span>
|
||||
)
|
||||
|
||||
return <span className="model">
|
||||
<ModelCollapse
|
||||
modelName={name}
|
||||
title={titleEl}
|
||||
onToggle = {onToggle}
|
||||
expanded={ expanded ? true : depth <= expandDepth }
|
||||
collapsedContent={ collapsedContent }>
|
||||
|
||||
<span className="brace-open object">{ braceOpen }</span>
|
||||
{
|
||||
!isRef ? null : <JumpToPathSection />
|
||||
}
|
||||
return (
|
||||
<span className="model">
|
||||
<ModelCollapse
|
||||
modelName={name}
|
||||
title={titleEl}
|
||||
onToggle={onToggle}
|
||||
expanded={expanded ? true : depth <= expandDepth}
|
||||
collapsedContent={collapsedContent}
|
||||
>
|
||||
<span className="brace-open object">{braceOpen}</span>
|
||||
{!isRef ? null : <JumpToPathSection />}
|
||||
<span className="inner-object">
|
||||
{
|
||||
<table className="model"><tbody>
|
||||
{
|
||||
!description ? null : <tr className="description">
|
||||
<td>description:</td>
|
||||
<td>
|
||||
<Markdown source={ description } />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
externalDocsUrl &&
|
||||
<tr className={"external-docs"}>
|
||||
<td>
|
||||
externalDocs:
|
||||
</td>
|
||||
<td>
|
||||
<Link target="_blank" href={sanitizeUrl(externalDocsUrl)}>{externalDocsDescription || externalDocsUrl}</Link>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
!deprecated ? null :
|
||||
<tr className={"property"}>
|
||||
<td>
|
||||
deprecated:
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
!(properties && properties.size) ? null : properties.entrySeq().filter(
|
||||
([, value]) => {
|
||||
return (!value.get("readOnly") || includeReadOnly) &&
|
||||
(!value.get("writeOnly") || includeWriteOnly)
|
||||
}
|
||||
).map(
|
||||
([key, value]) => {
|
||||
let isDeprecated = isOAS3() && value.get("deprecated")
|
||||
let isRequired = List.isList(requiredProperties) && requiredProperties.contains(key)
|
||||
<table className="model">
|
||||
<tbody>
|
||||
{!description ? null : (
|
||||
<tr className="description">
|
||||
<td>description:</td>
|
||||
<td>
|
||||
<Markdown source={description} />
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{externalDocsUrl && (
|
||||
<tr className={"external-docs"}>
|
||||
<td>externalDocs:</td>
|
||||
<td>
|
||||
<Link
|
||||
target="_blank"
|
||||
href={sanitizeUrl(externalDocsUrl)}
|
||||
>
|
||||
{externalDocsDescription || externalDocsUrl}
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!deprecated ? null : (
|
||||
<tr className={"property"}>
|
||||
<td>deprecated:</td>
|
||||
<td>true</td>
|
||||
</tr>
|
||||
)}
|
||||
{!(properties && properties.size)
|
||||
? null
|
||||
: properties
|
||||
.entrySeq()
|
||||
.filter(([, value]) => {
|
||||
return (
|
||||
(!value.get("readOnly") || includeReadOnly) &&
|
||||
(!value.get("writeOnly") || includeWriteOnly)
|
||||
)
|
||||
})
|
||||
.map(([key, value]) => {
|
||||
let isDeprecated = isOAS3() && value.get("deprecated")
|
||||
let isRequired =
|
||||
List.isList(requiredProperties) &&
|
||||
requiredProperties.contains(key)
|
||||
|
||||
let classNames = ["property-row"]
|
||||
let classNames = ["property-row"]
|
||||
|
||||
if (isDeprecated) {
|
||||
classNames.push("deprecated")
|
||||
}
|
||||
if (isDeprecated) {
|
||||
classNames.push("deprecated")
|
||||
}
|
||||
|
||||
if (isRequired) {
|
||||
classNames.push("required")
|
||||
}
|
||||
if (isRequired) {
|
||||
classNames.push("required")
|
||||
}
|
||||
|
||||
return (<tr key={key} className={classNames.join(" ")}>
|
||||
<td>
|
||||
{ key }{ isRequired && <span className="star">*</span> }
|
||||
</td>
|
||||
<td>
|
||||
<Model key={ `object-${name}-${key}_${value}` } { ...otherProps }
|
||||
required={ isRequired }
|
||||
getComponent={ getComponent }
|
||||
specPath={specPath.push("properties", key)}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ value }
|
||||
depth={ depth + 1 } />
|
||||
</td>
|
||||
</tr>)
|
||||
}).toArray()
|
||||
}
|
||||
{
|
||||
// empty row before extensions...
|
||||
!showExtensions ? null : <tr><td> </td></tr>
|
||||
}
|
||||
{
|
||||
!showExtensions ? null :
|
||||
schema.entrySeq().map(
|
||||
([key, value]) => {
|
||||
if(key.slice(0,2) !== "x-") {
|
||||
return
|
||||
}
|
||||
|
||||
const normalizedValue = !value ? null : value.toJS ? value.toJS() : value
|
||||
|
||||
return (<tr key={key} className="extension">
|
||||
<td>
|
||||
{ key }
|
||||
</td>
|
||||
<td>
|
||||
{ JSON.stringify(normalizedValue) }
|
||||
</td>
|
||||
</tr>)
|
||||
}).toArray()
|
||||
}
|
||||
{
|
||||
!additionalProperties || !additionalProperties.size ? null
|
||||
: <tr>
|
||||
<td>{ "< * >:" }</td>
|
||||
<td>
|
||||
<Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={specPath.push("additionalProperties")}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ additionalProperties }
|
||||
depth={ depth + 1 } />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
!allOf ? null
|
||||
: <tr>
|
||||
<td>{ "allOf ->" }</td>
|
||||
<td>
|
||||
{allOf.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={specPath.push("allOf", k)}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
})}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
!anyOf ? null
|
||||
: <tr>
|
||||
<td>{ "anyOf ->" }</td>
|
||||
<td>
|
||||
{anyOf.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={specPath.push("anyOf", k)}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
})}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
!oneOf ? null
|
||||
: <tr>
|
||||
<td>{ "oneOf ->" }</td>
|
||||
<td>
|
||||
{oneOf.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={specPath.push("oneOf", k)}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
})}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
!not ? null
|
||||
: <tr>
|
||||
<td>{ "not ->" }</td>
|
||||
<td>
|
||||
<div>
|
||||
<Model { ...otherProps }
|
||||
required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={specPath.push("not")}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ not }
|
||||
depth={ depth + 1 } />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody></table>
|
||||
}
|
||||
</span>
|
||||
<span className="brace-close">{ braceClose }</span>
|
||||
</ModelCollapse>
|
||||
{
|
||||
infoProperties.size ? infoProperties.entrySeq().map( ( [ key, v ] ) => <Property key={`${key}-${v}`} propKey={ key } propVal={ v } propClass={ propClass } />) : null
|
||||
}
|
||||
</span>
|
||||
return (
|
||||
<tr key={key} className={classNames.join(" ")}>
|
||||
<td>
|
||||
{key}
|
||||
{isRequired && <span className="star">*</span>}
|
||||
</td>
|
||||
<td>
|
||||
<Model
|
||||
key={`object-${name}-${key}_${value}`}
|
||||
{...otherProps}
|
||||
required={isRequired}
|
||||
getComponent={getComponent}
|
||||
specPath={specPath.push("properties", key)}
|
||||
getConfigs={getConfigs}
|
||||
schema={value}
|
||||
depth={depth + 1}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})
|
||||
.toArray()}
|
||||
{extensions.size === 0 ? null : (
|
||||
<>
|
||||
<tr>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<ModelExtensions
|
||||
extensions={extensions}
|
||||
propClass="extension"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{!additionalProperties ||
|
||||
!additionalProperties.size ? null : (
|
||||
<tr>
|
||||
<td>{"< * >:"}</td>
|
||||
<td>
|
||||
<Model
|
||||
{...otherProps}
|
||||
required={false}
|
||||
getComponent={getComponent}
|
||||
specPath={specPath.push("additionalProperties")}
|
||||
getConfigs={getConfigs}
|
||||
schema={additionalProperties}
|
||||
depth={depth + 1}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!allOf ? null : (
|
||||
<tr>
|
||||
<td>{"allOf ->"}</td>
|
||||
<td>
|
||||
{allOf.map((schema, k) => {
|
||||
return (
|
||||
<div key={k}>
|
||||
<Model
|
||||
{...otherProps}
|
||||
required={false}
|
||||
getComponent={getComponent}
|
||||
specPath={specPath.push("allOf", k)}
|
||||
getConfigs={getConfigs}
|
||||
schema={schema}
|
||||
depth={depth + 1}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!anyOf ? null : (
|
||||
<tr>
|
||||
<td>{"anyOf ->"}</td>
|
||||
<td>
|
||||
{anyOf.map((schema, k) => {
|
||||
return (
|
||||
<div key={k}>
|
||||
<Model
|
||||
{...otherProps}
|
||||
required={false}
|
||||
getComponent={getComponent}
|
||||
specPath={specPath.push("anyOf", k)}
|
||||
getConfigs={getConfigs}
|
||||
schema={schema}
|
||||
depth={depth + 1}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!oneOf ? null : (
|
||||
<tr>
|
||||
<td>{"oneOf ->"}</td>
|
||||
<td>
|
||||
{oneOf.map((schema, k) => {
|
||||
return (
|
||||
<div key={k}>
|
||||
<Model
|
||||
{...otherProps}
|
||||
required={false}
|
||||
getComponent={getComponent}
|
||||
specPath={specPath.push("oneOf", k)}
|
||||
getConfigs={getConfigs}
|
||||
schema={schema}
|
||||
depth={depth + 1}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!not ? null : (
|
||||
<tr>
|
||||
<td>{"not ->"}</td>
|
||||
<td>
|
||||
<div>
|
||||
<Model
|
||||
{...otherProps}
|
||||
required={false}
|
||||
getComponent={getComponent}
|
||||
specPath={specPath.push("not")}
|
||||
getConfigs={getConfigs}
|
||||
schema={not}
|
||||
depth={depth + 1}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</span>
|
||||
<span className="brace-close">{braceClose}</span>
|
||||
</ModelCollapse>
|
||||
{infoProperties.size
|
||||
? infoProperties
|
||||
.entrySeq()
|
||||
.map(([key, v]) => (
|
||||
<Property
|
||||
key={`${key}-${v}`}
|
||||
propKey={key}
|
||||
propVal={v}
|
||||
propClass={propClass}
|
||||
/>
|
||||
))
|
||||
: null}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { Component } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { getExtensions, sanitizeUrl } from "core/utils"
|
||||
import { getExtensions } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
|
||||
const propClass = "property primitive"
|
||||
|
||||
@@ -12,11 +16,19 @@ export default class Primitive extends Component {
|
||||
name: PropTypes.string,
|
||||
displayName: PropTypes.string,
|
||||
depth: PropTypes.number,
|
||||
expandDepth: PropTypes.number
|
||||
expandDepth: PropTypes.number,
|
||||
}
|
||||
|
||||
render() {
|
||||
let { schema, getComponent, getConfigs, name, displayName, depth, expandDepth } = this.props
|
||||
let {
|
||||
schema,
|
||||
getComponent,
|
||||
getConfigs,
|
||||
name,
|
||||
displayName,
|
||||
depth,
|
||||
expandDepth,
|
||||
} = this.props
|
||||
|
||||
const { showExtensions } = getConfigs()
|
||||
|
||||
@@ -31,9 +43,20 @@ export default class Primitive extends Component {
|
||||
let enumArray = schema.get("enum")
|
||||
let title = schema.get("title") || displayName || name
|
||||
let description = schema.get("description")
|
||||
let extensions = getExtensions(schema)
|
||||
const extensions = getExtensions(schema)
|
||||
|
||||
let properties = schema
|
||||
.filter((_, key) => ["enum", "type", "format", "description", "$$ref", "externalDocs"].indexOf(key) === -1)
|
||||
.filter(
|
||||
(_, key) =>
|
||||
[
|
||||
"enum",
|
||||
"type",
|
||||
"format",
|
||||
"description",
|
||||
"$$ref",
|
||||
"externalDocs",
|
||||
].indexOf(key) === -1
|
||||
)
|
||||
.filterNot((_, key) => extensions.has(key))
|
||||
let externalDocsUrl = schema.getIn(["externalDocs", "url"])
|
||||
let externalDocsDescription = schema.getIn(["externalDocs", "description"])
|
||||
@@ -43,46 +66,72 @@ export default class Primitive extends Component {
|
||||
const Property = getComponent("Property")
|
||||
const ModelCollapse = getComponent("ModelCollapse")
|
||||
const Link = getComponent("Link")
|
||||
const ModelExtensions = getComponent("ModelExtensions")
|
||||
|
||||
const titleEl = title &&
|
||||
const titleEl = title && (
|
||||
<span className="model-title">
|
||||
<span className="model-title__text">{title}</span>
|
||||
</span>
|
||||
)
|
||||
|
||||
return <span className="model">
|
||||
<ModelCollapse title={titleEl} expanded={depth <= expandDepth} collapsedContent="[...]">
|
||||
<span className="prop">
|
||||
{name && depth > 1 && <span className="prop-name">{title}</span>}
|
||||
<span className="prop-type">{type}</span>
|
||||
{format && <span className="prop-format">(${format})</span>}
|
||||
{
|
||||
properties.size ? properties.entrySeq().map(([key, v]) => <Property key={`${key}-${v}`} propKey={key} propVal={v} propClass={propClass} />) : null
|
||||
}
|
||||
{
|
||||
showExtensions && extensions.size ? extensions.entrySeq().map(([key, v]) => <Property key={`${key}-${v}`} propKey={key} propVal={v} propClass={propClass} />) : null
|
||||
}
|
||||
{
|
||||
!description ? null :
|
||||
<Markdown source={description} />
|
||||
}
|
||||
{
|
||||
externalDocsUrl &&
|
||||
<div className="external-docs">
|
||||
<Link target="_blank" href={sanitizeUrl(externalDocsUrl)}>{externalDocsDescription || externalDocsUrl}</Link>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
xml && xml.size ? (<span><br /><span className={propClass}>xml:</span>
|
||||
{
|
||||
xml.entrySeq().map(([key, v]) => <span key={`${key}-${v}`} className={propClass}><br /> {key}: {String(v)}</span>).toArray()
|
||||
}
|
||||
</span>) : null
|
||||
}
|
||||
{
|
||||
enumArray && <EnumModel value={enumArray} getComponent={getComponent} />
|
||||
}
|
||||
</span>
|
||||
</ModelCollapse>
|
||||
</span>
|
||||
return (
|
||||
<span className="model">
|
||||
<ModelCollapse
|
||||
title={titleEl}
|
||||
expanded={depth <= expandDepth}
|
||||
collapsedContent="[...]"
|
||||
>
|
||||
<span className="prop">
|
||||
{name && depth > 1 && <span className="prop-name">{title}</span>}
|
||||
<span className="prop-type">{type}</span>
|
||||
{format && <span className="prop-format">(${format})</span>}
|
||||
{properties.size
|
||||
? properties
|
||||
.entrySeq()
|
||||
.map(([key, v]) => (
|
||||
<Property
|
||||
key={`${key}-${v}`}
|
||||
propKey={key}
|
||||
propVal={v}
|
||||
propClass={propClass}
|
||||
/>
|
||||
))
|
||||
: null}
|
||||
{showExtensions && extensions.size > 0 ? (
|
||||
<ModelExtensions
|
||||
extensions={extensions}
|
||||
propClass={`${propClass} extension`}
|
||||
/>
|
||||
) : null}
|
||||
{!description ? null : <Markdown source={description} />}
|
||||
{externalDocsUrl && (
|
||||
<div className="external-docs">
|
||||
<Link target="_blank" href={sanitizeUrl(externalDocsUrl)}>
|
||||
{externalDocsDescription || externalDocsUrl}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
{xml && xml.size ? (
|
||||
<span>
|
||||
<br />
|
||||
<span className={propClass}>xml:</span>
|
||||
{xml
|
||||
.entrySeq()
|
||||
.map(([key, v]) => (
|
||||
<span key={`${key}-${v}`} className={propClass}>
|
||||
<br />
|
||||
{key}: {String(v)}
|
||||
</span>
|
||||
))
|
||||
.toArray()}
|
||||
</span>
|
||||
) : null}
|
||||
{enumArray && (
|
||||
<EnumModel value={enumArray} getComponent={getComponent} />
|
||||
)}
|
||||
</span>
|
||||
</ModelCollapse>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import PrimitiveModel from "./components/primitive-model"
|
||||
import Schemes from "./components/schemes"
|
||||
import SchemesContainer from "./containers/schemes"
|
||||
import * as JSONSchemaComponents from "./components/json-schema-components"
|
||||
import { ModelExtensions } from "./components/model-extensions"
|
||||
|
||||
const JSONSchema5Plugin = () => ({
|
||||
components: {
|
||||
@@ -25,6 +26,7 @@ const JSONSchema5Plugin = () => ({
|
||||
ObjectModel,
|
||||
ArrayModel,
|
||||
PrimitiveModel,
|
||||
ModelExtensions,
|
||||
schemes: Schemes,
|
||||
SchemesContainer,
|
||||
...JSONSchemaComponents,
|
||||
|
||||
@@ -32,7 +32,7 @@ export const definitionsToAuthorize = onlyOAS3(createSelector(
|
||||
}
|
||||
|
||||
definitions.entrySeq().forEach( ([ defName, definition ]) => {
|
||||
const type = definition.get("type")
|
||||
const type = definition?.get("type")
|
||||
|
||||
if(type === "oauth2") {
|
||||
definition.get("flows").entrySeq().forEach(([flowKey, flowVal]) => {
|
||||
|
||||
@@ -8,7 +8,8 @@ export default class HttpAuth extends React.Component {
|
||||
errSelectors: PropTypes.object.isRequired,
|
||||
schema: PropTypes.object.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func
|
||||
onChange: PropTypes.func,
|
||||
authSelectors: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
constructor(props, context) {
|
||||
@@ -46,7 +47,7 @@ export default class HttpAuth extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let { schema, getComponent, errSelectors, name } = this.props
|
||||
let { schema, getComponent, errSelectors, name, authSelectors } = this.props
|
||||
const Input = getComponent("Input")
|
||||
const Row = getComponent("Row")
|
||||
const Col = getComponent("Col")
|
||||
@@ -55,6 +56,7 @@ export default class HttpAuth extends React.Component {
|
||||
const JumpToPath = getComponent("JumpToPath", true)
|
||||
|
||||
const scheme = (schema.get("scheme") || "").toLowerCase()
|
||||
const path = authSelectors.selectAuthPath(name)
|
||||
let value = this.getValue()
|
||||
let errors = errSelectors.allErrors().filter( err => err.get("authId") === name)
|
||||
|
||||
@@ -62,9 +64,9 @@ export default class HttpAuth extends React.Component {
|
||||
let username = value ? value.get("username") : null
|
||||
return <div>
|
||||
<h4>
|
||||
<code>{ name || schema.get("name") }</code>
|
||||
<code>{name}</code>
|
||||
(http, Basic)
|
||||
<JumpToPath path={[ "securityDefinitions", name ]} />
|
||||
<JumpToPath path={path} />
|
||||
</h4>
|
||||
{ username && <h6>Authorized</h6> }
|
||||
<Row>
|
||||
@@ -116,9 +118,9 @@ export default class HttpAuth extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
<h4>
|
||||
<code>{ name || schema.get("name") }</code>
|
||||
<code>{name}</code>
|
||||
(http, Bearer)
|
||||
<JumpToPath path={[ "securityDefinitions", name ]} />
|
||||
<JumpToPath path={path} />
|
||||
</h4>
|
||||
{ value && <h6>Authorized</h6>}
|
||||
<Row>
|
||||
|
||||
@@ -2,9 +2,11 @@ import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import { Map, OrderedMap, List, fromJS } from "immutable"
|
||||
import { getCommonExtensions, stringify, isEmptyValue } from "core/utils"
|
||||
import { getCommonExtensions, stringify, isEmptyValue, immutableToJS } from "core/utils"
|
||||
import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse"
|
||||
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
|
||||
export const getDefaultRequestBodyValue = (requestBody, mediaType, activeExamplesKey, fn) => {
|
||||
const mediaTypeValue = requestBody.getIn(["content", mediaType]) ?? OrderedMap()
|
||||
const schema = mediaTypeValue.get("schema", OrderedMap()).toJS()
|
||||
@@ -159,7 +161,9 @@ const RequestBody = ({
|
||||
|
||||
let commonExt = showCommonExtensions ? getCommonExtensions(schema) : null
|
||||
const required = schemaForMediaType.get("required", List()).includes(key)
|
||||
const type = schema.get("type")
|
||||
const typeLabel = fn.jsonSchema202012.getType(immutableToJS(schema))
|
||||
const type = fn.jsonSchema202012.foldType(immutableToJS(schema?.get("type")))
|
||||
const itemType = fn.jsonSchema202012.foldType(immutableToJS(schema?.getIn(["items", "type"])))
|
||||
const format = schema.get("format")
|
||||
const description = schema.get("description")
|
||||
const currentValue = requestBodyValue.getIn([key, "value"])
|
||||
@@ -188,6 +192,20 @@ const RequestBody = ({
|
||||
|
||||
const isFile = type === "string" && (format === "binary" || format === "base64")
|
||||
|
||||
const jsonSchemaForm = <JsonSchemaForm
|
||||
fn={fn}
|
||||
dispatchInitialValue={!isFile}
|
||||
schema={schema}
|
||||
description={key}
|
||||
getComponent={getComponent}
|
||||
value={currentValue === undefined ? initialValue : currentValue}
|
||||
required={required}
|
||||
errors={currentErrors}
|
||||
onChange={(value) => {
|
||||
onChange(value, [key])
|
||||
}}
|
||||
/>
|
||||
|
||||
return <tr key={key} className="parameters" data-property-name={key}>
|
||||
<td className="parameters-col_name">
|
||||
<div className={required ? "parameter__name required" : "parameter__name"}>
|
||||
@@ -195,7 +213,7 @@ const RequestBody = ({
|
||||
{ !required ? null : <span> *</span> }
|
||||
</div>
|
||||
<div className="parameter__type">
|
||||
{ type }
|
||||
{ typeLabel }
|
||||
{ format && <span className="prop-format">(${format})</span>}
|
||||
{!showCommonExtensions || !commonExt.size ? null : commonExt.entrySeq().map(([key, v]) => <ParameterExt key={`${key}-${v}`} xKey={key} xVal={v} />)}
|
||||
</div>
|
||||
@@ -206,19 +224,18 @@ const RequestBody = ({
|
||||
<td className="parameters-col_description">
|
||||
<Markdown source={ description }></Markdown>
|
||||
{isExecute ? <div>
|
||||
<JsonSchemaForm
|
||||
fn={fn}
|
||||
dispatchInitialValue={!isFile}
|
||||
schema={schema}
|
||||
description={key}
|
||||
getComponent={getComponent}
|
||||
value={currentValue === undefined ? initialValue : currentValue}
|
||||
required = { required }
|
||||
errors = { currentErrors }
|
||||
onChange={(value) => {
|
||||
onChange(value, [key])
|
||||
}}
|
||||
/>
|
||||
{(type === "object" || itemType === "object") ? (
|
||||
<ModelExample
|
||||
getComponent={getComponent}
|
||||
specPath={specPath.push("schema")}
|
||||
getConfigs={getConfigs}
|
||||
isExecute={isExecute}
|
||||
specSelectors={specSelectors}
|
||||
schema={schema}
|
||||
example={jsonSchemaForm}
|
||||
/>
|
||||
) : jsonSchemaForm
|
||||
}
|
||||
{required ? null : (
|
||||
<ParameterIncludeEmpty
|
||||
onChange={(value) => onChangeIncludeEmpty(key, value)}
|
||||
|
||||
@@ -52,7 +52,10 @@ export const findSchema = (state, schemaName) => {
|
||||
["resolvedSubtrees", "components", "schemas", schemaName],
|
||||
null
|
||||
)
|
||||
const unresolvedSchema = state.getIn(["json", "components", "schemas", schemaName], null)
|
||||
const unresolvedSchema = state.getIn(
|
||||
["json", "components", "schemas", schemaName],
|
||||
null
|
||||
)
|
||||
|
||||
return resolvedSchema || unresolvedSchema || null
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { OAS3ComponentWrapFactory } from "../../helpers"
|
||||
|
||||
export default OAS3ComponentWrapFactory(({ Ori, ...props }) => {
|
||||
const {
|
||||
schema, getComponent, errSelectors, authorized, onAuthChange, name
|
||||
schema, getComponent, errSelectors, authorized, onAuthChange, name, authSelectors
|
||||
} = props
|
||||
|
||||
const HttpAuth = getComponent("HttpAuth")
|
||||
@@ -17,7 +17,8 @@ export default OAS3ComponentWrapFactory(({ Ori, ...props }) => {
|
||||
errSelectors={ errSelectors }
|
||||
authorized={ authorized }
|
||||
getComponent={ getComponent }
|
||||
onChange={ onAuthChange }/>
|
||||
onChange={ onAuthChange }
|
||||
authSelectors= { authSelectors }/>
|
||||
} else {
|
||||
return <Ori {...props} />
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export const definitionsToAuthorize = createOnlyOAS31SelectorWrapper(
|
||||
if (!definitions) return list
|
||||
|
||||
definitions.entrySeq().forEach(([defName, definition]) => {
|
||||
const type = definition.get("type")
|
||||
const type = definition?.get("type")
|
||||
|
||||
if (type === "mutualTLS") {
|
||||
list = list.push(
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
@import './model/model';
|
||||
@import './models/models';
|
||||
@use "./model/model";
|
||||
@use "./models/models";
|
||||
|
||||
@@ -96,6 +96,7 @@ class Auths extends React.Component {
|
||||
onAuthChange={this.onAuthChange}
|
||||
authorized={authorized}
|
||||
errSelectors={errSelectors}
|
||||
authSelectors={authSelectors}
|
||||
/>
|
||||
)
|
||||
})
|
||||
@@ -110,7 +111,7 @@ class Auths extends React.Component {
|
||||
Logout
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
<Button
|
||||
type="submit"
|
||||
className="btn modal-btn auth authorize"
|
||||
aria-label="Apply credentials"
|
||||
@@ -170,6 +171,7 @@ class Auths extends React.Component {
|
||||
onAuthChange={this.onAuthChange}
|
||||
authorized={authorized}
|
||||
errSelectors={errSelectors}
|
||||
authSelectors={authSelectors}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
const MutualTLSAuth = ({ schema, getComponent }) => {
|
||||
const MutualTLSAuth = ({ schema, getComponent, name, authSelectors }) => {
|
||||
const JumpToPath = getComponent("JumpToPath", true)
|
||||
const path = authSelectors.selectAuthPath(name)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4>
|
||||
{schema.get("name")} (mutualTLS){" "}
|
||||
<JumpToPath path={["securityDefinitions", schema.get("name")]} />
|
||||
{name} (mutualTLS) <JumpToPath path={path} />
|
||||
</h4>
|
||||
<p>
|
||||
Mutual TLS is required by this API/Operation. Certificates are managed
|
||||
@@ -24,6 +25,8 @@ const MutualTLSAuth = ({ schema, getComponent }) => {
|
||||
MutualTLSAuth.propTypes = {
|
||||
schema: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
authSelectors: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
export default MutualTLSAuth
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
import { sanitizeUrl } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
|
||||
const Contact = ({ getComponent, specSelectors }) => {
|
||||
const name = specSelectors.selectContactNameField()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
import { sanitizeUrl } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
|
||||
const Info = ({ getComponent, specSelectors }) => {
|
||||
const version = specSelectors.version()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
import { sanitizeUrl } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
|
||||
const JsonSchemaDialect = ({ getComponent, specSelectors }) => {
|
||||
const jsonSchemaDialect = specSelectors.selectJsonSchemaDialectField()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
import { sanitizeUrl } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
|
||||
const License = ({ getComponent, specSelectors }) => {
|
||||
const name = specSelectors.selectLicenseNameField()
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
.model-box {
|
||||
// inferred names of Schema Objects
|
||||
& .json-schema-2020-12:not(.json-schema-2020-12--embedded) > .json-schema-2020-12-head .json-schema-2020-12__title:first-of-type {
|
||||
&
|
||||
.json-schema-2020-12:not(.json-schema-2020-12--embedded)
|
||||
> .json-schema-2020-12-head
|
||||
.json-schema-2020-12__title:first-of-type {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@@ -13,7 +16,8 @@
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.json-schema-2020-12-accordion, .json-schema-2020-12-expand-deep-button {
|
||||
background-color: transparent;
|
||||
.json-schema-2020-12-accordion,
|
||||
.json-schema-2020-12-expand-deep-button {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ const getModelName = (uri) => {
|
||||
}
|
||||
|
||||
const Model = forwardRef(
|
||||
({ schema, getComponent, onToggle = () => {} }, ref) => {
|
||||
({ schema, getComponent, onToggle = () => {}, specPath }, ref) => {
|
||||
const JSONSchema202012 = getComponent("JSONSchema202012")
|
||||
const name = getModelName(schema.get("$$ref"))
|
||||
|
||||
@@ -38,6 +38,7 @@ const Model = forwardRef(
|
||||
schema={schema.toJS()}
|
||||
ref={ref}
|
||||
onExpand={handleExpand}
|
||||
identifier={specPath.toJS().join("_")}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -47,6 +48,7 @@ Model.propTypes = {
|
||||
schema: ImPropTypes.map.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
onToggle: PropTypes.func,
|
||||
specPath: ImPropTypes.list.isRequired,
|
||||
}
|
||||
|
||||
export default Model
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
.models .json-schema-2020-12:not(.json-schema-2020-12--embedded) > .json-schema-2020-12-head .json-schema-2020-12__title:first-of-type {
|
||||
.models
|
||||
.json-schema-2020-12:not(.json-schema-2020-12--embedded)
|
||||
> .json-schema-2020-12-head
|
||||
.json-schema-2020-12__title:first-of-type {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.models .json-schema-2020-12:not(.json-schema-2020-12--embedded) {
|
||||
width: calc(100% - 40px);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
@@ -115,8 +115,8 @@ export const wrapOAS31Fn = (fn, system) => {
|
||||
specSelectors.isOAS31()
|
||||
? newImpl(...args)
|
||||
: typeof oriImpl === "function"
|
||||
? oriImpl(...args)
|
||||
: undefined
|
||||
? oriImpl(...args)
|
||||
: undefined
|
||||
|
||||
return [name, impl]
|
||||
})
|
||||
|
||||
@@ -59,9 +59,10 @@ 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 JSONSchema202012KeywordDiscriminator from "./json-schema-2020-12-extensions/components/keywords/Discriminator/Discriminator"
|
||||
import OpenAPIExtensions from "./json-schema-2020-12-extensions/components/keywords/OpenAPIExtensions"
|
||||
import JSONSchema202012KeywordExternalDocs from "./json-schema-2020-12-extensions/components/keywords/ExternalDocs"
|
||||
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 JSONSchema202012KeywordExamplesWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Examples"
|
||||
import JSONSchema202012KeywordPropertiesWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Properties"
|
||||
import afterLoad from "./after-load"
|
||||
|
||||
@@ -91,6 +92,7 @@ const OAS31Plugin = ({ fn }) => {
|
||||
JSONSchema202012KeywordXml,
|
||||
JSONSchema202012KeywordDiscriminator,
|
||||
JSONSchema202012KeywordExternalDocs,
|
||||
OpenAPI31Extensions: OpenAPIExtensions,
|
||||
},
|
||||
wrapComponents: {
|
||||
InfoContainer: InfoWrapper,
|
||||
@@ -103,7 +105,7 @@ const OAS31Plugin = ({ fn }) => {
|
||||
auths: AuthsWrapper,
|
||||
JSONSchema202012KeywordDescription:
|
||||
JSONSchema202012KeywordDescriptionWrapper,
|
||||
JSONSchema202012KeywordDefault: JSONSchema202012KeywordDefaultWrapper,
|
||||
JSONSchema202012KeywordExamples: JSONSchema202012KeywordExamplesWrapper,
|
||||
JSONSchema202012KeywordProperties:
|
||||
JSONSchema202012KeywordPropertiesWrapper,
|
||||
},
|
||||
|
||||
@@ -1,36 +1,50 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import classNames from "classnames"
|
||||
|
||||
import DiscriminatorMapping from "./DiscriminatorMapping"
|
||||
import { getExtensions } from "../../../../../../utils"
|
||||
|
||||
const Discriminator = ({ schema, getSystem }) => {
|
||||
const discriminator = schema?.discriminator || {}
|
||||
const { fn, getComponent } = getSystem()
|
||||
const { useIsExpandedDeeply, useComponent } = fn.jsonSchema202012
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const isExpandable = !!discriminator.mapping
|
||||
const [expanded, setExpanded] = useState(isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const { fn, getComponent, getConfigs } = getSystem()
|
||||
const { showExtensions } = getConfigs()
|
||||
const { useComponent, useIsExpanded, usePath, useLevel } = fn.jsonSchema202012
|
||||
const pathToken = "discriminator"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const extensions = showExtensions ? getExtensions(discriminator) : []
|
||||
const isExpandable = !!(discriminator.mapping || extensions.length > 0)
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONSchemaDeepExpansionContext = getComponent(
|
||||
"JSONSchema202012DeepExpansionContext"
|
||||
)()
|
||||
const OpenAPI31Extensions = getComponent("OpenAPI31Extensions")
|
||||
const JSONSchemaPathContext = getComponent("JSONSchema202012PathContext")()
|
||||
const JSONSchemaLevelContext = getComponent("JSONSchema202012LevelContext")()
|
||||
|
||||
/**
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -40,47 +54,59 @@ const Discriminator = ({ schema, getSystem }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--discriminator">
|
||||
{isExpandable ? (
|
||||
<>
|
||||
<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}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
Discriminator
|
||||
</span>
|
||||
)}
|
||||
|
||||
{discriminator.propertyName && (
|
||||
<span className="json-schema-2020-12__attribute json-schema-2020-12__attribute--muted">
|
||||
{discriminator.propertyName}
|
||||
</span>
|
||||
)}
|
||||
<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,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--discriminator"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
<li className="json-schema-2020-12-property">
|
||||
<DiscriminatorMapping discriminator={discriminator} />
|
||||
</li>
|
||||
{isExpandable ? (
|
||||
<>
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
Discriminator
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
Discriminator
|
||||
</span>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
|
||||
{discriminator.propertyName && (
|
||||
<span className="json-schema-2020-12__attribute json-schema-2020-12__attribute--muted">
|
||||
{discriminator.propertyName}
|
||||
</span>
|
||||
)}
|
||||
<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": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<li className="json-schema-2020-12-property">
|
||||
<DiscriminatorMapping discriminator={discriminator} />
|
||||
</li>
|
||||
)}
|
||||
{extensions.length > 0 && (
|
||||
<OpenAPI31Extensions
|
||||
openAPISpecObj={discriminator}
|
||||
openAPIExtensions={extensions}
|
||||
getSystem={getSystem}
|
||||
/>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,20 +5,18 @@ import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
const Example = ({ schema, getSystem }) => {
|
||||
const { fn } = getSystem()
|
||||
const { hasKeyword, stringify } = fn.jsonSchema202012.useFn()
|
||||
const { fn, getComponent } = getSystem()
|
||||
const { hasKeyword } = fn.jsonSchema202012.useFn()
|
||||
const JSONViewer = getComponent("JSONSchema202012JSONViewer")
|
||||
|
||||
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--secondary">
|
||||
Example
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const">
|
||||
{stringify(schema.example)}
|
||||
</span>
|
||||
</div>
|
||||
<JSONViewer
|
||||
name="Example"
|
||||
value={schema.example}
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--example"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,56 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import classNames from "classnames"
|
||||
|
||||
import { sanitizeUrl } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
import { getExtensions } from "../../../../../utils"
|
||||
|
||||
const ExternalDocs = ({ schema, getSystem }) => {
|
||||
const externalDocs = schema?.externalDocs || {}
|
||||
const { fn, getComponent } = getSystem()
|
||||
const { useIsExpandedDeeply, useComponent } = fn.jsonSchema202012
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const isExpandable = !!(externalDocs.description || externalDocs.url)
|
||||
const [expanded, setExpanded] = useState(isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const { fn, getComponent, getConfigs } = getSystem()
|
||||
const { showExtensions } = getConfigs()
|
||||
const { useComponent, useIsExpanded, usePath, useLevel } = fn.jsonSchema202012
|
||||
const pathToken = "externalDocs"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const extensions = showExtensions ? getExtensions(externalDocs) : []
|
||||
const isExpandable = !!(
|
||||
externalDocs.description ||
|
||||
externalDocs.url ||
|
||||
extensions.length > 0
|
||||
)
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const KeywordDescription = getComponent("JSONSchema202012KeywordDescription")
|
||||
const Link = getComponent("Link")
|
||||
const JSONSchemaDeepExpansionContext = getComponent(
|
||||
"JSONSchema202012DeepExpansionContext"
|
||||
)()
|
||||
const OpenAPI31Extensions = getComponent("OpenAPI31Extensions")
|
||||
const JSONSchemaPathContext = getComponent("JSONSchema202012PathContext")()
|
||||
const JSONSchemaLevelContext = getComponent("JSONSchema202012LevelContext")()
|
||||
|
||||
/**
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -42,66 +60,78 @@ const ExternalDocs = ({ schema, getSystem }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--externalDocs">
|
||||
{isExpandable ? (
|
||||
<>
|
||||
<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}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
External documentation
|
||||
</span>
|
||||
)}
|
||||
<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,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--externalDocs"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
{isExpandable ? (
|
||||
<>
|
||||
{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>
|
||||
)}
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
External documentation
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
External documentation
|
||||
</span>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
<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": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{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>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{extensions.length > 0 && (
|
||||
<OpenAPI31Extensions
|
||||
openAPISpecObj={externalDocs}
|
||||
openAPIExtensions={extensions}
|
||||
getSystem={getSystem}
|
||||
/>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
const OpenAPIExtensions = ({
|
||||
openAPISpecObj,
|
||||
getSystem,
|
||||
openAPIExtensions,
|
||||
}) => {
|
||||
const { fn } = getSystem()
|
||||
const { useComponent } = fn.jsonSchema202012
|
||||
|
||||
const JSONViewer = useComponent("JSONViewer")
|
||||
return openAPIExtensions.map((keyword) => (
|
||||
<JSONViewer
|
||||
key={keyword}
|
||||
name={keyword}
|
||||
value={openAPISpecObj[keyword]}
|
||||
className="json-schema-2020-12-json-viewer-extension-keyword"
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
||||
OpenAPIExtensions.propTypes = {
|
||||
openAPISpecObj: PropTypes.oneOfType([PropTypes.object, PropTypes.bool])
|
||||
.isRequired,
|
||||
getSystem: PropTypes.func.isRequired,
|
||||
openAPIExtensions: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
}
|
||||
|
||||
export default OpenAPIExtensions
|
||||
@@ -6,12 +6,14 @@ import PropTypes from "prop-types"
|
||||
import classNames from "classnames"
|
||||
|
||||
const Properties = ({ schema, getSystem }) => {
|
||||
const { fn } = getSystem()
|
||||
const { useComponent } = fn.jsonSchema202012
|
||||
const { fn, getComponent } = getSystem()
|
||||
const { useComponent, usePath } = fn.jsonSchema202012
|
||||
const { getDependentRequired, getProperties } = fn.jsonSchema202012.useFn()
|
||||
const config = fn.jsonSchema202012.useConfig()
|
||||
const required = Array.isArray(schema?.required) ? schema.required : []
|
||||
const { path } = usePath("properties")
|
||||
const JSONSchema = useComponent("JSONSchema")
|
||||
const JSONSchemaPathContext = getComponent("JSONSchema202012PathContext")()
|
||||
const properties = getProperties(schema, config)
|
||||
|
||||
/**
|
||||
@@ -22,29 +24,31 @@ const Properties = ({ schema, getSystem }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--properties">
|
||||
<ul>
|
||||
{Object.entries(properties).map(([propertyName, propertySchema]) => {
|
||||
const isRequired = required.includes(propertyName)
|
||||
const dependentRequired = getDependentRequired(propertyName, schema)
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--properties">
|
||||
<ul>
|
||||
{Object.entries(properties).map(([propertyName, propertySchema]) => {
|
||||
const isRequired = required.includes(propertyName)
|
||||
const dependentRequired = getDependentRequired(propertyName, schema)
|
||||
|
||||
return (
|
||||
<li
|
||||
key={propertyName}
|
||||
className={classNames("json-schema-2020-12-property", {
|
||||
"json-schema-2020-12-property--required": isRequired,
|
||||
})}
|
||||
>
|
||||
<JSONSchema
|
||||
name={propertyName}
|
||||
schema={propertySchema}
|
||||
dependentRequired={dependentRequired}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
return (
|
||||
<li
|
||||
key={propertyName}
|
||||
className={classNames("json-schema-2020-12-property", {
|
||||
"json-schema-2020-12-property--required": isRequired,
|
||||
})}
|
||||
>
|
||||
<JSONSchema
|
||||
name={propertyName}
|
||||
schema={propertySchema}
|
||||
dependentRequired={dependentRequired}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +1,53 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import React, { useCallback, useState } from "react"
|
||||
import React, { useCallback } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import classNames from "classnames"
|
||||
import { getExtensions } from "../../../../../utils"
|
||||
|
||||
const Xml = ({ schema, getSystem }) => {
|
||||
const xml = schema?.xml || {}
|
||||
const { fn, getComponent } = getSystem()
|
||||
const { useIsExpandedDeeply, useComponent } = fn.jsonSchema202012
|
||||
const isExpandedDeeply = useIsExpandedDeeply()
|
||||
const isExpandable = !!(xml.name || xml.namespace || xml.prefix)
|
||||
const [expanded, setExpanded] = useState(isExpandedDeeply)
|
||||
const [expandedDeeply, setExpandedDeeply] = useState(false)
|
||||
const { fn, getComponent, getConfigs } = getSystem()
|
||||
const { showExtensions } = getConfigs()
|
||||
const { useComponent, useIsExpanded, usePath, useLevel } = fn.jsonSchema202012
|
||||
const pathToken = "xml"
|
||||
const { path } = usePath(pathToken)
|
||||
const { isExpanded, setExpanded, setCollapsed } = useIsExpanded(pathToken)
|
||||
const [level, nextLevel] = useLevel()
|
||||
const extensions = showExtensions ? getExtensions(xml) : []
|
||||
const isExpandable = !!(
|
||||
xml.name ||
|
||||
xml.namespace ||
|
||||
xml.prefix ||
|
||||
extensions.length > 0
|
||||
)
|
||||
const Accordion = useComponent("Accordion")
|
||||
const ExpandDeepButton = useComponent("ExpandDeepButton")
|
||||
const JSONSchemaDeepExpansionContext = getComponent(
|
||||
"JSONSchema202012DeepExpansionContext"
|
||||
)()
|
||||
const OpenAPI31Extensions = getComponent("OpenAPI31Extensions")
|
||||
const JSONSchemaPathContext = getComponent("JSONSchema202012PathContext")()
|
||||
const JSONSchemaLevelContext = getComponent("JSONSchema202012LevelContext")()
|
||||
|
||||
/**
|
||||
* Event handlers.
|
||||
*/
|
||||
const handleExpansion = useCallback(() => {
|
||||
setExpanded((prev) => !prev)
|
||||
}, [])
|
||||
const handleExpansionDeep = useCallback((e, expandedDeepNew) => {
|
||||
setExpanded(expandedDeepNew)
|
||||
setExpandedDeeply(expandedDeepNew)
|
||||
}, [])
|
||||
if (isExpanded) {
|
||||
setCollapsed()
|
||||
} else {
|
||||
setExpanded()
|
||||
}
|
||||
}, [isExpanded, setExpanded, setCollapsed])
|
||||
const handleExpansionDeep = useCallback(
|
||||
(e, expandedDeepNew) => {
|
||||
if (expandedDeepNew) {
|
||||
setExpanded({ deep: true })
|
||||
} else {
|
||||
setCollapsed({ deep: true })
|
||||
}
|
||||
},
|
||||
[setExpanded, setCollapsed]
|
||||
)
|
||||
|
||||
/**
|
||||
* Rendering.
|
||||
@@ -38,88 +57,100 @@ const Xml = ({ schema, getSystem }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
|
||||
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--xml">
|
||||
{isExpandable ? (
|
||||
<>
|
||||
<Accordion expanded={expanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
XML
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={expanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
XML
|
||||
</span>
|
||||
)}
|
||||
{xml.attribute === true && (
|
||||
<span className="json-schema-2020-12__attribute json-schema-2020-12__attribute--muted">
|
||||
attribute
|
||||
</span>
|
||||
)}
|
||||
{xml.wrapped === true && (
|
||||
<span className="json-schema-2020-12__attribute json-schema-2020-12__attribute--muted">
|
||||
wrapped
|
||||
</span>
|
||||
)}
|
||||
<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,
|
||||
})}
|
||||
<JSONSchemaPathContext.Provider value={path}>
|
||||
<JSONSchemaLevelContext.Provider value={nextLevel}>
|
||||
<div
|
||||
className="json-schema-2020-12-keyword json-schema-2020-12-keyword--xml"
|
||||
data-json-schema-level={level}
|
||||
>
|
||||
{expanded && (
|
||||
{isExpandable ? (
|
||||
<>
|
||||
{xml.name && (
|
||||
<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">
|
||||
name
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||
{xml.name}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{xml.namespace && (
|
||||
<li className="json-schema-2020-12-property">
|
||||
<div className="json-schema-2020-12-keyword">
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
namespace
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||
{xml.namespace}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{xml.prefix && (
|
||||
<li className="json-schema-2020-12-property">
|
||||
<div className="json-schema-2020-12-keyword">
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
prefix
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||
{xml.prefix}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
<Accordion expanded={isExpanded} onChange={handleExpansion}>
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
XML
|
||||
</span>
|
||||
</Accordion>
|
||||
<ExpandDeepButton
|
||||
expanded={isExpanded}
|
||||
onClick={handleExpansionDeep}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
XML
|
||||
</span>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaDeepExpansionContext.Provider>
|
||||
{xml.attribute === true && (
|
||||
<span className="json-schema-2020-12__attribute json-schema-2020-12__attribute--muted">
|
||||
attribute
|
||||
</span>
|
||||
)}
|
||||
{xml.wrapped === true && (
|
||||
<span className="json-schema-2020-12__attribute json-schema-2020-12__attribute--muted">
|
||||
wrapped
|
||||
</span>
|
||||
)}
|
||||
<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": !isExpanded,
|
||||
})}
|
||||
>
|
||||
{isExpanded && (
|
||||
<>
|
||||
{xml.name && (
|
||||
<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">
|
||||
name
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||
{xml.name}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{xml.namespace && (
|
||||
<li className="json-schema-2020-12-property">
|
||||
<div className="json-schema-2020-12-keyword">
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
namespace
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||
{xml.namespace}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{xml.prefix && (
|
||||
<li className="json-schema-2020-12-property">
|
||||
<div className="json-schema-2020-12-keyword">
|
||||
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary">
|
||||
prefix
|
||||
</span>
|
||||
<span className="json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary">
|
||||
{xml.prefix}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{extensions.length > 0 && (
|
||||
<OpenAPI31Extensions
|
||||
openAPISpecObj={xml}
|
||||
openAPIExtensions={extensions}
|
||||
getSystem={getSystem}
|
||||
/>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</JSONSchemaLevelContext.Provider>
|
||||
</JSONSchemaPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,3 +37,21 @@ export const getProperties = (
|
||||
|
||||
return Object.fromEntries(filteredProperties)
|
||||
}
|
||||
|
||||
export const makeGetSchemaKeywords = (original) => {
|
||||
if (typeof original !== "function") {
|
||||
return null
|
||||
}
|
||||
|
||||
const jsonSchema202012Keywords = original()
|
||||
|
||||
return () => [
|
||||
...jsonSchema202012Keywords,
|
||||
"discriminator",
|
||||
"xml",
|
||||
"externalDocs",
|
||||
"example",
|
||||
// $$ref is an internal keyword used for dereferencing
|
||||
"$$ref",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
import React from "react"
|
||||
import { createOnlyOAS31ComponentWrapper } from "../../../fn"
|
||||
|
||||
const DefaultWrapper = createOnlyOAS31ComponentWrapper(
|
||||
({ schema, getSystem, originalComponent: KeywordDefault }) => {
|
||||
const ExamplesWrapper = createOnlyOAS31ComponentWrapper(
|
||||
({ schema, getSystem, originalComponent: KeywordExamples }) => {
|
||||
const { getComponent } = getSystem()
|
||||
const KeywordDiscriminator = getComponent(
|
||||
"JSONSchema202012KeywordDiscriminator"
|
||||
@@ -18,7 +18,7 @@ const DefaultWrapper = createOnlyOAS31ComponentWrapper(
|
||||
|
||||
return (
|
||||
<>
|
||||
<KeywordDefault schema={schema} />
|
||||
<KeywordExamples schema={schema} />
|
||||
<KeywordDiscriminator schema={schema} getSystem={getSystem} />
|
||||
<KeywordXml schema={schema} getSystem={getSystem} />
|
||||
<KeywordExternalDocs schema={schema} getSystem={getSystem} />
|
||||
@@ -28,4 +28,4 @@ const DefaultWrapper = createOnlyOAS31ComponentWrapper(
|
||||
}
|
||||
)
|
||||
|
||||
export default DefaultWrapper
|
||||
export default ExamplesWrapper
|
||||
@@ -7,12 +7,12 @@ import { createOnlyOAS31ComponentWrapper } from "../../fn"
|
||||
|
||||
const AuthItem = createOnlyOAS31ComponentWrapper(
|
||||
({ originalComponent: Ori, ...props }) => {
|
||||
const { getComponent, schema } = props
|
||||
const { getComponent, schema, name } = props
|
||||
const MutualTLSAuth = getComponent("MutualTLSAuth", true)
|
||||
const type = schema.get("type")
|
||||
|
||||
if (type === "mutualTLS") {
|
||||
return <MutualTLSAuth schema={schema} />
|
||||
return <MutualTLSAuth schema={schema} name={name} />
|
||||
}
|
||||
|
||||
return <Ori {...props} />
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import React from "react"
|
||||
|
||||
import { createOnlyOAS31ComponentWrapper } from "../fn"
|
||||
import { makeGetSchemaKeywords } from "../json-schema-2020-12-extensions/fn"
|
||||
|
||||
const ModelWrapper = createOnlyOAS31ComponentWrapper(
|
||||
({ getSystem, ...props }) => {
|
||||
@@ -12,135 +13,31 @@ const ModelWrapper = createOnlyOAS31ComponentWrapper(
|
||||
const configs = getConfigs()
|
||||
|
||||
const Model = getComponent("OAS31Model")
|
||||
const JSONSchema = getComponent("JSONSchema202012")
|
||||
const Keyword$schema = getComponent("JSONSchema202012Keyword$schema")
|
||||
const Keyword$vocabulary = getComponent(
|
||||
"JSONSchema202012Keyword$vocabulary"
|
||||
const withJSONSchemaSystemContext = getComponent(
|
||||
"withJSONSchema202012SystemContext"
|
||||
)
|
||||
const Keyword$id = getComponent("JSONSchema202012Keyword$id")
|
||||
const Keyword$anchor = getComponent("JSONSchema202012Keyword$anchor")
|
||||
const Keyword$dynamicAnchor = getComponent(
|
||||
"JSONSchema202012Keyword$dynamicAnchor"
|
||||
)
|
||||
const Keyword$ref = getComponent("JSONSchema202012Keyword$ref")
|
||||
const Keyword$dynamicRef = getComponent(
|
||||
"JSONSchema202012Keyword$dynamicRef"
|
||||
)
|
||||
const Keyword$defs = getComponent("JSONSchema202012Keyword$defs")
|
||||
const Keyword$comment = getComponent("JSONSchema202012Keyword$comment")
|
||||
const KeywordAllOf = getComponent("JSONSchema202012KeywordAllOf")
|
||||
const KeywordAnyOf = getComponent("JSONSchema202012KeywordAnyOf")
|
||||
const KeywordOneOf = getComponent("JSONSchema202012KeywordOneOf")
|
||||
const KeywordNot = getComponent("JSONSchema202012KeywordNot")
|
||||
const KeywordIf = getComponent("JSONSchema202012KeywordIf")
|
||||
const KeywordThen = getComponent("JSONSchema202012KeywordThen")
|
||||
const KeywordElse = getComponent("JSONSchema202012KeywordElse")
|
||||
const KeywordDependentSchemas = getComponent(
|
||||
"JSONSchema202012KeywordDependentSchemas"
|
||||
)
|
||||
const KeywordPrefixItems = getComponent(
|
||||
"JSONSchema202012KeywordPrefixItems"
|
||||
)
|
||||
const KeywordItems = getComponent("JSONSchema202012KeywordItems")
|
||||
const KeywordContains = getComponent("JSONSchema202012KeywordContains")
|
||||
const KeywordProperties = getComponent("JSONSchema202012KeywordProperties")
|
||||
const KeywordPatternProperties = getComponent(
|
||||
"JSONSchema202012KeywordPatternProperties"
|
||||
)
|
||||
const KeywordAdditionalProperties = getComponent(
|
||||
"JSONSchema202012KeywordAdditionalProperties"
|
||||
)
|
||||
const KeywordPropertyNames = getComponent(
|
||||
"JSONSchema202012KeywordPropertyNames"
|
||||
)
|
||||
const KeywordUnevaluatedItems = getComponent(
|
||||
"JSONSchema202012KeywordUnevaluatedItems"
|
||||
)
|
||||
const KeywordUnevaluatedProperties = getComponent(
|
||||
"JSONSchema202012KeywordUnevaluatedProperties"
|
||||
)
|
||||
const KeywordType = getComponent("JSONSchema202012KeywordType")
|
||||
const KeywordEnum = getComponent("JSONSchema202012KeywordEnum")
|
||||
const KeywordConst = getComponent("JSONSchema202012KeywordConst")
|
||||
const KeywordConstraint = getComponent("JSONSchema202012KeywordConstraint")
|
||||
const KeywordDependentRequired = getComponent(
|
||||
"JSONSchema202012KeywordDependentRequired"
|
||||
)
|
||||
const KeywordContentSchema = getComponent(
|
||||
"JSONSchema202012KeywordContentSchema"
|
||||
)
|
||||
const KeywordTitle = getComponent("JSONSchema202012KeywordTitle")
|
||||
const KeywordDescription = getComponent(
|
||||
"JSONSchema202012KeywordDescription"
|
||||
)
|
||||
const KeywordDefault = getComponent("JSONSchema202012KeywordDefault")
|
||||
const KeywordDeprecated = getComponent("JSONSchema202012KeywordDeprecated")
|
||||
const KeywordReadOnly = getComponent("JSONSchema202012KeywordReadOnly")
|
||||
const KeywordWriteOnly = getComponent("JSONSchema202012KeywordWriteOnly")
|
||||
const Accordion = getComponent("JSONSchema202012Accordion")
|
||||
const ExpandDeepButton = getComponent("JSONSchema202012ExpandDeepButton")
|
||||
const ChevronRightIcon = getComponent("JSONSchema202012ChevronRightIcon")
|
||||
const withSchemaContext = getComponent("withJSONSchema202012Context")
|
||||
|
||||
const ModelWithJSONSchemaContext = withSchemaContext(Model, {
|
||||
config: {
|
||||
default$schema: "https://spec.openapis.org/oas/3.1/dialect/base",
|
||||
defaultExpandedLevels: configs.defaultModelExpandDepth,
|
||||
includeReadOnly: Boolean(props.includeReadOnly),
|
||||
includeWriteOnly: Boolean(props.includeWriteOnly),
|
||||
},
|
||||
components: {
|
||||
JSONSchema,
|
||||
Keyword$schema,
|
||||
Keyword$vocabulary,
|
||||
Keyword$id,
|
||||
Keyword$anchor,
|
||||
Keyword$dynamicAnchor,
|
||||
Keyword$ref,
|
||||
Keyword$dynamicRef,
|
||||
Keyword$defs,
|
||||
Keyword$comment,
|
||||
KeywordAllOf,
|
||||
KeywordAnyOf,
|
||||
KeywordOneOf,
|
||||
KeywordNot,
|
||||
KeywordIf,
|
||||
KeywordThen,
|
||||
KeywordElse,
|
||||
KeywordDependentSchemas,
|
||||
KeywordPrefixItems,
|
||||
KeywordItems,
|
||||
KeywordContains,
|
||||
KeywordProperties,
|
||||
KeywordPatternProperties,
|
||||
KeywordAdditionalProperties,
|
||||
KeywordPropertyNames,
|
||||
KeywordUnevaluatedItems,
|
||||
KeywordUnevaluatedProperties,
|
||||
KeywordType,
|
||||
KeywordEnum,
|
||||
KeywordConst,
|
||||
KeywordConstraint,
|
||||
KeywordDependentRequired,
|
||||
KeywordContentSchema,
|
||||
KeywordTitle,
|
||||
KeywordDescription,
|
||||
KeywordDefault,
|
||||
KeywordDeprecated,
|
||||
KeywordReadOnly,
|
||||
KeywordWriteOnly,
|
||||
Accordion,
|
||||
ExpandDeepButton,
|
||||
ChevronRightIcon,
|
||||
},
|
||||
fn: {
|
||||
upperFirst: fn.upperFirst,
|
||||
isExpandable: fn.jsonSchema202012.isExpandable,
|
||||
getProperties: fn.jsonSchema202012.getProperties,
|
||||
},
|
||||
})
|
||||
// we cache the HOC as recreating it with every re-render is quite expensive
|
||||
ModelWrapper.ModelWithJSONSchemaContext ??= withJSONSchemaSystemContext(
|
||||
Model,
|
||||
{
|
||||
config: {
|
||||
default$schema: "https://spec.openapis.org/oas/3.1/dialect/base",
|
||||
defaultExpandedLevels: configs.defaultModelExpandDepth,
|
||||
includeReadOnly: props.includeReadOnly,
|
||||
includeWriteOnly: props.includeWriteOnly,
|
||||
},
|
||||
fn: {
|
||||
getProperties: fn.jsonSchema202012.getProperties,
|
||||
isExpandable: fn.jsonSchema202012.isExpandable,
|
||||
getSchemaKeywords: makeGetSchemaKeywords(
|
||||
fn.jsonSchema202012.getSchemaKeywords
|
||||
),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
return <ModelWithJSONSchemaContext {...props} />
|
||||
return <ModelWrapper.ModelWithJSONSchemaContext {...props} />
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import React from "react"
|
||||
|
||||
import { createOnlyOAS31ComponentWrapper } from "../fn"
|
||||
import { makeGetSchemaKeywords } from "../json-schema-2020-12-extensions/fn"
|
||||
|
||||
const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
|
||||
const { getComponent, fn, getConfigs } = getSystem()
|
||||
@@ -14,126 +15,29 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
|
||||
}
|
||||
|
||||
const Models = getComponent("OAS31Models", true)
|
||||
const JSONSchema = getComponent("JSONSchema202012")
|
||||
const Keyword$schema = getComponent("JSONSchema202012Keyword$schema")
|
||||
const Keyword$vocabulary = getComponent("JSONSchema202012Keyword$vocabulary")
|
||||
const Keyword$id = getComponent("JSONSchema202012Keyword$id")
|
||||
const Keyword$anchor = getComponent("JSONSchema202012Keyword$anchor")
|
||||
const Keyword$dynamicAnchor = getComponent(
|
||||
"JSONSchema202012Keyword$dynamicAnchor"
|
||||
const withJSONSchemaSystemContext = getComponent(
|
||||
"withJSONSchema202012SystemContext"
|
||||
)
|
||||
const Keyword$ref = getComponent("JSONSchema202012Keyword$ref")
|
||||
const Keyword$dynamicRef = getComponent("JSONSchema202012Keyword$dynamicRef")
|
||||
const Keyword$defs = getComponent("JSONSchema202012Keyword$defs")
|
||||
const Keyword$comment = getComponent("JSONSchema202012Keyword$comment")
|
||||
const KeywordAllOf = getComponent("JSONSchema202012KeywordAllOf")
|
||||
const KeywordAnyOf = getComponent("JSONSchema202012KeywordAnyOf")
|
||||
const KeywordOneOf = getComponent("JSONSchema202012KeywordOneOf")
|
||||
const KeywordNot = getComponent("JSONSchema202012KeywordNot")
|
||||
const KeywordIf = getComponent("JSONSchema202012KeywordIf")
|
||||
const KeywordThen = getComponent("JSONSchema202012KeywordThen")
|
||||
const KeywordElse = getComponent("JSONSchema202012KeywordElse")
|
||||
const KeywordDependentSchemas = getComponent(
|
||||
"JSONSchema202012KeywordDependentSchemas"
|
||||
)
|
||||
const KeywordPrefixItems = getComponent("JSONSchema202012KeywordPrefixItems")
|
||||
const KeywordItems = getComponent("JSONSchema202012KeywordItems")
|
||||
const KeywordContains = getComponent("JSONSchema202012KeywordContains")
|
||||
const KeywordProperties = getComponent("JSONSchema202012KeywordProperties")
|
||||
const KeywordPatternProperties = getComponent(
|
||||
"JSONSchema202012KeywordPatternProperties"
|
||||
)
|
||||
const KeywordAdditionalProperties = getComponent(
|
||||
"JSONSchema202012KeywordAdditionalProperties"
|
||||
)
|
||||
const KeywordPropertyNames = getComponent(
|
||||
"JSONSchema202012KeywordPropertyNames"
|
||||
)
|
||||
const KeywordUnevaluatedItems = getComponent(
|
||||
"JSONSchema202012KeywordUnevaluatedItems"
|
||||
)
|
||||
const KeywordUnevaluatedProperties = getComponent(
|
||||
"JSONSchema202012KeywordUnevaluatedProperties"
|
||||
)
|
||||
const KeywordType = getComponent("JSONSchema202012KeywordType")
|
||||
const KeywordEnum = getComponent("JSONSchema202012KeywordEnum")
|
||||
const KeywordConst = getComponent("JSONSchema202012KeywordConst")
|
||||
const KeywordConstraint = getComponent("JSONSchema202012KeywordConstraint")
|
||||
const KeywordDependentRequired = getComponent(
|
||||
"JSONSchema202012KeywordDependentRequired"
|
||||
)
|
||||
const KeywordContentSchema = getComponent(
|
||||
"JSONSchema202012KeywordContentSchema"
|
||||
)
|
||||
const KeywordTitle = getComponent("JSONSchema202012KeywordTitle")
|
||||
const KeywordDescription = getComponent("JSONSchema202012KeywordDescription")
|
||||
const KeywordDefault = getComponent("JSONSchema202012KeywordDefault")
|
||||
const KeywordDeprecated = getComponent("JSONSchema202012KeywordDeprecated")
|
||||
const KeywordReadOnly = getComponent("JSONSchema202012KeywordReadOnly")
|
||||
const KeywordWriteOnly = getComponent("JSONSchema202012KeywordWriteOnly")
|
||||
const Accordion = getComponent("JSONSchema202012Accordion")
|
||||
const ExpandDeepButton = getComponent("JSONSchema202012ExpandDeepButton")
|
||||
const ChevronRightIcon = getComponent("JSONSchema202012ChevronRightIcon")
|
||||
const withSchemaContext = getComponent("withJSONSchema202012Context")
|
||||
|
||||
// we cache the HOC as recreating it with every re-render is quite expensive
|
||||
ModelsWrapper.ModelsWithJSONSchemaContext = withSchemaContext(Models, {
|
||||
config: {
|
||||
default$schema: "https://spec.openapis.org/oas/3.1/dialect/base",
|
||||
defaultExpandedLevels: configs.defaultModelsExpandDepth - 1,
|
||||
includeReadOnly: true,
|
||||
includeWriteOnly: true,
|
||||
},
|
||||
components: {
|
||||
JSONSchema,
|
||||
Keyword$schema,
|
||||
Keyword$vocabulary,
|
||||
Keyword$id,
|
||||
Keyword$anchor,
|
||||
Keyword$dynamicAnchor,
|
||||
Keyword$ref,
|
||||
Keyword$dynamicRef,
|
||||
Keyword$defs,
|
||||
Keyword$comment,
|
||||
KeywordAllOf,
|
||||
KeywordAnyOf,
|
||||
KeywordOneOf,
|
||||
KeywordNot,
|
||||
KeywordIf,
|
||||
KeywordThen,
|
||||
KeywordElse,
|
||||
KeywordDependentSchemas,
|
||||
KeywordPrefixItems,
|
||||
KeywordItems,
|
||||
KeywordContains,
|
||||
KeywordProperties,
|
||||
KeywordPatternProperties,
|
||||
KeywordAdditionalProperties,
|
||||
KeywordPropertyNames,
|
||||
KeywordUnevaluatedItems,
|
||||
KeywordUnevaluatedProperties,
|
||||
KeywordType,
|
||||
KeywordEnum,
|
||||
KeywordConst,
|
||||
KeywordConstraint,
|
||||
KeywordDependentRequired,
|
||||
KeywordContentSchema,
|
||||
KeywordTitle,
|
||||
KeywordDescription,
|
||||
KeywordDefault,
|
||||
KeywordDeprecated,
|
||||
KeywordReadOnly,
|
||||
KeywordWriteOnly,
|
||||
Accordion,
|
||||
ExpandDeepButton,
|
||||
ChevronRightIcon,
|
||||
},
|
||||
fn: {
|
||||
upperFirst: fn.upperFirst,
|
||||
isExpandable: fn.jsonSchema202012.isExpandable,
|
||||
getProperties: fn.jsonSchema202012.getProperties,
|
||||
},
|
||||
})
|
||||
ModelsWrapper.ModelsWithJSONSchemaContext ??= withJSONSchemaSystemContext(
|
||||
Models,
|
||||
{
|
||||
config: {
|
||||
default$schema: "https://spec.openapis.org/oas/3.1/dialect/base",
|
||||
defaultExpandedLevels: configs.defaultModelsExpandDepth - 1,
|
||||
includeReadOnly: true,
|
||||
includeWriteOnly: true,
|
||||
},
|
||||
fn: {
|
||||
getProperties: fn.jsonSchema202012.getProperties,
|
||||
isExpandable: fn.jsonSchema202012.isExpandable,
|
||||
getSchemaKeywords: makeGetSchemaKeywords(
|
||||
fn.jsonSchema202012.getSchemaKeywords
|
||||
),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
return <ModelsWrapper.ModelsWithJSONSchemaContext />
|
||||
})
|
||||
|
||||
@@ -156,17 +156,14 @@ const curlify = (request, escape, newLine, ext = "") => {
|
||||
return curlified
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
export const requestSnippetGenerator_curl_powershell = (request) => {
|
||||
return curlify(request, escapePowershell, "`\n", ".exe")
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
export const requestSnippetGenerator_curl_bash = (request) => {
|
||||
return curlify(request, escapeShell, "\\\n")
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
export const requestSnippetGenerator_curl_cmd = (request) => {
|
||||
return curlify(request, escapeCMD, "^\n")
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import * as fn from "./fn"
|
||||
import { requestSnippetGenerator_curl_bash, requestSnippetGenerator_curl_cmd, requestSnippetGenerator_curl_powershell } from "./fn"
|
||||
import * as selectors from "./selectors"
|
||||
import RequestSnippets from "./request-snippets"
|
||||
|
||||
export default () => {
|
||||
return {
|
||||
components: {
|
||||
RequestSnippets
|
||||
},
|
||||
fn,
|
||||
fn: {
|
||||
requestSnippetGenerator_curl_bash,
|
||||
requestSnippetGenerator_curl_cmd,
|
||||
requestSnippetGenerator_curl_powershell,
|
||||
},
|
||||
statePlugins: {
|
||||
requestSnippets: {
|
||||
selectors
|
||||
|
||||
@@ -78,7 +78,7 @@ export const parseToJson = (str) => ({specActions, specSelectors, errActions}) =
|
||||
if(json && typeof json === "object") {
|
||||
return specActions.updateJsonSpec(json)
|
||||
}
|
||||
return {}
|
||||
return specActions.updateJsonSpec({})
|
||||
}
|
||||
|
||||
let hasWarnedAboutResolveSpecDeprecation = false
|
||||
@@ -194,7 +194,7 @@ const debResolveSubtrees = debounce(() => {
|
||||
// keep if...
|
||||
return err.get("type") !== "thrown" // it's not a thrown error
|
||||
|| err.get("source") !== "resolver" // it's not a resolver error
|
||||
|| !err.get("fullPath").every((key, i) => key === path[i] || path[i] === undefined) // it's not within the path we're resolving
|
||||
|| !err.get("fullPath")?.every((key, i) => key === path[i] || path[i] === undefined) // it's not within the path we're resolving
|
||||
})
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ const debResolveSubtrees = debounce(() => {
|
||||
if (spec && specSelectors.isOAS3() && path[0] === "components" && path[1] === "securitySchemes") {
|
||||
// Resolve OIDC URLs if present
|
||||
await Promise.all(Object.values(spec)
|
||||
.filter((scheme) => scheme.type === "openIdConnect")
|
||||
.filter((scheme) => scheme?.type === "openIdConnect")
|
||||
.map(async (oidcScheme) => {
|
||||
const req = {
|
||||
url: oidcScheme.openIdConnectUrl,
|
||||
|
||||
@@ -124,13 +124,10 @@ export const validOperationMethods = constant(["get", "put", "post", "delete", "
|
||||
export const operations = createSelector(
|
||||
paths,
|
||||
paths => {
|
||||
if(!paths || paths.size < 1)
|
||||
return List()
|
||||
|
||||
let list = List()
|
||||
|
||||
if(!paths || !paths.forEach) {
|
||||
return List()
|
||||
if (!Map.isMap(paths) || paths.isEmpty()) {
|
||||
return list
|
||||
}
|
||||
|
||||
paths.forEach((path, pathName) => {
|
||||
@@ -499,8 +496,8 @@ export const validationErrors = (state, pathMethod) => {
|
||||
const getErrorsWithPaths = (errors, path = []) => {
|
||||
const getNestedErrorsWithPaths = (e, path) => {
|
||||
const currPath = [...path, e.get("propKey") || e.get("index")]
|
||||
return Map.isMap(e.get("error"))
|
||||
? getErrorsWithPaths(e.get("error"), currPath)
|
||||
return Map.isMap(e.get("error"))
|
||||
? getErrorsWithPaths(e.get("error"), currPath)
|
||||
: { error: e.get("error"), path: currPath }
|
||||
}
|
||||
|
||||
@@ -511,10 +508,10 @@ export const validationErrors = (state, pathMethod) => {
|
||||
|
||||
const formatError = (error, path, paramName) => {
|
||||
path = path.reduce((acc, curr) => {
|
||||
return typeof curr === "number"
|
||||
? `${acc}[${curr}]`
|
||||
: acc
|
||||
? `${acc}.${curr}`
|
||||
return typeof curr === "number"
|
||||
? `${acc}[${curr}]`
|
||||
: acc
|
||||
? `${acc}.${curr}`
|
||||
: curr
|
||||
}, "")
|
||||
return `For '${paramName}'${path ? ` at path '${path}'` : ""}: ${error}.`
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { shallowEqualKeys } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils/url"
|
||||
|
||||
export default function() {
|
||||
return {
|
||||
fn: { shallowEqualKeys }
|
||||
fn: {
|
||||
shallowEqualKeys,
|
||||
sanitizeUrl,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user