@kubb/adapter-oas 5.0.0-alpha.11 → 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.cjs +97 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +97 -24
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter.ts +2 -3
- package/src/parser.ts +121 -16
package/dist/index.cjs
CHANGED
|
@@ -185,9 +185,12 @@ function toCamelOrPascal(text, pascal) {
|
|
|
185
185
|
* Splits `text` on `.` and applies `transformPart` to each segment.
|
|
186
186
|
* The last segment receives `isLast = true`, all earlier segments receive `false`.
|
|
187
187
|
* Segments are joined with `/` to form a file path.
|
|
188
|
+
*
|
|
189
|
+
* Only splits on dots followed by a letter so that version numbers
|
|
190
|
+
* embedded in operationIds (e.g. `v2025.0`) are kept intact.
|
|
188
191
|
*/
|
|
189
192
|
function applyToFileParts(text, transformPart) {
|
|
190
|
-
const parts = text.split(
|
|
193
|
+
const parts = text.split(/\.(?=[a-zA-Z])/);
|
|
191
194
|
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
192
195
|
}
|
|
193
196
|
/**
|
|
@@ -1278,6 +1281,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1278
1281
|
pattern: schema.pattern ?? ("pattern" in memberNode ? memberNode.pattern : void 0)
|
|
1279
1282
|
});
|
|
1280
1283
|
}
|
|
1284
|
+
const filteredDiscriminantValues = [];
|
|
1281
1285
|
const allOfMembers = schema.allOf.filter((item) => {
|
|
1282
1286
|
if (!isReference(item) || !name) return true;
|
|
1283
1287
|
const deref = oas.get(item.$ref);
|
|
@@ -1287,7 +1291,15 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1287
1291
|
const childRef = `#/components/schemas/${name}`;
|
|
1288
1292
|
const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef);
|
|
1289
1293
|
const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
|
|
1290
|
-
|
|
1294
|
+
if (inOneOf || inMapping) {
|
|
1295
|
+
const discriminatorValue = Object.entries(deref.discriminator.mapping ?? {}).find(([, v]) => v === childRef)?.[0];
|
|
1296
|
+
if (discriminatorValue) filteredDiscriminantValues.push({
|
|
1297
|
+
propertyName: deref.discriminator.propertyName,
|
|
1298
|
+
value: discriminatorValue
|
|
1299
|
+
});
|
|
1300
|
+
return false;
|
|
1301
|
+
}
|
|
1302
|
+
return true;
|
|
1291
1303
|
}).map((s) => convertSchema({ schema: s }, options));
|
|
1292
1304
|
const syntheticStart = allOfMembers.length;
|
|
1293
1305
|
if (Array.isArray(schema.required) && schema.required.length) {
|
|
@@ -1312,9 +1324,22 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1312
1324
|
const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
|
|
1313
1325
|
allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf }, options));
|
|
1314
1326
|
}
|
|
1327
|
+
for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push((0, _kubb_ast.createSchema)({
|
|
1328
|
+
type: "object",
|
|
1329
|
+
primitive: "object",
|
|
1330
|
+
properties: [(0, _kubb_ast.createProperty)({
|
|
1331
|
+
name: propertyName,
|
|
1332
|
+
schema: (0, _kubb_ast.createSchema)({
|
|
1333
|
+
type: "enum",
|
|
1334
|
+
primitive: "string",
|
|
1335
|
+
enumValues: [value]
|
|
1336
|
+
}),
|
|
1337
|
+
required: true
|
|
1338
|
+
})]
|
|
1339
|
+
}));
|
|
1315
1340
|
return (0, _kubb_ast.createSchema)({
|
|
1316
1341
|
type: "intersection",
|
|
1317
|
-
members: [...allOfMembers.slice(0, syntheticStart), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
|
|
1342
|
+
members: [...mergeAdjacentAnonymousObjects(allOfMembers.slice(0, syntheticStart)), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
|
|
1318
1343
|
...renderSchemaBase(schema, name, nullable, defaultValue)
|
|
1319
1344
|
});
|
|
1320
1345
|
}
|
|
@@ -1358,6 +1383,33 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1358
1383
|
})
|
|
1359
1384
|
});
|
|
1360
1385
|
}
|
|
1386
|
+
const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
|
|
1387
|
+
if (discriminator?.mapping) return (0, _kubb_ast.createSchema)({
|
|
1388
|
+
type: "union",
|
|
1389
|
+
...unionBase,
|
|
1390
|
+
members: unionMembers.map((s) => {
|
|
1391
|
+
const ref = isReference(s) ? s.$ref : void 0;
|
|
1392
|
+
const discriminatorValue = ref ? Object.entries(discriminator.mapping).find(([, v]) => v === ref)?.[0] : void 0;
|
|
1393
|
+
const memberNode = convertSchema({ schema: s }, options);
|
|
1394
|
+
if (!discriminatorValue) return memberNode;
|
|
1395
|
+
return (0, _kubb_ast.createSchema)({
|
|
1396
|
+
type: "intersection",
|
|
1397
|
+
members: [memberNode, (0, _kubb_ast.createSchema)({
|
|
1398
|
+
type: "object",
|
|
1399
|
+
primitive: "object",
|
|
1400
|
+
properties: [(0, _kubb_ast.createProperty)({
|
|
1401
|
+
name: discriminator.propertyName,
|
|
1402
|
+
schema: (0, _kubb_ast.createSchema)({
|
|
1403
|
+
type: "enum",
|
|
1404
|
+
primitive: "string",
|
|
1405
|
+
enumValues: [discriminatorValue]
|
|
1406
|
+
}),
|
|
1407
|
+
required: true
|
|
1408
|
+
})]
|
|
1409
|
+
})]
|
|
1410
|
+
});
|
|
1411
|
+
})
|
|
1412
|
+
});
|
|
1361
1413
|
return (0, _kubb_ast.createSchema)({
|
|
1362
1414
|
type: "union",
|
|
1363
1415
|
...unionBase,
|
|
@@ -1377,8 +1429,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1377
1429
|
name,
|
|
1378
1430
|
title: schema.title,
|
|
1379
1431
|
description: schema.description,
|
|
1380
|
-
deprecated: schema.deprecated
|
|
1381
|
-
nullable
|
|
1432
|
+
deprecated: schema.deprecated
|
|
1382
1433
|
});
|
|
1383
1434
|
return (0, _kubb_ast.createSchema)({
|
|
1384
1435
|
type: "enum",
|
|
@@ -1580,14 +1631,23 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1580
1631
|
const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
|
|
1581
1632
|
const resolvedPropSchema = propSchema;
|
|
1582
1633
|
const propNullable = isNullable(resolvedPropSchema);
|
|
1634
|
+
let schemaNode = applyEnumName(convertSchema({
|
|
1635
|
+
schema: resolvedPropSchema,
|
|
1636
|
+
name: resolveChildName(name, propName)
|
|
1637
|
+
}, options), name, propName, mergedOptions.enumSuffix);
|
|
1638
|
+
const tupleNode = (0, _kubb_ast.narrowSchema)(schemaNode, "tuple");
|
|
1639
|
+
if (tupleNode?.items) {
|
|
1640
|
+
const namedItems = tupleNode.items.map((item) => applyEnumName(item, name, propName, mergedOptions.enumSuffix));
|
|
1641
|
+
if (namedItems.some((item, i) => item !== tupleNode.items[i])) schemaNode = {
|
|
1642
|
+
...tupleNode,
|
|
1643
|
+
items: namedItems
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1583
1646
|
return (0, _kubb_ast.createProperty)({
|
|
1584
1647
|
name: propName,
|
|
1585
1648
|
schema: {
|
|
1586
|
-
...
|
|
1587
|
-
|
|
1588
|
-
name: resolveChildName(name, propName)
|
|
1589
|
-
}, options), name, propName, mergedOptions.enumSuffix),
|
|
1590
|
-
nullable: propNullable || void 0,
|
|
1649
|
+
...schemaNode,
|
|
1650
|
+
nullable: schemaNode.type === "null" ? void 0 : propNullable || void 0,
|
|
1591
1651
|
optional: !required && !propNullable ? true : void 0,
|
|
1592
1652
|
nullish: !required && propNullable ? true : void 0
|
|
1593
1653
|
},
|
|
@@ -1624,15 +1684,17 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1624
1684
|
/**
|
|
1625
1685
|
* Converts an OAS 3.1 `prefixItems` tuple into a `TupleSchemaNode`.
|
|
1626
1686
|
*
|
|
1627
|
-
* Each `prefixItems` element maps to a positional tuple slot.
|
|
1628
|
-
*
|
|
1687
|
+
* Each `prefixItems` element maps to a positional tuple slot. When an explicit `items` schema
|
|
1688
|
+
* is present alongside `prefixItems`, it becomes the rest element. When `items` is absent,
|
|
1689
|
+
* a rest element of type `any` is emitted to match JSON Schema semantics (absent `items`
|
|
1690
|
+
* means additional items are allowed).
|
|
1629
1691
|
*/
|
|
1630
1692
|
function convertTuple({ schema, name, nullable, defaultValue, options }) {
|
|
1631
1693
|
return (0, _kubb_ast.createSchema)({
|
|
1632
1694
|
type: "tuple",
|
|
1633
1695
|
primitive: "array",
|
|
1634
1696
|
items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item }, options)),
|
|
1635
|
-
rest: schema.items ? convertSchema({ schema: schema.items }, options) :
|
|
1697
|
+
rest: schema.items ? convertSchema({ schema: schema.items }, options) : (0, _kubb_ast.createSchema)({ type: "any" }),
|
|
1636
1698
|
min: schema.minItems,
|
|
1637
1699
|
max: schema.maxItems,
|
|
1638
1700
|
...renderSchemaBase(schema, name, nullable, defaultValue)
|
|
@@ -1799,11 +1861,11 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1799
1861
|
}
|
|
1800
1862
|
/**
|
|
1801
1863
|
* Converts a single dereferenced OAS parameter object into a `ParameterNode`.
|
|
1802
|
-
* When the parameter has no `schema
|
|
1864
|
+
* When the parameter has no `schema`, falls back to `unknownType`; `$ref` schemas are resolved through `convertSchema` to produce a proper named type reference.
|
|
1803
1865
|
*/
|
|
1804
1866
|
function parseParameter(options, param) {
|
|
1805
1867
|
const required = param["required"] ?? false;
|
|
1806
|
-
const schema = param["schema"]
|
|
1868
|
+
const schema = param["schema"] ? convertSchema({ schema: param["schema"] }, options) : (0, _kubb_ast.createSchema)({ type: resolveTypeOption(options.unknownType) });
|
|
1807
1869
|
return (0, _kubb_ast.createParameter)({
|
|
1808
1870
|
name: param["name"],
|
|
1809
1871
|
in: param["in"],
|
|
@@ -1822,18 +1884,28 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1822
1884
|
function parseOperation(options, oas, operation) {
|
|
1823
1885
|
const parameters = oas.getParameters(operation).map((param) => parseParameter(options, param));
|
|
1824
1886
|
const requestBodySchema = oas.getRequestSchema(operation);
|
|
1825
|
-
const
|
|
1887
|
+
const requestBodySchemaNode = requestBodySchema ? convertSchema({ schema: requestBodySchema }, options) : void 0;
|
|
1888
|
+
const requestBodyDescription = operation.schema.requestBody && !isReference(operation.schema.requestBody) ? operation.schema.requestBody.description : void 0;
|
|
1889
|
+
const requestBodyKeysToOmit = requestBodySchema?.properties ? Object.entries(requestBodySchema.properties).filter(([, prop]) => !isReference(prop) && prop.readOnly).map(([key]) => key) : void 0;
|
|
1890
|
+
const requestBody = requestBodySchemaNode ? {
|
|
1891
|
+
description: requestBodyDescription,
|
|
1892
|
+
schema: requestBodySchemaNode,
|
|
1893
|
+
keysToOmit: requestBodyKeysToOmit?.length ? requestBodyKeysToOmit : void 0
|
|
1894
|
+
} : void 0;
|
|
1826
1895
|
const responses = operation.getResponseStatusCodes().map((statusCode) => {
|
|
1827
1896
|
const responseObj = operation.getResponseByStatusCode(statusCode);
|
|
1828
1897
|
const responseSchema = oas.getResponseSchema(operation, statusCode);
|
|
1829
1898
|
const schema = responseSchema && Object.keys(responseSchema).length > 0 ? convertSchema({ schema: responseSchema }, options) : (0, _kubb_ast.createSchema)({ type: resolveTypeOption(options.emptySchemaType) });
|
|
1830
1899
|
const description = typeof responseObj === "object" && responseObj !== null && !Array.isArray(responseObj) ? responseObj.description : void 0;
|
|
1831
1900
|
const rawContent = typeof responseObj === "object" && responseObj !== null && !Array.isArray(responseObj) ? responseObj.content : void 0;
|
|
1901
|
+
const mediaType = rawContent ? toMediaType(Object.keys(rawContent)[0] ?? "") : toMediaType(operation.contentType ?? "");
|
|
1902
|
+
const keysToOmit = responseSchema?.properties ? Object.entries(responseSchema.properties).filter(([, prop]) => !isReference(prop) && prop.writeOnly).map(([key]) => key) : void 0;
|
|
1832
1903
|
return (0, _kubb_ast.createResponse)({
|
|
1833
1904
|
statusCode,
|
|
1834
1905
|
description,
|
|
1835
1906
|
schema,
|
|
1836
|
-
mediaType
|
|
1907
|
+
mediaType,
|
|
1908
|
+
keysToOmit: keysToOmit?.length ? keysToOmit : void 0
|
|
1837
1909
|
});
|
|
1838
1910
|
});
|
|
1839
1911
|
return (0, _kubb_ast.createOperation)({
|
|
@@ -1967,16 +2039,17 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
|
|
|
1967
2039
|
contentType,
|
|
1968
2040
|
collisionDetection
|
|
1969
2041
|
});
|
|
2042
|
+
const root = parser.parse({
|
|
2043
|
+
dateType,
|
|
2044
|
+
integerType,
|
|
2045
|
+
unknownType,
|
|
2046
|
+
emptySchemaType,
|
|
2047
|
+
enumSuffix
|
|
2048
|
+
});
|
|
1970
2049
|
nameMapping.clear();
|
|
1971
2050
|
for (const [key, value] of parser.nameMapping) nameMapping.set(key, value);
|
|
1972
2051
|
return (0, _kubb_ast.createRoot)({
|
|
1973
|
-
...
|
|
1974
|
-
dateType,
|
|
1975
|
-
integerType,
|
|
1976
|
-
unknownType,
|
|
1977
|
-
emptySchemaType,
|
|
1978
|
-
enumSuffix
|
|
1979
|
-
}),
|
|
2052
|
+
...root,
|
|
1980
2053
|
meta: {
|
|
1981
2054
|
title: oas.api.info?.title,
|
|
1982
2055
|
description: oas.api.info?.description,
|