@kubb/adapter-oas 5.0.0-beta.64 → 5.0.0-beta.65

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
@@ -1133,7 +1133,7 @@ type SchemaObject$1 = {
1133
1133
  * Allowed values for this schema.
1134
1134
  */
1135
1135
  enum?: Array<string | number | boolean | null>;
1136
- } & (OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject | JSONSchema4 | JSONSchema6 | JSONSchema7);
1136
+ } & (OpenAPIV3_1.SchemaObject | JSONSchema4 | JSONSchema6 | JSONSchema7);
1137
1137
  /**
1138
1138
  * HTTP method in the lowercase form an OpenAPI path item uses for its keys.
1139
1139
  */
@@ -1141,27 +1141,27 @@ type HttpMethod = Lowercase<ast.HttpMethod>;
1141
1141
  /**
1142
1142
  * Normalized OpenAPI document after parsing.
1143
1143
  */
1144
- type Document = (OpenAPIV3.Document | OpenAPIV3_1.Document) & Record<string, unknown>;
1144
+ type Document = OpenAPIV3_1.Document & Record<string, unknown>;
1145
1145
  /**
1146
1146
  * Single operation object (the `get`/`post`/… entry on a path item) plus any vendor extensions.
1147
1147
  */
1148
- type OperationObject$1 = (OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject) & Record<string, unknown>;
1148
+ type OperationObject$1 = OpenAPIV3_1.OperationObject & Record<string, unknown>;
1149
1149
  /**
1150
1150
  * Discriminator object for `oneOf`/`anyOf` schemas in OpenAPI.
1151
1151
  */
1152
- type DiscriminatorObject$1 = OpenAPIV3.DiscriminatorObject | OpenAPIV3_1.DiscriminatorObject;
1152
+ type DiscriminatorObject$1 = OpenAPIV3_1.DiscriminatorObject;
1153
1153
  /**
1154
1154
  * OpenAPI reference object pointing to a schema definition via `$ref`.
1155
1155
  */
1156
- type ReferenceObject$1 = OpenAPIV3.ReferenceObject;
1156
+ type ReferenceObject$1 = OpenAPIV3_1.ReferenceObject;
1157
1157
  /**
1158
1158
  * OpenAPI response object holding the content and headers for one status code.
1159
1159
  */
1160
- type ResponseObject$1 = OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject;
1160
+ type ResponseObject$1 = OpenAPIV3_1.ResponseObject;
1161
1161
  /**
1162
1162
  * OpenAPI media type object that maps a content-type string to its schema.
1163
1163
  */
1164
- type MediaTypeObject$1 = OpenAPIV3.MediaTypeObject | OpenAPIV3_1.MediaTypeObject;
1164
+ type MediaTypeObject$1 = OpenAPIV3_1.MediaTypeObject;
1165
1165
  /**
1166
1166
  * Configuration for the OpenAPI adapter: spec validation, content-type selection,
1167
1167
  * server URL resolution, and how schema types are derived.
package/dist/index.js CHANGED
@@ -53,18 +53,6 @@ const SUPPORTED_METHODS = new Set([
53
53
  "trace"
54
54
  ]);
55
55
  /**
56
- * OpenAPI version string written into the stub document created during multi-spec merges.
57
- */
58
- const MERGE_OPENAPI_VERSION = "3.0.0";
59
- /**
60
- * Fallback `info.title` placed in the stub document when merging multiple API files.
61
- */
62
- const MERGE_DEFAULT_TITLE = "Merged API";
63
- /**
64
- * Fallback `info.version` placed in the stub document when merging multiple API files.
65
- */
66
- const MERGE_DEFAULT_VERSION = "1.0.0";
67
- /**
68
56
  * Set of JSON Schema keywords that prevent a schema fragment from being inlined during `allOf` flattening.
69
57
  *
70
58
  * A fragment that contains any of these keys carries structural meaning of its own and must stay as a separate
@@ -144,15 +132,6 @@ const formatMap = {
144
132
  * ```
145
133
  */
146
134
  const enumExtensionKeys = ["x-enumNames", "x-enum-varnames"];
147
- /**
148
- * Maps the `unknownType`/`emptySchemaType` option string to its `ScalarSchemaType` constant.
149
- * A `Map` (over a plain object) lets callers test key membership with `.has()`.
150
- */
151
- const typeOptionMap = new Map([
152
- ["any", ast.schemaTypes.any],
153
- ["unknown", ast.schemaTypes.unknown],
154
- ["void", ast.schemaTypes.void]
155
- ]);
156
135
  //#endregion
157
136
  //#region ../../internals/utils/src/casing.ts
158
137
  /**
@@ -293,27 +272,6 @@ async function read(path) {
293
272
  return readFile(path, { encoding: "utf8" });
294
273
  }
295
274
  //#endregion
296
- //#region ../../internals/utils/src/object.ts
297
- /**
298
- * Recursively merges `source` into `target`, combining nested plain objects.
299
- * Arrays and non-object values from `source` override the corresponding values in `target`.
300
- *
301
- * @example
302
- * ```ts
303
- * mergeDeep({ a: { x: 1 } }, { a: { y: 2 } })
304
- * // { a: { x: 1, y: 2 } }
305
- * ```
306
- */
307
- function mergeDeep(target, source) {
308
- const result = { ...target };
309
- for (const key of Object.keys(source)) {
310
- const sv = source[key];
311
- const tv = result[key];
312
- result[key] = sv !== null && typeof sv === "object" && !Array.isArray(sv) && tv !== null && typeof tv === "object" && !Array.isArray(tv) ? mergeDeep(tv, sv) : sv;
313
- }
314
- return result;
315
- }
316
- //#endregion
317
275
  //#region ../../internals/utils/src/reserved.ts
318
276
  /**
319
277
  * JavaScript and Java reserved words.
@@ -565,58 +523,25 @@ async function bundleDocument(pathOrUrl) {
565
523
  /**
566
524
  * Loads and bundles an OpenAPI document, returning the raw `Document`.
567
525
  *
568
- * Accepts a file path string or an already-parsed document object. File paths and URLs are
569
- * bundled via `api-ref-bundler`, hoisting external file schemas into named `components.schemas`
570
- * entries so generators can emit named types and imports. Swagger 2.0 documents are
571
- * automatically up-converted to OpenAPI 3.0 via `@scalar/openapi-upgrader`.
526
+ * A string is a file path or URL: it is bundled via `api-ref-bundler`, hoisting external file
527
+ * schemas into named `components.schemas` entries so generators can emit named types and imports.
528
+ * An object is treated as an already-parsed document. Swagger 2.0 and OpenAPI 3.0 documents are
529
+ * up-converted to OpenAPI 3.1 via `@scalar/openapi-upgrader`.
572
530
  *
573
531
  * @example
574
532
  * ```ts
575
533
  * const document = await parseDocument('./openapi.yaml')
576
- * const document = await parse(rawDocumentObject, { canBundle: false })
577
- * ```
578
- */
579
- async function parseDocument(pathOrApi, { canBundle = true } = {}) {
580
- if (typeof pathOrApi === "string" && canBundle) return parseDocument(await bundleDocument(pathOrApi), { canBundle: false });
581
- return upgrade(typeof pathOrApi === "string" ? parse(pathOrApi) : pathOrApi, "3.0");
582
- }
583
- /**
584
- * Deep-merges multiple OpenAPI documents into a single `Document`.
585
- *
586
- * Each document is parsed independently, then deep-merged into one in array order.
587
- * Throws when the input array is empty.
588
- *
589
- * @example
590
- * ```ts
591
- * const document = await mergeDocuments(['./pets.yaml', './orders.yaml'])
534
+ * const document = await parseDocument(rawDocumentObject)
592
535
  * ```
593
536
  */
594
- async function mergeDocuments(pathOrApi) {
595
- const documents = await Promise.all(pathOrApi.map((p) => parseDocument(p, { canBundle: false })));
596
- if (documents.length === 0) throw new Diagnostics.Error({
597
- code: Diagnostics.code.inputRequired,
598
- severity: "error",
599
- message: "No OAS documents were provided for merging.",
600
- help: "Pass at least one path or document to `input.path`.",
601
- location: { kind: "config" }
602
- });
603
- const seed = {
604
- openapi: MERGE_OPENAPI_VERSION,
605
- info: {
606
- title: MERGE_DEFAULT_TITLE,
607
- version: MERGE_DEFAULT_VERSION
608
- },
609
- paths: {},
610
- components: { schemas: {} }
611
- };
612
- return parseDocument(documents.reduce((acc, current) => mergeDeep(acc, current), seed));
537
+ async function parseDocument(pathOrApi) {
538
+ if (typeof pathOrApi === "string") return parseDocument(await bundleDocument(pathOrApi));
539
+ return upgrade(pathOrApi, "3.1");
613
540
  }
614
541
  /**
615
542
  * Creates a `Document` from an `AdapterSource`.
616
543
  *
617
- * Handles all three source types:
618
544
  * - `{ type: 'path' }` resolves and bundles a local file path or remote URL.
619
- * - `{ type: 'paths' }` merges multiple file paths into a single document.
620
545
  * - `{ type: 'data' }` parses an inline string (YAML/JSON) or raw object.
621
546
  *
622
547
  * @example
@@ -626,11 +551,7 @@ async function mergeDocuments(pathOrApi) {
626
551
  * ```
627
552
  */
628
553
  async function parseFromConfig(source) {
629
- if (source.type === "data") {
630
- if (typeof source.data === "object") return parseDocument(structuredClone(source.data));
631
- return parseDocument(source.data, { canBundle: false });
632
- }
633
- if (source.type === "paths") return mergeDocuments(source.paths);
554
+ if (source.type === "data") return parseDocument(typeof source.data === "string" ? parse(source.data) : structuredClone(source.data));
634
555
  if (Url.canParse(source.path)) return parseDocument(source.path);
635
556
  const resolved = path.resolve(path.dirname(source.path), source.path);
636
557
  await assertInputExists(resolved);
@@ -689,7 +610,7 @@ function createRefNode(node, target) {
689
610
  deprecated: node.deprecated,
690
611
  description: node.description,
691
612
  default: node.default,
692
- example: node.example
613
+ examples: node.examples
693
614
  });
694
615
  }
695
616
  /**
@@ -1358,14 +1279,16 @@ function getResponseBody(responseBody, contentType) {
1358
1279
  * getResponseSchema(document, operation, '4XX') // {}
1359
1280
  * ```
1360
1281
  */
1361
- function getResponseSchema(document, operation, statusCode, options = {}) {
1362
- if (operation.schema.responses) {
1363
- const responses = operation.schema.responses;
1364
- for (const key in responses) {
1365
- const schema = responses[key];
1366
- if (schema && isReference(schema)) responses[key] = resolveRef(document, schema.$ref);
1367
- }
1282
+ function resolveResponseRefs(document, operation) {
1283
+ const responses = operation.schema.responses;
1284
+ if (!responses) return;
1285
+ for (const key in responses) {
1286
+ const schema = responses[key];
1287
+ if (schema && isReference(schema)) responses[key] = resolveRef(document, schema.$ref);
1368
1288
  }
1289
+ }
1290
+ function getResponseSchema(document, operation, statusCode, options = {}) {
1291
+ resolveResponseRefs(document, operation);
1369
1292
  const responseBody = getResponseBody(getResponseByStatusCode({
1370
1293
  document,
1371
1294
  operation,
@@ -1509,9 +1432,6 @@ const semanticSuffixes = {
1509
1432
  responses: "Response",
1510
1433
  requestBodies: "Request"
1511
1434
  };
1512
- function getSemanticSuffix(source) {
1513
- return semanticSuffixes[source];
1514
- }
1515
1435
  function resolveSchemaRef(document, schema) {
1516
1436
  if (!isReference(schema)) return schema;
1517
1437
  const resolved = resolveRef(document, schema.$ref);
@@ -1566,7 +1486,7 @@ function getSchemas(document, { contentType }) {
1566
1486
  }
1567
1487
  }
1568
1488
  items.forEach((item, index) => {
1569
- const suffix = isSingle ? "" : hasMultipleSources ? getSemanticSuffix(item.source) : index === 0 ? "" : String(index + 1);
1489
+ const suffix = isSingle ? "" : hasMultipleSources ? semanticSuffixes[item.source] : index === 0 ? "" : String(index + 1);
1570
1490
  const uniqueName = item.originalName + suffix;
1571
1491
  schemas[uniqueName] = item.schema;
1572
1492
  nameMapping.set(`#/components/${item.source}/${item.originalName}`, uniqueName);
@@ -1613,6 +1533,15 @@ function getDateType(options, format) {
1613
1533
  /**
1614
1534
  * Collects the shared metadata fields passed to every `createSchema` call.
1615
1535
  */
1536
+ /**
1537
+ * Reads schema examples as an array. OAS 3.1 uses an `examples` array, but specs (including ones
1538
+ * labeled 3.1) still use the singular OAS 3.0 `example`, which the upgrader only converts on the
1539
+ * 3.0 -> 3.1 hop. Normalize both into one array so the AST node exposes only `examples`.
1540
+ */
1541
+ function extractExamples(schema) {
1542
+ if (Array.isArray(schema.examples)) return schema.examples;
1543
+ return schema.example !== void 0 ? [schema.example] : void 0;
1544
+ }
1616
1545
  function buildSchemaNode(schema, name, nullable, defaultValue) {
1617
1546
  return {
1618
1547
  name,
@@ -1623,7 +1552,7 @@ function buildSchemaNode(schema, name, nullable, defaultValue) {
1623
1552
  readOnly: schema.readOnly,
1624
1553
  writeOnly: schema.writeOnly,
1625
1554
  default: defaultValue,
1626
- example: schema.example,
1555
+ examples: extractExamples(schema),
1627
1556
  format: schema.format
1628
1557
  };
1629
1558
  }
@@ -1659,13 +1588,7 @@ function getRequestBodyContentTypes(document, operation) {
1659
1588
  * ```
1660
1589
  */
1661
1590
  function getResponseBodyContentTypes(document, operation, statusCode) {
1662
- if (operation.schema.responses) {
1663
- const responses = operation.schema.responses;
1664
- for (const key in responses) {
1665
- const schema = responses[key];
1666
- if (schema && isReference(schema)) responses[key] = resolveRef(document, schema.$ref);
1667
- }
1668
- }
1591
+ resolveResponseRefs(document, operation);
1669
1592
  const responseObj = getResponseByStatusCode({
1670
1593
  document,
1671
1594
  operation,
@@ -1809,7 +1732,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
1809
1732
  readOnly: schema.readOnly ?? memberNode.readOnly,
1810
1733
  writeOnly: schema.writeOnly ?? memberNode.writeOnly,
1811
1734
  default: mergedDefault,
1812
- example: schema.example ?? memberNode.example,
1735
+ examples: extractExamples(schema) ?? memberNode.examples,
1813
1736
  pattern: schema.pattern ?? ("pattern" in memberNode ? memberNode.pattern : void 0),
1814
1737
  format: schema.format ?? memberNode.format
1815
1738
  });
@@ -2053,7 +1976,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2053
1976
  readOnly: schema.readOnly,
2054
1977
  writeOnly: schema.writeOnly,
2055
1978
  default: enumDefault,
2056
- example: schema.example,
1979
+ examples: extractExamples(schema),
2057
1980
  format: schema.format
2058
1981
  };
2059
1982
  const extensionKey = enumExtensionKeys.find((key) => key in schema);
@@ -2111,10 +2034,10 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2111
2034
  if (additionalProperties === true) return true;
2112
2035
  if (additionalProperties === false) return false;
2113
2036
  if (additionalProperties && Object.keys(additionalProperties).length > 0) return parseSchema({ schema: additionalProperties }, rawOptions);
2114
- if (additionalProperties) return ast.factory.createSchema({ type: typeOptionMap.get(options.unknownType) });
2037
+ if (additionalProperties) return ast.factory.createSchema({ type: options.unknownType });
2115
2038
  })();
2116
2039
  const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
2117
- 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: typeOptionMap.get(options.unknownType) }) : parseSchema({ schema: patternSchema }, rawOptions)])) : void 0;
2040
+ 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;
2118
2041
  const objectNode = ast.factory.createSchema({
2119
2042
  type: "object",
2120
2043
  primitive: "object",
@@ -2390,7 +2313,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2390
2313
  const node = rule.convert(schemaCtx);
2391
2314
  if (node) return node;
2392
2315
  }
2393
- const emptyType = typeOptionMap.get(options.emptySchemaType);
2316
+ const emptyType = options.emptySchemaType;
2394
2317
  return ast.factory.createSchema({
2395
2318
  type: emptyType,
2396
2319
  name,
@@ -2409,7 +2332,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2409
2332
  const schema = param["schema"] ? parseSchema({
2410
2333
  schema: param["schema"],
2411
2334
  name: schemaName
2412
- }, options) : ast.factory.createSchema({ type: typeOptionMap.get(options.unknownType) });
2335
+ }, options) : ast.factory.createSchema({ type: options.unknownType });
2413
2336
  return ast.factory.createParameter({
2414
2337
  name: paramName,
2415
2338
  in: param["in"],
@@ -2497,7 +2420,7 @@ function createSchemaParser(ctx, dialect = oasDialect) {
2497
2420
  schema: raw && Object.keys(raw).length > 0 ? parseSchema({
2498
2421
  schema: raw,
2499
2422
  name: responseName
2500
- }, options) : ast.factory.createSchema({ type: typeOptionMap.get(options.emptySchemaType) }),
2423
+ }, options) : ast.factory.createSchema({ type: options.emptySchemaType }),
2501
2424
  keysToOmit: collectPropertyKeysByFlag(raw, "writeOnly")
2502
2425
  };
2503
2426
  };