-
-
Notifications
You must be signed in to change notification settings - Fork 19
Refactor: Minor safety and modernization updates in processSchema #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
b7a2eb9
de598eb
e91043f
2f9b1f3
a8841e6
d94d408
2fb2ff8
89ddde0
85878cf
3e339e3
aa909da
16f71cc
d522478
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1,88 @@ | ||
| const NESTED_WITH_NAME = ["definitions", "properties"]; | ||
| /** | ||
| * @typedef {Object} JSONSchema | ||
| * @property {string} [$id] | ||
| * @property {string} [$schema] | ||
| * @property {string} [$ref] | ||
| * @property {string} [title] | ||
| * @property {string} [description] | ||
| * @property {string | string[]} [type] | ||
| * @property {boolean} [nullable] | ||
| * @property {JSONSchema | boolean} [items] | ||
| * @property {Record<string, JSONSchema | boolean>} [properties] | ||
| * @property {JSONSchema | boolean} [additionalProperties] | ||
| * @property {JSONSchema[]} [oneOf] | ||
| * @property {JSONSchema[]} [anyOf] | ||
| * @property {JSONSchema[]} [allOf] | ||
| * @property {Record<string, JSONSchema | boolean>} [definitions] | ||
| * @property {unknown} [enum] | ||
| * @property {unknown} [const] | ||
| * @property {unknown} [default] | ||
| * @property {Record<string, unknown>} [examples] | ||
| * @property {Record<string, unknown>} [other] - Any additional schema fields. | ||
| */ | ||
|
|
||
| const NESTED_DIRECT = ["items", "additionalProperties", "not"]; | ||
| /** | ||
| * @typedef {Object} ProcessContext | ||
| * @property {JSONSchema} [rootSchema] - The root schema being processed. | ||
| * @property {string[]} [path] - Path segments from the root to the current node. | ||
| * @property {Record<string, unknown>} [meta] - Arbitrary metadata shared across recursion. | ||
| */ | ||
|
|
||
| /** | ||
| * @typedef {Object} SchemaVisitor | ||
| * @property {(schema: JSONSchema | boolean, context?: ProcessContext) => JSONSchema | boolean | void} [schema] | ||
| * @property {(obj: JSONSchema | boolean, context?: ProcessContext) => JSONSchema | boolean | void} [object] | ||
| * @property {(arr: (JSONSchema | boolean)[], context?: ProcessContext) => void} [array] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just interesting why we have
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. JSON Schema allows boolean schemas, but instead of manually adding boolean I can switch to JSONSchema7Definition from json-schema types which already includes it.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We support more than
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| */ | ||
|
Manas-Dikshit marked this conversation as resolved.
|
||
|
|
||
| // Constants defining nested schema traversal structure | ||
| const NESTED_WITH_NAME = ["definitions", "properties"]; | ||
| const NESTED_DIRECT = ["items", "additionalProperties", "not"]; | ||
| const NESTED_ARRAY = ["oneOf", "anyOf", "allOf"]; | ||
|
|
||
| /** | ||
| * Recursively processes a JSON Schema using the visitor pattern. | ||
| * | ||
| * @param {SchemaVisitor} visitor - Visitor functions to apply. | ||
| * @param {JSONSchema | boolean} json - JSON Schema to process. | ||
| * @param {ProcessContext} [context] - Optional shared context passed through recursion. | ||
| * @returns {JSONSchema | boolean} - The processed JSON Schema. | ||
| */ | ||
| const processSchema = (visitor, json, context) => { | ||
|
Manas-Dikshit marked this conversation as resolved.
|
||
| if (!json || typeof json !== "object") return json; // safety check | ||
|
|
||
| json = { ...json }; | ||
| if (visitor.schema) json = visitor.schema(json, context); | ||
| if (typeof visitor?.schema === "function") { | ||
| json = visitor.schema(json, context) || json; | ||
| } | ||
|
|
||
| for (const name of NESTED_WITH_NAME) { | ||
| if (name in json && json[name] && typeof json[name] === "object") { | ||
| if (visitor.object) json[name] = visitor.object(json[name], context); | ||
| for (const key in json[name]) { | ||
| if (json[name] && typeof json[name] === "object" && !Array.isArray(json[name])) { | ||
|
Manas-Dikshit marked this conversation as resolved.
Outdated
|
||
| if (typeof visitor?.object === "function") { | ||
| json[name] = visitor.object(json[name], context) || json[name]; | ||
| } | ||
| for (const key of Object.keys(json[name])) { | ||
| json[name][key] = processSchema(visitor, json[name][key], context); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| for (const name of NESTED_DIRECT) { | ||
| if (name in json && json[name] && typeof json[name] === "object") { | ||
| if (json[name] && typeof json[name] === "object" && !Array.isArray(json[name])) { | ||
| json[name] = processSchema(visitor, json[name], context); | ||
| } | ||
| } | ||
|
|
||
| for (const name of NESTED_ARRAY) { | ||
| if (name in json && Array.isArray(json[name])) { | ||
| json[name] = json[name].slice(); | ||
| for (let i = 0; i < json[name].length; i++) { | ||
| json[name][i] = processSchema(visitor, json[name][i], context); | ||
| if (Array.isArray(json[name])) { | ||
| json[name] = json[name].map((item) => processSchema(visitor, item, context)); | ||
| if (typeof visitor?.array === "function") { | ||
| visitor.array(json[name], context); | ||
| } | ||
| if (visitor.array) visitor.array(json[name], context); | ||
| } | ||
| } | ||
|
|
||
| return json; | ||
| }; | ||
|
|
||
| module.exports = processSchema; | ||

Uh oh!
There was an error while loading. Please reload this page.