79 lines
No EOL
3.2 KiB
JavaScript
79 lines
No EOL
3.2 KiB
JavaScript
import { parseDef } from "./parseDef.mjs";
|
|
import { getRefs } from "./Refs.mjs";
|
|
import { zodDef, isEmptyObj } from "./util.mjs";
|
|
const zodToJsonSchema = (schema, options) => {
|
|
const refs = getRefs(options);
|
|
const name = typeof options === 'string' ? options
|
|
: options?.nameStrategy === 'title' ? undefined
|
|
: options?.name;
|
|
const main = parseDef(schema._def, name === undefined ? refs : ({
|
|
...refs,
|
|
currentPath: [...refs.basePath, refs.definitionPath, name],
|
|
}), false) ?? {};
|
|
const title = typeof options === 'object' && options.name !== undefined && options.nameStrategy === 'title' ?
|
|
options.name
|
|
: undefined;
|
|
if (title !== undefined) {
|
|
main.title = title;
|
|
}
|
|
const definitions = (() => {
|
|
if (isEmptyObj(refs.definitions)) {
|
|
return undefined;
|
|
}
|
|
const definitions = {};
|
|
const processedDefinitions = new Set();
|
|
// the call to `parseDef()` here might itself add more entries to `.definitions`
|
|
// so we need to continually evaluate definitions until we've resolved all of them
|
|
//
|
|
// we have a generous iteration limit here to avoid blowing up the stack if there
|
|
// are any bugs that would otherwise result in us iterating indefinitely
|
|
for (let i = 0; i < 500; i++) {
|
|
const newDefinitions = Object.entries(refs.definitions).filter(([key]) => !processedDefinitions.has(key));
|
|
if (newDefinitions.length === 0)
|
|
break;
|
|
for (const [key, schema] of newDefinitions) {
|
|
definitions[key] =
|
|
parseDef(zodDef(schema), { ...refs, currentPath: [...refs.basePath, refs.definitionPath, key] }, true) ?? {};
|
|
processedDefinitions.add(key);
|
|
}
|
|
}
|
|
return definitions;
|
|
})();
|
|
const combined = name === undefined ?
|
|
definitions ?
|
|
{
|
|
...main,
|
|
[refs.definitionPath]: definitions,
|
|
}
|
|
: main
|
|
: refs.nameStrategy === 'duplicate-ref' ?
|
|
{
|
|
...main,
|
|
...(definitions || refs.seenRefs.size ?
|
|
{
|
|
[refs.definitionPath]: {
|
|
...definitions,
|
|
// only actually duplicate the schema definition if it was ever referenced
|
|
// otherwise the duplication is completely pointless
|
|
...(refs.seenRefs.size ? { [name]: main } : undefined),
|
|
},
|
|
}
|
|
: undefined),
|
|
}
|
|
: {
|
|
$ref: [...(refs.$refStrategy === 'relative' ? [] : refs.basePath), refs.definitionPath, name].join('/'),
|
|
[refs.definitionPath]: {
|
|
...definitions,
|
|
[name]: main,
|
|
},
|
|
};
|
|
if (refs.target === 'jsonSchema7') {
|
|
combined.$schema = 'http://json-schema.org/draft-07/schema#';
|
|
}
|
|
else if (refs.target === 'jsonSchema2019-09') {
|
|
combined.$schema = 'https://json-schema.org/draft/2019-09/schema#';
|
|
}
|
|
return combined;
|
|
};
|
|
export { zodToJsonSchema };
|
|
//# sourceMappingURL=zodToJsonSchema.mjs.map
|