@kubb/adapter-oas 5.0.0-alpha.2 → 5.0.0-alpha.3

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.d.ts CHANGED
@@ -5,6 +5,7 @@ import { DiscriminatorObject, OASDocument, SchemaObject } from "oas/types";
5
5
  import BaseOas from "oas";
6
6
  import * as oas_normalize_lib_types0 from "oas-normalize/lib/types";
7
7
  import { Operation } from "oas/operation";
8
+ import { OpenAPIV3 } from "openapi-types";
8
9
 
9
10
  //#region src/oas/types.d.ts
10
11
  type contentType = 'application/json' | (string & {});
@@ -24,10 +25,30 @@ type SchemaObject$1 = SchemaObject & {
24
25
  */
25
26
  contentMediaType?: string;
26
27
  $ref?: string;
28
+ /**
29
+ * OAS 3.1 / JSON Schema: positional items in a tuple schema.
30
+ * Replaces the OAS 3.0 multi-item `items` array syntax.
31
+ */
32
+ prefixItems?: Array<SchemaObject$1 | ReferenceObject>;
33
+ /**
34
+ * JSON Schema: maps regex patterns to sub-schemas for additional property validation.
35
+ */
36
+ patternProperties?: Record<string, SchemaObject$1 | boolean>;
37
+ /**
38
+ * OAS 3.0 / JSON Schema: single-schema form.
39
+ * The OAS base type already includes this, but we re-declare it here to ensure
40
+ * the single-schema overload takes precedence over the multi-schema tuple form.
41
+ */
42
+ items?: SchemaObject$1 | ReferenceObject;
43
+ /**
44
+ * Enum values for this schema (narrowed from `unknown[]` in the base type).
45
+ */
46
+ enum?: Array<string | number | boolean | null>;
27
47
  };
28
48
  type Document = OASDocument;
29
49
  type Operation$1 = Operation;
30
50
  type DiscriminatorObject$1 = DiscriminatorObject;
51
+ type ReferenceObject = OpenAPIV3.ReferenceObject;
31
52
  //#endregion
32
53
  //#region src/oas/Oas.d.ts
33
54
  type OasOptions = {
@@ -149,6 +170,12 @@ type OasAdapterResolvedOptions = {
149
170
  integerType: NonNullable<OasAdapterOptions['integerType']>;
150
171
  unknownType: NonNullable<OasAdapterOptions['unknownType']>;
151
172
  emptySchemaType: NonNullable<OasAdapterOptions['emptySchemaType']>;
173
+ /**
174
+ * Map from original `$ref` paths to their collision-resolved schema names.
175
+ * Populated by the adapter after each `parse()` call.
176
+ * e.g. `'#/components/schemas/Order'` → `'OrderSchema'`
177
+ */
178
+ nameMapping: Map<string, string>;
152
179
  };
153
180
  type OasAdapter = AdapterFactoryOptions<'oas', OasAdapterOptions, OasAdapterResolvedOptions>;
154
181
  //#endregion
package/dist/index.js CHANGED
@@ -900,6 +900,137 @@ function resolveCollisions(schemasWithMeta) {
900
900
  };
901
901
  }
902
902
  //#endregion
903
+ //#region src/utils.ts
904
+ /**
905
+ * Extracts the schema name from a `$ref` string.
906
+ * For `#/components/schemas/Order` this returns `'Order'`.
907
+ * Falls back to the full ref string when no slash is present.
908
+ */
909
+ function extractRefName($ref) {
910
+ return $ref.split("/").at(-1) ?? $ref;
911
+ }
912
+ /**
913
+ * Replaces the discriminator property's schema inside an `ObjectSchemaNode`
914
+ * with an enum of the given `values`.
915
+ *
916
+ * - When `enumName` is provided the enum is named, which lets printers emit a
917
+ * standalone enum declaration + type reference (e.g. `PetTypeEnum`).
918
+ * - When `enumName` is omitted the enum stays anonymous, so printers inline it
919
+ * as a literal union (e.g. `'dog'`).
920
+ *
921
+ * Returns the node unchanged when it is not an object or lacks the target property.
922
+ */
923
+ function applyDiscriminatorEnum({ node, propertyName, values, enumName }) {
924
+ if (node.type !== "object" || !node.properties?.length) return node;
925
+ if (!node.properties.some((prop) => prop.name === propertyName)) return node;
926
+ return createSchema({
927
+ ...node,
928
+ properties: node.properties.map((prop) => {
929
+ if (prop.name !== propertyName) return prop;
930
+ const enumSchema = createSchema({
931
+ type: "enum",
932
+ primitive: "string",
933
+ enumValues: values,
934
+ name: enumName,
935
+ readOnly: prop.schema.readOnly,
936
+ writeOnly: prop.schema.writeOnly
937
+ });
938
+ return createProperty({
939
+ ...prop,
940
+ schema: enumSchema
941
+ });
942
+ })
943
+ });
944
+ }
945
+ /**
946
+ * Merges consecutive anonymous (`name`-less) `ObjectSchemaNode`s in `members` into a
947
+ * single object by combining their `properties` arrays.
948
+ *
949
+ * Only adjacent pairs are merged — non-object or named nodes act as boundaries.
950
+ * This collapses patterns like `Address & { streetNumber } & { streetName }` into
951
+ * `Address & { streetNumber; streetName }`.
952
+ */
953
+ function mergeAdjacentAnonymousObjects(members) {
954
+ return members.reduce((acc, member) => {
955
+ const obj = narrowSchema(member, "object");
956
+ if (obj && !obj.name) {
957
+ const prev = acc[acc.length - 1];
958
+ const prevObj = prev ? narrowSchema(prev, "object") : null;
959
+ if (prevObj && !prevObj.name) {
960
+ acc[acc.length - 1] = createSchema({
961
+ ...prevObj,
962
+ properties: [...prevObj.properties ?? [], ...obj.properties ?? []]
963
+ });
964
+ return acc;
965
+ }
966
+ }
967
+ acc.push(member);
968
+ return acc;
969
+ }, []);
970
+ }
971
+ /**
972
+ * Simplifies a union member list by removing `enum` nodes whose `primitive` type is
973
+ * already represented by a broader scalar node in the same union.
974
+ *
975
+ * For example `['placed', 'approved'] | string` collapses to `string` because
976
+ * `string` subsumes all string literals. `'' | string` similarly becomes `string`.
977
+ *
978
+ * Only scalar primitives (`string`, `number`, `integer`, `bigint`, `boolean`) are
979
+ * considered — object, array, and ref members are left untouched.
980
+ */
981
+ function simplifyUnionMembers(members) {
982
+ const scalarPrimitives = new Set(members.filter((m) => [
983
+ "string",
984
+ "number",
985
+ "integer",
986
+ "bigint",
987
+ "boolean"
988
+ ].includes(m.type)).map((m) => m.type));
989
+ if (!scalarPrimitives.size) return members;
990
+ return members.filter((m) => {
991
+ if (m.type !== "enum") return true;
992
+ const prim = m.primitive;
993
+ if (!prim) return true;
994
+ if (scalarPrimitives.has(prim)) return false;
995
+ if ((prim === "integer" || prim === "number") && (scalarPrimitives.has("integer") || scalarPrimitives.has("number"))) return false;
996
+ return true;
997
+ });
998
+ }
999
+ /**
1000
+ * `nameMapping`, and calls `resolve` to obtain the `{ name, path }` pair for
1001
+ * each import. When `oas` is supplied, only `$ref`s that are resolvable in the
1002
+ * spec are included; omit it to skip the existence check.
1003
+ *
1004
+ * This function is the pure, state-free alternative to `OasParser.getImports`.
1005
+ * Because it receives `nameMapping` explicitly it can be called without holding
1006
+ * a reference to the parser or the OAS instance.
1007
+ *
1008
+ * @example
1009
+ * ```ts
1010
+ * // Use adapter state directly — no parser reference needed
1011
+ * const imports = getImports({
1012
+ * node: schemaNode,
1013
+ * nameMapping: adapter.options.nameMapping,
1014
+ * resolve: (schemaName) => ({
1015
+ * name: schemaManager.getName(schemaName, { type: 'type' }),
1016
+ * path: schemaManager.getFile(schemaName).path,
1017
+ * }),
1018
+ * })
1019
+ * ```
1020
+ */
1021
+ function getImports({ node, nameMapping, resolve }) {
1022
+ return collect(node, { schema(schemaNode) {
1023
+ if (schemaNode.type !== "ref" || !schemaNode.ref) return;
1024
+ const rawName = extractRefName(schemaNode.ref);
1025
+ const result = resolve(nameMapping.get(rawName) ?? rawName);
1026
+ if (!result) return;
1027
+ return {
1028
+ name: [result.name],
1029
+ path: result.path
1030
+ };
1031
+ } });
1032
+ }
1033
+ //#endregion
903
1034
  //#region src/parser.ts
904
1035
  /**
905
1036
  * Default values for all `Options` fields.
@@ -920,14 +1051,6 @@ function formatToSchemaType(format) {
920
1051
  return formatMap[format];
921
1052
  }
922
1053
  /**
923
- * Extracts the final path segment of a JSON Pointer `$ref` string.
924
- * For `#/components/schemas/Order` this returns `'Order'`.
925
- * Falls back to the full ref string when no slash is present.
926
- */
927
- function extractRefName($ref) {
928
- return $ref.split("/").at(-1) ?? $ref;
929
- }
930
- /**
931
1054
  * Maps an OAS primitive type string to its `PrimitiveSchemaType` equivalent.
932
1055
  * Numeric types (`number`, `integer`, `bigint`) are returned unchanged;
933
1056
  * `boolean` maps to `'boolean'`; everything else defaults to `'string'`.
@@ -945,26 +1068,6 @@ function toMediaType(contentType) {
945
1068
  return knownMediaTypes.includes(contentType) ? contentType : void 0;
946
1069
  }
947
1070
  /**
948
- * When a discriminator is present, replaces the discriminator property's schema with
949
- * an enum of the mapping keys so downstream code emits a precise literal-union type.
950
- * Returns the original schema unchanged when there is no discriminator or no mapping.
951
- */
952
- function applyDiscriminatorEnum(schema) {
953
- if (!isDiscriminator(schema)) return schema;
954
- const propName = schema.discriminator.propertyName;
955
- if (!schema.properties?.[propName]) return schema;
956
- return {
957
- ...schema,
958
- properties: {
959
- ...schema.properties,
960
- [propName]: {
961
- ...schema.properties[propName],
962
- enum: schema.discriminator.mapping ? Object.keys(schema.discriminator.mapping) : void 0
963
- }
964
- }
965
- };
966
- }
967
- /**
968
1071
  * Creates an OAS parser that converts an OpenAPI/Swagger spec into
969
1072
  * the `@kubb/ast` tree.
970
1073
  *
@@ -1055,18 +1158,17 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1055
1158
  * reflected in generated JSDoc and type modifiers.
1056
1159
  */
1057
1160
  function convertRef({ schema, nullable, defaultValue }) {
1058
- const schemaObject = schema;
1059
1161
  return createSchema({
1060
1162
  type: "ref",
1061
- name: extractRefName(schemaObject.$ref),
1062
- ref: schemaObject.$ref,
1163
+ name: extractRefName(schema.$ref),
1164
+ ref: schema.$ref,
1063
1165
  nullable,
1064
- description: schemaObject.description,
1065
- deprecated: schemaObject.deprecated,
1066
- readOnly: schemaObject.readOnly,
1067
- writeOnly: schemaObject.writeOnly,
1068
- pattern: schemaObject.type === "string" ? schemaObject.pattern : void 0,
1069
- example: schemaObject.example,
1166
+ description: schema.description,
1167
+ deprecated: schema.deprecated,
1168
+ readOnly: schema.readOnly,
1169
+ writeOnly: schema.writeOnly,
1170
+ pattern: schema.type === "string" ? schema.pattern : void 0,
1171
+ example: schema.example,
1070
1172
  default: defaultValue
1071
1173
  });
1072
1174
  }
@@ -1117,6 +1219,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1117
1219
  const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
1118
1220
  return !inOneOf && !inMapping;
1119
1221
  }).map((s) => convertSchema({ schema: s }, options));
1222
+ const syntheticStart = allOfMembers.length;
1120
1223
  if (Array.isArray(schema.required) && schema.required.length) {
1121
1224
  const outerKeys = schema.properties ? new Set(Object.keys(schema.properties)) : /* @__PURE__ */ new Set();
1122
1225
  const missingRequired = schema.required.filter((key) => !outerKeys.has(key));
@@ -1141,7 +1244,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1141
1244
  }
1142
1245
  return createSchema({
1143
1246
  type: "intersection",
1144
- members: allOfMembers,
1247
+ members: [...allOfMembers.slice(0, syntheticStart), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
1145
1248
  ...buildSchemaBase(schema, name, nullable, defaultValue)
1146
1249
  });
1147
1250
  }
@@ -1161,20 +1264,34 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1161
1264
  };
1162
1265
  if (schema.properties) {
1163
1266
  const { oneOf: _oneOf, anyOf: _anyOf, ...schemaWithoutUnion } = schema;
1164
- const propertiesNode = convertSchema({ schema: schemaWithoutUnion }, options);
1267
+ const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
1268
+ const memberBaseSchema = discriminator ? Object.fromEntries(Object.entries(schemaWithoutUnion).filter(([key]) => key !== "discriminator")) : schemaWithoutUnion;
1165
1269
  return createSchema({
1166
1270
  type: "union",
1167
1271
  ...unionBase,
1168
- members: unionMembers.map((s) => createSchema({
1169
- type: "intersection",
1170
- members: [convertSchema({ schema: s }, options), propertiesNode]
1171
- }))
1272
+ members: unionMembers.map((s) => {
1273
+ const ref = isReference(s) ? s.$ref : void 0;
1274
+ const discriminatorValue = discriminator?.mapping && ref ? Object.entries(discriminator.mapping).find(([, v]) => v === ref)?.[0] : void 0;
1275
+ let propertiesNode = convertSchema({
1276
+ schema: memberBaseSchema,
1277
+ name
1278
+ }, options);
1279
+ if (discriminatorValue && discriminator) propertiesNode = applyDiscriminatorEnum({
1280
+ node: propertiesNode,
1281
+ propertyName: discriminator.propertyName,
1282
+ values: [discriminatorValue]
1283
+ });
1284
+ return createSchema({
1285
+ type: "intersection",
1286
+ members: [convertSchema({ schema: s }, options), propertiesNode]
1287
+ });
1288
+ })
1172
1289
  });
1173
1290
  }
1174
1291
  return createSchema({
1175
1292
  type: "union",
1176
1293
  ...unionBase,
1177
- members: unionMembers.map((s) => convertSchema({ schema: s }, options))
1294
+ members: simplifyUnionMembers(unionMembers.map((s) => convertSchema({ schema: s }, options)))
1178
1295
  });
1179
1296
  }
1180
1297
  /**
@@ -1259,9 +1376,8 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1259
1376
  */
1260
1377
  function convertEnum({ schema, name, nullable, type, options }) {
1261
1378
  if (type === "array") {
1262
- const rawSchema = schema;
1263
1379
  const normalizedItems = {
1264
- ...typeof rawSchema.items === "object" && !Array.isArray(rawSchema.items) ? rawSchema.items : {},
1380
+ ...typeof schema.items === "object" && !Array.isArray(schema.items) ? schema.items : {},
1265
1381
  enum: schema.enum
1266
1382
  };
1267
1383
  const { enum: _enum, ...schemaWithoutEnum } = schema;
@@ -1341,22 +1457,28 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1341
1457
  * - not required + nullable → `nullish: true`
1342
1458
  */
1343
1459
  function convertObject({ schema, name, nullable, defaultValue, options, mergedOptions }) {
1344
- const resolvedSchema = applyDiscriminatorEnum(schema);
1345
- const properties = resolvedSchema.properties ? Object.entries(resolvedSchema.properties).map(([propName, propSchema]) => {
1346
- const required = Array.isArray(resolvedSchema.required) ? resolvedSchema.required.includes(propName) : !!resolvedSchema.required;
1460
+ const properties = schema.properties ? Object.entries(schema.properties).map(([propName, propSchema]) => {
1461
+ const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
1347
1462
  const resolvedPropSchema = propSchema;
1348
1463
  const propNullable = isNullable(resolvedPropSchema);
1464
+ const basePropName = name ? pascalCase([name, propName].join(" ")) : void 0;
1465
+ const propNode = convertSchema({
1466
+ schema: resolvedPropSchema,
1467
+ name: basePropName
1468
+ }, options);
1469
+ const isEnumNode = !!narrowSchema(propNode, "enum");
1470
+ const derivedPropName = isEnumNode && name ? pascalCase([
1471
+ name,
1472
+ propName,
1473
+ mergedOptions.enumSuffix
1474
+ ].filter(Boolean).join(" ")) : basePropName;
1349
1475
  return createProperty({
1350
1476
  name: propName,
1351
1477
  schema: {
1352
- ...convertSchema({
1353
- schema: resolvedPropSchema,
1354
- name: name ? pascalCase([
1355
- name,
1356
- propName,
1357
- mergedOptions.enumSuffix
1358
- ].filter(Boolean).join(" ")) : void 0
1359
- }, options),
1478
+ ...isEnumNode && derivedPropName !== basePropName ? {
1479
+ ...propNode,
1480
+ name: derivedPropName
1481
+ } : propNode,
1360
1482
  nullable: propNullable || void 0,
1361
1483
  optional: !required && !propNullable ? true : void 0,
1362
1484
  nullish: !required && propNullable ? true : void 0
@@ -1364,15 +1486,15 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1364
1486
  required
1365
1487
  });
1366
1488
  }) : [];
1367
- const additionalProperties = resolvedSchema.additionalProperties;
1489
+ const additionalProperties = schema.additionalProperties;
1368
1490
  let additionalPropertiesNode;
1369
1491
  if (additionalProperties === true) additionalPropertiesNode = true;
1370
1492
  else if (additionalProperties && Object.keys(additionalProperties).length > 0) additionalPropertiesNode = convertSchema({ schema: additionalProperties }, options);
1371
1493
  else if (additionalProperties === false) additionalPropertiesNode = void 0;
1372
1494
  else if (additionalProperties) additionalPropertiesNode = createSchema({ type: resolveTypeOption(mergedOptions.unknownType) });
1373
- const rawPatternProperties = "patternProperties" in resolvedSchema ? resolvedSchema.patternProperties : void 0;
1374
- const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || Object.keys(patternSchema).length === 0 ? createSchema({ type: resolveTypeOption(mergedOptions.unknownType) }) : convertSchema({ schema: patternSchema }, options)])) : void 0;
1375
- return createSchema({
1495
+ const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
1496
+ 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;
1497
+ const objectNode = createSchema({
1376
1498
  type: "object",
1377
1499
  primitive: "object",
1378
1500
  properties,
@@ -1380,6 +1502,20 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1380
1502
  patternProperties,
1381
1503
  ...buildSchemaBase(schema, name, nullable, defaultValue)
1382
1504
  });
1505
+ if (isDiscriminator(schema) && schema.discriminator.mapping) {
1506
+ const discPropName = schema.discriminator.propertyName;
1507
+ return applyDiscriminatorEnum({
1508
+ node: objectNode,
1509
+ propertyName: discPropName,
1510
+ values: Object.keys(schema.discriminator.mapping),
1511
+ enumName: name ? pascalCase([
1512
+ name,
1513
+ discPropName,
1514
+ mergedOptions.enumSuffix
1515
+ ].filter(Boolean).join(" ")) : void 0
1516
+ });
1517
+ }
1518
+ return objectNode;
1383
1519
  }
1384
1520
  /**
1385
1521
  * Converts an OAS 3.1 `prefixItems` tuple into a `TupleSchemaNode`.
@@ -1388,12 +1524,11 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1388
1524
  * after the prefix items is mapped to the rest parameter of the tuple.
1389
1525
  */
1390
1526
  function convertTuple({ schema, name, nullable, defaultValue, options }) {
1391
- const rawSchema = schema;
1392
1527
  return createSchema({
1393
1528
  type: "tuple",
1394
1529
  primitive: "array",
1395
- items: rawSchema.prefixItems.map((item) => convertSchema({ schema: item }, options)),
1396
- rest: rawSchema.items ? convertSchema({ schema: rawSchema.items }, options) : void 0,
1530
+ items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item }, options)),
1531
+ rest: schema.items ? convertSchema({ schema: schema.items }, options) : void 0,
1397
1532
  min: schema.minItems,
1398
1533
  max: schema.maxItems,
1399
1534
  ...buildSchemaBase(schema, name, nullable, defaultValue)
@@ -1406,13 +1541,13 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1406
1541
  * `enumSuffix` is forwarded so generators can emit a named enum declaration.
1407
1542
  */
1408
1543
  function convertArray({ schema, name, nullable, defaultValue, options, mergedOptions }) {
1409
- const rawSchema = schema;
1410
- const itemName = rawSchema.items?.enum?.length && name ? pascalCase([name, mergedOptions.enumSuffix].join(" ")) : void 0;
1544
+ const rawItems = schema.items;
1545
+ const itemName = rawItems?.enum?.length && name ? pascalCase([name, mergedOptions.enumSuffix].join(" ")) : void 0;
1411
1546
  return createSchema({
1412
1547
  type: "array",
1413
1548
  primitive: "array",
1414
- items: rawSchema.items ? [convertSchema({
1415
- schema: rawSchema.items,
1549
+ items: rawItems ? [convertSchema({
1550
+ schema: rawItems,
1416
1551
  name: itemName
1417
1552
  }, options)] : [],
1418
1553
  min: schema.minItems,
@@ -1528,10 +1663,13 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1528
1663
  const arrayNullable = schema.type.includes("null") || nullable || void 0;
1529
1664
  if (nonNullTypes.length > 1) return createSchema({
1530
1665
  type: "union",
1531
- members: nonNullTypes.map((t) => convertSchema({ schema: {
1532
- ...schema,
1533
- type: t
1534
- } }, options)),
1666
+ members: nonNullTypes.map((t) => convertSchema({
1667
+ schema: {
1668
+ ...schema,
1669
+ type: t
1670
+ },
1671
+ name
1672
+ }, options)),
1535
1673
  ...buildSchemaBase(schema, name, arrayNullable, defaultValue)
1536
1674
  });
1537
1675
  }
@@ -1560,12 +1698,16 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1560
1698
  * When the parameter has no `schema` or its schema is a `$ref`, falls back to `unknownType`.
1561
1699
  */
1562
1700
  function parseParameter(options, param) {
1701
+ const required = param["required"] ?? false;
1563
1702
  const schema = param["schema"] && !isReference(param["schema"]) ? convertSchema({ schema: param["schema"] }, options) : createSchema({ type: resolveTypeOption(options.unknownType) });
1564
1703
  return createParameter({
1565
1704
  name: param["name"],
1566
1705
  in: param["in"],
1567
- schema,
1568
- required: param["required"] ?? false
1706
+ schema: {
1707
+ ...schema,
1708
+ optional: !required || !!schema.optional ? true : void 0
1709
+ },
1710
+ required
1569
1711
  });
1570
1712
  }
1571
1713
  /**
@@ -1594,7 +1736,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1594
1736
  return createOperation({
1595
1737
  operationId: operation.getOperationId(),
1596
1738
  method: operation.method.toUpperCase(),
1597
- path: operation.path,
1739
+ path: new URLPath(operation.path).URL,
1598
1740
  tags: operation.getTags().map((tag) => tag.name),
1599
1741
  summary: operation.getSummary() || void 0,
1600
1742
  description: operation.getDescription() || void 0,
@@ -1651,31 +1793,11 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1651
1793
  }
1652
1794
  } });
1653
1795
  }
1654
- /**
1655
- * Collects all `KubbFile.Import` descriptors needed by a `SchemaNode` tree.
1656
- *
1657
- * Walks the tree looking for `ref` nodes, verifies each `$ref` is resolvable in the spec,
1658
- * applies collision-resolved names from `nameMapping`, and calls `resolve` to obtain the
1659
- * import path and name. Returns an empty array for refs that cannot be resolved.
1660
- */
1661
- function getImports(node, resolve) {
1662
- return collect(node, { schema(schemaNode) {
1663
- if (schemaNode.type !== "ref" || !schemaNode.ref) return;
1664
- if (!oas.get(schemaNode.ref)) return;
1665
- const rawName = extractRefName(schemaNode.ref);
1666
- const result = resolve(nameMapping.get(rawName) ?? rawName);
1667
- if (!result) return;
1668
- return {
1669
- name: [result.name],
1670
- path: result.path
1671
- };
1672
- } });
1673
- }
1674
1796
  return {
1675
1797
  parse,
1676
1798
  convertSchema,
1677
1799
  resolveRefs,
1678
- getImports
1800
+ nameMapping
1679
1801
  };
1680
1802
  }
1681
1803
  //#endregion
@@ -1701,6 +1823,7 @@ const adapterOasName = "oas";
1701
1823
  */
1702
1824
  const adapterOas = defineAdapter((options) => {
1703
1825
  const { validate = true, oasClass, contentType, serverIndex, serverVariables, discriminator = "strict", collisionDetection = false, dateType = "string", integerType = "number", unknownType = "any", emptySchemaType = unknownType } = options;
1826
+ const nameMapping = /* @__PURE__ */ new Map();
1704
1827
  return {
1705
1828
  name: "oas",
1706
1829
  options: {
@@ -1714,7 +1837,15 @@ const adapterOas = defineAdapter((options) => {
1714
1837
  dateType,
1715
1838
  integerType,
1716
1839
  unknownType,
1717
- emptySchemaType
1840
+ emptySchemaType,
1841
+ nameMapping
1842
+ },
1843
+ getImports(node, resolve) {
1844
+ return getImports({
1845
+ node,
1846
+ nameMapping,
1847
+ resolve
1848
+ });
1718
1849
  },
1719
1850
  async parse(source) {
1720
1851
  const oas = await parseFromConfig(sourceToFakeConfig(source), oasClass);
@@ -1728,11 +1859,14 @@ const adapterOas = defineAdapter((options) => {
1728
1859
  } catch (_err) {}
1729
1860
  const server = serverIndex !== void 0 ? oas.api.servers?.at(serverIndex) : void 0;
1730
1861
  const baseURL = server?.url ? resolveServerUrl(server, serverVariables) : void 0;
1862
+ const parser = createOasParser(oas, {
1863
+ contentType,
1864
+ collisionDetection
1865
+ });
1866
+ nameMapping.clear();
1867
+ for (const [key, value] of parser.nameMapping) nameMapping.set(key, value);
1731
1868
  return createRoot({
1732
- ...createOasParser(oas, {
1733
- contentType,
1734
- collisionDetection
1735
- }).parse({
1869
+ ...parser.parse({
1736
1870
  dateType,
1737
1871
  integerType,
1738
1872
  unknownType,