UNPKG

zod-to-x

Version:

Multi language types generation from Zod schemas.

668 lines (667 loc) 33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Zod2Ast = void 0; const core_1 = require("../core"); const zod_helpers_1 = require("../lib/zod_helpers"); const logger_1 = require("../utils/logger"); const errors_1 = require("./errors"); /** * This class creates AST nodes used to transpile Zod Schemas to other languages. * Simply create an instance and call build with a ZodObject to obtain a list with transpilerable * nodes. */ class Zod2Ast { constructor(opt = {}) { var _a; this.nodes = new Map(); this.lazyPointers = []; this.warnings = []; this.opt = Object.assign(Object.assign({}, opt), { strict: (_a = opt.strict) !== null && _a !== void 0 ? _a : true }); } /** * Determines if the current node is an "own property" based on the provided parent file. * * @param parentFile - The file path of the parent to compare against, if exist. * @returns `true` if the node is an "own property"; otherwise, `false`. */ _isOwnProperty(parentFile) { var _a; return (this.opt.layer === undefined || parentFile === undefined || ((_a = this.opt.layer) === null || _a === void 0 ? void 0 : _a.file) === parentFile); } /** * Check if the layer of the item is compatible with the layer of the schema. If does and the * transpilerable item is in a different file, it returns the file name. * * @param itemName * @param metadata * @returns */ _getTranspilerableFile(itemName, metadata) { var _a, _b; let layer; if (this.opt.layer !== undefined && (metadata === null || metadata === void 0 ? void 0 : metadata.layer) !== undefined) { if (Array.isArray(metadata.genericTypes)) { // Check that all templates used with a generic type follows the layering rules if (metadata.genericTypes.some((i) => this.opt.layer.index < i.layer.index)) { throw new errors_1.BadLayerDefinitionError(`${itemName}: Layer with number ${this.opt.layer.index} can only use models` + `from the same or lower layer. Review templates used for generic ` + `type ${metadata.typeName}.`); } } const templatesTranslation = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.genericTypes) === null || _a === void 0 ? void 0 : _a.map((i) => { var _a, _b; return ({ parentFile: ((_a = this.opt.layer) === null || _a === void 0 ? void 0 : _a.file) !== i.layer.file ? i.layer.file : undefined, parentNamespace: ((_b = this.opt.layer) === null || _b === void 0 ? void 0 : _b.file) !== i.layer.file ? i.layer.namespace : undefined, aliasOf: i.typeName, }); }); if (metadata.layer.file === this.opt.layer.file) { // Case 1: Only layer exists and belongs to the same file // Case 2: Layer (belongs to same file) and parentLayer exist // Behaviour: New type is created extending the parent layer (if any) layer = (_b = metadata.parentLayer) !== null && _b !== void 0 ? _b : metadata.layer; if (this.opt.layer.index < layer.index) { throw new errors_1.BadLayerDefinitionError(`${itemName}: Layer with number ${this.opt.layer.index} can only use models` + `from the same or lower layer. Found layer with number ${layer.index}`); } if (this.opt.layer.file !== layer.file) { return { parentFile: layer.file, parentNamespace: layer.namespace, aliasOf: metadata === null || metadata === void 0 ? void 0 : metadata.aliasOf, templatesTranslation, isGenericChild: metadata === null || metadata === void 0 ? void 0 : metadata.isGenericChild, }; } else { return { aliasOf: metadata === null || metadata === void 0 ? void 0 : metadata.aliasOf, templatesTranslation, isGenericChild: metadata === null || metadata === void 0 ? void 0 : metadata.isGenericChild, }; } } else { // Case 3: Only layer exists and belongs to a different file // Case 4: Layer (belongs to different file) and parentLayer exist // Behaviour: Type is imported from Layer file layer = metadata.layer; if (this.opt.layer.index < layer.index) { throw new errors_1.BadLayerDefinitionError(`${itemName}: Layer with number ${this.opt.layer.index} can only use models` + `from the same or lower layer. Found layer with number ${layer.index}`); } return { parentFile: layer.file, parentNamespace: layer.namespace, aliasOf: undefined, templatesTranslation, isGenericChild: metadata === null || metadata === void 0 ? void 0 : metadata.isGenericChild, }; } } return {}; } /** * Transpilerable items are treated as references in the AST * @param node: AST node from which the definition will be created * @param constraints - Constraints to be added to the definition * @returns */ _createDefinition(node, constraints = {}, templatesTranslation = []) { return new core_1.ASTDefinition({ name: node.name, instanceType: node.constructor.name, parentFile: node.parentFile, parentNamespace: node.parentNamespace, aliasOf: node.aliasOf, templatesTranslation, constraints: "constraints" in node ? Object.assign(Object.assign({}, node.constraints), constraints) : constraints, }); } /** * Extracts and formats the enumeration values from a given ZodEnum or ZodNativeEnum schema. * @param schema - A ZodEnum or ZodNativeEnum schema containing the enumeration values. * @returns A list of key-value pairs where the key is a formatted string and the value * is either a string or a number. */ _getEnumValues(schema) { return Object.entries(schema.enum) .filter(([key, _value]) => isNaN(Number(key))) .map(([key, value]) => { // Creates a string key if it starts with number. key = isNaN(Number(key.at(0))) ? key : `"${key}"`; return [key, value]; }); } /** * Intersects the properties of two Zod object schemas and returns the combined properties. * Processes the Zod shapes directly instead of looking up cached AST nodes, ensuring that * instantiated generic types (from useGenericType) are correctly resolved. * * @param left - The left Zod object schema. * @param right - The right Zod object schema. * @returns An object containing the combined properties of the left and right schemas. */ _intersectAstNodes(left, right) { const properties = {}; for (const schema of [left, right]) { const shape = schema.def.shape; for (const key in shape) { const prevWasRequired = properties[key] !== undefined && !properties[key].isOptional; if (zod_helpers_1.ZodHelpers.isZodPromise(shape[key]) && zod_helpers_1.ZodHelpers.isZod2XGeneric(shape[key])) { const templateKey = shape[key].unwrap().def.values[0]; properties[key] = new core_1.ASTGenericType(templateKey); } else { properties[key] = this._zodToAST(shape[key]); } if (prevWasRequired && properties[key].isOptional) { // In intersection, if a property is required in one schema and optional in // another, it should be considered required. properties[key].isOptional = false; } } } return { properties }; } /** * Merges multiple AST definitions into a single AST object containing combined properties. * - Equal properties must have the same type and array dimension. * - If a property is optional in one definition and required in another, it will be considered * optional in the merged object. * - If a property is nullable in one definition and non-nullable in another, it will be * considered nullable in the merged object. * * @param options - An array of AST definitions to be merged. * @returns An object containing the merged properties. * @throws AstNodeError - If properties with different types or array dimensions are encountered. */ _unionAstNodes(options) { let typeA, typeB; const data = options.map((i) => this.nodes.get(i.name)); const properties = data.reduce((acc, i, j) => { for (const key in i.properties) { if (acc[key]) { acc[key] = Object.assign(Object.create(Object.getPrototypeOf(acc[key])), acc[key]); typeA = acc[key].constructor.name; typeB = i.properties[key].constructor.name; if (typeA !== typeB) { this.warnings.push(`Merging properties with different types: ${typeA} ` + `(from a previous variant) and ${typeB} ` + `(from ${i.name})`); } if (acc[key].arrayDimension !== i.properties[key].arrayDimension) { this.warnings.push(`Merging properties with different array dimensions: ` + `${acc[key].arrayDimension} (from a previous variant) and ` + `${i.properties[key].arrayDimension} (from ${i.name})`); acc[key].arrayDimension = Math.max(acc[key].arrayDimension || 0, i.properties[key].arrayDimension || 0); } if (acc[key].isNullable !== i.properties[key].isNullable) { acc[key].isNullable = true; } if (acc[key].isOptional !== i.properties[key].isOptional) { acc[key].isOptional = true; } if (i.properties[key].description) { acc[key].description = i.properties[key].description; } } else { acc[key] = i.properties[key]; // New property, just add it } } return acc; }, {}); for (const key in properties) { if (!data.every((variant) => key in variant.properties)) { // In Union, if a property is not present in all variants, it should be considered // optional. Shallow-clone preserving prototype before mutating, to avoid corrupting // the original cached AST node. properties[key] = Object.assign(Object.create(Object.getPrototypeOf(properties[key])), properties[key]); properties[key].isOptional = true; } } return { properties }; } /** * Retrieves the name and associated transpilerable file information for a given Zod schema. * * @param schema - The Zod schema to extract the name and file information from. * * @returns An object containing the `name` of the schema and additional transpilerable file * details. * * @throws AstTypeNameDefinitionError - If the schema does not have a `typeName` defined. * This can occur if layered modeling is used with nested schema definitions or if the `zod2x` * method is not used to provide a `typeName`. The error message includes details about the * affected type properties. */ _getNames(schema) { var _a, _b, _c; const name = (_a = schema._zod2x) === null || _a === void 0 ? void 0 : _a.typeName; if (!name) { let itemProperties = ["Unknown type"]; if (zod_helpers_1.ZodHelpers.isZodObject(schema)) { itemProperties = Object.keys(schema.def.shape); } else if (zod_helpers_1.ZodHelpers.isZodAnyUnionType(schema)) { itemProperties = schema.def.options.map((i) => { var _a; return ((_a = i._zod2x) === null || _a === void 0 ? void 0 : _a.typeName) || i.def.type; }); } else if (zod_helpers_1.ZodHelpers.isZodIntersection(schema)) { const left = schema.def.left; const right = schema.def.right; itemProperties = [ ((_b = left._zod2x) === null || _b === void 0 ? void 0 : _b.typeName) || left.def.type, ((_c = right._zod2x) === null || _c === void 0 ? void 0 : _c.typeName) || right.def.type, ]; } else if (zod_helpers_1.ZodHelpers.isZodEnum(schema)) { itemProperties = this._getEnumValues(schema).map((i) => i[0]); } throw new errors_1.AstTypeNameDefinitionError(`${schema.def.type} type must have a typeName. If Layered modeling is used, ` + `avoid nesting schemas definitions. Otherwise, use zod2x method to provide one. ` + `Affected type properties: ${itemProperties.join(", ")}`); } return Object.assign({ name }, this._getTranspilerableFile(name, schema._zod2x)); } /** * Generates an Abstract Syntax Tree (AST) definition for a Zod enum schema. * * @param schema - The Zod enum schema to process. * @param opt - Optional metadata for schema processing. * - `isInjectedEnum` (optional): Indicates if the enum is part of a discriminated union. * * @returns The AST definition for the provided enum schema. */ _getEnumAst(schema, opt) { var _a; const { name, parentFile, parentNamespace, aliasOf } = this._getNames(schema); const item = new core_1.ASTEnum({ name, values: this._getEnumValues(schema), description: (_a = schema.meta()) === null || _a === void 0 ? void 0 : _a.description, parentFile, parentNamespace, aliasOf, isFromDiscriminatedUnion: opt === null || opt === void 0 ? void 0 : opt.isInjectedEnum, }); if (!this.nodes.has(name)) { this.nodes.set(name, item); } return this._createDefinition(item); } /** * Generates an abstract syntax tree (AST) definition for a Zod object schema. * * @param schema - The ZodObject schema to be converted into an AST definition. * @param opt - Optional metadata for schema processing. * - `discriminantKey`: A key used to determine the discriminant value for the schema. * * @returns The AST definition for the provided Zod object schema. */ _getObjectAst(schema, opt) { var _a; const { name, parentFile, parentNamespace, aliasOf, templatesTranslation, isGenericChild } = this._getNames(schema); let discriminantValue = undefined; const shape = schema.def.shape; if (!this.nodes.has(name)) { const properties = {}; const templates = new Set(); for (const key in shape) { if (zod_helpers_1.ZodHelpers.isZodPromise(shape[key]) && zod_helpers_1.ZodHelpers.isZod2XGeneric(shape[key])) { const templateKey = shape[key].unwrap().def.values[0]; properties[key] = new core_1.ASTGenericType(templateKey); if (templates.has(templateKey)) { throw new errors_1.AstTypeNameDefinitionError(`Duplicate template key found for model ${name}: ${templateKey}`); } templates.add(templateKey); } else { properties[key] = this._zodToAST(shape[key]); } } if (opt === null || opt === void 0 ? void 0 : opt.skipLayerClass) { return {}; // Layer classes are not transpilerable } this.nodes.set(name, new core_1.ASTObject({ name, properties, description: (_a = schema.meta()) === null || _a === void 0 ? void 0 : _a.description, parentFile, parentNamespace, aliasOf, templates, templatesTranslation: templatesTranslation || [], })); } const item = this.nodes.get(name); if (opt === null || opt === void 0 ? void 0 : opt.discriminantKey) { if (Object.keys(item.properties).includes(opt.discriminantKey)) { const key = opt.discriminantKey; if (item.properties[key] instanceof core_1.ASTLiteral) { /* Used for serialization purposes, it is parsed as string for * convenience */ discriminantValue = item.properties[key].value.toString(); } else { console.warn(`Consider to set '${key}' key of '${name}' as ZodLiteral`); } } } return this._createDefinition(this.nodes.get(name), { discriminantValue }, isGenericChild ? undefined : templatesTranslation); } /** * Generates an Abstract Syntax Tree (AST) definition for a Zod union schema. * * This method processes a Zod union schema and creates an `ASTUnion` object * that represents the schema in an AST format. It handles both regular unions * and discriminated unions, and provides warnings for certain bad data modeling * practices, such as unions of non-object types or the use of `ZodUnion` instead * of `ZodDiscriminatedUnion`. * * @param schema - The Zod union schema to be converted into an AST definition. * This can be a regular union or a discriminated union. * * @returns The AST definition for the given Zod union schema. */ _getUnionAst(schema) { var _a, _b, _c; const def = schema.def; const discriminator = zod_helpers_1.ZodHelpers.isZodDiscriminatedUnion(schema) ? schema._zod.def.discriminator : undefined; const { name, parentFile, parentNamespace, aliasOf } = this._getNames(schema); const item = new core_1.ASTUnion({ name, options: def.options.map((i) => this._zodToAST(i, { discriminantKey: discriminator })), areAllObjects: def.options.every((i) => zod_helpers_1.ZodHelpers.isZodObject(i)), description: (_a = schema.meta()) === null || _a === void 0 ? void 0 : _a.description, discriminantKey: discriminator, parentFile, parentNamespace, aliasOf, }); if (!item.areAllObjects) { if (this._isOwnProperty(parentFile)) { this.warnings.push(`[affected type: ${name}] Union of non-object types is a bad data modeling ` + "practice, and could lead to unexpected results. Avoid it, or disable " + "strict mode if not possible."); } } else if (zod_helpers_1.ZodHelpers.isZodUnion(schema)) { if (this._isOwnProperty(parentFile)) { this.warnings.push(`[affected type: ${name}] Using ZodUnion is a bad data modeling practice. ` + "Use ZodDiscriminatedUnion instead, or disable strict mode if not possible."); } const unifiedProperties = this._unionAstNodes(item.options); item.newObject = new core_1.ASTObject({ name, properties: unifiedProperties.properties, description: (((_b = schema.meta()) === null || _b === void 0 ? void 0 : _b.description) ? `${(_c = schema.meta()) === null || _c === void 0 ? void 0 : _c.description} - ` : "") + `Built from union of ` + `${item.options.map((i) => i.name).join(", ")}`, templates: new Set(Object.values(unifiedProperties.properties) .filter((i) => i instanceof core_1.ASTGenericType) .map((i) => i.name)), templatesTranslation: [], }); } if (name && !this.nodes.has(name)) { this.nodes.set(name, item); } return this._createDefinition(item); } /** * Processes a ZodIntersection schema and generates an ASTDefinition for it. * * @param schema - The ZodIntersection schema to process, which combines two Zod types. * * @returns An ASTDefinition representing the intersection of the two Zod types. */ _getIntersectionAst(schema) { var _a, _b, _c; const def = schema.def; const { name, parentFile, parentNamespace, aliasOf } = this._getNames(schema); const item = new core_1.ASTIntersection({ name, left: this._zodToAST(def.left), right: this._zodToAST(def.right), areAllObjects: zod_helpers_1.ZodHelpers.isZodObject(def.left) && zod_helpers_1.ZodHelpers.isZodObject(def.right), description: (_a = schema.meta()) === null || _a === void 0 ? void 0 : _a.description, parentFile, parentNamespace, aliasOf, }); if (!item.areAllObjects) { if (this._isOwnProperty(parentFile)) { this.warnings.push(`[affected type: ${name}] Intersection of non-object is a bad data modeling ` + "practice, and could lead to unexpected results. Avoid it, or disable " + "strict mode if not possible."); } } else { const intersectedProperties = this._intersectAstNodes(def.left, def.right); item.newObject = new core_1.ASTObject({ name, properties: intersectedProperties.properties, description: (((_b = schema.meta()) === null || _b === void 0 ? void 0 : _b.description) ? `${(_c = schema.meta()) === null || _c === void 0 ? void 0 : _c.description} - ` : "") + `Built from intersection of ` + `${item.left.name} and ` + `${item.right.name}`, templates: new Set(Object.values(intersectedProperties.properties) .filter((i) => i instanceof core_1.ASTGenericType) .map((i) => i.name)), templatesTranslation: [], }); } if (name && !this.nodes.has(name)) { this.nodes.set(name, item); } return this._createDefinition(item); } /** * Generates an AST (Abstract Syntax Tree) definition for a Zod array schema. * * @param schema - The Zod array schema to process. * @param innerSchema - The AST type representing the inner schema of the array. * @returns The AST definition for the array schema. */ _getArrayAst(schema, innerSchema) { var _a; const { name, parentFile, parentNamespace, aliasOf } = this._getNames(schema); const item = new core_1.ASTArray({ name, item: innerSchema, description: (_a = schema.meta()) === null || _a === void 0 ? void 0 : _a.description, parentFile, parentNamespace, aliasOf, }); if (!this.nodes.has(name)) { this.nodes.set(name, item); } return this._createDefinition(item); } _getAliasAst(schema, item) { var _a; if (((_a = schema._zod2x) === null || _a === void 0 ? void 0 : _a.typeName) === undefined || this.opt.skipBasicTypes === true) { return item; } const { name, parentFile, parentNamespace, aliasOf } = this._getNames(schema); item.name = name; item.parentFile = parentFile; item.parentNamespace = parentNamespace; item.aliasOf = aliasOf; if (!this.nodes.has(name)) { this.nodes.set(name, item); } return this._createDefinition(item); } /** * Build the AST node of provided Zod Schema * @param schema * @returns */ _zodToAST(schema, opt) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; if (zod_helpers_1.ZodHelpers.isZodString(schema)) { return this._getAliasAst(schema, new core_1.ASTString({ description: (_a = schema.meta()) === null || _a === void 0 ? void 0 : _a.description })); } else if (zod_helpers_1.ZodHelpers.isZodAnyNumberType(schema)) { return this._getAliasAst(schema, new core_1.ASTNumber({ description: (_b = schema.meta()) === null || _b === void 0 ? void 0 : _b.description, constraints: zod_helpers_1.ZodHelpers.getZodNumberConstraints(schema), })); } else if (zod_helpers_1.ZodHelpers.isZodBoolean(schema)) { return this._getAliasAst(schema, new core_1.ASTBoolean({ description: (_c = schema.meta()) === null || _c === void 0 ? void 0 : _c.description })); } else if (zod_helpers_1.ZodHelpers.isZodDate(schema)) { return this._getAliasAst(schema, new core_1.ASTDate({ description: (_d = schema.meta()) === null || _d === void 0 ? void 0 : _d.description })); } else if (zod_helpers_1.ZodHelpers.isZodAny(schema)) { return this._getAliasAst(schema, new core_1.ASTAny({ description: (_e = schema.meta()) === null || _e === void 0 ? void 0 : _e.description })); } else if (zod_helpers_1.ZodHelpers.isZodNullable(schema)) { const subSchema = this._zodToAST(schema.unwrap()); subSchema.isNullable = true; subSchema.description = ((_f = schema.meta()) === null || _f === void 0 ? void 0 : _f.description) || subSchema.description; return subSchema; } else if (zod_helpers_1.ZodHelpers.isZodOptional(schema)) { const subSchema = this._zodToAST(schema.unwrap()); subSchema.isOptional = true; subSchema.description = ((_g = schema.meta()) === null || _g === void 0 ? void 0 : _g.description) || subSchema.description; return subSchema; } else if (zod_helpers_1.ZodHelpers.isZodDefault(schema)) { const subSchema = this._zodToAST(schema.def.defaultValue()); subSchema.description = ((_h = schema.meta()) === null || _h === void 0 ? void 0 : _h.description) || subSchema.description; return subSchema; } else if (zod_helpers_1.ZodHelpers.isZodArray(schema)) { const isParentArray = (opt === null || opt === void 0 ? void 0 : opt.calledFromArray) !== true; const subSchema = this._zodToAST(schema.element, { calledFromArray: true }); subSchema.description = ((_j = schema.meta()) === null || _j === void 0 ? void 0 : _j.description) || subSchema.description; subSchema.arrayDimension = Number.isInteger(subSchema.arrayDimension) ? ++subSchema.arrayDimension : 1; if (isParentArray && ((_k = schema._zod2x) === null || _k === void 0 ? void 0 : _k.typeName)) { return this._getArrayAst(schema, subSchema); } else { return subSchema; } } else if (zod_helpers_1.ZodHelpers.isZodSet(schema)) { return this._getAliasAst(schema, new core_1.ASTSet({ value: this._zodToAST(schema.def.valueType), description: (_l = schema.meta()) === null || _l === void 0 ? void 0 : _l.description, })); } else if (zod_helpers_1.ZodHelpers.isZodLiteral(schema)) { let parentEnum = undefined; let parentEnumKey = undefined; // TODO: Support multiple values if ((_m = schema._zod2x) === null || _m === void 0 ? void 0 : _m.parentEnum) { parentEnumKey = (_p = this._getEnumValues((_o = schema._zod2x) === null || _o === void 0 ? void 0 : _o.parentEnum).find((i) => i[1] === schema.def.values.at(0))) === null || _p === void 0 ? void 0 : _p[0]; parentEnum = this._zodToAST((_q = schema._zod2x) === null || _q === void 0 ? void 0 : _q.parentEnum, { isInjectedEnum: true, }); } return new core_1.ASTLiteral({ value: schema.def.values.at(0), // TODO: Support multiple values description: (_r = schema.meta()) === null || _r === void 0 ? void 0 : _r.description, parentEnum: parentEnum, parentEnumKey, }); } else if (zod_helpers_1.ZodHelpers.isZodAnyMapType(schema)) { return this._getAliasAst(schema, new core_1.ASTMap({ type: zod_helpers_1.ZodHelpers.isZodRecord(schema) ? "record" : "map", key: this._zodToAST(schema.keyType), value: this._zodToAST(schema.valueType), description: (_s = schema.meta()) === null || _s === void 0 ? void 0 : _s.description, })); } else if (zod_helpers_1.ZodHelpers.isZodLazy(schema)) { /** Lazy items use to be recursive schemas of its own, so the are trated as another * definition */ const lazySchema = schema.def.getter(); const lazyPointer = this._createDefinition({ name: "pending" }); this.lazyPointers.push([lazyPointer, lazySchema]); return lazyPointer; } else if (zod_helpers_1.ZodHelpers.isZodTuple(schema)) { return this._getAliasAst(schema, new core_1.ASTTuple({ items: schema.def.items.map(this._zodToAST.bind(this)), description: (_t = schema.meta()) === null || _t === void 0 ? void 0 : _t.description, })); /** * * * Transpilerable items * * * */ } else if (zod_helpers_1.ZodHelpers.isZodEnum(schema)) { return this._getEnumAst(schema, opt); } else if (zod_helpers_1.ZodHelpers.isZodObject(schema)) { return this._getObjectAst(schema, opt); } else if (zod_helpers_1.ZodHelpers.isZodAnyUnionType(schema)) { return this._getUnionAst(schema); } else if (zod_helpers_1.ZodHelpers.isZodIntersection(schema)) { return this._getIntersectionAst(schema); } else { logger_1.log.warn(`Unsupported Zod type: ${JSON.stringify(schema)}`); return new core_1.ASTAny({ description: `Unsupported Zod type: ${schema.def.type}`, }); } } /** * Create the AST identifying the nodes that can be transpiled. * @param schema * @returns Transpilerable nodes. */ build(schema) { var _a, _b, _c; this._zodToAST(schema, { skipLayerClass: ((_a = this.opt) === null || _a === void 0 ? void 0 : _a.layer) !== undefined && ((_c = (_b = this.opt) === null || _b === void 0 ? void 0 : _b.layer) === null || _c === void 0 ? void 0 : _c.skipLayerInterface) !== false, }); while (this.lazyPointers.length > 0) { const [pointer, schema] = this.lazyPointers.shift(); const lazyResolve = this._zodToAST(schema); /** Pointer to the pending AST node is updated with the lazy resolve */ Object.keys(pointer).forEach((key) => { delete pointer[key]; }); Object.entries(lazyResolve).forEach(([key, value]) => { pointer[key] = value; }); } if (this.opt.strict !== false && this.warnings.length > 0) { throw new errors_1.AstNodeError(this.warnings.join("\n")); } return { nodes: this.nodes, warnings: this.warnings, }; } } exports.Zod2Ast = Zod2Ast;