UNPKG

zod-to-json-schema

Version:
74 lines (73 loc) 2.33 kB
import { ZodOptional } from "zod"; import { parseDef } from "../parseDef.js"; export function parseObjectDef(def, refs) { const forceOptionalIntoNullable = refs.target === "openAi"; const result = { type: "object", properties: {}, }; const required = []; const shape = def.shape(); for (const propName in shape) { let propDef = shape[propName]; if (propDef === undefined || propDef._def === undefined) { continue; } let propOptional = safeIsOptional(propDef); if (propOptional && forceOptionalIntoNullable) { if (propDef instanceof ZodOptional) { propDef = propDef._def.innerType; } if (!propDef.isNullable()) { propDef = propDef.nullable(); } propOptional = false; } const parsedDef = parseDef(propDef._def, { ...refs, currentPath: [...refs.currentPath, "properties", propName], propertyPath: [...refs.currentPath, "properties", propName], }); if (parsedDef === undefined) { continue; } result.properties[propName] = parsedDef; if (!propOptional) { required.push(propName); } } if (required.length) { result.required = required; } const additionalProperties = decideAdditionalProperties(def, refs); if (additionalProperties !== undefined) { result.additionalProperties = additionalProperties; } return result; } function decideAdditionalProperties(def, refs) { if (def.catchall._def.typeName !== "ZodNever") { return parseDef(def.catchall._def, { ...refs, currentPath: [...refs.currentPath, "additionalProperties"], }); } switch (def.unknownKeys) { case "passthrough": return refs.allowedAdditionalProperties; case "strict": return refs.rejectedAdditionalProperties; case "strip": return refs.removeAdditionalStrategy === "strict" ? refs.allowedAdditionalProperties : refs.rejectedAdditionalProperties; } } function safeIsOptional(schema) { try { return schema.isOptional(); } catch { return true; } }