Skip to content

Commit

Permalink
feat: qualifier message - unsolvedRefs (useful for recursive schemas)
Browse files Browse the repository at this point in the history
  • Loading branch information
jy95 committed Dec 17, 2023
1 parent 8b3286e commit b325887
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/theme/JSONSchemaViewer/contexts/jsvOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ export type JSVOptions = {
* @default undefined
*/
DescriptionComponent?: (params: { description: string }) => JSX.Element
/**
* To overwrite the default handling of unresolved $refs
* By default, print out as provided
* @default undefined
*/
UnresolvedRefsComponent?: (params: { schema: JSONSchema }) => JSX.Element
}

export const JSVOptionsContext = createContext<JSVOptions>({
fullSchema: false,
showExamples: false,
qualifierMessagesOrder: undefined,
DescriptionComponent: undefined,
UnresolvedRefsComponent: undefined,
})

export const useJSVOptionsContext = () => useContext(JSVOptionsContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as QMS from "@theme/JSONSchemaViewer/utils/QualifierMessages"

import type { JSONSchema, JSONSchemaNS } from "@theme/JSONSchemaViewer/types"
import type { JSVOptions } from "@theme/JSONSchemaViewer/contexts"
import { hasUnresolvedRefs } from "../detectTypes"

type Props = {
schema: Exclude<JSONSchema, true | false>
Expand Down Expand Up @@ -42,6 +43,7 @@ export type CheckKey =
| "contentMediaType"
| "contentEncoding"
| "contentSchema"
| "unsolvedRefs"

// Available qualifier message
const CHECKS_MAP: Record<CheckKey, CheckInfo> = {
Expand Down Expand Up @@ -173,6 +175,15 @@ const CHECKS_MAP: Record<CheckKey, CheckInfo> = {
/>
),
},
unsolvedRefs: {
match: ({ schema }) => hasUnresolvedRefs(schema),
Component: (props) => (
<QMS.UnsolvedRefsQM
key={"unsolvedRefs"}
{...(props as any)}
></QMS.UnsolvedRefsQM>
),
},
}

// Default order I assume
Expand All @@ -198,6 +209,7 @@ const DEFAULT_ORDER: CheckKey[] = [
"default",
"const",
"examples",
"unsolvedRefs",
]

export { CHECKS_MAP, DEFAULT_ORDER }
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from "react"

import { JSONSchema } from "json-schema-typed"
import { JSVOptions } from "../../contexts"
import Translate from "@docusaurus/Translate"

type Props = {
schema: Exclude<JSONSchema, true | false>
options: JSVOptions
nullable?: boolean
}

export default function UnsolvedRefsQM(props: Props): JSX.Element {
const {
schema,
options: { UnresolvedRefsComponent },
} = props

// Translated label
const unsolvedRefLabel = (
<strong>
<Translate
values={{
id: "json-schema.labels.unsolvedRefs",
}}
>
{"Unsolved ref :"}
</Translate>
</strong>
)

// Unsolved ref(s)
// Technically speak, nothing prevents people to combine $ref / $dynamicRef / ..
// So generic approach instead
let unsolvedRefValue: string = [schema.$ref, schema.$dynamicRef]
.filter((s) => s !== undefined)
.join(" ")

return (
<div key={"unsolvedRefs"}>
{UnresolvedRefsComponent ? (
<UnresolvedRefsComponent schema={schema} />
) : (
<>
{unsolvedRefLabel}
&nbsp;
{unsolvedRefValue}
</>
)}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export { default as NullableQM } from "@theme/JSONSchemaViewer/utils/QualifierMe
export { default as ContentMediaTypeQM } from "@theme/JSONSchemaViewer/utils/QualifierMessages/ContentMediaType"
export { default as ContentEncodingQM } from "@theme/JSONSchemaViewer/utils/QualifierMessages/ContentEncoding"
export { default as ContentSchemaQM } from "@theme/JSONSchemaViewer/utils/QualifierMessages/ContentSchema"
export { default as UnsolvedRefsQM } from "@theme/JSONSchemaViewer/utils/QualifierMessages/UnsolvedRefs"
export {
CHECKS_MAP as QUALIFIERS_MAP,
DEFAULT_ORDER as QUALIFIERS_DEFAULT_ORDER,
Expand Down
6 changes: 6 additions & 0 deletions src/theme/JSONSchemaViewer/utils/detectTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
JSONSchema,
JSONSchemaNS,
TypeValues,
JSONSchema_Draft_2019_09,
} from "@theme/JSONSchemaViewer/types"

// Utility functions to know which case we have
Expand Down Expand Up @@ -86,6 +87,11 @@ export const isNull = (schema: JSONSchema) =>
schema.enum?.some((val) => val === null) ||
schema.const === null)

export const hasUnresolvedRefs = (schema: JSONSchema) =>
typeof schema !== "boolean" &&
(schema.$ref !== undefined ||
(schema as JSONSchemaNS.Object).$dynamicRef !== undefined)

// Detect types in schema
// Zero, One or multiple types can match
function* foundUndeclaredTypes(
Expand Down
2 changes: 2 additions & 0 deletions testsite/docs/api/JSONSchemaViewer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ type CheckKey =
| "contentMediaType"
| "contentEncoding"
| "contentSchema"
// For unsolved recursive refs ($ref, $dynamicRef, ...)
| "unsolvedRefs"
```
## Examples
Expand Down

0 comments on commit b325887

Please sign in to comment.