zod-to-x
Version:
Multi language types generation from Zod schemas.
71 lines (70 loc) • 3.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.zod2JsonSchemaDefinitions = zod2JsonSchemaDefinitions;
const zod_1 = require("zod");
/**
* Recursively extracts custom type definitions from a Zod schema and collects them into a
* definitions object.
*
* This function traverses the provided Zod schema and its nested schemas to collect all schemas
* that have a custom `typeName` defined in `schema._zod2x.typeName`. It accumulates these
* schemas into a `definitions` object, which maps each `typeName` to its corresponding schema.
* This is useful for generating JSON Schema definitions or for any scenario where you need to
* collect and reference custom types.
*
* @param schema - The root Zod schema from which to extract definitions.
* @param definitions - (Optional) An object to accumulate the definitions.
* Used across recursive calls.
* @param visited - (Optional) A Set to keep track of visited schemas and prevent infinite recursion
* in cases of circular references. Used across recursive calls.
* @returns An object containing all extracted definitions, where each key is a `typeName` and the
* value is the corresponding Zod schema.
*/
function zod2JsonSchemaDefinitions(schema, definitions = {}, visited = new Set()) {
var _a;
if (visited.has(schema)) {
return definitions;
}
visited.add(schema);
const typeName = (_a = schema._zod2x) === null || _a === void 0 ? void 0 : _a.typeName;
if (typeName && definitions[typeName]) {
return definitions;
}
if (schema instanceof zod_1.ZodOptional || schema instanceof zod_1.ZodNullable) {
zod2JsonSchemaDefinitions(schema.unwrap(), definitions, visited);
}
else if (schema instanceof zod_1.ZodArray) {
zod2JsonSchemaDefinitions(schema.element, definitions, visited);
}
else if (schema instanceof zod_1.ZodSet) {
const innerSchema = schema._def.valueType;
zod2JsonSchemaDefinitions(innerSchema, definitions, visited);
}
else if (schema instanceof zod_1.ZodTuple) {
for (const item of schema.items) {
zod2JsonSchemaDefinitions(item, definitions, visited);
}
}
else if (schema instanceof zod_1.ZodRecord || schema instanceof zod_1.ZodMap) {
zod2JsonSchemaDefinitions(schema.keySchema, definitions, visited);
zod2JsonSchemaDefinitions(schema.valueSchema, definitions, visited);
}
else if (schema instanceof zod_1.ZodObject) {
for (const value of Object.values(schema.shape)) {
zod2JsonSchemaDefinitions(value, definitions, visited);
}
}
else if (schema instanceof zod_1.ZodUnion || schema instanceof zod_1.ZodDiscriminatedUnion) {
for (const option of schema.options) {
zod2JsonSchemaDefinitions(option, definitions, visited);
}
}
else if (schema instanceof zod_1.ZodIntersection) {
zod2JsonSchemaDefinitions(schema._def.left, definitions, visited);
zod2JsonSchemaDefinitions(schema._def.right, definitions, visited);
}
if (typeName && !definitions[typeName]) {
definitions[typeName] = schema;
}
return definitions;
}