@kubb/adapter-oas 5.0.0-alpha.12 → 5.0.0-alpha.13

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
@@ -1253,6 +1253,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1253
1253
  pattern: schema.pattern ?? ("pattern" in memberNode ? memberNode.pattern : void 0)
1254
1254
  });
1255
1255
  }
1256
+ const filteredDiscriminantValues = [];
1256
1257
  const allOfMembers = schema.allOf.filter((item) => {
1257
1258
  if (!isReference(item) || !name) return true;
1258
1259
  const deref = oas.get(item.$ref);
@@ -1262,7 +1263,15 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1262
1263
  const childRef = `#/components/schemas/${name}`;
1263
1264
  const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef);
1264
1265
  const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
1265
- return !inOneOf && !inMapping;
1266
+ if (inOneOf || inMapping) {
1267
+ const discriminatorValue = Object.entries(deref.discriminator.mapping ?? {}).find(([, v]) => v === childRef)?.[0];
1268
+ if (discriminatorValue) filteredDiscriminantValues.push({
1269
+ propertyName: deref.discriminator.propertyName,
1270
+ value: discriminatorValue
1271
+ });
1272
+ return false;
1273
+ }
1274
+ return true;
1266
1275
  }).map((s) => convertSchema({ schema: s }, options));
1267
1276
  const syntheticStart = allOfMembers.length;
1268
1277
  if (Array.isArray(schema.required) && schema.required.length) {
@@ -1287,9 +1296,22 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1287
1296
  const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
1288
1297
  allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf }, options));
1289
1298
  }
1299
+ for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push(createSchema({
1300
+ type: "object",
1301
+ primitive: "object",
1302
+ properties: [createProperty({
1303
+ name: propertyName,
1304
+ schema: createSchema({
1305
+ type: "enum",
1306
+ primitive: "string",
1307
+ enumValues: [value]
1308
+ }),
1309
+ required: true
1310
+ })]
1311
+ }));
1290
1312
  return createSchema({
1291
1313
  type: "intersection",
1292
- members: [...allOfMembers.slice(0, syntheticStart), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
1314
+ members: [...mergeAdjacentAnonymousObjects(allOfMembers.slice(0, syntheticStart)), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
1293
1315
  ...renderSchemaBase(schema, name, nullable, defaultValue)
1294
1316
  });
1295
1317
  }
@@ -1333,6 +1355,33 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1333
1355
  })
1334
1356
  });
1335
1357
  }
1358
+ const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
1359
+ if (discriminator?.mapping) return createSchema({
1360
+ type: "union",
1361
+ ...unionBase,
1362
+ members: unionMembers.map((s) => {
1363
+ const ref = isReference(s) ? s.$ref : void 0;
1364
+ const discriminatorValue = ref ? Object.entries(discriminator.mapping).find(([, v]) => v === ref)?.[0] : void 0;
1365
+ const memberNode = convertSchema({ schema: s }, options);
1366
+ if (!discriminatorValue) return memberNode;
1367
+ return createSchema({
1368
+ type: "intersection",
1369
+ members: [memberNode, createSchema({
1370
+ type: "object",
1371
+ primitive: "object",
1372
+ properties: [createProperty({
1373
+ name: discriminator.propertyName,
1374
+ schema: createSchema({
1375
+ type: "enum",
1376
+ primitive: "string",
1377
+ enumValues: [discriminatorValue]
1378
+ }),
1379
+ required: true
1380
+ })]
1381
+ })]
1382
+ });
1383
+ })
1384
+ });
1336
1385
  return createSchema({
1337
1386
  type: "union",
1338
1387
  ...unionBase,
@@ -1352,8 +1401,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1352
1401
  name,
1353
1402
  title: schema.title,
1354
1403
  description: schema.description,
1355
- deprecated: schema.deprecated,
1356
- nullable
1404
+ deprecated: schema.deprecated
1357
1405
  });
1358
1406
  return createSchema({
1359
1407
  type: "enum",
@@ -1555,14 +1603,23 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1555
1603
  const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
1556
1604
  const resolvedPropSchema = propSchema;
1557
1605
  const propNullable = isNullable(resolvedPropSchema);
1606
+ let schemaNode = applyEnumName(convertSchema({
1607
+ schema: resolvedPropSchema,
1608
+ name: resolveChildName(name, propName)
1609
+ }, options), name, propName, mergedOptions.enumSuffix);
1610
+ const tupleNode = narrowSchema(schemaNode, "tuple");
1611
+ if (tupleNode?.items) {
1612
+ const namedItems = tupleNode.items.map((item) => applyEnumName(item, name, propName, mergedOptions.enumSuffix));
1613
+ if (namedItems.some((item, i) => item !== tupleNode.items[i])) schemaNode = {
1614
+ ...tupleNode,
1615
+ items: namedItems
1616
+ };
1617
+ }
1558
1618
  return createProperty({
1559
1619
  name: propName,
1560
1620
  schema: {
1561
- ...applyEnumName(convertSchema({
1562
- schema: resolvedPropSchema,
1563
- name: resolveChildName(name, propName)
1564
- }, options), name, propName, mergedOptions.enumSuffix),
1565
- nullable: propNullable || void 0,
1621
+ ...schemaNode,
1622
+ nullable: schemaNode.type === "null" ? void 0 : propNullable || void 0,
1566
1623
  optional: !required && !propNullable ? true : void 0,
1567
1624
  nullish: !required && propNullable ? true : void 0
1568
1625
  },
@@ -1599,15 +1656,17 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1599
1656
  /**
1600
1657
  * Converts an OAS 3.1 `prefixItems` tuple into a `TupleSchemaNode`.
1601
1658
  *
1602
- * Each `prefixItems` element maps to a positional tuple slot. An optional `items` schema
1603
- * after the prefix items is mapped to the rest parameter of the tuple.
1659
+ * Each `prefixItems` element maps to a positional tuple slot. When an explicit `items` schema
1660
+ * is present alongside `prefixItems`, it becomes the rest element. When `items` is absent,
1661
+ * a rest element of type `any` is emitted to match JSON Schema semantics (absent `items`
1662
+ * means additional items are allowed).
1604
1663
  */
1605
1664
  function convertTuple({ schema, name, nullable, defaultValue, options }) {
1606
1665
  return createSchema({
1607
1666
  type: "tuple",
1608
1667
  primitive: "array",
1609
1668
  items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item }, options)),
1610
- rest: schema.items ? convertSchema({ schema: schema.items }, options) : void 0,
1669
+ rest: schema.items ? convertSchema({ schema: schema.items }, options) : createSchema({ type: "any" }),
1611
1670
  min: schema.minItems,
1612
1671
  max: schema.maxItems,
1613
1672
  ...renderSchemaBase(schema, name, nullable, defaultValue)
@@ -1774,11 +1833,11 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1774
1833
  }
1775
1834
  /**
1776
1835
  * Converts a single dereferenced OAS parameter object into a `ParameterNode`.
1777
- * When the parameter has no `schema` or its schema is a `$ref`, falls back to `unknownType`.
1836
+ * When the parameter has no `schema`, falls back to `unknownType`; `$ref` schemas are resolved through `convertSchema` to produce a proper named type reference.
1778
1837
  */
1779
1838
  function parseParameter(options, param) {
1780
1839
  const required = param["required"] ?? false;
1781
- const schema = param["schema"] && !isReference(param["schema"]) ? convertSchema({ schema: param["schema"] }, options) : createSchema({ type: resolveTypeOption(options.unknownType) });
1840
+ const schema = param["schema"] ? convertSchema({ schema: param["schema"] }, options) : createSchema({ type: resolveTypeOption(options.unknownType) });
1782
1841
  return createParameter({
1783
1842
  name: param["name"],
1784
1843
  in: param["in"],
@@ -1798,8 +1857,10 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
1798
1857
  const parameters = oas.getParameters(operation).map((param) => parseParameter(options, param));
1799
1858
  const requestBodySchema = oas.getRequestSchema(operation);
1800
1859
  const requestBodySchemaNode = requestBodySchema ? convertSchema({ schema: requestBodySchema }, options) : void 0;
1860
+ const requestBodyDescription = operation.schema.requestBody && !isReference(operation.schema.requestBody) ? operation.schema.requestBody.description : void 0;
1801
1861
  const requestBodyKeysToOmit = requestBodySchema?.properties ? Object.entries(requestBodySchema.properties).filter(([, prop]) => !isReference(prop) && prop.readOnly).map(([key]) => key) : void 0;
1802
1862
  const requestBody = requestBodySchemaNode ? {
1863
+ description: requestBodyDescription,
1803
1864
  schema: requestBodySchemaNode,
1804
1865
  keysToOmit: requestBodyKeysToOmit?.length ? requestBodyKeysToOmit : void 0
1805
1866
  } : void 0;
@@ -1950,16 +2011,17 @@ const adapterOas = createAdapter((options) => {
1950
2011
  contentType,
1951
2012
  collisionDetection
1952
2013
  });
2014
+ const root = parser.parse({
2015
+ dateType,
2016
+ integerType,
2017
+ unknownType,
2018
+ emptySchemaType,
2019
+ enumSuffix
2020
+ });
1953
2021
  nameMapping.clear();
1954
2022
  for (const [key, value] of parser.nameMapping) nameMapping.set(key, value);
1955
2023
  return createRoot({
1956
- ...parser.parse({
1957
- dateType,
1958
- integerType,
1959
- unknownType,
1960
- emptySchemaType,
1961
- enumSuffix
1962
- }),
2024
+ ...root,
1963
2025
  meta: {
1964
2026
  title: oas.api.info?.title,
1965
2027
  description: oas.api.info?.description,