parseDef.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.parseDef = void 0;
  4. const zod_1 = require("zod");
  5. const any_1 = require("./parsers/any.js");
  6. const array_1 = require("./parsers/array.js");
  7. const bigint_1 = require("./parsers/bigint.js");
  8. const boolean_1 = require("./parsers/boolean.js");
  9. const branded_1 = require("./parsers/branded.js");
  10. const catch_1 = require("./parsers/catch.js");
  11. const date_1 = require("./parsers/date.js");
  12. const default_1 = require("./parsers/default.js");
  13. const effects_1 = require("./parsers/effects.js");
  14. const enum_1 = require("./parsers/enum.js");
  15. const intersection_1 = require("./parsers/intersection.js");
  16. const literal_1 = require("./parsers/literal.js");
  17. const map_1 = require("./parsers/map.js");
  18. const nativeEnum_1 = require("./parsers/nativeEnum.js");
  19. const never_1 = require("./parsers/never.js");
  20. const null_1 = require("./parsers/null.js");
  21. const nullable_1 = require("./parsers/nullable.js");
  22. const number_1 = require("./parsers/number.js");
  23. const object_1 = require("./parsers/object.js");
  24. const optional_1 = require("./parsers/optional.js");
  25. const pipeline_1 = require("./parsers/pipeline.js");
  26. const promise_1 = require("./parsers/promise.js");
  27. const record_1 = require("./parsers/record.js");
  28. const set_1 = require("./parsers/set.js");
  29. const string_1 = require("./parsers/string.js");
  30. const tuple_1 = require("./parsers/tuple.js");
  31. const undefined_1 = require("./parsers/undefined.js");
  32. const union_1 = require("./parsers/union.js");
  33. const unknown_1 = require("./parsers/unknown.js");
  34. const readonly_1 = require("./parsers/readonly.js");
  35. const Options_1 = require("./Options.js");
  36. function parseDef(def, refs, forceResolution = false) {
  37. const seenItem = refs.seen.get(def);
  38. if (refs.override) {
  39. const overrideResult = refs.override?.(def, refs, seenItem, forceResolution);
  40. if (overrideResult !== Options_1.ignoreOverride) {
  41. return overrideResult;
  42. }
  43. }
  44. if (seenItem && !forceResolution) {
  45. const seenSchema = get$ref(seenItem, refs);
  46. if (seenSchema !== undefined) {
  47. if ('$ref' in seenSchema) {
  48. refs.seenRefs.add(seenSchema.$ref);
  49. }
  50. return seenSchema;
  51. }
  52. }
  53. const newItem = { def, path: refs.currentPath, jsonSchema: undefined };
  54. refs.seen.set(def, newItem);
  55. const jsonSchema = selectParser(def, def.typeName, refs, forceResolution);
  56. if (jsonSchema) {
  57. addMeta(def, refs, jsonSchema);
  58. }
  59. newItem.jsonSchema = jsonSchema;
  60. return jsonSchema;
  61. }
  62. exports.parseDef = parseDef;
  63. const get$ref = (item, refs) => {
  64. switch (refs.$refStrategy) {
  65. case 'root':
  66. return { $ref: item.path.join('/') };
  67. // this case is needed as OpenAI strict mode doesn't support top-level `$ref`s, i.e.
  68. // the top-level schema *must* be `{"type": "object", "properties": {...}}` but if we ever
  69. // need to define a `$ref`, relative `$ref`s aren't supported, so we need to extract
  70. // the schema to `#/definitions/` and reference that.
  71. //
  72. // e.g. if we need to reference a schema at
  73. // `["#","definitions","contactPerson","properties","person1","properties","name"]`
  74. // then we'll extract it out to `contactPerson_properties_person1_properties_name`
  75. case 'extract-to-root':
  76. const name = item.path.slice(refs.basePath.length + 1).join('_');
  77. // we don't need to extract the root schema in this case, as it's already
  78. // been added to the definitions
  79. if (name !== refs.name && refs.nameStrategy === 'duplicate-ref') {
  80. refs.definitions[name] = item.def;
  81. }
  82. return { $ref: [...refs.basePath, refs.definitionPath, name].join('/') };
  83. case 'relative':
  84. return { $ref: getRelativePath(refs.currentPath, item.path) };
  85. case 'none':
  86. case 'seen': {
  87. if (item.path.length < refs.currentPath.length &&
  88. item.path.every((value, index) => refs.currentPath[index] === value)) {
  89. console.warn(`Recursive reference detected at ${refs.currentPath.join('/')}! Defaulting to any`);
  90. return {};
  91. }
  92. return refs.$refStrategy === 'seen' ? {} : undefined;
  93. }
  94. }
  95. };
  96. const getRelativePath = (pathA, pathB) => {
  97. let i = 0;
  98. for (; i < pathA.length && i < pathB.length; i++) {
  99. if (pathA[i] !== pathB[i])
  100. break;
  101. }
  102. return [(pathA.length - i).toString(), ...pathB.slice(i)].join('/');
  103. };
  104. const selectParser = (def, typeName, refs, forceResolution) => {
  105. switch (typeName) {
  106. case zod_1.ZodFirstPartyTypeKind.ZodString:
  107. return (0, string_1.parseStringDef)(def, refs);
  108. case zod_1.ZodFirstPartyTypeKind.ZodNumber:
  109. return (0, number_1.parseNumberDef)(def, refs);
  110. case zod_1.ZodFirstPartyTypeKind.ZodObject:
  111. return (0, object_1.parseObjectDef)(def, refs);
  112. case zod_1.ZodFirstPartyTypeKind.ZodBigInt:
  113. return (0, bigint_1.parseBigintDef)(def, refs);
  114. case zod_1.ZodFirstPartyTypeKind.ZodBoolean:
  115. return (0, boolean_1.parseBooleanDef)();
  116. case zod_1.ZodFirstPartyTypeKind.ZodDate:
  117. return (0, date_1.parseDateDef)(def, refs);
  118. case zod_1.ZodFirstPartyTypeKind.ZodUndefined:
  119. return (0, undefined_1.parseUndefinedDef)();
  120. case zod_1.ZodFirstPartyTypeKind.ZodNull:
  121. return (0, null_1.parseNullDef)(refs);
  122. case zod_1.ZodFirstPartyTypeKind.ZodArray:
  123. return (0, array_1.parseArrayDef)(def, refs);
  124. case zod_1.ZodFirstPartyTypeKind.ZodUnion:
  125. case zod_1.ZodFirstPartyTypeKind.ZodDiscriminatedUnion:
  126. return (0, union_1.parseUnionDef)(def, refs);
  127. case zod_1.ZodFirstPartyTypeKind.ZodIntersection:
  128. return (0, intersection_1.parseIntersectionDef)(def, refs);
  129. case zod_1.ZodFirstPartyTypeKind.ZodTuple:
  130. return (0, tuple_1.parseTupleDef)(def, refs);
  131. case zod_1.ZodFirstPartyTypeKind.ZodRecord:
  132. return (0, record_1.parseRecordDef)(def, refs);
  133. case zod_1.ZodFirstPartyTypeKind.ZodLiteral:
  134. return (0, literal_1.parseLiteralDef)(def, refs);
  135. case zod_1.ZodFirstPartyTypeKind.ZodEnum:
  136. return (0, enum_1.parseEnumDef)(def);
  137. case zod_1.ZodFirstPartyTypeKind.ZodNativeEnum:
  138. return (0, nativeEnum_1.parseNativeEnumDef)(def);
  139. case zod_1.ZodFirstPartyTypeKind.ZodNullable:
  140. return (0, nullable_1.parseNullableDef)(def, refs);
  141. case zod_1.ZodFirstPartyTypeKind.ZodOptional:
  142. return (0, optional_1.parseOptionalDef)(def, refs);
  143. case zod_1.ZodFirstPartyTypeKind.ZodMap:
  144. return (0, map_1.parseMapDef)(def, refs);
  145. case zod_1.ZodFirstPartyTypeKind.ZodSet:
  146. return (0, set_1.parseSetDef)(def, refs);
  147. case zod_1.ZodFirstPartyTypeKind.ZodLazy:
  148. return parseDef(def.getter()._def, refs);
  149. case zod_1.ZodFirstPartyTypeKind.ZodPromise:
  150. return (0, promise_1.parsePromiseDef)(def, refs);
  151. case zod_1.ZodFirstPartyTypeKind.ZodNaN:
  152. case zod_1.ZodFirstPartyTypeKind.ZodNever:
  153. return (0, never_1.parseNeverDef)();
  154. case zod_1.ZodFirstPartyTypeKind.ZodEffects:
  155. return (0, effects_1.parseEffectsDef)(def, refs, forceResolution);
  156. case zod_1.ZodFirstPartyTypeKind.ZodAny:
  157. return (0, any_1.parseAnyDef)();
  158. case zod_1.ZodFirstPartyTypeKind.ZodUnknown:
  159. return (0, unknown_1.parseUnknownDef)();
  160. case zod_1.ZodFirstPartyTypeKind.ZodDefault:
  161. return (0, default_1.parseDefaultDef)(def, refs);
  162. case zod_1.ZodFirstPartyTypeKind.ZodBranded:
  163. return (0, branded_1.parseBrandedDef)(def, refs);
  164. case zod_1.ZodFirstPartyTypeKind.ZodReadonly:
  165. return (0, readonly_1.parseReadonlyDef)(def, refs);
  166. case zod_1.ZodFirstPartyTypeKind.ZodCatch:
  167. return (0, catch_1.parseCatchDef)(def, refs);
  168. case zod_1.ZodFirstPartyTypeKind.ZodPipeline:
  169. return (0, pipeline_1.parsePipelineDef)(def, refs);
  170. case zod_1.ZodFirstPartyTypeKind.ZodFunction:
  171. case zod_1.ZodFirstPartyTypeKind.ZodVoid:
  172. case zod_1.ZodFirstPartyTypeKind.ZodSymbol:
  173. return undefined;
  174. default:
  175. return ((_) => undefined)(typeName);
  176. }
  177. };
  178. const addMeta = (def, refs, jsonSchema) => {
  179. if (def.description) {
  180. jsonSchema.description = def.description;
  181. if (refs.markdownDescription) {
  182. jsonSchema.markdownDescription = def.description;
  183. }
  184. }
  185. return jsonSchema;
  186. };
  187. //# sourceMappingURL=parseDef.js.map