@kubb/adapter-oas 5.0.0-alpha.12 → 5.0.0-alpha.14
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.cjs +90 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +90 -30
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter.ts +2 -3
- package/src/oas/utils.ts +7 -8
- package/src/parser.ts +100 -18
package/dist/index.js
CHANGED
|
@@ -886,12 +886,13 @@ function extractSchemaFromContent(content, preferredContentType) {
|
|
|
886
886
|
* Returns the PascalCase suffix appended to a component name when resolving
|
|
887
887
|
* cross-source name collisions (schemas vs. responses vs. requestBodies).
|
|
888
888
|
*/
|
|
889
|
+
const semanticSuffixes = {
|
|
890
|
+
schemas: "Schema",
|
|
891
|
+
responses: "Response",
|
|
892
|
+
requestBodies: "Request"
|
|
893
|
+
};
|
|
889
894
|
function getSemanticSuffix(source) {
|
|
890
|
-
|
|
891
|
-
case "schemas": return "Schema";
|
|
892
|
-
case "responses": return "Response";
|
|
893
|
-
case "requestBodies": return "Request";
|
|
894
|
-
}
|
|
895
|
+
return semanticSuffixes[source];
|
|
895
896
|
}
|
|
896
897
|
/**
|
|
897
898
|
* Builds `GetSchemasResult` without any collision detection.
|
|
@@ -1253,6 +1254,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1253
1254
|
pattern: schema.pattern ?? ("pattern" in memberNode ? memberNode.pattern : void 0)
|
|
1254
1255
|
});
|
|
1255
1256
|
}
|
|
1257
|
+
const filteredDiscriminantValues = [];
|
|
1256
1258
|
const allOfMembers = schema.allOf.filter((item) => {
|
|
1257
1259
|
if (!isReference(item) || !name) return true;
|
|
1258
1260
|
const deref = oas.get(item.$ref);
|
|
@@ -1262,7 +1264,15 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1262
1264
|
const childRef = `#/components/schemas/${name}`;
|
|
1263
1265
|
const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef);
|
|
1264
1266
|
const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
|
|
1265
|
-
|
|
1267
|
+
if (inOneOf || inMapping) {
|
|
1268
|
+
const discriminatorValue = Object.entries(deref.discriminator.mapping ?? {}).find(([, v]) => v === childRef)?.[0];
|
|
1269
|
+
if (discriminatorValue) filteredDiscriminantValues.push({
|
|
1270
|
+
propertyName: deref.discriminator.propertyName,
|
|
1271
|
+
value: discriminatorValue
|
|
1272
|
+
});
|
|
1273
|
+
return false;
|
|
1274
|
+
}
|
|
1275
|
+
return true;
|
|
1266
1276
|
}).map((s) => convertSchema({ schema: s }, options));
|
|
1267
1277
|
const syntheticStart = allOfMembers.length;
|
|
1268
1278
|
if (Array.isArray(schema.required) && schema.required.length) {
|
|
@@ -1287,9 +1297,22 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1287
1297
|
const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
|
|
1288
1298
|
allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf }, options));
|
|
1289
1299
|
}
|
|
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
|
+
}));
|
|
1290
1313
|
return createSchema({
|
|
1291
1314
|
type: "intersection",
|
|
1292
|
-
members: [...allOfMembers.slice(0, syntheticStart), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
|
|
1315
|
+
members: [...mergeAdjacentAnonymousObjects(allOfMembers.slice(0, syntheticStart)), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
|
|
1293
1316
|
...renderSchemaBase(schema, name, nullable, defaultValue)
|
|
1294
1317
|
});
|
|
1295
1318
|
}
|
|
@@ -1333,6 +1356,33 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1333
1356
|
})
|
|
1334
1357
|
});
|
|
1335
1358
|
}
|
|
1359
|
+
const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
|
|
1360
|
+
if (discriminator?.mapping) return createSchema({
|
|
1361
|
+
type: "union",
|
|
1362
|
+
...unionBase,
|
|
1363
|
+
members: unionMembers.map((s) => {
|
|
1364
|
+
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;
|
|
1368
|
+
return createSchema({
|
|
1369
|
+
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
|
+
})]
|
|
1383
|
+
});
|
|
1384
|
+
})
|
|
1385
|
+
});
|
|
1336
1386
|
return createSchema({
|
|
1337
1387
|
type: "union",
|
|
1338
1388
|
...unionBase,
|
|
@@ -1352,8 +1402,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1352
1402
|
name,
|
|
1353
1403
|
title: schema.title,
|
|
1354
1404
|
description: schema.description,
|
|
1355
|
-
deprecated: schema.deprecated
|
|
1356
|
-
nullable
|
|
1405
|
+
deprecated: schema.deprecated
|
|
1357
1406
|
});
|
|
1358
1407
|
return createSchema({
|
|
1359
1408
|
type: "enum",
|
|
@@ -1555,16 +1604,23 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1555
1604
|
const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
|
|
1556
1605
|
const resolvedPropSchema = propSchema;
|
|
1557
1606
|
const propNullable = isNullable(resolvedPropSchema);
|
|
1607
|
+
let schemaNode = applyEnumName(convertSchema({
|
|
1608
|
+
schema: resolvedPropSchema,
|
|
1609
|
+
name: resolveChildName(name, propName)
|
|
1610
|
+
}, options), name, propName, mergedOptions.enumSuffix);
|
|
1611
|
+
const tupleNode = narrowSchema(schemaNode, "tuple");
|
|
1612
|
+
if (tupleNode?.items) {
|
|
1613
|
+
const namedItems = tupleNode.items.map((item) => applyEnumName(item, name, propName, mergedOptions.enumSuffix));
|
|
1614
|
+
if (namedItems.some((item, i) => item !== tupleNode.items[i])) schemaNode = {
|
|
1615
|
+
...tupleNode,
|
|
1616
|
+
items: namedItems
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1558
1619
|
return createProperty({
|
|
1559
1620
|
name: propName,
|
|
1560
1621
|
schema: {
|
|
1561
|
-
...
|
|
1562
|
-
|
|
1563
|
-
name: resolveChildName(name, propName)
|
|
1564
|
-
}, options), name, propName, mergedOptions.enumSuffix),
|
|
1565
|
-
nullable: propNullable || void 0,
|
|
1566
|
-
optional: !required && !propNullable ? true : void 0,
|
|
1567
|
-
nullish: !required && propNullable ? true : void 0
|
|
1622
|
+
...schemaNode,
|
|
1623
|
+
nullable: schemaNode.type === "null" ? void 0 : propNullable || void 0
|
|
1568
1624
|
},
|
|
1569
1625
|
required
|
|
1570
1626
|
});
|
|
@@ -1599,15 +1655,17 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1599
1655
|
/**
|
|
1600
1656
|
* Converts an OAS 3.1 `prefixItems` tuple into a `TupleSchemaNode`.
|
|
1601
1657
|
*
|
|
1602
|
-
* Each `prefixItems` element maps to a positional tuple slot.
|
|
1603
|
-
*
|
|
1658
|
+
* Each `prefixItems` element maps to a positional tuple slot. When an explicit `items` schema
|
|
1659
|
+
* is present alongside `prefixItems`, it becomes the rest element. When `items` is absent,
|
|
1660
|
+
* a rest element of type `any` is emitted to match JSON Schema semantics (absent `items`
|
|
1661
|
+
* means additional items are allowed).
|
|
1604
1662
|
*/
|
|
1605
1663
|
function convertTuple({ schema, name, nullable, defaultValue, options }) {
|
|
1606
1664
|
return createSchema({
|
|
1607
1665
|
type: "tuple",
|
|
1608
1666
|
primitive: "array",
|
|
1609
1667
|
items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item }, options)),
|
|
1610
|
-
rest: schema.items ? convertSchema({ schema: schema.items }, options) :
|
|
1668
|
+
rest: schema.items ? convertSchema({ schema: schema.items }, options) : createSchema({ type: "any" }),
|
|
1611
1669
|
min: schema.minItems,
|
|
1612
1670
|
max: schema.maxItems,
|
|
1613
1671
|
...renderSchemaBase(schema, name, nullable, defaultValue)
|
|
@@ -1774,18 +1832,17 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1774
1832
|
}
|
|
1775
1833
|
/**
|
|
1776
1834
|
* Converts a single dereferenced OAS parameter object into a `ParameterNode`.
|
|
1777
|
-
* When the parameter has no `schema
|
|
1835
|
+
* When the parameter has no `schema`, falls back to `unknownType`; `$ref` schemas are resolved through `convertSchema` to produce a proper named type reference.
|
|
1778
1836
|
*/
|
|
1779
1837
|
function parseParameter(options, param) {
|
|
1780
1838
|
const required = param["required"] ?? false;
|
|
1781
|
-
const schema = param["schema"]
|
|
1839
|
+
const schema = param["schema"] ? convertSchema({ schema: param["schema"] }, options) : createSchema({ type: resolveTypeOption(options.unknownType) });
|
|
1782
1840
|
return createParameter({
|
|
1783
1841
|
name: param["name"],
|
|
1784
1842
|
in: param["in"],
|
|
1785
1843
|
schema: {
|
|
1786
1844
|
...schema,
|
|
1787
|
-
description: param["description"] ?? schema.description
|
|
1788
|
-
optional: !required || !!schema.optional ? true : void 0
|
|
1845
|
+
description: param["description"] ?? schema.description
|
|
1789
1846
|
},
|
|
1790
1847
|
required
|
|
1791
1848
|
});
|
|
@@ -1798,8 +1855,10 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1798
1855
|
const parameters = oas.getParameters(operation).map((param) => parseParameter(options, param));
|
|
1799
1856
|
const requestBodySchema = oas.getRequestSchema(operation);
|
|
1800
1857
|
const requestBodySchemaNode = requestBodySchema ? convertSchema({ schema: requestBodySchema }, options) : void 0;
|
|
1858
|
+
const requestBodyDescription = operation.schema.requestBody && !isReference(operation.schema.requestBody) ? operation.schema.requestBody.description : void 0;
|
|
1801
1859
|
const requestBodyKeysToOmit = requestBodySchema?.properties ? Object.entries(requestBodySchema.properties).filter(([, prop]) => !isReference(prop) && prop.readOnly).map(([key]) => key) : void 0;
|
|
1802
1860
|
const requestBody = requestBodySchemaNode ? {
|
|
1861
|
+
description: requestBodyDescription,
|
|
1803
1862
|
schema: requestBodySchemaNode,
|
|
1804
1863
|
keysToOmit: requestBodyKeysToOmit?.length ? requestBodyKeysToOmit : void 0
|
|
1805
1864
|
} : void 0;
|
|
@@ -1950,16 +2009,17 @@ const adapterOas = createAdapter((options) => {
|
|
|
1950
2009
|
contentType,
|
|
1951
2010
|
collisionDetection
|
|
1952
2011
|
});
|
|
2012
|
+
const root = parser.parse({
|
|
2013
|
+
dateType,
|
|
2014
|
+
integerType,
|
|
2015
|
+
unknownType,
|
|
2016
|
+
emptySchemaType,
|
|
2017
|
+
enumSuffix
|
|
2018
|
+
});
|
|
1953
2019
|
nameMapping.clear();
|
|
1954
2020
|
for (const [key, value] of parser.nameMapping) nameMapping.set(key, value);
|
|
1955
2021
|
return createRoot({
|
|
1956
|
-
...
|
|
1957
|
-
dateType,
|
|
1958
|
-
integerType,
|
|
1959
|
-
unknownType,
|
|
1960
|
-
emptySchemaType,
|
|
1961
|
-
enumSuffix
|
|
1962
|
-
}),
|
|
2022
|
+
...root,
|
|
1963
2023
|
meta: {
|
|
1964
2024
|
title: oas.api.info?.title,
|
|
1965
2025
|
description: oas.api.info?.description,
|