@kubb/adapter-oas 5.0.0-alpha.14 → 5.0.0-alpha.16

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,6 +1,6 @@
1
- import "./chunk--u3MIqq1.js";
1
+ import { t as __name } from "./chunk--u3MIqq1.js";
2
2
  import path from "node:path";
3
- import { collect, createOperation, createParameter, createProperty, createResponse, createRoot, createSchema, narrowSchema, schemaTypes, transform } from "@kubb/ast";
3
+ import { applyDiscriminatorEnum, collect, createOperation, createParameter, createProperty, createResponse, createRoot, createSchema, extractRefName, mediaTypes, mergeAdjacentAnonymousObjects, narrowSchema, schemaTypes, simplifyUnionMembers, transform } from "@kubb/ast";
4
4
  import { createAdapter } from "@kubb/core";
5
5
  import { bundle, loadConfig } from "@redocly/openapi-core";
6
6
  import yaml from "@stoplight/yaml";
@@ -76,44 +76,10 @@ const formatMap = {
76
76
  double: "number"
77
77
  };
78
78
  /**
79
- * Exhaustive list of media types that Kubb recognizes.
80
- */
81
- const knownMediaTypes = new Set([
82
- "application/json",
83
- "application/xml",
84
- "application/x-www-form-urlencoded",
85
- "application/octet-stream",
86
- "application/pdf",
87
- "application/zip",
88
- "application/graphql",
89
- "multipart/form-data",
90
- "text/plain",
91
- "text/html",
92
- "text/csv",
93
- "text/xml",
94
- "image/png",
95
- "image/jpeg",
96
- "image/gif",
97
- "image/webp",
98
- "image/svg+xml",
99
- "audio/mpeg",
100
- "video/mp4"
101
- ]);
102
- /**
103
79
  * Vendor extension keys used to attach human-readable labels to enum values.
104
80
  * Checked in priority order: the first key found wins.
105
81
  */
106
82
  const enumExtensionKeys = ["x-enumNames", "x-enum-varnames"];
107
- /**
108
- * Scalar primitive schema types used for union member simplification.
109
- */
110
- const SCALAR_PRIMITIVE_TYPES = new Set([
111
- "string",
112
- "number",
113
- "integer",
114
- "bigint",
115
- "boolean"
116
- ]);
117
83
  //#endregion
118
84
  //#region src/oas/resolveServerUrl.ts
119
85
  /**
@@ -196,27 +162,6 @@ function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
196
162
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
197
163
  }
198
164
  //#endregion
199
- //#region ../../internals/utils/src/names.ts
200
- /**
201
- * Returns a unique name by appending an incrementing numeric suffix when the name has already been used.
202
- * Mutates `data` in-place as a usage counter so subsequent calls remain consistent.
203
- *
204
- * @example
205
- * const seen: Record<string, number> = {}
206
- * getUniqueName('Foo', seen) // 'Foo'
207
- * getUniqueName('Foo', seen) // 'Foo2'
208
- * getUniqueName('Foo', seen) // 'Foo3'
209
- */
210
- function getUniqueName(originalName, data) {
211
- let used = data[originalName] || 0;
212
- if (used) {
213
- data[originalName] = ++used;
214
- originalName += used;
215
- }
216
- data[originalName] = 1;
217
- return originalName;
218
- }
219
- //#endregion
220
165
  //#region ../../internals/utils/src/reserved.ts
221
166
  /**
222
167
  * Returns `true` when `name` is a syntactically valid JavaScript variable name.
@@ -620,7 +565,6 @@ var Oas = class extends BaseOas {
620
565
  "requestBodies",
621
566
  "responses"
622
567
  ];
623
- const shouldResolveCollisions = options.collisionDetection ?? this.#options.collisionDetection ?? false;
624
568
  const components = this.getDefinition().components;
625
569
  const schemasWithMeta = [];
626
570
  if (includes.includes("schemas")) {
@@ -674,7 +618,7 @@ var Oas = class extends BaseOas {
674
618
  }
675
619
  }
676
620
  }
677
- const { schemas, nameMapping } = shouldResolveCollisions ? resolveCollisions(schemasWithMeta) : legacyResolve(schemasWithMeta);
621
+ const { schemas, nameMapping } = resolveCollisions(schemasWithMeta);
678
622
  return {
679
623
  schemas: sortSchemas(schemas),
680
624
  nameMapping
@@ -895,23 +839,6 @@ function getSemanticSuffix(source) {
895
839
  return semanticSuffixes[source];
896
840
  }
897
841
  /**
898
- * Builds `GetSchemasResult` without any collision detection.
899
- * Each schema is registered under its original component name and its full
900
- * `#/components/<source>/<name>` ref path.
901
- */
902
- function legacyResolve(schemasWithMeta) {
903
- const schemas = {};
904
- const nameMapping = /* @__PURE__ */ new Map();
905
- for (const item of schemasWithMeta) {
906
- schemas[item.originalName] = item.schema;
907
- nameMapping.set(`#/components/${item.source}/${item.originalName}`, item.originalName);
908
- }
909
- return {
910
- schemas,
911
- nameMapping
912
- };
913
- }
914
- /**
915
842
  * Builds `GetSchemasResult` with automatic name-collision resolution.
916
843
  *
917
844
  * When two or more schemas normalize to the same PascalCase name:
@@ -955,122 +882,54 @@ function resolveCollisions(schemasWithMeta) {
955
882
  };
956
883
  }
957
884
  //#endregion
958
- //#region src/utils.ts
959
- /**
960
- * Extracts the schema name from a `$ref` string.
961
- * For `#/components/schemas/Order` this returns `'Order'`.
962
- * Falls back to the full ref string when no slash is present.
963
- */
964
- function extractRefName($ref) {
965
- return $ref.split("/").at(-1) ?? $ref;
885
+ //#region src/discriminator.ts
886
+ function resolveDiscriminatorValue(mapping, ref) {
887
+ if (!mapping || !ref) return void 0;
888
+ return Object.entries(mapping).find(([, value]) => value === ref)?.[0];
966
889
  }
967
- /**
968
- * Replaces the discriminator property's schema inside an `ObjectSchemaNode`
969
- * with an enum of the given `values`.
970
- *
971
- * - When `enumName` is provided the enum is named, which lets printers emit a
972
- * standalone enum declaration + type reference (e.g. `PetTypeEnum`).
973
- * - When `enumName` is omitted the enum stays anonymous, so printers inline it
974
- * as a literal union (e.g. `'dog'`).
975
- *
976
- * Returns the node unchanged when it is not an object or lacks the target property.
977
- */
978
- function applyDiscriminatorEnum({ node, propertyName, values, enumName }) {
979
- if (node.type !== "object" || !node.properties?.length) return node;
980
- if (!node.properties.some((prop) => prop.name === propertyName)) return node;
890
+ function createDiscriminantNode(propertyName, value) {
981
891
  return createSchema({
982
- ...node,
983
- properties: node.properties.map((prop) => {
984
- if (prop.name !== propertyName) return prop;
985
- const enumSchema = createSchema({
892
+ type: "object",
893
+ primitive: "object",
894
+ properties: [createProperty({
895
+ name: propertyName,
896
+ schema: createSchema({
986
897
  type: "enum",
987
898
  primitive: "string",
988
- enumValues: values,
989
- name: enumName,
990
- readOnly: prop.schema.readOnly,
991
- writeOnly: prop.schema.writeOnly
992
- });
993
- return createProperty({
994
- ...prop,
995
- schema: enumSchema
996
- });
997
- })
899
+ enumValues: [value]
900
+ }),
901
+ required: true
902
+ })]
998
903
  });
999
904
  }
1000
- /**
1001
- * Merges consecutive anonymous (`name`-less) `ObjectSchemaNode`s in `members` into a
1002
- * single object by combining their `properties` arrays.
1003
- *
1004
- * Only adjacent pairs are merged — non-object or named nodes act as boundaries.
1005
- * This collapses patterns like `Address & { streetNumber } & { streetName }` into
1006
- * `Address & { streetNumber; streetName }`.
1007
- */
1008
- function mergeAdjacentAnonymousObjects(members) {
1009
- return members.reduce((acc, member) => {
1010
- const obj = narrowSchema(member, "object");
1011
- if (obj && !obj.name) {
1012
- const prev = acc[acc.length - 1];
1013
- const prevObj = prev ? narrowSchema(prev, "object") : null;
1014
- if (prevObj && !prevObj.name) {
1015
- acc[acc.length - 1] = createSchema({
1016
- ...prevObj,
1017
- properties: [...prevObj.properties ?? [], ...obj.properties ?? []]
1018
- });
1019
- return acc;
1020
- }
1021
- }
1022
- acc.push(member);
1023
- return acc;
1024
- }, []);
905
+ //#endregion
906
+ //#region src/naming.ts
907
+ function resolveChildName(parentName, propName) {
908
+ return parentName ? pascalCase([parentName, propName].join(" ")) : void 0;
1025
909
  }
1026
- /**
1027
- * Simplifies a union member list by removing `enum` nodes whose `primitive` type is
1028
- * already represented by a broader scalar node in the same union.
1029
- *
1030
- * For example `['placed', 'approved'] | string` collapses to `string` because
1031
- * `string` subsumes all string literals. `'' | string` similarly becomes `string`.
1032
- *
1033
- * Only scalar primitives (`string`, `number`, `integer`, `bigint`, `boolean`) are
1034
- * considered object, array, and ref members are left untouched.
1035
- *
1036
- * Const-derived enums (those without an `enumType`, produced from an OpenAPI `const`
1037
- * keyword) are **never** removed — `'accepted' | string` must stay as-is because the
1038
- * literal is intentional.
1039
- */
1040
- function simplifyUnionMembers(members) {
1041
- const scalarPrimitives = new Set(members.filter((m) => SCALAR_PRIMITIVE_TYPES.has(m.type)).map((m) => m.type));
1042
- if (!scalarPrimitives.size) return members;
1043
- return members.filter((m) => {
1044
- if (m.type !== "enum") return true;
1045
- const prim = m.primitive;
1046
- if (!prim) return true;
1047
- if (!m.enumType) return true;
1048
- if (scalarPrimitives.has(prim)) return false;
1049
- if ((prim === "integer" || prim === "number") && (scalarPrimitives.has("integer") || scalarPrimitives.has("number"))) return false;
1050
- return true;
1051
- });
910
+ function resolveEnumPropName(parentName, propName, enumSuffix) {
911
+ return pascalCase([
912
+ parentName,
913
+ propName,
914
+ enumSuffix
915
+ ].filter(Boolean).join(" "));
916
+ }
917
+ function applyEnumName(propNode, parentName, propName, enumSuffix) {
918
+ const enumNode = narrowSchema(propNode, "enum");
919
+ if (enumNode?.primitive === "boolean") return {
920
+ ...propNode,
921
+ name: void 0
922
+ };
923
+ if (enumNode) return {
924
+ ...propNode,
925
+ name: resolveEnumPropName(parentName, propName, enumSuffix)
926
+ };
927
+ return propNode;
1052
928
  }
929
+ //#endregion
930
+ //#region src/refResolver.ts
1053
931
  /**
1054
- * `nameMapping`, and calls `resolve` to obtain the `{ name, path }` pair for
1055
- * each import. When `oas` is supplied, only `$ref`s that are resolvable in the
1056
- * spec are included; omit it to skip the existence check.
1057
- *
1058
- * This function is the pure, state-free alternative to `OasParser.getImports`.
1059
- * Because it receives `nameMapping` explicitly it can be called without holding
1060
- * a reference to the parser or the OAS instance.
1061
- *
1062
- * @example
1063
- * ```ts
1064
- * // Use adapter state directly — no parser reference needed
1065
- * const imports = getImports({
1066
- * node: schemaNode,
1067
- * nameMapping: adapter.options.nameMapping,
1068
- * resolve: (schemaName) => ({
1069
- * name: schemaManager.getName(schemaName, { type: 'type' }),
1070
- * path: schemaManager.getFile(schemaName).path,
1071
- * }),
1072
- * })
1073
- * ```
932
+ * Collects import entries for all `ref` schema nodes in `node`.
1074
933
  */
1075
934
  function getImports({ node, nameMapping, resolve }) {
1076
935
  return collect(node, { schema(schemaNode) {
@@ -1084,6 +943,29 @@ function getImports({ node, nameMapping, resolve }) {
1084
943
  };
1085
944
  } });
1086
945
  }
946
+ /**
947
+ * Walks a schema tree and resolves `ref`/`enum` names through callbacks.
948
+ */
949
+ function resolveRefs({ node, nameMapping, resolveName, resolveEnumName }) {
950
+ return transform(node, { schema(schemaNode) {
951
+ const schemaRef = narrowSchema(schemaNode, schemaTypes.ref);
952
+ if (schemaRef && (schemaRef.ref || schemaRef.name)) {
953
+ const rawRef = schemaRef.ref ?? schemaRef.name;
954
+ const resolved = resolveName(nameMapping.get(rawRef) ?? rawRef);
955
+ if (resolved) return {
956
+ ...schemaNode,
957
+ name: resolved
958
+ };
959
+ }
960
+ if (schemaNode.type === "enum" && schemaNode.name) {
961
+ const resolved = (resolveEnumName ?? resolveName)(schemaNode.name);
962
+ if (resolved) return {
963
+ ...schemaNode,
964
+ name: resolved
965
+ };
966
+ }
967
+ } });
968
+ }
1087
969
  //#endregion
1088
970
  //#region src/parser.ts
1089
971
  /**
@@ -1109,7 +991,7 @@ function getPrimitiveType(type) {
1109
991
  * Returns `undefined` for content types not present in `KNOWN_MEDIA_TYPES`.
1110
992
  */
1111
993
  function toMediaType(contentType) {
1112
- return knownMediaTypes.has(contentType) ? contentType : void 0;
994
+ return Object.values(mediaTypes).includes(contentType) ? contentType : void 0;
1113
995
  }
1114
996
  /**
1115
997
  * Creates an OAS parser that converts an OpenAPI/Swagger spec into
@@ -1130,21 +1012,30 @@ function toMediaType(contentType) {
1130
1012
  * const root = parser.parse({ emptySchemaType: 'unknown' })
1131
1013
  * ```
1132
1014
  */
1133
- function createOasParser(oas, { contentType, collisionDetection } = {}) {
1134
- const { schemas: schemaObjects, nameMapping } = oas.getSchemas({
1135
- contentType,
1136
- collisionDetection
1137
- });
1138
- const usedEnumNames = {};
1139
- const isLegacyNaming = collisionDetection === false;
1015
+ function createOasParser(oas, { contentType } = {}) {
1016
+ const { schemas: schemaObjects, nameMapping } = oas.getSchemas({ contentType });
1017
+ const TYPE_OPTION_MAP = {
1018
+ any: schemaTypes.any,
1019
+ unknown: schemaTypes.unknown,
1020
+ void: schemaTypes.void
1021
+ };
1140
1022
  /**
1141
1023
  * Maps an `'any' | 'unknown' | 'void'` option string to the corresponding `SchemaType` constant.
1142
1024
  * Used for both `unknownType` (unannotated schemas) and `emptySchemaType` (empty `{}` schemas).
1143
1025
  */
1144
1026
  function resolveTypeOption(value) {
1145
- if (value === "any") return schemaTypes.any;
1146
- if (value === "void") return schemaTypes.void;
1147
- return schemaTypes.unknown;
1027
+ return TYPE_OPTION_MAP[value];
1028
+ }
1029
+ function normalizeArrayEnum(schema) {
1030
+ const normalizedItems = {
1031
+ ...typeof schema.items === "object" && !Array.isArray(schema.items) ? schema.items : {},
1032
+ enum: schema.enum
1033
+ };
1034
+ const { enum: _enum, ...schemaWithoutEnum } = schema;
1035
+ return {
1036
+ ...schemaWithoutEnum,
1037
+ items: normalizedItems
1038
+ };
1148
1039
  }
1149
1040
  /**
1150
1041
  * Resolves the AST type and datetime modifiers for a date/time format, honoring the `dateType` option.
@@ -1233,10 +1124,10 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1233
1124
  * Circular references through discriminator parents are detected and skipped to prevent
1234
1125
  * infinite recursion during code generation.
1235
1126
  */
1236
- function convertAllOf({ schema, name, nullable, defaultValue, options }) {
1127
+ function convertAllOf({ schema, name, nullable, defaultValue, rawOptions }) {
1237
1128
  if (schema.allOf.length === 1 && !schema.properties && !(Array.isArray(schema.required) && schema.required.length) && schema.additionalProperties === void 0) {
1238
1129
  const [memberSchema] = schema.allOf;
1239
- const memberNode = convertSchema({ schema: memberSchema }, options);
1130
+ const memberNode = convertSchema({ schema: memberSchema }, rawOptions);
1240
1131
  const { kind: _kind, ...memberNodeProps } = memberNode;
1241
1132
  const mergedNullable = nullable || memberNode.nullable || void 0;
1242
1133
  const mergedDefault = schema.default === null && mergedNullable ? void 0 : schema.default ?? memberNode.default;
@@ -1265,7 +1156,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1265
1156
  const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef);
1266
1157
  const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
1267
1158
  if (inOneOf || inMapping) {
1268
- const discriminatorValue = Object.entries(deref.discriminator.mapping ?? {}).find(([, v]) => v === childRef)?.[0];
1159
+ const discriminatorValue = resolveDiscriminatorValue(deref.discriminator.mapping, childRef);
1269
1160
  if (discriminatorValue) filteredDiscriminantValues.push({
1270
1161
  propertyName: deref.discriminator.propertyName,
1271
1162
  value: discriminatorValue
@@ -1273,7 +1164,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1273
1164
  return false;
1274
1165
  }
1275
1166
  return true;
1276
- }).map((s) => convertSchema({ schema: s }, options));
1167
+ }).map((s) => convertSchema({ schema: s }, rawOptions));
1277
1168
  const syntheticStart = allOfMembers.length;
1278
1169
  if (Array.isArray(schema.required) && schema.required.length) {
1279
1170
  const outerKeys = schema.properties ? new Set(Object.keys(schema.properties)) : /* @__PURE__ */ new Set();
@@ -1288,28 +1179,16 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1288
1179
  allOfMembers.push(convertSchema({ schema: {
1289
1180
  properties: { [key]: resolved.properties[key] },
1290
1181
  required: [key]
1291
- } }, options));
1182
+ } }, rawOptions));
1292
1183
  break;
1293
1184
  }
1294
1185
  }
1295
1186
  }
1296
1187
  if (schema.properties) {
1297
1188
  const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
1298
- allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf }, options));
1189
+ allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf }, rawOptions));
1299
1190
  }
1300
- for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push(createSchema({
1301
- type: "object",
1302
- primitive: "object",
1303
- properties: [createProperty({
1304
- name: propertyName,
1305
- schema: createSchema({
1306
- type: "enum",
1307
- primitive: "string",
1308
- enumValues: [value]
1309
- }),
1310
- required: true
1311
- })]
1312
- }));
1191
+ for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push(createDiscriminantNode(propertyName, value));
1313
1192
  return createSchema({
1314
1193
  type: "intersection",
1315
1194
  members: [...mergeAdjacentAnonymousObjects(allOfMembers.slice(0, syntheticStart)), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
@@ -1324,69 +1203,46 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1324
1203
  * individually intersected with the shared properties node to match the OAS pattern of
1325
1204
  * adding common fields next to a discriminated union.
1326
1205
  */
1327
- function convertUnion({ schema, name, nullable, defaultValue, options }) {
1206
+ function convertUnion({ schema, name, nullable, defaultValue, rawOptions }) {
1328
1207
  const unionMembers = [...schema.oneOf ?? [], ...schema.anyOf ?? []];
1329
1208
  const unionBase = {
1330
1209
  ...renderSchemaBase(schema, name, nullable, defaultValue),
1331
1210
  discriminatorPropertyName: isDiscriminator(schema) ? schema.discriminator.propertyName : void 0
1332
1211
  };
1333
- if (schema.properties) {
1212
+ const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
1213
+ const sharedPropertiesNode = schema.properties ? (() => {
1334
1214
  const { oneOf: _oneOf, anyOf: _anyOf, ...schemaWithoutUnion } = schema;
1335
- const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
1336
- const sharedPropertiesNode = convertSchema({
1215
+ return convertSchema({
1337
1216
  schema: discriminator ? Object.fromEntries(Object.entries(schemaWithoutUnion).filter(([key]) => key !== "discriminator")) : schemaWithoutUnion,
1338
- name: isLegacyNaming ? void 0 : name
1339
- }, options);
1340
- return createSchema({
1341
- type: "union",
1342
- ...unionBase,
1343
- members: unionMembers.map((s) => {
1344
- const ref = isReference(s) ? s.$ref : void 0;
1345
- const discriminatorValue = discriminator?.mapping && ref ? Object.entries(discriminator.mapping).find(([, v]) => v === ref)?.[0] : void 0;
1346
- let propertiesNode = sharedPropertiesNode;
1347
- if (discriminatorValue && discriminator) propertiesNode = applyDiscriminatorEnum({
1348
- node: propertiesNode,
1349
- propertyName: discriminator.propertyName,
1350
- values: [discriminatorValue]
1351
- });
1352
- return createSchema({
1353
- type: "intersection",
1354
- members: [convertSchema({ schema: s }, options), propertiesNode]
1355
- });
1356
- })
1357
- });
1358
- }
1359
- const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
1360
- if (discriminator?.mapping) return createSchema({
1217
+ name
1218
+ }, rawOptions);
1219
+ })() : void 0;
1220
+ if (sharedPropertiesNode || discriminator?.mapping) return createSchema({
1361
1221
  type: "union",
1362
1222
  ...unionBase,
1363
1223
  members: unionMembers.map((s) => {
1364
1224
  const ref = isReference(s) ? s.$ref : void 0;
1365
- const discriminatorValue = ref ? Object.entries(discriminator.mapping).find(([, v]) => v === ref)?.[0] : void 0;
1366
- const memberNode = convertSchema({ schema: s }, options);
1367
- if (!discriminatorValue) return memberNode;
1225
+ const discriminatorValue = resolveDiscriminatorValue(discriminator?.mapping, ref);
1226
+ const memberNode = convertSchema({ schema: s }, rawOptions);
1227
+ if (sharedPropertiesNode) return createSchema({
1228
+ type: "intersection",
1229
+ members: [memberNode, discriminatorValue && discriminator ? applyDiscriminatorEnum({
1230
+ node: sharedPropertiesNode,
1231
+ propertyName: discriminator.propertyName,
1232
+ values: [discriminatorValue]
1233
+ }) : sharedPropertiesNode]
1234
+ });
1235
+ if (!discriminatorValue || !discriminator) return memberNode;
1368
1236
  return createSchema({
1369
1237
  type: "intersection",
1370
- members: [memberNode, createSchema({
1371
- type: "object",
1372
- primitive: "object",
1373
- properties: [createProperty({
1374
- name: discriminator.propertyName,
1375
- schema: createSchema({
1376
- type: "enum",
1377
- primitive: "string",
1378
- enumValues: [discriminatorValue]
1379
- }),
1380
- required: true
1381
- })]
1382
- })]
1238
+ members: [memberNode, createDiscriminantNode(discriminator.propertyName, discriminatorValue)]
1383
1239
  });
1384
1240
  })
1385
1241
  });
1386
1242
  return createSchema({
1387
1243
  type: "union",
1388
1244
  ...unionBase,
1389
- members: simplifyUnionMembers(unionMembers.map((s) => convertSchema({ schema: s }, options)))
1245
+ members: simplifyUnionMembers(unionMembers.map((s) => convertSchema({ schema: s }, rawOptions)))
1390
1246
  });
1391
1247
  }
1392
1248
  /**
@@ -1416,10 +1272,10 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1416
1272
  * Returns `undefined` when the format should fall through to string handling
1417
1273
  * (i.e. `format: 'date-time'` with `dateType: false`).
1418
1274
  */
1419
- function convertFormat({ schema, name, nullable, defaultValue, mergedOptions }) {
1275
+ function convertFormat({ schema, name, nullable, defaultValue, options }) {
1420
1276
  const base = renderSchemaBase(schema, name, nullable, defaultValue);
1421
1277
  if (schema.format === "int64") return createSchema({
1422
- type: mergedOptions.integerType === "bigint" ? "bigint" : "integer",
1278
+ type: options.integerType === "bigint" ? "bigint" : "integer",
1423
1279
  primitive: "integer",
1424
1280
  ...base,
1425
1281
  min: schema.minimum,
@@ -1428,7 +1284,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1428
1284
  exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0
1429
1285
  });
1430
1286
  if (schema.format === "date-time" || schema.format === "date" || schema.format === "time") {
1431
- const dateType = getDateType(mergedOptions, schema.format);
1287
+ const dateType = getDateType(options, schema.format);
1432
1288
  if (!dateType) return void 0;
1433
1289
  if (dateType.type === "datetime") return createSchema({
1434
1290
  ...base,
@@ -1473,28 +1329,19 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1473
1329
  * - Numeric and boolean enums require a const-map representation because most generators cannot
1474
1330
  * use string-enum syntax for non-string values.
1475
1331
  */
1476
- function convertEnum({ schema, name, nullable, type, options }) {
1477
- if (type === "array") {
1478
- const normalizedItems = {
1479
- ...typeof schema.items === "object" && !Array.isArray(schema.items) ? schema.items : {},
1480
- enum: schema.enum
1481
- };
1482
- const { enum: _enum, ...schemaWithoutEnum } = schema;
1483
- return convertSchema({
1484
- schema: {
1485
- ...schemaWithoutEnum,
1486
- items: normalizedItems
1487
- },
1488
- name
1489
- }, options);
1490
- }
1332
+ function convertEnum({ schema, name, nullable, type, rawOptions }) {
1333
+ if (type === "array") return convertSchema({
1334
+ schema: normalizeArrayEnum(schema),
1335
+ name
1336
+ }, rawOptions);
1491
1337
  const nullInEnum = schema.enum.includes(null);
1492
1338
  const filteredValues = nullInEnum ? schema.enum.filter((v) => v !== null) : schema.enum;
1493
1339
  const enumNullable = nullable || nullInEnum || void 0;
1494
1340
  const enumDefault = schema.default === null && enumNullable ? void 0 : schema.default;
1341
+ const enumPrimitive = getPrimitiveType(type);
1495
1342
  const enumBase = {
1496
1343
  type: "enum",
1497
- primitive: getPrimitiveType(type),
1344
+ primitive: enumPrimitive,
1498
1345
  name,
1499
1346
  title: schema.title,
1500
1347
  description: schema.description,
@@ -1506,38 +1353,19 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1506
1353
  example: schema.example
1507
1354
  };
1508
1355
  const extensionKey = enumExtensionKeys.find((key) => key in schema);
1509
- if (extensionKey) {
1510
- const rawNames = schema[extensionKey];
1511
- const uniqueNames = [...new Set(rawNames)];
1512
- const enumType = getPrimitiveType(type) === "number" || getPrimitiveType(type) === "integer" ? "number" : getPrimitiveType(type) === "boolean" ? "boolean" : "string";
1356
+ if (extensionKey || enumPrimitive === "number" || enumPrimitive === "integer" || enumPrimitive === "boolean") {
1357
+ const enumType = enumPrimitive === "number" || enumPrimitive === "integer" ? "number" : enumPrimitive === "boolean" ? "boolean" : "string";
1358
+ const sourceValues = extensionKey ? [...new Set(schema[extensionKey])] : [...new Set(filteredValues)];
1513
1359
  return createSchema({
1514
1360
  ...enumBase,
1515
1361
  enumType,
1516
- namedEnumValues: uniqueNames.map((label, index) => ({
1362
+ namedEnumValues: sourceValues.map((label, index) => ({
1517
1363
  name: String(label),
1518
- value: filteredValues[index] ?? label,
1364
+ value: extensionKey ? filteredValues[index] ?? label : label,
1519
1365
  format: enumType
1520
1366
  }))
1521
1367
  });
1522
1368
  }
1523
- if (type === "number" || type === "integer") return createSchema({
1524
- ...enumBase,
1525
- enumType: "number",
1526
- namedEnumValues: [...new Set(filteredValues)].map((value) => ({
1527
- name: String(value),
1528
- value,
1529
- format: "number"
1530
- }))
1531
- });
1532
- if (type === "boolean") return createSchema({
1533
- ...enumBase,
1534
- enumType: "boolean",
1535
- namedEnumValues: [...new Set(filteredValues)].map((value) => ({
1536
- name: String(value),
1537
- value,
1538
- format: "boolean"
1539
- }))
1540
- });
1541
1369
  return createSchema({
1542
1370
  ...enumBase,
1543
1371
  enumValues: [...new Set(filteredValues)]
@@ -1555,51 +1383,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1555
1383
  * - not required + not nullable → `optional: true`
1556
1384
  * - not required + nullable → `nullish: true`
1557
1385
  */
1558
- /**
1559
- * Builds the propagation name for a child property during recursive schema conversion.
1560
- *
1561
- * - **Legacy naming** (`isLegacyNaming`): only the immediate property key is used
1562
- * (e.g. `Params` for property `params`), keeping nested names short.
1563
- * - **Default naming**: the parent name is prepended so the full path is encoded
1564
- * (e.g. `OrderParams` when parent is `Order`).
1565
- */
1566
- function resolveChildName(parentName, propName) {
1567
- if (isLegacyNaming) return pascalCase(propName);
1568
- return parentName ? pascalCase([parentName, propName].join(" ")) : void 0;
1569
- }
1570
- /**
1571
- * Derives the final name for an enum property schema node.
1572
- *
1573
- * The raw name always includes the enum suffix (e.g. `StatusEnum`).
1574
- * In legacy mode an additional deduplication step appends a numeric suffix
1575
- * when the same name has already been used (e.g. `ParamsStatusEnum2`).
1576
- */
1577
- function resolveEnumPropName(parentName, propName, enumSuffix) {
1578
- const raw = pascalCase([
1579
- parentName,
1580
- propName,
1581
- enumSuffix
1582
- ].filter(Boolean).join(" "));
1583
- return isLegacyNaming ? getUniqueName(raw, usedEnumNames) : raw;
1584
- }
1585
- /**
1586
- * Given a freshly-converted property schema, returns the node with a correct
1587
- * `name` attached — or stripped — depending on whether the node is a named
1588
- * enum, a boolean const-enum (always inlined), or a regular schema.
1589
- */
1590
- function applyEnumName(propNode, parentName, propName, enumSuffix) {
1591
- const enumNode = narrowSchema(propNode, "enum");
1592
- if (enumNode?.primitive === "boolean") return {
1593
- ...propNode,
1594
- name: void 0
1595
- };
1596
- if (enumNode) return {
1597
- ...propNode,
1598
- name: resolveEnumPropName(parentName, propName, enumSuffix)
1599
- };
1600
- return propNode;
1601
- }
1602
- function convertObject({ schema, name, nullable, defaultValue, options, mergedOptions }) {
1386
+ function convertObject({ schema, name, nullable, defaultValue, rawOptions, options }) {
1603
1387
  const properties = schema.properties ? Object.entries(schema.properties).map(([propName, propSchema]) => {
1604
1388
  const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
1605
1389
  const resolvedPropSchema = propSchema;
@@ -1607,10 +1391,10 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1607
1391
  let schemaNode = applyEnumName(convertSchema({
1608
1392
  schema: resolvedPropSchema,
1609
1393
  name: resolveChildName(name, propName)
1610
- }, options), name, propName, mergedOptions.enumSuffix);
1394
+ }, rawOptions), name, propName, options.enumSuffix);
1611
1395
  const tupleNode = narrowSchema(schemaNode, "tuple");
1612
1396
  if (tupleNode?.items) {
1613
- const namedItems = tupleNode.items.map((item) => applyEnumName(item, name, propName, mergedOptions.enumSuffix));
1397
+ const namedItems = tupleNode.items.map((item) => applyEnumName(item, name, propName, options.enumSuffix));
1614
1398
  if (namedItems.some((item, i) => item !== tupleNode.items[i])) schemaNode = {
1615
1399
  ...tupleNode,
1616
1400
  items: namedItems
@@ -1628,11 +1412,11 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1628
1412
  const additionalProperties = schema.additionalProperties;
1629
1413
  let additionalPropertiesNode;
1630
1414
  if (additionalProperties === true) additionalPropertiesNode = true;
1631
- else if (additionalProperties && Object.keys(additionalProperties).length > 0) additionalPropertiesNode = convertSchema({ schema: additionalProperties }, options);
1415
+ else if (additionalProperties && Object.keys(additionalProperties).length > 0) additionalPropertiesNode = convertSchema({ schema: additionalProperties }, rawOptions);
1632
1416
  else if (additionalProperties === false) additionalPropertiesNode = void 0;
1633
- else if (additionalProperties) additionalPropertiesNode = createSchema({ type: resolveTypeOption(mergedOptions.unknownType) });
1417
+ else if (additionalProperties) additionalPropertiesNode = createSchema({ type: resolveTypeOption(options.unknownType) });
1634
1418
  const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
1635
- const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? createSchema({ type: resolveTypeOption(mergedOptions.unknownType) }) : convertSchema({ schema: patternSchema }, options)])) : void 0;
1419
+ const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? createSchema({ type: resolveTypeOption(options.unknownType) }) : convertSchema({ schema: patternSchema }, rawOptions)])) : void 0;
1636
1420
  const objectNode = createSchema({
1637
1421
  type: "object",
1638
1422
  primitive: "object",
@@ -1647,7 +1431,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1647
1431
  node: objectNode,
1648
1432
  propertyName: discPropName,
1649
1433
  values: Object.keys(schema.discriminator.mapping),
1650
- enumName: name ? resolveEnumPropName(name, discPropName, mergedOptions.enumSuffix) : void 0
1434
+ enumName: name ? resolveEnumPropName(name, discPropName, options.enumSuffix) : void 0
1651
1435
  });
1652
1436
  }
1653
1437
  return objectNode;
@@ -1660,12 +1444,12 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1660
1444
  * a rest element of type `any` is emitted to match JSON Schema semantics (absent `items`
1661
1445
  * means additional items are allowed).
1662
1446
  */
1663
- function convertTuple({ schema, name, nullable, defaultValue, options }) {
1447
+ function convertTuple({ schema, name, nullable, defaultValue, rawOptions }) {
1664
1448
  return createSchema({
1665
1449
  type: "tuple",
1666
1450
  primitive: "array",
1667
- items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item }, options)),
1668
- rest: schema.items ? convertSchema({ schema: schema.items }, options) : createSchema({ type: "any" }),
1451
+ items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item }, rawOptions)),
1452
+ rest: schema.items ? convertSchema({ schema: schema.items }, rawOptions) : createSchema({ type: "any" }),
1669
1453
  min: schema.minItems,
1670
1454
  max: schema.maxItems,
1671
1455
  ...renderSchemaBase(schema, name, nullable, defaultValue)
@@ -1677,16 +1461,16 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1677
1461
  * When the items schema is an inline enum, a name derived from the parent array's name and
1678
1462
  * `enumSuffix` is forwarded so generators can emit a named enum declaration.
1679
1463
  */
1680
- function convertArray({ schema, name, nullable, defaultValue, options, mergedOptions }) {
1464
+ function convertArray({ schema, name, nullable, defaultValue, rawOptions, options }) {
1681
1465
  const rawItems = schema.items;
1682
- const itemName = rawItems?.enum?.length && name ? resolveEnumPropName(void 0, name, mergedOptions.enumSuffix) : void 0;
1466
+ const itemName = rawItems?.enum?.length && name ? resolveEnumPropName(void 0, name, options.enumSuffix) : void 0;
1683
1467
  return createSchema({
1684
1468
  type: "array",
1685
1469
  primitive: "array",
1686
1470
  items: rawItems ? [convertSchema({
1687
1471
  schema: rawItems,
1688
1472
  name: itemName
1689
- }, options)] : [],
1473
+ }, rawOptions)] : [],
1690
1474
  min: schema.minItems,
1691
1475
  max: schema.maxItems,
1692
1476
  unique: schema.uniqueItems ?? void 0,
@@ -1760,16 +1544,16 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1760
1544
  * 10. Object / array / tuple / scalar by `type`
1761
1545
  * 11. Empty schema fallback (`emptySchemaType` option)
1762
1546
  */
1763
- function convertSchema({ schema, name }, options) {
1764
- const mergedOptions = {
1547
+ function convertSchema({ schema, name }, rawOptions) {
1548
+ const options = {
1765
1549
  ...DEFAULT_PARSER_OPTIONS,
1766
- ...options
1550
+ ...rawOptions
1767
1551
  };
1768
1552
  const flattenedSchema = flattenSchema(schema);
1769
1553
  if (flattenedSchema && flattenedSchema !== schema) return convertSchema({
1770
1554
  schema: flattenedSchema,
1771
1555
  name
1772
- }, options);
1556
+ }, rawOptions);
1773
1557
  const nullable = isNullable(schema) || void 0;
1774
1558
  const defaultValue = schema.default === null && nullable ? void 0 : schema.default;
1775
1559
  const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
@@ -1779,8 +1563,8 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1779
1563
  nullable,
1780
1564
  defaultValue,
1781
1565
  type,
1782
- options,
1783
- mergedOptions
1566
+ rawOptions,
1567
+ options
1784
1568
  };
1785
1569
  if (isReference(schema)) return convertRef(ctx);
1786
1570
  if (schema.allOf?.length) return convertAllOf(ctx);
@@ -1806,7 +1590,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1806
1590
  type: t
1807
1591
  },
1808
1592
  name
1809
- }, options)),
1593
+ }, rawOptions)),
1810
1594
  ...renderSchemaBase(schema, name, arrayNullable, defaultValue)
1811
1595
  });
1812
1596
  }
@@ -1824,7 +1608,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1824
1608
  if (type === "boolean") return convertBoolean(ctx);
1825
1609
  if (type === "null") return convertNull(ctx);
1826
1610
  return createSchema({
1827
- type: resolveTypeOption(mergedOptions.emptySchemaType),
1611
+ type: resolveTypeOption(options.emptySchemaType),
1828
1612
  name,
1829
1613
  title: schema.title,
1830
1614
  description: schema.description
@@ -1910,38 +1694,15 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1910
1694
  operations: Object.entries(paths).flatMap(([_path, methods]) => Object.entries(methods).map(([, operation]) => operation ? parseOperation(mergedOptions, oas, operation) : null).filter((op) => op !== null))
1911
1695
  });
1912
1696
  }
1913
- /**
1914
- * Walks a `SchemaNode` tree and resolves all `ref` node names through the provided callbacks.
1915
- *
1916
- * `resolveName` handles all schema types; `resolveEnumName` (when provided) takes precedence
1917
- * for `enum` nodes, enabling a separate naming strategy for enums (e.g. different suffix).
1918
- *
1919
- * Collision-resolved names (from `nameMapping`) are applied before user-supplied resolvers.
1920
- */
1921
- function resolveRefs(node, resolveName, resolveEnumName) {
1922
- return transform(node, { schema(schemaNode) {
1923
- const schemaRef = narrowSchema(schemaNode, schemaTypes.ref);
1924
- if (schemaRef && (schemaRef.ref || schemaRef.name)) {
1925
- const rawRef = schemaRef.ref ?? schemaRef.name;
1926
- const resolved = resolveName(nameMapping.get(rawRef) ?? rawRef);
1927
- if (resolved) return {
1928
- ...schemaNode,
1929
- name: resolved
1930
- };
1931
- }
1932
- if (schemaNode.type === "enum" && schemaNode.name) {
1933
- const resolved = (resolveEnumName ?? resolveName)(schemaNode.name);
1934
- if (resolved) return {
1935
- ...schemaNode,
1936
- name: resolved
1937
- };
1938
- }
1939
- } });
1940
- }
1941
1697
  return {
1942
1698
  parse,
1943
1699
  convertSchema,
1944
- resolveRefs,
1700
+ resolveRefs: /* @__PURE__ */ __name((node, resolveName, resolveEnumName) => resolveRefs({
1701
+ node,
1702
+ nameMapping,
1703
+ resolveName,
1704
+ resolveEnumName
1705
+ }), "resolveRefs"),
1945
1706
  nameMapping
1946
1707
  };
1947
1708
  }
@@ -1967,7 +1728,7 @@ const adapterOasName = "oas";
1967
1728
  * ```
1968
1729
  */
1969
1730
  const adapterOas = createAdapter((options) => {
1970
- const { validate = true, oasClass, contentType, serverIndex, serverVariables, discriminator = "strict", collisionDetection = true, dateType = DEFAULT_PARSER_OPTIONS.dateType, integerType = DEFAULT_PARSER_OPTIONS.integerType, unknownType = DEFAULT_PARSER_OPTIONS.unknownType, enumSuffix = DEFAULT_PARSER_OPTIONS.enumSuffix, emptySchemaType = unknownType || DEFAULT_PARSER_OPTIONS.emptySchemaType } = options;
1731
+ const { validate = true, oasClass, contentType, serverIndex, serverVariables, discriminator = "strict", dateType = DEFAULT_PARSER_OPTIONS.dateType, integerType = DEFAULT_PARSER_OPTIONS.integerType, unknownType = DEFAULT_PARSER_OPTIONS.unknownType, enumSuffix = DEFAULT_PARSER_OPTIONS.enumSuffix, emptySchemaType = unknownType || DEFAULT_PARSER_OPTIONS.emptySchemaType } = options;
1971
1732
  const nameMapping = /* @__PURE__ */ new Map();
1972
1733
  return {
1973
1734
  name: "oas",
@@ -1978,7 +1739,6 @@ const adapterOas = createAdapter((options) => {
1978
1739
  serverIndex,
1979
1740
  serverVariables,
1980
1741
  discriminator,
1981
- collisionDetection,
1982
1742
  dateType,
1983
1743
  integerType,
1984
1744
  unknownType,
@@ -1997,18 +1757,14 @@ const adapterOas = createAdapter((options) => {
1997
1757
  const oas = await parseFromConfig(sourceToFakeConfig(source), oasClass);
1998
1758
  oas.setOptions({
1999
1759
  contentType,
2000
- discriminator,
2001
- collisionDetection
1760
+ discriminator
2002
1761
  });
2003
1762
  if (validate) try {
2004
1763
  await oas.validate();
2005
1764
  } catch (_err) {}
2006
1765
  const server = serverIndex !== void 0 ? oas.api.servers?.at(serverIndex) : void 0;
2007
1766
  const baseURL = server?.url ? resolveServerUrl(server, serverVariables) : void 0;
2008
- const parser = createOasParser(oas, {
2009
- contentType,
2010
- collisionDetection
2011
- });
1767
+ const parser = createOasParser(oas, { contentType });
2012
1768
  const root = parser.parse({
2013
1769
  dateType,
2014
1770
  integerType,