60 lines
1.9 KiB
JavaScript
60 lines
1.9 KiB
JavaScript
|
import { parseDef } from "./parseDef.js";
|
||
|
import { getRefs } from "./Refs.js";
|
||
|
const zodToJsonSchema = (schema, options) => {
|
||
|
const refs = getRefs(options);
|
||
|
const definitions = typeof options === "object" && options.definitions
|
||
|
? Object.entries(options.definitions).reduce((acc, [name, schema]) => ({
|
||
|
...acc,
|
||
|
[name]: parseDef(schema._def, {
|
||
|
...refs,
|
||
|
currentPath: [...refs.basePath, refs.definitionPath, name],
|
||
|
}, true) ?? {},
|
||
|
}), {})
|
||
|
: undefined;
|
||
|
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 combined = name === undefined
|
||
|
? definitions
|
||
|
? {
|
||
|
...main,
|
||
|
[refs.definitionPath]: definitions,
|
||
|
}
|
||
|
: main
|
||
|
: {
|
||
|
$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 };
|