@kubb/adapter-oas 5.0.0-beta.93 → 5.0.0-beta.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import "./rolldown-runtime-C0LytTxp.js";
2
- import { ast, childName, collect, enumPropName, extractRefName, findCircularSchemas, macroDiscriminatorEnum, macroEnumName, macroSimplifyUnion, mergeAdjacentObjectsLazy, narrowSchema } from "@kubb/ast";
2
+ import { ast, childName, enumPropName, extractRefName, findCircularSchemas, macroDiscriminatorEnum, macroEnumName, macroSimplifyUnion, mergeAdjacentObjectsLazy, narrowSchema } from "@kubb/ast";
3
3
  import { Diagnostics, createAdapter } from "@kubb/core";
4
4
  import path from "node:path";
5
5
  import { access, readFile } from "node:fs/promises";
6
6
  import { compileErrors, validate } from "@readme/openapi-parser";
7
7
  import { upgrade } from "@scalar/openapi-upgrader";
8
- import { parse } from "yaml";
9
8
  import { bundle } from "api-ref-bundler";
9
+ import { parse } from "yaml";
10
10
  //#region src/constants.ts
11
11
  /**
12
12
  * Default parser options applied when no explicit options are provided.
@@ -344,7 +344,7 @@ async function read(path) {
344
344
  return readFile(path, { encoding: "utf8" });
345
345
  }
346
346
  //#endregion
347
- //#region src/bundler.ts
347
+ //#region src/factory.ts
348
348
  const urlRegExp = /^https?:\/+/i;
349
349
  async function readSource(sourcePath) {
350
350
  if (urlRegExp.test(sourcePath)) {
@@ -387,8 +387,6 @@ async function bundleDocument(pathOrUrl) {
387
387
  await resolver(pathOrUrl);
388
388
  return await bundle(pathOrUrl, resolver);
389
389
  }
390
- //#endregion
391
- //#region src/factory.ts
392
390
  /**
393
391
  * Loads and bundles an OpenAPI document, returning the raw `Document`.
394
392
  *
@@ -458,19 +456,12 @@ async function validateDocument(document, { throwOnError = false } = {}) {
458
456
  }
459
457
  }
460
458
  //#endregion
461
- //#region src/guards.ts
459
+ //#region src/oas.ts
462
460
  /**
463
461
  * Returns `true` when a schema should be treated as nullable.
464
462
  *
465
463
  * Recognizes all nullable signals across OAS versions: `nullable: true` (OAS 3.0),
466
464
  * `x-nullable: true` (vendor extension), `type: 'null'`, and `type: ['null', ...]` (OAS 3.1).
467
- *
468
- * @example
469
- * ```ts
470
- * isNullable({ type: 'string', nullable: true }) // true
471
- * isNullable({ type: ['string', 'null'] }) // true
472
- * isNullable({ type: 'string' }) // false
473
- * ```
474
465
  */
475
466
  function isNullable(schema) {
476
467
  if ((schema?.nullable ?? schema?.["x-nullable"]) === true) return true;
@@ -481,24 +472,13 @@ function isNullable(schema) {
481
472
  }
482
473
  /**
483
474
  * Returns `true` when `obj` is an OpenAPI `$ref` pointer object.
484
- *
485
- * @example
486
- * ```ts
487
- * isReference({ $ref: '#/components/schemas/Pet' }) // true
488
- * isReference({ type: 'string' }) // false
489
- * ```
490
475
  */
491
476
  function isReference(obj) {
492
477
  return !!obj && typeof obj === "object" && "$ref" in obj;
493
478
  }
494
479
  /**
495
- * Returns `true` when `obj` is a schema with a structured OAS 3.x `discriminator` object.
496
- *
497
- * @example
498
- * ```ts
499
- * isDiscriminator({ discriminator: { propertyName: 'type', mapping: {} } }) // true
500
- * isDiscriminator({ discriminator: 'type' }) // false (Swagger 2 string form)
501
- * ```
480
+ * Returns `true` when `obj` is a schema with a structured OAS 3.x `discriminator` object,
481
+ * excluding the Swagger 2 string form.
502
482
  */
503
483
  function isDiscriminator(obj) {
504
484
  const record = obj;
@@ -506,18 +486,10 @@ function isDiscriminator(obj) {
506
486
  }
507
487
  /**
508
488
  * Returns `true` when a schema is a binary payload: an octet-stream string body.
509
- *
510
- * @example
511
- * ```ts
512
- * isBinary({ type: 'string', contentMediaType: 'application/octet-stream' }) // true
513
- * isBinary({ type: 'string' }) // false
514
- * ```
515
489
  */
516
490
  function isBinary(schema) {
517
491
  return schema.type === "string" && schema.contentMediaType === "application/octet-stream";
518
492
  }
519
- //#endregion
520
- //#region src/mime.ts
521
493
  /**
522
494
  * MIME type fragments that mark a media type as JSON-like.
523
495
  *
@@ -610,6 +582,23 @@ function dereferenceWithRef(document, schema) {
610
582
  };
611
583
  return schema;
612
584
  }
585
+ /**
586
+ * Resolves a `$ref` slot in place: when `container[key]` holds a `$ref`, replaces it with the
587
+ * resolved value and returns that value. Returns `null` when the slot is empty, cannot be resolved,
588
+ * or is still a `$ref` after resolving. A non-`$ref` value is returned untouched, without writing.
589
+ *
590
+ * @example
591
+ * ```ts
592
+ * derefInPlace<ResponseObject>({ document, container: operation.schema.responses, key: '200' })
593
+ * ```
594
+ */
595
+ function derefInPlace({ document, container, key }) {
596
+ const value = container[key];
597
+ if (!isReference(value)) return value ? value : null;
598
+ const resolved = resolveRef(document, value.$ref);
599
+ container[key] = resolved;
600
+ return resolved && !isReference(resolved) ? resolved : null;
601
+ }
613
602
  //#endregion
614
603
  //#region src/operation.ts
615
604
  /**
@@ -641,31 +630,22 @@ function getResponseStatusCodes({ schema }) {
641
630
  function getResponseByStatusCode({ document, operation, statusCode }) {
642
631
  const responses = operation.schema.responses;
643
632
  if (!responses || isReference(responses)) return false;
644
- const response = responses[statusCode];
645
- if (!response) return false;
646
- if (isReference(response)) {
647
- const resolved = resolveRef(document, response.$ref);
648
- responses[statusCode] = resolved;
649
- if (!resolved || isReference(resolved)) return false;
650
- return resolved;
651
- }
652
- return response;
633
+ return derefInPlace({
634
+ document,
635
+ container: responses,
636
+ key: statusCode
637
+ }) ?? false;
653
638
  }
654
639
  /**
655
640
  * Resolves the request body (dereferencing a `$ref` in place) and returns its content map, or
656
641
  * `undefined` when the operation has no request body.
657
642
  */
658
643
  function getRequestBodyContent({ document, operation }) {
659
- const { schema } = operation;
660
- let requestBody = schema.requestBody;
661
- if (!requestBody) return;
662
- if (isReference(requestBody)) {
663
- const resolved = resolveRef(document, requestBody.$ref);
664
- schema.requestBody = resolved;
665
- if (!resolved || isReference(resolved)) return;
666
- requestBody = resolved;
667
- }
668
- return requestBody.content;
644
+ return derefInPlace({
645
+ document,
646
+ container: operation.schema,
647
+ key: "requestBody"
648
+ })?.content;
669
649
  }
670
650
  /**
671
651
  * Returns the request body media type. With `mediaType` set, returns that entry or `false`.
@@ -714,14 +694,12 @@ function getOperations(document) {
714
694
  if (!paths) return operations;
715
695
  for (const path of Object.keys(paths)) {
716
696
  if (path.startsWith("x-")) continue;
717
- let pathItem = paths[path];
697
+ const pathItem = derefInPlace({
698
+ document,
699
+ container: paths,
700
+ key: path
701
+ });
718
702
  if (!pathItem) continue;
719
- if (isReference(pathItem)) {
720
- const resolved = resolveRef(document, pathItem.$ref);
721
- paths[path] = resolved;
722
- if (!resolved || isReference(resolved)) continue;
723
- pathItem = resolved;
724
- }
725
703
  const item = pathItem;
726
704
  for (const method of Object.keys(item)) {
727
705
  if (!SUPPORTED_METHODS.has(method)) continue;
@@ -849,6 +827,15 @@ function getResponseBody(responseBody, contentType) {
849
827
  if (!availableContentType) return false;
850
828
  return body.content[availableContentType];
851
829
  }
830
+ function resolveResponseRefs(document, operation) {
831
+ const responses = operation.schema.responses;
832
+ if (!responses) return;
833
+ for (const key in responses) derefInPlace({
834
+ document,
835
+ container: responses,
836
+ key
837
+ });
838
+ }
852
839
  /**
853
840
  * Returns the response schema for a given operation and HTTP status code.
854
841
  *
@@ -860,14 +847,6 @@ function getResponseBody(responseBody, contentType) {
860
847
  * getResponseSchema(document, operation, '4XX') // {}
861
848
  * ```
862
849
  */
863
- function resolveResponseRefs(document, operation) {
864
- const responses = operation.schema.responses;
865
- if (!responses) return;
866
- for (const key in responses) {
867
- const schema = responses[key];
868
- if (schema && isReference(schema)) responses[key] = resolveRef(document, schema.$ref);
869
- }
870
- }
871
850
  function getResponseSchema(document, operation, statusCode, options = {}) {
872
851
  resolveResponseRefs(document, operation);
873
852
  const responseBody = getResponseBody(getResponseByStatusCode({
@@ -906,6 +885,16 @@ function getRequestSchema(document, operation, options = {}) {
906
885
  return dereferenceWithRef(document, schema);
907
886
  }
908
887
  /**
888
+ * Returns `true` when `fragment` carries any JSON Schema keyword that makes it
889
+ * structurally significant on its own (see `structuralKeys`).
890
+ *
891
+ * A fragment with a structural keyword can't be safely merged into a parent schema.
892
+ */
893
+ function hasStructuralKeywords(fragment) {
894
+ for (const key in fragment) if (structuralKeys.has(key)) return true;
895
+ return false;
896
+ }
897
+ /**
909
898
  * Flattens a keyword-only `allOf` into its parent schema.
910
899
  *
911
900
  * Only flattens when every member is a plain fragment, with no `$ref` and no structural keywords
@@ -924,16 +913,6 @@ function getRequestSchema(document, operation, options = {}) {
924
913
  * // returned unchanged, contains a $ref
925
914
  * ```
926
915
  */
927
- /**
928
- * Returns `true` when `fragment` carries any JSON Schema keyword that makes it
929
- * structurally significant on its own (see `structuralKeys`).
930
- *
931
- * A fragment with a structural keyword can't be safely merged into a parent schema.
932
- */
933
- function hasStructuralKeywords(fragment) {
934
- for (const key in fragment) if (structuralKeys.has(key)) return true;
935
- return false;
936
- }
937
916
  function flattenSchema(schema) {
938
917
  if (!schema?.allOf || schema.allOf.length === 0) return schema ?? null;
939
918
  const allOfFragments = schema.allOf;
@@ -1035,7 +1014,7 @@ function resolveSchemaRef(document, schema) {
1035
1014
  *
1036
1015
  * @example
1037
1016
  * ```ts
1038
- * const { schemas, nameMapping } = getSchemas(document, { contentType: 'application/json' })
1017
+ * const { schemas, renames } = getSchemas(document, { contentType: 'application/json' })
1039
1018
  * ```
1040
1019
  */
1041
1020
  function getSchemas(document, { contentType }) {
@@ -1060,7 +1039,7 @@ function getSchemas(document, { contentType }) {
1060
1039
  normalizedNames.set(key, bucket);
1061
1040
  }
1062
1041
  const schemas = {};
1063
- const nameMapping = /* @__PURE__ */ new Map();
1042
+ const renames = /* @__PURE__ */ new Map();
1064
1043
  for (const [, items] of normalizedNames) {
1065
1044
  const isSingle = items.length === 1;
1066
1045
  let hasMultipleSources = false;
@@ -1075,12 +1054,12 @@ function getSchemas(document, { contentType }) {
1075
1054
  const suffix = isSingle ? "" : hasMultipleSources ? semanticSuffixes[item.source] : index === 0 ? "" : String(index + 1);
1076
1055
  const uniqueName = item.originalName + suffix;
1077
1056
  schemas[uniqueName] = item.schema;
1078
- nameMapping.set(`#/components/${item.source}/${item.originalName}`, uniqueName);
1057
+ if (suffix) renames.set(`#/components/${item.source}/${item.originalName}`, uniqueName);
1079
1058
  });
1080
1059
  }
1081
1060
  return {
1082
1061
  schemas: sortSchemas(schemas),
1083
- nameMapping
1062
+ renames
1084
1063
  };
1085
1064
  }
1086
1065
  /**
@@ -1185,7 +1164,7 @@ function getResponseBodyContentTypes(document, operation, statusCode) {
1185
1164
  return body.content ? Object.keys(body.content) : [];
1186
1165
  }
1187
1166
  //#endregion
1188
- //#region src/parser.ts
1167
+ //#region src/converters.ts
1189
1168
  /**
1190
1169
  * Normalizes malformed `{ type: 'array', enum: [...] }` schemas by moving enum values into items.
1191
1170
  *
@@ -1209,7 +1188,7 @@ function normalizeArrayEnum(schema) {
1209
1188
  * Builds a `null` scalar node carrying the schema's documentation. Shared by the `const: null`
1210
1189
  * and the drf-spectacular `NullEnum` (`{ enum: [null] }`) branches, which render identically.
1211
1190
  */
1212
- function createNullSchema(schema, name, nullable) {
1191
+ function createNullNode(schema, name, nullable) {
1213
1192
  return ast.factory.createSchema({
1214
1193
  type: "null",
1215
1194
  primitive: "null",
@@ -1239,620 +1218,638 @@ function nameEnums(node, options) {
1239
1218
  return named;
1240
1219
  }
1241
1220
  /**
1242
- * Factory function that creates schema and operation converters for a given OpenAPI context.
1221
+ * Converts a `$ref` schema into a `RefSchemaNode`.
1243
1222
  *
1244
- * Returns closures that share mutable state (`resolvingRefs` set for cycle detection).
1245
- * Each converter branch (`convertRef`, `convertAllOf`, etc.) mutually recursively calls `parseSchema`,
1246
- * which works because function declarations hoist.
1247
- *
1248
- * @internal
1223
+ * The resolved schema is stored in `node.schema`. Usage-site sibling fields
1224
+ * (description, readOnly, nullable, etc.) are stored directly on the ref node.
1225
+ * Use `syncSchemaRef(node)` in printers to get a merged view of both.
1226
+ * Circular refs are detected in `resolveRefNode` and leave `schema` as `null`.
1227
+ */
1228
+ function convertRef({ schema, name, nullable, defaultValue, rawOptions, document, resolveRefNode, refExists, renames }) {
1229
+ const refPath = schema.$ref;
1230
+ const resolvedSchema = refPath ? resolveRefNode(refPath, rawOptions) : null;
1231
+ if (refPath && document.components && !refExists(refPath)) return ast.factory.createSchema({
1232
+ ...buildSchemaNode(schema, name, nullable, defaultValue),
1233
+ type: "unknown"
1234
+ });
1235
+ const targetName = renames?.get(schema.$ref);
1236
+ return ast.factory.createSchema({
1237
+ ...buildSchemaNode(schema, name, nullable, defaultValue),
1238
+ type: "ref",
1239
+ name: extractRefName(schema.$ref),
1240
+ ref: schema.$ref,
1241
+ ...targetName ? { targetName } : {},
1242
+ schema: resolvedSchema
1243
+ });
1244
+ }
1245
+ /**
1246
+ * Converts an `allOf` schema into a flattened node or an `IntersectionSchemaNode`.
1249
1247
  */
1250
- function createSchemaParser(ctx) {
1251
- const document = ctx.document;
1252
- /**
1253
- * Tracks `$ref` paths that are currently being resolved to prevent infinite
1254
- * recursion when schemas contain circular references (e.g. `Pet → parent → Pet`).
1255
- */
1256
- const resolvingRefs = /* @__PURE__ */ new Set();
1257
- /**
1258
- * Cache of `$ref` schemas already resolved in this parser instance, keyed by ref path.
1259
- *
1260
- * Without it, a shared schema (e.g. `customer`) is re-expanded for every `$ref` that points at
1261
- * it. In cross-referenced specs like Stripe (~1400 schemas) that becomes exponential blowup,
1262
- * since one schema can be referenced from dozens of parents, each re-walking its whole subtree.
1263
- * Memoizing by ref path drops the work from O(2^depth) to O(N) unique schema names.
1264
- */
1265
- const resolvedRefCache = /* @__PURE__ */ new Map();
1266
- /**
1267
- * Memoized record of whether a `$ref` path resolves to a node the document actually defines.
1268
- * A circular ref still resolves to an existing target, so this stays `true` for cycles and only
1269
- * goes `false` for a `$ref` that points at a component the spec never declares.
1270
- */
1271
- const refExistence = /* @__PURE__ */ new Map();
1272
- function refExists(refPath) {
1273
- if (!refExistence.has(refPath)) {
1274
- let exists = false;
1275
- try {
1276
- exists = !!resolveRef(document, refPath);
1277
- } catch {
1278
- exists = false;
1279
- }
1280
- refExistence.set(refPath, exists);
1281
- }
1282
- return refExistence.get(refPath) ?? false;
1283
- }
1284
- /**
1285
- * Converts a `$ref` schema into a `RefSchemaNode`.
1286
- *
1287
- * The resolved schema is stored in `node.schema`. Usage-site sibling fields
1288
- * (description, readOnly, nullable, etc.) are stored directly on the ref node.
1289
- * Use `syncSchemaRef(node)` in printers to get a merged view of both.
1290
- * Circular refs are detected via `resolvingRefs` and leave `schema` as `undefined`.
1291
- */
1292
- function convertRef({ schema, name, nullable, defaultValue, rawOptions }) {
1293
- let resolvedSchema = null;
1294
- const refPath = schema.$ref;
1295
- if (refPath && !resolvingRefs.has(refPath)) {
1296
- if (!resolvedRefCache.has(refPath)) {
1297
- try {
1298
- const referenced = resolveRef(document, refPath);
1299
- if (referenced) {
1300
- resolvingRefs.add(refPath);
1301
- resolvedSchema = parseSchema({ schema: referenced }, rawOptions);
1302
- resolvingRefs.delete(refPath);
1303
- }
1304
- } catch {}
1305
- resolvedRefCache.set(refPath, resolvedSchema);
1306
- }
1307
- resolvedSchema = resolvedRefCache.get(refPath) ?? null;
1308
- }
1309
- if (refPath && document.components && !refExists(refPath)) return ast.factory.createSchema({
1310
- ...buildSchemaNode(schema, name, nullable, defaultValue),
1311
- type: "unknown"
1312
- });
1248
+ function convertAllOf({ schema, name, nullable, defaultValue, rawOptions, parse, document }) {
1249
+ if (schema.allOf.length === 1 && !schema.properties && !(Array.isArray(schema.required) && schema.required.length) && schema.additionalProperties === void 0) {
1250
+ const [memberSchema] = schema.allOf;
1251
+ const memberNode = parse({
1252
+ schema: memberSchema,
1253
+ name
1254
+ }, rawOptions);
1255
+ const { kind: _kind, ...memberNodeProps } = memberNode;
1256
+ const mergedNullable = nullable || memberNode.nullable || void 0;
1257
+ const mergedDefault = schema.default === null && mergedNullable ? void 0 : schema.default ?? memberNode.default;
1313
1258
  return ast.factory.createSchema({
1314
- ...buildSchemaNode(schema, name, nullable, defaultValue),
1315
- type: "ref",
1316
- name: extractRefName(schema.$ref),
1317
- ref: schema.$ref,
1318
- schema: resolvedSchema
1259
+ ...memberNodeProps,
1260
+ name,
1261
+ title: schema.title ?? memberNode.title,
1262
+ description: schema.description ?? memberNode.description,
1263
+ deprecated: schema.deprecated ?? memberNode.deprecated,
1264
+ nullable: mergedNullable,
1265
+ readOnly: schema.readOnly ?? memberNode.readOnly,
1266
+ writeOnly: schema.writeOnly ?? memberNode.writeOnly,
1267
+ default: mergedDefault,
1268
+ examples: extractExamples(schema) ?? memberNode.examples,
1269
+ pattern: schema.pattern ?? ("pattern" in memberNode ? memberNode.pattern : void 0),
1270
+ format: schema.format ?? memberNode.format
1319
1271
  });
1320
1272
  }
1321
- /**
1322
- * Converts an `allOf` schema into a flattened node or an `IntersectionSchemaNode`.
1323
- */
1324
- function convertAllOf({ schema, name, nullable, defaultValue, rawOptions }) {
1325
- if (schema.allOf.length === 1 && !schema.properties && !(Array.isArray(schema.required) && schema.required.length) && schema.additionalProperties === void 0) {
1326
- const [memberSchema] = schema.allOf;
1327
- const memberNode = parseSchema({
1328
- schema: memberSchema,
1329
- name
1330
- }, rawOptions);
1331
- const { kind: _kind, ...memberNodeProps } = memberNode;
1332
- const mergedNullable = nullable || memberNode.nullable || void 0;
1333
- const mergedDefault = schema.default === null && mergedNullable ? void 0 : schema.default ?? memberNode.default;
1334
- return ast.factory.createSchema({
1335
- ...memberNodeProps,
1336
- name,
1337
- title: schema.title ?? memberNode.title,
1338
- description: schema.description ?? memberNode.description,
1339
- deprecated: schema.deprecated ?? memberNode.deprecated,
1340
- nullable: mergedNullable,
1341
- readOnly: schema.readOnly ?? memberNode.readOnly,
1342
- writeOnly: schema.writeOnly ?? memberNode.writeOnly,
1343
- default: mergedDefault,
1344
- examples: extractExamples(schema) ?? memberNode.examples,
1345
- pattern: schema.pattern ?? ("pattern" in memberNode ? memberNode.pattern : void 0),
1346
- format: schema.format ?? memberNode.format
1273
+ const filteredDiscriminantValues = [];
1274
+ const allOfMembers = schema.allOf.filter((item) => {
1275
+ if (!isReference(item) || !name) return true;
1276
+ const deref = resolveRef(document, item.$ref);
1277
+ if (!deref || !isDiscriminator(deref)) return true;
1278
+ const parentUnion = deref.oneOf ?? deref.anyOf;
1279
+ if (!parentUnion) return true;
1280
+ const childRef = `${SCHEMA_REF_PREFIX}${name}`;
1281
+ const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef);
1282
+ const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
1283
+ if (inOneOf || inMapping) {
1284
+ const discriminatorValue = findDiscriminator(deref.discriminator.mapping, childRef);
1285
+ if (discriminatorValue) filteredDiscriminantValues.push({
1286
+ propertyName: deref.discriminator.propertyName,
1287
+ value: discriminatorValue
1347
1288
  });
1289
+ return false;
1348
1290
  }
1349
- const filteredDiscriminantValues = [];
1350
- const allOfMembers = schema.allOf.filter((item) => {
1351
- if (!isReference(item) || !name) return true;
1352
- const deref = resolveRef(document, item.$ref);
1353
- if (!deref || !isDiscriminator(deref)) return true;
1354
- const parentUnion = deref.oneOf ?? deref.anyOf;
1355
- if (!parentUnion) return true;
1356
- const childRef = `${SCHEMA_REF_PREFIX}${name}`;
1357
- const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef);
1358
- const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
1359
- if (inOneOf || inMapping) {
1360
- const discriminatorValue = findDiscriminator(deref.discriminator.mapping, childRef);
1361
- if (discriminatorValue) filteredDiscriminantValues.push({
1362
- propertyName: deref.discriminator.propertyName,
1363
- value: discriminatorValue
1364
- });
1365
- return false;
1366
- }
1367
- return true;
1368
- }).map((s) => parseSchema({
1369
- schema: s,
1370
- name
1371
- }, rawOptions));
1372
- const syntheticStart = allOfMembers.length;
1373
- if (Array.isArray(schema.required) && schema.required.length) {
1374
- const outerKeys = schema.properties ? new Set(Object.keys(schema.properties)) : /* @__PURE__ */ new Set();
1375
- const missingRequired = schema.required.filter((key) => !outerKeys.has(key));
1376
- if (missingRequired.length) {
1377
- const resolvedMembers = schema.allOf.flatMap((item) => {
1378
- if (!isReference(item)) return [item];
1379
- const deref = resolveRef(document, item.$ref);
1380
- return deref && !isReference(deref) ? [deref] : [];
1381
- });
1382
- for (const key of missingRequired) for (const resolved of resolvedMembers) if (resolved.properties?.[key]) {
1383
- allOfMembers.push(parseSchema({
1384
- schema: {
1385
- properties: { [key]: resolved.properties[key] },
1386
- required: [key]
1387
- },
1291
+ return true;
1292
+ }).map((s) => parse({
1293
+ schema: s,
1294
+ name
1295
+ }, rawOptions));
1296
+ const syntheticStart = allOfMembers.length;
1297
+ if (Array.isArray(schema.required) && schema.required.length) {
1298
+ const outerKeys = schema.properties ? new Set(Object.keys(schema.properties)) : /* @__PURE__ */ new Set();
1299
+ const missingRequired = schema.required.filter((key) => !outerKeys.has(key));
1300
+ if (missingRequired.length) {
1301
+ const resolvedMembers = schema.allOf.flatMap((item) => {
1302
+ if (!isReference(item)) return [item];
1303
+ const deref = resolveRef(document, item.$ref);
1304
+ return deref && !isReference(deref) ? [deref] : [];
1305
+ });
1306
+ for (const key of missingRequired) for (const resolved of resolvedMembers) {
1307
+ const prop = resolved.properties?.[key];
1308
+ if (prop) {
1309
+ const memberSchema = {
1310
+ properties: { [key]: prop },
1311
+ required: [key]
1312
+ };
1313
+ allOfMembers.push(parse({
1314
+ schema: memberSchema,
1388
1315
  name
1389
1316
  }, rawOptions));
1390
1317
  break;
1391
1318
  }
1392
1319
  }
1393
1320
  }
1394
- if (schema.properties) {
1395
- const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
1396
- allOfMembers.push(parseSchema({ schema: schemaWithoutAllOf }, rawOptions));
1397
- }
1398
- for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push(createDiscriminantNode({
1399
- propertyName,
1400
- value
1401
- }));
1321
+ }
1322
+ if (schema.properties) {
1323
+ const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
1324
+ allOfMembers.push(parse({ schema: schemaWithoutAllOf }, rawOptions));
1325
+ }
1326
+ for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push(createDiscriminantNode({
1327
+ propertyName,
1328
+ value
1329
+ }));
1330
+ return ast.factory.createSchema({
1331
+ type: "intersection",
1332
+ members: [...mergeAdjacentObjectsLazy(allOfMembers.slice(0, syntheticStart)), ...mergeAdjacentObjectsLazy(allOfMembers.slice(syntheticStart))],
1333
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1334
+ });
1335
+ }
1336
+ /**
1337
+ * Converts a `oneOf` / `anyOf` schema into a `UnionSchemaNode`.
1338
+ */
1339
+ function convertUnion({ schema, name, nullable, defaultValue, rawOptions, parse, document }) {
1340
+ function pickDiscriminatorPropertyNode(node, propertyName) {
1341
+ const discriminatorProperty = ast.narrowSchema(node, "object")?.properties?.find((property) => property.name === propertyName);
1342
+ if (!discriminatorProperty) return null;
1402
1343
  return ast.factory.createSchema({
1403
- type: "intersection",
1404
- members: [...mergeAdjacentObjectsLazy(allOfMembers.slice(0, syntheticStart)), ...mergeAdjacentObjectsLazy(allOfMembers.slice(syntheticStart))],
1405
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1344
+ type: "object",
1345
+ primitive: "object",
1346
+ properties: [discriminatorProperty]
1406
1347
  });
1407
1348
  }
1408
- /**
1409
- * Converts a `oneOf` / `anyOf` schema into a `UnionSchemaNode`.
1410
- */
1411
- function convertUnion({ schema, name, nullable, defaultValue, rawOptions }) {
1412
- function pickDiscriminatorPropertyNode(node, propertyName) {
1413
- const discriminatorProperty = ast.narrowSchema(node, "object")?.properties?.find((property) => property.name === propertyName);
1414
- if (!discriminatorProperty) return null;
1415
- return ast.factory.createSchema({
1416
- type: "object",
1417
- primitive: "object",
1418
- properties: [discriminatorProperty]
1349
+ function resolveRefSilent($ref) {
1350
+ if (!$ref.startsWith("#")) return null;
1351
+ return decodeURIComponent($ref.substring(1)).split("/").filter(Boolean).reduce((obj, key) => obj?.[key], document) ?? null;
1352
+ }
1353
+ function implicitDiscriminantValue(member) {
1354
+ if (!discriminator || discriminator.mapping || !isReference(member)) return null;
1355
+ const value = extractRefName(member.$ref);
1356
+ if (!value) return null;
1357
+ const variant = resolveRefSilent(member.$ref);
1358
+ if (!variant) return null;
1359
+ const propertyName = discriminator.propertyName;
1360
+ const seen = /* @__PURE__ */ new Set([member.$ref]);
1361
+ function constrains(v) {
1362
+ const prop = v.properties?.[propertyName];
1363
+ const resolved = prop && isReference(prop) ? resolveRefSilent(prop.$ref) : prop;
1364
+ if (resolved && (Array.isArray(resolved.enum) || resolved.const !== void 0)) return true;
1365
+ const composition = v.allOf ?? v.oneOf ?? v.anyOf;
1366
+ if (!composition) return false;
1367
+ return composition.some((m) => {
1368
+ if (!isReference(m)) return constrains(m);
1369
+ if (seen.has(m.$ref)) return false;
1370
+ seen.add(m.$ref);
1371
+ const r = resolveRefSilent(m.$ref);
1372
+ return r ? constrains(r) : false;
1419
1373
  });
1420
1374
  }
1421
- function resolveRefSilent($ref) {
1422
- if (!$ref.startsWith("#")) return null;
1423
- return decodeURIComponent($ref.substring(1)).split("/").filter(Boolean).reduce((obj, key) => obj?.[key], document) ?? null;
1424
- }
1425
- function implicitDiscriminantValue(member) {
1426
- if (!discriminator || discriminator.mapping || !isReference(member)) return null;
1427
- const value = extractRefName(member.$ref);
1428
- if (!value) return null;
1429
- const variant = resolveRefSilent(member.$ref);
1430
- if (!variant) return null;
1431
- const propertyName = discriminator.propertyName;
1432
- const seen = /* @__PURE__ */ new Set([member.$ref]);
1433
- function constrains(v) {
1434
- const prop = v.properties?.[propertyName];
1435
- const resolved = prop && isReference(prop) ? resolveRefSilent(prop.$ref) : prop;
1436
- if (resolved && (Array.isArray(resolved.enum) || resolved.const !== void 0)) return true;
1437
- const composition = v.allOf ?? v.oneOf ?? v.anyOf;
1438
- if (!composition) return false;
1439
- return composition.some((m) => {
1440
- if (!isReference(m)) return constrains(m);
1441
- if (seen.has(m.$ref)) return false;
1442
- seen.add(m.$ref);
1443
- const r = resolveRefSilent(m.$ref);
1444
- return r ? constrains(r) : false;
1445
- });
1446
- }
1447
- return constrains(variant) ? null : value;
1448
- }
1449
- const unionMembers = [...schema.oneOf ?? [], ...schema.anyOf ?? []];
1450
- const strategy = schema.oneOf ? "one" : "any";
1451
- const unionBase = {
1452
- ...buildSchemaNode(schema, name, nullable, defaultValue),
1453
- discriminatorPropertyName: isDiscriminator(schema) ? schema.discriminator.propertyName : void 0,
1454
- strategy
1455
- };
1456
- const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
1457
- const { oneOf: _o, anyOf: _a, discriminator: _d, ...memberBaseSchema } = schema;
1458
- const sharedPropertiesNode = schema.properties ? parseSchema({
1459
- schema: memberBaseSchema,
1460
- name
1461
- }, rawOptions) : void 0;
1462
- if (sharedPropertiesNode || discriminator) {
1463
- const members = unionMembers.map((s) => {
1464
- const ref = isReference(s) ? s.$ref : void 0;
1465
- const discriminatorValue = findDiscriminator(discriminator?.mapping, ref) ?? implicitDiscriminantValue(s);
1466
- const memberNode = parseSchema({
1467
- schema: s,
1468
- name
1469
- }, rawOptions);
1470
- if (!discriminatorValue || !discriminator) return memberNode;
1471
- const narrowedDiscriminatorNode = sharedPropertiesNode ? pickDiscriminatorPropertyNode(ast.applyMacros(sharedPropertiesNode, [macroDiscriminatorEnum({
1472
- propertyName: discriminator.propertyName,
1473
- values: [discriminatorValue]
1474
- })], { depth: "shallow" }), discriminator.propertyName) : void 0;
1475
- return ast.factory.createSchema({
1476
- type: "intersection",
1477
- members: [memberNode, narrowedDiscriminatorNode ?? createDiscriminantNode({
1478
- propertyName: discriminator.propertyName,
1479
- value: discriminatorValue
1480
- })]
1481
- });
1482
- });
1483
- const unionNode = ast.factory.createSchema({
1484
- type: "union",
1485
- ...unionBase,
1486
- members
1487
- });
1488
- if (!sharedPropertiesNode) return unionNode;
1375
+ return constrains(variant) ? null : value;
1376
+ }
1377
+ const unionMembers = [...schema.oneOf ?? [], ...schema.anyOf ?? []];
1378
+ const strategy = schema.oneOf ? "one" : "any";
1379
+ const unionBase = {
1380
+ ...buildSchemaNode(schema, name, nullable, defaultValue),
1381
+ discriminatorPropertyName: isDiscriminator(schema) ? schema.discriminator.propertyName : void 0,
1382
+ strategy
1383
+ };
1384
+ const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
1385
+ const { oneOf: _o, anyOf: _a, discriminator: _d, ...memberBaseSchema } = schema;
1386
+ const sharedPropertiesNode = schema.properties ? parse({
1387
+ schema: memberBaseSchema,
1388
+ name
1389
+ }, rawOptions) : void 0;
1390
+ if (sharedPropertiesNode || discriminator) {
1391
+ const members = unionMembers.map((s) => {
1392
+ const ref = isReference(s) ? s.$ref : void 0;
1393
+ const discriminatorValue = findDiscriminator(discriminator?.mapping, ref) ?? implicitDiscriminantValue(s);
1394
+ const memberNode = parse({
1395
+ schema: s,
1396
+ name
1397
+ }, rawOptions);
1398
+ if (!discriminatorValue || !discriminator) return memberNode;
1399
+ const narrowedDiscriminatorNode = sharedPropertiesNode ? pickDiscriminatorPropertyNode(ast.applyMacros(sharedPropertiesNode, [macroDiscriminatorEnum({
1400
+ propertyName: discriminator.propertyName,
1401
+ values: [discriminatorValue]
1402
+ })], { depth: "shallow" }), discriminator.propertyName) : void 0;
1489
1403
  return ast.factory.createSchema({
1490
1404
  type: "intersection",
1491
- ...buildSchemaNode(schema, name, nullable, defaultValue),
1492
- members: [unionNode, sharedPropertiesNode]
1405
+ members: [memberNode, narrowedDiscriminatorNode ?? createDiscriminantNode({
1406
+ propertyName: discriminator.propertyName,
1407
+ value: discriminatorValue
1408
+ })]
1493
1409
  });
1494
- }
1410
+ });
1495
1411
  const unionNode = ast.factory.createSchema({
1496
1412
  type: "union",
1497
1413
  ...unionBase,
1498
- members: unionMembers.map((s) => parseSchema({
1499
- schema: s,
1500
- name
1501
- }, rawOptions))
1414
+ members
1502
1415
  });
1503
- return ast.applyMacros(unionNode, [macroSimplifyUnion], { depth: "shallow" });
1504
- }
1505
- /**
1506
- * Converts an OAS 3.1 `const` schema into a null scalar or a single-value `EnumSchemaNode`.
1507
- */
1508
- function convertConst({ schema, name, nullable, defaultValue }) {
1509
- const constValue = schema.const;
1510
- if (constValue === null) return createNullSchema(schema, name);
1511
- const constPrimitive = getPrimitiveType(typeof constValue === "number" ? "number" : typeof constValue === "boolean" ? "boolean" : "string");
1416
+ if (!sharedPropertiesNode) return unionNode;
1512
1417
  return ast.factory.createSchema({
1513
- type: "enum",
1514
- primitive: constPrimitive,
1515
- enumValues: [constValue],
1516
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1418
+ type: "intersection",
1419
+ ...buildSchemaNode(schema, name, nullable, defaultValue),
1420
+ members: [unionNode, sharedPropertiesNode]
1517
1421
  });
1518
1422
  }
1519
- /**
1520
- * Converts a format-annotated schema into a special-type `SchemaNode`.
1521
- * Returns `null` when the format should fall through to string handling (`dateType: false`).
1522
- */
1523
- function convertFormat({ schema, name, nullable, defaultValue, options }) {
1524
- const base = buildSchemaNode(schema, name, nullable, defaultValue);
1525
- if (schema.format === "int64") return ast.factory.createSchema({
1526
- type: options.integerType === "bigint" ? "bigint" : "integer",
1527
- primitive: "integer",
1423
+ const unionNode = ast.factory.createSchema({
1424
+ type: "union",
1425
+ ...unionBase,
1426
+ members: unionMembers.map((s) => parse({
1427
+ schema: s,
1428
+ name
1429
+ }, rawOptions))
1430
+ });
1431
+ return ast.applyMacros(unionNode, [macroSimplifyUnion], { depth: "shallow" });
1432
+ }
1433
+ /**
1434
+ * Converts an OAS 3.1 `const` schema into a null scalar or a single-value `EnumSchemaNode`.
1435
+ */
1436
+ function convertConst({ schema, name, nullable, defaultValue }) {
1437
+ const constValue = schema.const;
1438
+ if (constValue === null) return createNullNode(schema, name);
1439
+ const constPrimitive = getPrimitiveType(typeof constValue === "number" ? "number" : typeof constValue === "boolean" ? "boolean" : "string");
1440
+ return ast.factory.createSchema({
1441
+ type: "enum",
1442
+ primitive: constPrimitive,
1443
+ enumValues: [constValue],
1444
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1445
+ });
1446
+ }
1447
+ /**
1448
+ * Converts a format-annotated schema into a special-type `SchemaNode`.
1449
+ * Returns `null` when the format should fall through to string handling (`dateType: false`).
1450
+ */
1451
+ function convertFormat({ schema, name, nullable, defaultValue, options }) {
1452
+ const base = buildSchemaNode(schema, name, nullable, defaultValue);
1453
+ if (schema.format === "int64") return ast.factory.createSchema({
1454
+ type: options.integerType === "bigint" ? "bigint" : "integer",
1455
+ primitive: "integer",
1456
+ ...base,
1457
+ min: schema.minimum,
1458
+ max: schema.maximum,
1459
+ exclusiveMinimum: typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : void 0,
1460
+ exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0
1461
+ });
1462
+ if (schema.format === "date-time" || schema.format === "date" || schema.format === "time") {
1463
+ const dateType = getDateType(options, schema.format);
1464
+ if (!dateType) return null;
1465
+ if (dateType.type === "datetime") return ast.factory.createSchema({
1528
1466
  ...base,
1529
- min: schema.minimum,
1530
- max: schema.maximum,
1531
- exclusiveMinimum: typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : void 0,
1532
- exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0
1467
+ primitive: "string",
1468
+ type: "datetime",
1469
+ offset: dateType.offset,
1470
+ local: dateType.local
1533
1471
  });
1534
- if (schema.format === "date-time" || schema.format === "date" || schema.format === "time") {
1535
- const dateType = getDateType(options, schema.format);
1536
- if (!dateType) return null;
1537
- if (dateType.type === "datetime") return ast.factory.createSchema({
1538
- ...base,
1539
- primitive: "string",
1540
- type: "datetime",
1541
- offset: dateType.offset,
1542
- local: dateType.local
1543
- });
1544
- return ast.factory.createSchema({
1545
- ...base,
1546
- primitive: "string",
1547
- type: dateType.type,
1548
- representation: dateType.representation
1549
- });
1550
- }
1551
- const specialType = getSchemaType(schema.format);
1552
- if (!specialType) return null;
1553
- const specialPrimitive = specialType === "number" || specialType === "integer" || specialType === "bigint" ? specialType : "string";
1554
- const hasLength = specialType === "url" || specialType === "uuid" || specialType === "email";
1555
1472
  return ast.factory.createSchema({
1556
1473
  ...base,
1557
- primitive: specialPrimitive,
1558
- type: specialType,
1559
- ...hasLength ? {
1560
- min: schema.minLength,
1561
- max: schema.maxLength
1562
- } : {}
1474
+ primitive: "string",
1475
+ type: dateType.type,
1476
+ representation: dateType.representation
1563
1477
  });
1564
1478
  }
1565
- /**
1566
- * Converts an `enum` schema into an `EnumSchemaNode`.
1567
- */
1568
- function convertEnum({ schema, name, nullable, type, rawOptions }) {
1569
- if (type === "array") return parseSchema({
1570
- schema: normalizeArrayEnum(schema),
1571
- name
1572
- }, rawOptions);
1573
- const nullInEnum = schema.enum.includes(null);
1574
- const filteredValues = nullInEnum ? schema.enum.filter((v) => v !== null) : schema.enum;
1575
- if (nullInEnum && filteredValues.length === 0) return createNullSchema(schema, name);
1576
- const enumNullable = nullable || nullInEnum || void 0;
1577
- const enumDefault = schema.default === null && enumNullable ? void 0 : schema.default;
1578
- const enumPrimitive = getPrimitiveType(type);
1579
- const enumBase = {
1580
- type: "enum",
1581
- primitive: enumPrimitive,
1582
- ...buildSchemaNode(schema, name, enumNullable, enumDefault)
1583
- };
1584
- const extensionKey = enumExtensionKeys.find((key) => key in schema);
1585
- const descriptionKey = enumDescriptionKeys.find((key) => key in schema);
1586
- if (extensionKey || descriptionKey || enumPrimitive === "number" || enumPrimitive === "integer" || enumPrimitive === "boolean") {
1587
- const enumPrimitiveType = enumPrimitive === "number" || enumPrimitive === "integer" ? "number" : enumPrimitive === "boolean" ? "boolean" : "string";
1588
- const rawEnumNames = extensionKey ? schema[extensionKey] : void 0;
1589
- const rawEnumDescriptions = descriptionKey ? schema[descriptionKey] : void 0;
1590
- const uniqueValues = [...new Set(filteredValues)];
1591
- const seenNames = /* @__PURE__ */ new Set();
1592
- return ast.factory.createSchema({
1593
- ...enumBase,
1594
- primitive: enumPrimitiveType,
1595
- namedEnumValues: uniqueValues.map((value, index) => ({
1596
- name: String(rawEnumNames?.[index] ?? value),
1597
- value,
1598
- primitive: enumPrimitiveType,
1599
- description: rawEnumDescriptions?.[index]
1600
- })).filter((entry) => {
1601
- if (seenNames.has(entry.name)) return false;
1602
- seenNames.add(entry.name);
1603
- return true;
1604
- })
1605
- });
1606
- }
1479
+ const specialType = getSchemaType(schema.format);
1480
+ if (!specialType) return null;
1481
+ const specialPrimitive = specialType === "number" || specialType === "integer" || specialType === "bigint" ? specialType : "string";
1482
+ const hasLength = specialType === "url" || specialType === "uuid" || specialType === "email";
1483
+ return ast.factory.createSchema({
1484
+ ...base,
1485
+ primitive: specialPrimitive,
1486
+ type: specialType,
1487
+ ...hasLength ? {
1488
+ min: schema.minLength,
1489
+ max: schema.maxLength
1490
+ } : {}
1491
+ });
1492
+ }
1493
+ /**
1494
+ * Converts an `enum` schema into an `EnumSchemaNode`.
1495
+ */
1496
+ function convertEnum({ schema, name, nullable, type, rawOptions, parse }) {
1497
+ if (type === "array") return parse({
1498
+ schema: normalizeArrayEnum(schema),
1499
+ name
1500
+ }, rawOptions);
1501
+ const nullInEnum = schema.enum.includes(null);
1502
+ const filteredValues = nullInEnum ? schema.enum.filter((v) => v !== null) : schema.enum;
1503
+ if (nullInEnum && filteredValues.length === 0) return createNullNode(schema, name);
1504
+ const enumNullable = nullable || nullInEnum || void 0;
1505
+ const enumDefault = schema.default === null && enumNullable ? void 0 : schema.default;
1506
+ const enumPrimitive = getPrimitiveType(type);
1507
+ const enumBase = {
1508
+ type: "enum",
1509
+ primitive: enumPrimitive,
1510
+ ...buildSchemaNode(schema, name, enumNullable, enumDefault)
1511
+ };
1512
+ const extensionKey = enumExtensionKeys.find((key) => key in schema);
1513
+ const descriptionKey = enumDescriptionKeys.find((key) => key in schema);
1514
+ if (extensionKey || descriptionKey || enumPrimitive === "number" || enumPrimitive === "integer" || enumPrimitive === "boolean") {
1515
+ const enumPrimitiveType = enumPrimitive === "number" || enumPrimitive === "integer" ? "number" : enumPrimitive === "boolean" ? "boolean" : "string";
1516
+ const rawEnumNames = extensionKey ? schema[extensionKey] : void 0;
1517
+ const rawEnumDescriptions = descriptionKey ? schema[descriptionKey] : void 0;
1518
+ const uniqueValues = [...new Set(filteredValues)];
1519
+ const seenNames = /* @__PURE__ */ new Set();
1607
1520
  return ast.factory.createSchema({
1608
1521
  ...enumBase,
1609
- enumValues: [...new Set(filteredValues)]
1610
- });
1611
- }
1612
- /**
1613
- * Converts an object-like schema into an `ObjectSchemaNode`.
1614
- */
1615
- function convertObject({ schema, name, nullable, defaultValue, rawOptions, options }) {
1616
- const properties = schema.properties ? Object.entries(schema.properties).map(([propName, propSchema]) => {
1617
- const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
1618
- const resolvedPropSchema = propSchema;
1619
- const propNullable = isNullable(resolvedPropSchema);
1620
- const schemaNode = nameEnums(parseSchema({
1621
- schema: resolvedPropSchema,
1622
- name: childName(name, propName)
1623
- }, rawOptions), {
1624
- parentName: name,
1625
- propName,
1626
- enumSuffix: options.enumSuffix
1627
- });
1628
- return ast.factory.createProperty({
1629
- name: propName,
1630
- schema: {
1631
- ...schemaNode,
1632
- nullable: schemaNode.type === "null" ? void 0 : propNullable || void 0
1633
- },
1634
- required
1635
- });
1636
- }) : [];
1637
- const additionalProperties = schema.additionalProperties;
1638
- const additionalPropertiesNode = (() => {
1639
- if (additionalProperties === true) return true;
1640
- if (additionalProperties === false) return false;
1641
- if (additionalProperties && Object.keys(additionalProperties).length > 0) return parseSchema({ schema: additionalProperties }, rawOptions);
1642
- if (additionalProperties) return ast.factory.createSchema({ type: options.unknownType });
1643
- })();
1644
- const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
1645
- const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? ast.factory.createSchema({ type: options.unknownType }) : parseSchema({ schema: patternSchema }, rawOptions)])) : void 0;
1646
- const objectNode = ast.factory.createSchema({
1647
- type: "object",
1648
- primitive: "object",
1649
- properties,
1650
- additionalProperties: additionalPropertiesNode,
1651
- patternProperties,
1652
- minProperties: schema.minProperties,
1653
- maxProperties: schema.maxProperties,
1654
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1655
- });
1656
- if (isDiscriminator(schema) && schema.discriminator.mapping) {
1657
- const discPropName = schema.discriminator.propertyName;
1658
- const values = Object.keys(schema.discriminator.mapping);
1659
- const enumName = name ? enumPropName(name, discPropName, options.enumSuffix) : void 0;
1660
- return ast.applyMacros(objectNode, [macroDiscriminatorEnum({
1661
- propertyName: discPropName,
1662
- values,
1663
- enumName
1664
- })], { depth: "shallow" });
1665
- }
1666
- return objectNode;
1667
- }
1668
- /**
1669
- * Converts an OAS 3.1 `prefixItems` tuple into a `TupleSchemaNode`.
1670
- */
1671
- function convertTuple({ schema, name, nullable, defaultValue, rawOptions }) {
1672
- const tupleItems = (schema.prefixItems ?? []).map((item) => parseSchema({ schema: item }, rawOptions));
1673
- const rest = schema.items === false ? void 0 : !schema.items || schema.items === true ? ast.factory.createSchema({ type: "any" }) : parseSchema({ schema: schema.items }, rawOptions);
1674
- return ast.factory.createSchema({
1675
- type: "tuple",
1676
- primitive: "array",
1677
- items: tupleItems,
1678
- rest,
1679
- min: schema.minItems,
1680
- max: schema.maxItems,
1681
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1522
+ primitive: enumPrimitiveType,
1523
+ namedEnumValues: uniqueValues.map((value, index) => ({
1524
+ name: String(rawEnumNames?.[index] ?? value),
1525
+ value,
1526
+ primitive: enumPrimitiveType,
1527
+ description: rawEnumDescriptions?.[index]
1528
+ })).filter((entry) => {
1529
+ if (seenNames.has(entry.name)) return false;
1530
+ seenNames.add(entry.name);
1531
+ return true;
1532
+ })
1682
1533
  });
1683
1534
  }
1684
- /**
1685
- * Converts a `type: 'array'` schema into an `ArraySchemaNode`.
1686
- */
1687
- function convertArray({ schema, name, nullable, defaultValue, rawOptions, options }) {
1688
- const rawItems = schema.items;
1689
- const itemName = rawItems?.enum?.length && name ? enumPropName(null, name, options.enumSuffix) : name;
1690
- const items = rawItems ? [parseSchema({
1691
- schema: rawItems,
1692
- name: itemName
1693
- }, rawOptions)] : [];
1694
- return ast.factory.createSchema({
1695
- type: "array",
1696
- primitive: "array",
1697
- items,
1698
- min: schema.minItems,
1699
- max: schema.maxItems,
1700
- unique: schema.uniqueItems ?? void 0,
1701
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1535
+ return ast.factory.createSchema({
1536
+ ...enumBase,
1537
+ enumValues: [...new Set(filteredValues)]
1538
+ });
1539
+ }
1540
+ /**
1541
+ * Converts an object-like schema into an `ObjectSchemaNode`.
1542
+ */
1543
+ function convertObject({ schema, name, nullable, defaultValue, rawOptions, options, parse }) {
1544
+ const properties = schema.properties ? Object.entries(schema.properties).map(([propName, propSchema]) => {
1545
+ const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
1546
+ const resolvedPropSchema = propSchema;
1547
+ const propNullable = isNullable(resolvedPropSchema);
1548
+ const schemaNode = nameEnums(parse({
1549
+ schema: resolvedPropSchema,
1550
+ name: childName(name, propName)
1551
+ }, rawOptions), {
1552
+ parentName: name,
1553
+ propName,
1554
+ enumSuffix: options.enumSuffix
1702
1555
  });
1703
- }
1704
- /**
1705
- * Converts a `type: 'string'` schema into a `StringSchemaNode`.
1706
- */
1707
- function convertString({ schema, name, nullable, defaultValue }) {
1708
- return ast.factory.createSchema({
1709
- type: "string",
1710
- primitive: "string",
1711
- min: schema.minLength,
1712
- max: schema.maxLength,
1713
- pattern: schema.pattern,
1714
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1556
+ return ast.factory.createProperty({
1557
+ name: propName,
1558
+ schema: {
1559
+ ...schemaNode,
1560
+ nullable: schemaNode.type === "null" ? void 0 : propNullable || void 0
1561
+ },
1562
+ required
1715
1563
  });
1564
+ }) : [];
1565
+ const additionalProperties = schema.additionalProperties;
1566
+ const additionalPropertiesNode = (() => {
1567
+ if (additionalProperties === true) return true;
1568
+ if (additionalProperties === false) return false;
1569
+ if (additionalProperties && Object.keys(additionalProperties).length > 0) return parse({ schema: additionalProperties }, rawOptions);
1570
+ if (additionalProperties) return ast.factory.createSchema({ type: options.unknownType });
1571
+ })();
1572
+ const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
1573
+ const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? ast.factory.createSchema({ type: options.unknownType }) : parse({ schema: patternSchema }, rawOptions)])) : void 0;
1574
+ const objectNode = ast.factory.createSchema({
1575
+ type: "object",
1576
+ primitive: "object",
1577
+ properties,
1578
+ additionalProperties: additionalPropertiesNode,
1579
+ patternProperties,
1580
+ minProperties: schema.minProperties,
1581
+ maxProperties: schema.maxProperties,
1582
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1583
+ });
1584
+ if (isDiscriminator(schema) && schema.discriminator.mapping) {
1585
+ const discPropName = schema.discriminator.propertyName;
1586
+ const values = Object.keys(schema.discriminator.mapping);
1587
+ const enumName = name ? enumPropName(name, discPropName, options.enumSuffix) : void 0;
1588
+ return ast.applyMacros(objectNode, [macroDiscriminatorEnum({
1589
+ propertyName: discPropName,
1590
+ values,
1591
+ enumName
1592
+ })], { depth: "shallow" });
1716
1593
  }
1717
- /**
1718
- * Converts a `type: 'number'` or `type: 'integer'` schema.
1719
- */
1720
- function convertNumeric({ schema, name, nullable, defaultValue }, type) {
1721
- return ast.factory.createSchema({
1722
- type,
1723
- primitive: type,
1724
- min: schema.minimum,
1725
- max: schema.maximum,
1726
- exclusiveMinimum: typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : void 0,
1727
- exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0,
1728
- multipleOf: schema.multipleOf,
1729
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1730
- });
1594
+ return objectNode;
1595
+ }
1596
+ /**
1597
+ * Converts an OAS 3.1 `prefixItems` tuple into a `TupleSchemaNode`.
1598
+ */
1599
+ function convertTuple({ schema, name, nullable, defaultValue, rawOptions, parse }) {
1600
+ const tupleItems = (schema.prefixItems ?? []).map((item) => parse({ schema: item }, rawOptions));
1601
+ const rest = schema.items === false ? void 0 : !schema.items || schema.items === true ? ast.factory.createSchema({ type: "any" }) : parse({ schema: schema.items }, rawOptions);
1602
+ return ast.factory.createSchema({
1603
+ type: "tuple",
1604
+ primitive: "array",
1605
+ items: tupleItems,
1606
+ rest,
1607
+ min: schema.minItems,
1608
+ max: schema.maxItems,
1609
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1610
+ });
1611
+ }
1612
+ /**
1613
+ * Converts a `type: 'array'` schema into an `ArraySchemaNode`.
1614
+ */
1615
+ function convertArray({ schema, name, nullable, defaultValue, rawOptions, options, parse }) {
1616
+ const rawItems = schema.items;
1617
+ const itemName = rawItems?.enum?.length && name ? enumPropName(null, name, options.enumSuffix) : name;
1618
+ const items = rawItems ? [parse({
1619
+ schema: rawItems,
1620
+ name: itemName
1621
+ }, rawOptions)] : [];
1622
+ return ast.factory.createSchema({
1623
+ type: "array",
1624
+ primitive: "array",
1625
+ items,
1626
+ min: schema.minItems,
1627
+ max: schema.maxItems,
1628
+ unique: schema.uniqueItems ?? void 0,
1629
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1630
+ });
1631
+ }
1632
+ /**
1633
+ * Converts a `type: 'string'` schema into a `StringSchemaNode`.
1634
+ */
1635
+ function convertString({ schema, name, nullable, defaultValue }) {
1636
+ return ast.factory.createSchema({
1637
+ type: "string",
1638
+ primitive: "string",
1639
+ min: schema.minLength,
1640
+ max: schema.maxLength,
1641
+ pattern: schema.pattern,
1642
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1643
+ });
1644
+ }
1645
+ /**
1646
+ * Converts a `type: 'number'` or `type: 'integer'` schema.
1647
+ */
1648
+ function convertNumeric({ schema, name, nullable, defaultValue }, type) {
1649
+ return ast.factory.createSchema({
1650
+ type,
1651
+ primitive: type,
1652
+ min: schema.minimum,
1653
+ max: schema.maximum,
1654
+ exclusiveMinimum: typeof schema.exclusiveMinimum === "number" ? schema.exclusiveMinimum : void 0,
1655
+ exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0,
1656
+ multipleOf: schema.multipleOf,
1657
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1658
+ });
1659
+ }
1660
+ /**
1661
+ * Converts a `type: 'boolean'` schema.
1662
+ */
1663
+ function convertBoolean({ schema, name, nullable, defaultValue }) {
1664
+ return ast.factory.createSchema({
1665
+ type: "boolean",
1666
+ primitive: "boolean",
1667
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1668
+ });
1669
+ }
1670
+ /**
1671
+ * Converts a binary string schema (`type: 'string'`, `contentMediaType: 'application/octet-stream'`)
1672
+ * into a `blob` node.
1673
+ */
1674
+ function convertBinary({ schema, name, nullable, defaultValue }) {
1675
+ return ast.factory.createSchema({
1676
+ type: "blob",
1677
+ primitive: "string",
1678
+ ...buildSchemaNode(schema, name, nullable, defaultValue)
1679
+ });
1680
+ }
1681
+ /**
1682
+ * Converts an OAS 3.1 multi-type array (e.g. `type: ['string', 'number']`) into a `UnionSchemaNode`.
1683
+ *
1684
+ * Returns `null` when only one non-`null` type remains (e.g. `['string', 'null']`), so `parse`
1685
+ * falls through and handles it as that single type with nullability already folded in.
1686
+ */
1687
+ function convertMultiType({ schema, name, nullable, defaultValue, rawOptions, parse }) {
1688
+ const types = schema.type;
1689
+ const nonNullTypes = types.filter((t) => t !== "null");
1690
+ if (nonNullTypes.length <= 1) return null;
1691
+ const arrayNullable = types.includes("null") || nullable || void 0;
1692
+ return ast.factory.createSchema({
1693
+ type: "union",
1694
+ members: nonNullTypes.map((t) => {
1695
+ return parse({
1696
+ schema: {
1697
+ ...schema,
1698
+ type: t
1699
+ },
1700
+ name
1701
+ }, rawOptions);
1702
+ }),
1703
+ ...buildSchemaNode(schema, name, arrayNullable, defaultValue)
1704
+ });
1705
+ }
1706
+ /**
1707
+ * Ordered schema rule table. Order is significant: composition keywords (`$ref`, `allOf`,
1708
+ * `oneOf`/`anyOf`) take precedence over `const`/`format`, which take precedence over the plain
1709
+ * `type`. The first matching rule that produces a node wins. See {@link SchemaRule} for the
1710
+ * match/convert/fall-through contract.
1711
+ */
1712
+ const schemaRules = [
1713
+ {
1714
+ match: ({ schema }) => isReference(schema),
1715
+ convert: convertRef
1716
+ },
1717
+ {
1718
+ match: ({ schema }) => !!schema.allOf?.length,
1719
+ convert: convertAllOf
1720
+ },
1721
+ {
1722
+ match: ({ schema }) => !!(schema.oneOf?.length || schema.anyOf?.length),
1723
+ convert: convertUnion
1724
+ },
1725
+ {
1726
+ match: ({ schema }) => "const" in schema && schema.const !== void 0,
1727
+ convert: convertConst
1728
+ },
1729
+ {
1730
+ match: ({ schema }) => !!schema.format,
1731
+ convert: convertFormat
1732
+ },
1733
+ {
1734
+ match: ({ schema }) => isBinary(schema),
1735
+ convert: convertBinary
1736
+ },
1737
+ {
1738
+ match: ({ schema }) => Array.isArray(schema.type) && schema.type.length > 1,
1739
+ convert: convertMultiType
1740
+ },
1741
+ {
1742
+ match: ({ schema, type }) => !type && (schema.minLength !== void 0 || schema.maxLength !== void 0 || schema.pattern !== void 0),
1743
+ convert: convertString
1744
+ },
1745
+ {
1746
+ match: ({ schema, type }) => !type && (schema.minimum !== void 0 || schema.maximum !== void 0),
1747
+ convert: (ctx) => convertNumeric(ctx, "number")
1748
+ },
1749
+ {
1750
+ match: ({ schema }) => !!schema.enum?.length,
1751
+ convert: convertEnum
1752
+ },
1753
+ {
1754
+ match: ({ schema, type }) => type === "object" || !!schema.properties || !!schema.additionalProperties || "patternProperties" in schema,
1755
+ convert: convertObject
1756
+ },
1757
+ {
1758
+ match: ({ schema }) => "prefixItems" in schema,
1759
+ convert: convertTuple
1760
+ },
1761
+ {
1762
+ match: ({ schema, type }) => type === "array" || "items" in schema,
1763
+ convert: convertArray
1764
+ },
1765
+ {
1766
+ match: ({ type }) => type === "string",
1767
+ convert: convertString
1768
+ },
1769
+ {
1770
+ match: ({ type }) => type === "number",
1771
+ convert: (ctx) => convertNumeric(ctx, "number")
1772
+ },
1773
+ {
1774
+ match: ({ type }) => type === "integer",
1775
+ convert: (ctx) => convertNumeric(ctx, "integer")
1776
+ },
1777
+ {
1778
+ match: ({ type }) => type === "boolean",
1779
+ convert: convertBoolean
1780
+ },
1781
+ {
1782
+ match: ({ type }) => type === "null",
1783
+ convert: ({ schema, name, nullable }) => createNullNode(schema, name, nullable)
1731
1784
  }
1785
+ ];
1786
+ //#endregion
1787
+ //#region src/parser.ts
1788
+ /**
1789
+ * Creates the schema and operation converters bound to one OpenAPI document.
1790
+ *
1791
+ * Owns the per-instance `$ref` state (cycle detection, resolved-node cache, existence cache) and
1792
+ * the `parseSchema` recursion seam, then dispatches each schema through the ordered `schemaRules`
1793
+ * table from `converters.ts`. Every converter is a standalone function that recurses through the
1794
+ * `parse` function passed to it, so this file only wires state to the converters.
1795
+ *
1796
+ * @internal
1797
+ */
1798
+ function createSchemaParser(ctx) {
1799
+ const document = ctx.document;
1732
1800
  /**
1733
- * Converts a `type: 'boolean'` schema.
1801
+ * Tracks `$ref` paths that are currently being resolved to prevent infinite
1802
+ * recursion when schemas contain circular references (e.g. `Pet → parent → Pet`).
1734
1803
  */
1735
- function convertBoolean({ schema, name, nullable, defaultValue }) {
1736
- return ast.factory.createSchema({
1737
- type: "boolean",
1738
- primitive: "boolean",
1739
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1740
- });
1741
- }
1804
+ const resolvingRefs = /* @__PURE__ */ new Set();
1742
1805
  /**
1743
- * Converts a binary string schema (`type: 'string'`, `contentMediaType: 'application/octet-stream'`)
1744
- * into a `blob` node.
1806
+ * Cache of `$ref` schemas already resolved in this parser instance, keyed by ref path.
1807
+ *
1808
+ * Without it, a shared schema (e.g. `customer`) is re-expanded for every `$ref` that points at
1809
+ * it. In cross-referenced specs like Stripe (~1400 schemas) that becomes exponential blowup,
1810
+ * since one schema can be referenced from dozens of parents, each re-walking its whole subtree.
1811
+ * Memoizing by ref path drops the work from O(2^depth) to O(N) unique schema names.
1745
1812
  */
1746
- function convertBlob({ schema, name, nullable, defaultValue }) {
1747
- return ast.factory.createSchema({
1748
- type: "blob",
1749
- primitive: "string",
1750
- ...buildSchemaNode(schema, name, nullable, defaultValue)
1751
- });
1752
- }
1813
+ const resolvedRefCache = /* @__PURE__ */ new Map();
1753
1814
  /**
1754
- * Converts an OAS 3.1 multi-type array (e.g. `type: ['string', 'number']`) into a `UnionSchemaNode`.
1755
- *
1756
- * Returns `null` when only one non-`null` type remains (e.g. `['string', 'null']`), so `parseSchema`
1757
- * falls through and handles it as that single type with nullability already folded in.
1815
+ * Memoized record of whether a `$ref` path resolves to a node the document actually defines.
1816
+ * A circular ref still resolves to an existing target, so this stays `true` for cycles and only
1817
+ * goes `false` for a `$ref` that points at a component the spec never declares.
1758
1818
  */
1759
- function convertMultiType({ schema, name, nullable, defaultValue, rawOptions }) {
1760
- const types = schema.type;
1761
- const nonNullTypes = types.filter((t) => t !== "null");
1762
- if (nonNullTypes.length <= 1) return null;
1763
- const arrayNullable = types.includes("null") || nullable || void 0;
1764
- return ast.factory.createSchema({
1765
- type: "union",
1766
- members: nonNullTypes.map((t) => parseSchema({
1767
- schema: {
1768
- ...schema,
1769
- type: t
1770
- },
1771
- name
1772
- }, rawOptions)),
1773
- ...buildSchemaNode(schema, name, arrayNullable, defaultValue)
1774
- });
1819
+ const refExistence = /* @__PURE__ */ new Map();
1820
+ function refExists(refPath) {
1821
+ if (!refExistence.has(refPath)) {
1822
+ let exists = false;
1823
+ try {
1824
+ exists = !!resolveRef(document, refPath);
1825
+ } catch {
1826
+ exists = false;
1827
+ }
1828
+ refExistence.set(refPath, exists);
1829
+ }
1830
+ return refExistence.get(refPath) ?? false;
1775
1831
  }
1776
1832
  /**
1777
- * Ordered schema rule table. Order is significant: composition keywords (`$ref`, `allOf`,
1778
- * `oneOf`/`anyOf`) take precedence over `const`/`format`, which take precedence over the plain
1779
- * `type`. The first matching rule that produces a node wins. See {@link SchemaRule} for the
1780
- * match/convert/fall-through contract.
1833
+ * Resolves a `$ref` to its parsed node, guarding against cycles and memoizing per instance.
1834
+ * Returns `null` when the ref is currently being resolved (a cycle) or cannot be resolved
1835
+ * (e.g. a minimal document in a unit test).
1781
1836
  */
1782
- const schemaRules = [
1783
- {
1784
- match: ({ schema }) => isReference(schema),
1785
- convert: convertRef
1786
- },
1787
- {
1788
- match: ({ schema }) => !!schema.allOf?.length,
1789
- convert: convertAllOf
1790
- },
1791
- {
1792
- match: ({ schema }) => !!(schema.oneOf?.length || schema.anyOf?.length),
1793
- convert: convertUnion
1794
- },
1795
- {
1796
- match: ({ schema }) => "const" in schema && schema.const !== void 0,
1797
- convert: convertConst
1798
- },
1799
- {
1800
- match: ({ schema }) => !!schema.format,
1801
- convert: convertFormat
1802
- },
1803
- {
1804
- match: ({ schema }) => isBinary(schema),
1805
- convert: convertBlob
1806
- },
1807
- {
1808
- match: ({ schema }) => Array.isArray(schema.type) && schema.type.length > 1,
1809
- convert: convertMultiType
1810
- },
1811
- {
1812
- match: ({ schema, type }) => !type && (schema.minLength !== void 0 || schema.maxLength !== void 0 || schema.pattern !== void 0),
1813
- convert: convertString
1814
- },
1815
- {
1816
- match: ({ schema, type }) => !type && (schema.minimum !== void 0 || schema.maximum !== void 0),
1817
- convert: (ctx) => convertNumeric(ctx, "number")
1818
- },
1819
- {
1820
- match: ({ schema }) => !!schema.enum?.length,
1821
- convert: convertEnum
1822
- },
1823
- {
1824
- match: ({ schema, type }) => type === "object" || !!schema.properties || !!schema.additionalProperties || "patternProperties" in schema,
1825
- convert: convertObject
1826
- },
1827
- {
1828
- match: ({ schema }) => "prefixItems" in schema,
1829
- convert: convertTuple
1830
- },
1831
- {
1832
- match: ({ schema, type }) => type === "array" || "items" in schema,
1833
- convert: convertArray
1834
- },
1835
- {
1836
- match: ({ type }) => type === "string",
1837
- convert: convertString
1838
- },
1839
- {
1840
- match: ({ type }) => type === "number",
1841
- convert: (ctx) => convertNumeric(ctx, "number")
1842
- },
1843
- {
1844
- match: ({ type }) => type === "integer",
1845
- convert: (ctx) => convertNumeric(ctx, "integer")
1846
- },
1847
- {
1848
- match: ({ type }) => type === "boolean",
1849
- convert: convertBoolean
1850
- },
1851
- {
1852
- match: ({ type }) => type === "null",
1853
- convert: ({ schema, name, nullable }) => createNullSchema(schema, name, nullable)
1837
+ function resolveRefNode(refPath, rawOptions) {
1838
+ if (resolvingRefs.has(refPath)) return null;
1839
+ if (!resolvedRefCache.has(refPath)) {
1840
+ let resolved = null;
1841
+ try {
1842
+ const referenced = resolveRef(document, refPath);
1843
+ if (referenced) {
1844
+ resolvingRefs.add(refPath);
1845
+ resolved = parseSchema({ schema: referenced }, rawOptions);
1846
+ resolvingRefs.delete(refPath);
1847
+ }
1848
+ } catch {}
1849
+ resolvedRefCache.set(refPath, resolved);
1854
1850
  }
1855
- ];
1851
+ return resolvedRefCache.get(refPath) ?? null;
1852
+ }
1856
1853
  /**
1857
1854
  * Converts an OAS `SchemaObject` into a `SchemaNode`.
1858
1855
  *
@@ -1871,18 +1868,23 @@ function createSchemaParser(ctx) {
1871
1868
  name
1872
1869
  }, rawOptions);
1873
1870
  const nullable = isNullable(schema) || void 0;
1874
- const schemaCtx = {
1871
+ const context = {
1875
1872
  schema,
1876
1873
  name,
1877
1874
  nullable,
1878
1875
  defaultValue: schema.default === null && nullable ? void 0 : schema.default,
1879
1876
  type: Array.isArray(schema.type) ? schema.type[0] : schema.type,
1880
1877
  rawOptions,
1881
- options
1878
+ options,
1879
+ parse: parseSchema,
1880
+ document,
1881
+ resolveRefNode,
1882
+ refExists,
1883
+ renames: ctx.renames
1882
1884
  };
1883
1885
  for (const rule of schemaRules) {
1884
- if (!rule.match(schemaCtx)) continue;
1885
- const node = rule.convert(schemaCtx);
1886
+ if (!rule.match(context)) continue;
1887
+ const node = rule.convert(context);
1886
1888
  if (node) return node;
1887
1889
  }
1888
1890
  const emptyType = options.emptySchemaType;
@@ -2179,7 +2181,6 @@ const adapterOas = createAdapter((options) => {
2179
2181
  emptySchemaType,
2180
2182
  enumSuffix
2181
2183
  };
2182
- let nameMapping = /* @__PURE__ */ new Map();
2183
2184
  let parsedDocument = null;
2184
2185
  const documentCache = /* @__PURE__ */ new WeakMap();
2185
2186
  const schemasCache = /* @__PURE__ */ new WeakMap();
@@ -2200,16 +2201,16 @@ const adapterOas = createAdapter((options) => {
2200
2201
  const cached = schemasCache.get(document);
2201
2202
  if (cached) return cached;
2202
2203
  const result = getSchemas(document, { contentType });
2203
- nameMapping = result.nameMapping;
2204
- schemasCache.set(document, result.schemas);
2205
- return result.schemas;
2204
+ schemasCache.set(document, result);
2205
+ return result;
2206
2206
  }
2207
- function ensureSchemaParser(document) {
2207
+ function ensureSchemaParser({ document, renames }) {
2208
2208
  const cached = schemaParserCache.get(document);
2209
2209
  if (cached) return cached;
2210
2210
  const parser = createSchemaParser({
2211
2211
  document,
2212
- contentType
2212
+ contentType,
2213
+ renames
2213
2214
  });
2214
2215
  schemaParserCache.set(document, parser);
2215
2216
  return parser;
@@ -2291,8 +2292,7 @@ const adapterOas = createAdapter((options) => {
2291
2292
  integerType,
2292
2293
  unknownType,
2293
2294
  emptySchemaType,
2294
- enumSuffix,
2295
- nameMapping
2295
+ enumSuffix
2296
2296
  };
2297
2297
  },
2298
2298
  get document() {
@@ -2302,24 +2302,16 @@ const adapterOas = createAdapter((options) => {
2302
2302
  await assertInputExists(input);
2303
2303
  await validateDocument(await parseDocument(input), options);
2304
2304
  },
2305
- getImports(node, resolve) {
2306
- return collect(node, { schema(schemaNode) {
2307
- const schemaRef = narrowSchema(schemaNode, "ref");
2308
- if (!schemaRef?.ref) return null;
2309
- const result = resolve(nameMapping.get(schemaRef.ref) ?? extractRefName(schemaRef.ref));
2310
- if (!result) return null;
2311
- return ast.factory.createImport({
2312
- name: [result.name],
2313
- path: result.path
2314
- });
2315
- } });
2316
- },
2317
2305
  async parse(source) {
2318
2306
  const document = await ensureDocument(source);
2307
+ const { schemas, renames } = ensureSchemas(document);
2319
2308
  return parseInput({
2320
2309
  document,
2321
- schemas: ensureSchemas(document),
2322
- parser: ensureSchemaParser(document)
2310
+ schemas,
2311
+ parser: ensureSchemaParser({
2312
+ document,
2313
+ renames
2314
+ })
2323
2315
  });
2324
2316
  }
2325
2317
  };