186 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			186 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | "use strict"; | ||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||
|  | exports.parseDef = parseDef; | ||
|  | const zod_1 = require("zod"); | ||
|  | const any_1 = require("./parsers/any.js"); | ||
|  | const array_1 = require("./parsers/array.js"); | ||
|  | const bigint_1 = require("./parsers/bigint.js"); | ||
|  | const boolean_1 = require("./parsers/boolean.js"); | ||
|  | const branded_1 = require("./parsers/branded.js"); | ||
|  | const catch_1 = require("./parsers/catch.js"); | ||
|  | const date_1 = require("./parsers/date.js"); | ||
|  | const default_1 = require("./parsers/default.js"); | ||
|  | const effects_1 = require("./parsers/effects.js"); | ||
|  | const enum_1 = require("./parsers/enum.js"); | ||
|  | const intersection_1 = require("./parsers/intersection.js"); | ||
|  | const literal_1 = require("./parsers/literal.js"); | ||
|  | const map_1 = require("./parsers/map.js"); | ||
|  | const nativeEnum_1 = require("./parsers/nativeEnum.js"); | ||
|  | const never_1 = require("./parsers/never.js"); | ||
|  | const null_1 = require("./parsers/null.js"); | ||
|  | const nullable_1 = require("./parsers/nullable.js"); | ||
|  | const number_1 = require("./parsers/number.js"); | ||
|  | const object_1 = require("./parsers/object.js"); | ||
|  | const optional_1 = require("./parsers/optional.js"); | ||
|  | const pipeline_1 = require("./parsers/pipeline.js"); | ||
|  | const promise_1 = require("./parsers/promise.js"); | ||
|  | const record_1 = require("./parsers/record.js"); | ||
|  | const set_1 = require("./parsers/set.js"); | ||
|  | const string_1 = require("./parsers/string.js"); | ||
|  | const tuple_1 = require("./parsers/tuple.js"); | ||
|  | const undefined_1 = require("./parsers/undefined.js"); | ||
|  | const union_1 = require("./parsers/union.js"); | ||
|  | const unknown_1 = require("./parsers/unknown.js"); | ||
|  | const readonly_1 = require("./parsers/readonly.js"); | ||
|  | const Options_1 = require("./Options.js"); | ||
|  | function parseDef(def, refs, forceResolution = false) { | ||
|  |     const seenItem = refs.seen.get(def); | ||
|  |     if (refs.override) { | ||
|  |         const overrideResult = refs.override?.(def, refs, seenItem, forceResolution); | ||
|  |         if (overrideResult !== Options_1.ignoreOverride) { | ||
|  |             return overrideResult; | ||
|  |         } | ||
|  |     } | ||
|  |     if (seenItem && !forceResolution) { | ||
|  |         const seenSchema = get$ref(seenItem, refs); | ||
|  |         if (seenSchema !== undefined) { | ||
|  |             if ('$ref' in seenSchema) { | ||
|  |                 refs.seenRefs.add(seenSchema.$ref); | ||
|  |             } | ||
|  |             return seenSchema; | ||
|  |         } | ||
|  |     } | ||
|  |     const newItem = { def, path: refs.currentPath, jsonSchema: undefined }; | ||
|  |     refs.seen.set(def, newItem); | ||
|  |     const jsonSchema = selectParser(def, def.typeName, refs, forceResolution); | ||
|  |     if (jsonSchema) { | ||
|  |         addMeta(def, refs, jsonSchema); | ||
|  |     } | ||
|  |     newItem.jsonSchema = jsonSchema; | ||
|  |     return jsonSchema; | ||
|  | } | ||
|  | const get$ref = (item, refs) => { | ||
|  |     switch (refs.$refStrategy) { | ||
|  |         case 'root': | ||
|  |             return { $ref: item.path.join('/') }; | ||
|  |         // this case is needed as OpenAI strict mode doesn't support top-level `$ref`s, i.e.
 | ||
|  |         // the top-level schema *must* be `{"type": "object", "properties": {...}}` but if we ever
 | ||
|  |         // need to define a `$ref`, relative `$ref`s aren't supported, so we need to extract
 | ||
|  |         // the schema to `#/definitions/` and reference that.
 | ||
|  |         //
 | ||
|  |         // e.g. if we need to reference a schema at
 | ||
|  |         // `["#","definitions","contactPerson","properties","person1","properties","name"]`
 | ||
|  |         // then we'll extract it out to `contactPerson_properties_person1_properties_name`
 | ||
|  |         case 'extract-to-root': | ||
|  |             const name = item.path.slice(refs.basePath.length + 1).join('_'); | ||
|  |             // we don't need to extract the root schema in this case, as it's already
 | ||
|  |             // been added to the definitions
 | ||
|  |             if (name !== refs.name && refs.nameStrategy === 'duplicate-ref') { | ||
|  |                 refs.definitions[name] = item.def; | ||
|  |             } | ||
|  |             return { $ref: [...refs.basePath, refs.definitionPath, name].join('/') }; | ||
|  |         case 'relative': | ||
|  |             return { $ref: getRelativePath(refs.currentPath, item.path) }; | ||
|  |         case 'none': | ||
|  |         case 'seen': { | ||
|  |             if (item.path.length < refs.currentPath.length && | ||
|  |                 item.path.every((value, index) => refs.currentPath[index] === value)) { | ||
|  |                 console.warn(`Recursive reference detected at ${refs.currentPath.join('/')}! Defaulting to any`); | ||
|  |                 return {}; | ||
|  |             } | ||
|  |             return refs.$refStrategy === 'seen' ? {} : undefined; | ||
|  |         } | ||
|  |     } | ||
|  | }; | ||
|  | const getRelativePath = (pathA, pathB) => { | ||
|  |     let i = 0; | ||
|  |     for (; i < pathA.length && i < pathB.length; i++) { | ||
|  |         if (pathA[i] !== pathB[i]) | ||
|  |             break; | ||
|  |     } | ||
|  |     return [(pathA.length - i).toString(), ...pathB.slice(i)].join('/'); | ||
|  | }; | ||
|  | const selectParser = (def, typeName, refs, forceResolution) => { | ||
|  |     switch (typeName) { | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodString: | ||
|  |             return (0, string_1.parseStringDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodNumber: | ||
|  |             return (0, number_1.parseNumberDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodObject: | ||
|  |             return (0, object_1.parseObjectDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodBigInt: | ||
|  |             return (0, bigint_1.parseBigintDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodBoolean: | ||
|  |             return (0, boolean_1.parseBooleanDef)(); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodDate: | ||
|  |             return (0, date_1.parseDateDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodUndefined: | ||
|  |             return (0, undefined_1.parseUndefinedDef)(); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodNull: | ||
|  |             return (0, null_1.parseNullDef)(refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodArray: | ||
|  |             return (0, array_1.parseArrayDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodUnion: | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: | ||
|  |             return (0, union_1.parseUnionDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodIntersection: | ||
|  |             return (0, intersection_1.parseIntersectionDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodTuple: | ||
|  |             return (0, tuple_1.parseTupleDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodRecord: | ||
|  |             return (0, record_1.parseRecordDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodLiteral: | ||
|  |             return (0, literal_1.parseLiteralDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodEnum: | ||
|  |             return (0, enum_1.parseEnumDef)(def); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodNativeEnum: | ||
|  |             return (0, nativeEnum_1.parseNativeEnumDef)(def); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodNullable: | ||
|  |             return (0, nullable_1.parseNullableDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodOptional: | ||
|  |             return (0, optional_1.parseOptionalDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodMap: | ||
|  |             return (0, map_1.parseMapDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodSet: | ||
|  |             return (0, set_1.parseSetDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodLazy: | ||
|  |             return parseDef(def.getter()._def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodPromise: | ||
|  |             return (0, promise_1.parsePromiseDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodNaN: | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodNever: | ||
|  |             return (0, never_1.parseNeverDef)(); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodEffects: | ||
|  |             return (0, effects_1.parseEffectsDef)(def, refs, forceResolution); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodAny: | ||
|  |             return (0, any_1.parseAnyDef)(); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodUnknown: | ||
|  |             return (0, unknown_1.parseUnknownDef)(); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodDefault: | ||
|  |             return (0, default_1.parseDefaultDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodBranded: | ||
|  |             return (0, branded_1.parseBrandedDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodReadonly: | ||
|  |             return (0, readonly_1.parseReadonlyDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodCatch: | ||
|  |             return (0, catch_1.parseCatchDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodPipeline: | ||
|  |             return (0, pipeline_1.parsePipelineDef)(def, refs); | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodFunction: | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodVoid: | ||
|  |         case zod_1.ZodFirstPartyTypeKind.ZodSymbol: | ||
|  |             return undefined; | ||
|  |         default: | ||
|  |             return ((_) => undefined)(typeName); | ||
|  |     } | ||
|  | }; | ||
|  | const addMeta = (def, refs, jsonSchema) => { | ||
|  |     if (def.description) { | ||
|  |         jsonSchema.description = def.description; | ||
|  |         if (refs.markdownDescription) { | ||
|  |             jsonSchema.markdownDescription = def.description; | ||
|  |         } | ||
|  |     } | ||
|  |     return jsonSchema; | ||
|  | }; | ||
|  | //# sourceMappingURL=parseDef.js.map
 |