@kubb/adapter-oas 5.0.0-alpha.2 → 5.0.0-alpha.4
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 +235 -101
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +27 -0
- package/dist/index.js +235 -101
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter.ts +16 -0
- package/src/oas/types.ts +19 -0
- package/src/parser.ts +104 -152
- package/src/types.ts +6 -0
- package/src/utils.ts +161 -0
package/dist/index.cjs
CHANGED
|
@@ -928,6 +928,137 @@ function resolveCollisions(schemasWithMeta) {
|
|
|
928
928
|
};
|
|
929
929
|
}
|
|
930
930
|
//#endregion
|
|
931
|
+
//#region src/utils.ts
|
|
932
|
+
/**
|
|
933
|
+
* Extracts the schema name from a `$ref` string.
|
|
934
|
+
* For `#/components/schemas/Order` this returns `'Order'`.
|
|
935
|
+
* Falls back to the full ref string when no slash is present.
|
|
936
|
+
*/
|
|
937
|
+
function extractRefName($ref) {
|
|
938
|
+
return $ref.split("/").at(-1) ?? $ref;
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Replaces the discriminator property's schema inside an `ObjectSchemaNode`
|
|
942
|
+
* with an enum of the given `values`.
|
|
943
|
+
*
|
|
944
|
+
* - When `enumName` is provided the enum is named, which lets printers emit a
|
|
945
|
+
* standalone enum declaration + type reference (e.g. `PetTypeEnum`).
|
|
946
|
+
* - When `enumName` is omitted the enum stays anonymous, so printers inline it
|
|
947
|
+
* as a literal union (e.g. `'dog'`).
|
|
948
|
+
*
|
|
949
|
+
* Returns the node unchanged when it is not an object or lacks the target property.
|
|
950
|
+
*/
|
|
951
|
+
function applyDiscriminatorEnum({ node, propertyName, values, enumName }) {
|
|
952
|
+
if (node.type !== "object" || !node.properties?.length) return node;
|
|
953
|
+
if (!node.properties.some((prop) => prop.name === propertyName)) return node;
|
|
954
|
+
return (0, _kubb_ast.createSchema)({
|
|
955
|
+
...node,
|
|
956
|
+
properties: node.properties.map((prop) => {
|
|
957
|
+
if (prop.name !== propertyName) return prop;
|
|
958
|
+
const enumSchema = (0, _kubb_ast.createSchema)({
|
|
959
|
+
type: "enum",
|
|
960
|
+
primitive: "string",
|
|
961
|
+
enumValues: values,
|
|
962
|
+
name: enumName,
|
|
963
|
+
readOnly: prop.schema.readOnly,
|
|
964
|
+
writeOnly: prop.schema.writeOnly
|
|
965
|
+
});
|
|
966
|
+
return (0, _kubb_ast.createProperty)({
|
|
967
|
+
...prop,
|
|
968
|
+
schema: enumSchema
|
|
969
|
+
});
|
|
970
|
+
})
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Merges consecutive anonymous (`name`-less) `ObjectSchemaNode`s in `members` into a
|
|
975
|
+
* single object by combining their `properties` arrays.
|
|
976
|
+
*
|
|
977
|
+
* Only adjacent pairs are merged — non-object or named nodes act as boundaries.
|
|
978
|
+
* This collapses patterns like `Address & { streetNumber } & { streetName }` into
|
|
979
|
+
* `Address & { streetNumber; streetName }`.
|
|
980
|
+
*/
|
|
981
|
+
function mergeAdjacentAnonymousObjects(members) {
|
|
982
|
+
return members.reduce((acc, member) => {
|
|
983
|
+
const obj = (0, _kubb_ast.narrowSchema)(member, "object");
|
|
984
|
+
if (obj && !obj.name) {
|
|
985
|
+
const prev = acc[acc.length - 1];
|
|
986
|
+
const prevObj = prev ? (0, _kubb_ast.narrowSchema)(prev, "object") : null;
|
|
987
|
+
if (prevObj && !prevObj.name) {
|
|
988
|
+
acc[acc.length - 1] = (0, _kubb_ast.createSchema)({
|
|
989
|
+
...prevObj,
|
|
990
|
+
properties: [...prevObj.properties ?? [], ...obj.properties ?? []]
|
|
991
|
+
});
|
|
992
|
+
return acc;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
acc.push(member);
|
|
996
|
+
return acc;
|
|
997
|
+
}, []);
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Simplifies a union member list by removing `enum` nodes whose `primitive` type is
|
|
1001
|
+
* already represented by a broader scalar node in the same union.
|
|
1002
|
+
*
|
|
1003
|
+
* For example `['placed', 'approved'] | string` collapses to `string` because
|
|
1004
|
+
* `string` subsumes all string literals. `'' | string` similarly becomes `string`.
|
|
1005
|
+
*
|
|
1006
|
+
* Only scalar primitives (`string`, `number`, `integer`, `bigint`, `boolean`) are
|
|
1007
|
+
* considered — object, array, and ref members are left untouched.
|
|
1008
|
+
*/
|
|
1009
|
+
function simplifyUnionMembers(members) {
|
|
1010
|
+
const scalarPrimitives = new Set(members.filter((m) => [
|
|
1011
|
+
"string",
|
|
1012
|
+
"number",
|
|
1013
|
+
"integer",
|
|
1014
|
+
"bigint",
|
|
1015
|
+
"boolean"
|
|
1016
|
+
].includes(m.type)).map((m) => m.type));
|
|
1017
|
+
if (!scalarPrimitives.size) return members;
|
|
1018
|
+
return members.filter((m) => {
|
|
1019
|
+
if (m.type !== "enum") return true;
|
|
1020
|
+
const prim = m.primitive;
|
|
1021
|
+
if (!prim) return true;
|
|
1022
|
+
if (scalarPrimitives.has(prim)) return false;
|
|
1023
|
+
if ((prim === "integer" || prim === "number") && (scalarPrimitives.has("integer") || scalarPrimitives.has("number"))) return false;
|
|
1024
|
+
return true;
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* `nameMapping`, and calls `resolve` to obtain the `{ name, path }` pair for
|
|
1029
|
+
* each import. When `oas` is supplied, only `$ref`s that are resolvable in the
|
|
1030
|
+
* spec are included; omit it to skip the existence check.
|
|
1031
|
+
*
|
|
1032
|
+
* This function is the pure, state-free alternative to `OasParser.getImports`.
|
|
1033
|
+
* Because it receives `nameMapping` explicitly it can be called without holding
|
|
1034
|
+
* a reference to the parser or the OAS instance.
|
|
1035
|
+
*
|
|
1036
|
+
* @example
|
|
1037
|
+
* ```ts
|
|
1038
|
+
* // Use adapter state directly — no parser reference needed
|
|
1039
|
+
* const imports = getImports({
|
|
1040
|
+
* node: schemaNode,
|
|
1041
|
+
* nameMapping: adapter.options.nameMapping,
|
|
1042
|
+
* resolve: (schemaName) => ({
|
|
1043
|
+
* name: schemaManager.getName(schemaName, { type: 'type' }),
|
|
1044
|
+
* path: schemaManager.getFile(schemaName).path,
|
|
1045
|
+
* }),
|
|
1046
|
+
* })
|
|
1047
|
+
* ```
|
|
1048
|
+
*/
|
|
1049
|
+
function getImports({ node, nameMapping, resolve }) {
|
|
1050
|
+
return (0, _kubb_ast.collect)(node, { schema(schemaNode) {
|
|
1051
|
+
if (schemaNode.type !== "ref" || !schemaNode.ref) return;
|
|
1052
|
+
const rawName = extractRefName(schemaNode.ref);
|
|
1053
|
+
const result = resolve(nameMapping.get(rawName) ?? rawName);
|
|
1054
|
+
if (!result) return;
|
|
1055
|
+
return {
|
|
1056
|
+
name: [result.name],
|
|
1057
|
+
path: result.path
|
|
1058
|
+
};
|
|
1059
|
+
} });
|
|
1060
|
+
}
|
|
1061
|
+
//#endregion
|
|
931
1062
|
//#region src/parser.ts
|
|
932
1063
|
/**
|
|
933
1064
|
* Default values for all `Options` fields.
|
|
@@ -948,14 +1079,6 @@ function formatToSchemaType(format) {
|
|
|
948
1079
|
return formatMap[format];
|
|
949
1080
|
}
|
|
950
1081
|
/**
|
|
951
|
-
* Extracts the final path segment of a JSON Pointer `$ref` string.
|
|
952
|
-
* For `#/components/schemas/Order` this returns `'Order'`.
|
|
953
|
-
* Falls back to the full ref string when no slash is present.
|
|
954
|
-
*/
|
|
955
|
-
function extractRefName($ref) {
|
|
956
|
-
return $ref.split("/").at(-1) ?? $ref;
|
|
957
|
-
}
|
|
958
|
-
/**
|
|
959
1082
|
* Maps an OAS primitive type string to its `PrimitiveSchemaType` equivalent.
|
|
960
1083
|
* Numeric types (`number`, `integer`, `bigint`) are returned unchanged;
|
|
961
1084
|
* `boolean` maps to `'boolean'`; everything else defaults to `'string'`.
|
|
@@ -973,26 +1096,6 @@ function toMediaType(contentType) {
|
|
|
973
1096
|
return knownMediaTypes.includes(contentType) ? contentType : void 0;
|
|
974
1097
|
}
|
|
975
1098
|
/**
|
|
976
|
-
* When a discriminator is present, replaces the discriminator property's schema with
|
|
977
|
-
* an enum of the mapping keys so downstream code emits a precise literal-union type.
|
|
978
|
-
* Returns the original schema unchanged when there is no discriminator or no mapping.
|
|
979
|
-
*/
|
|
980
|
-
function applyDiscriminatorEnum(schema) {
|
|
981
|
-
if (!isDiscriminator(schema)) return schema;
|
|
982
|
-
const propName = schema.discriminator.propertyName;
|
|
983
|
-
if (!schema.properties?.[propName]) return schema;
|
|
984
|
-
return {
|
|
985
|
-
...schema,
|
|
986
|
-
properties: {
|
|
987
|
-
...schema.properties,
|
|
988
|
-
[propName]: {
|
|
989
|
-
...schema.properties[propName],
|
|
990
|
-
enum: schema.discriminator.mapping ? Object.keys(schema.discriminator.mapping) : void 0
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
};
|
|
994
|
-
}
|
|
995
|
-
/**
|
|
996
1099
|
* Creates an OAS parser that converts an OpenAPI/Swagger spec into
|
|
997
1100
|
* the `@kubb/ast` tree.
|
|
998
1101
|
*
|
|
@@ -1083,18 +1186,17 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1083
1186
|
* reflected in generated JSDoc and type modifiers.
|
|
1084
1187
|
*/
|
|
1085
1188
|
function convertRef({ schema, nullable, defaultValue }) {
|
|
1086
|
-
const schemaObject = schema;
|
|
1087
1189
|
return (0, _kubb_ast.createSchema)({
|
|
1088
1190
|
type: "ref",
|
|
1089
|
-
name: extractRefName(
|
|
1090
|
-
ref:
|
|
1191
|
+
name: extractRefName(schema.$ref),
|
|
1192
|
+
ref: schema.$ref,
|
|
1091
1193
|
nullable,
|
|
1092
|
-
description:
|
|
1093
|
-
deprecated:
|
|
1094
|
-
readOnly:
|
|
1095
|
-
writeOnly:
|
|
1096
|
-
pattern:
|
|
1097
|
-
example:
|
|
1194
|
+
description: schema.description,
|
|
1195
|
+
deprecated: schema.deprecated,
|
|
1196
|
+
readOnly: schema.readOnly,
|
|
1197
|
+
writeOnly: schema.writeOnly,
|
|
1198
|
+
pattern: schema.type === "string" ? schema.pattern : void 0,
|
|
1199
|
+
example: schema.example,
|
|
1098
1200
|
default: defaultValue
|
|
1099
1201
|
});
|
|
1100
1202
|
}
|
|
@@ -1145,6 +1247,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1145
1247
|
const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
|
|
1146
1248
|
return !inOneOf && !inMapping;
|
|
1147
1249
|
}).map((s) => convertSchema({ schema: s }, options));
|
|
1250
|
+
const syntheticStart = allOfMembers.length;
|
|
1148
1251
|
if (Array.isArray(schema.required) && schema.required.length) {
|
|
1149
1252
|
const outerKeys = schema.properties ? new Set(Object.keys(schema.properties)) : /* @__PURE__ */ new Set();
|
|
1150
1253
|
const missingRequired = schema.required.filter((key) => !outerKeys.has(key));
|
|
@@ -1169,7 +1272,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1169
1272
|
}
|
|
1170
1273
|
return (0, _kubb_ast.createSchema)({
|
|
1171
1274
|
type: "intersection",
|
|
1172
|
-
members: allOfMembers,
|
|
1275
|
+
members: [...allOfMembers.slice(0, syntheticStart), ...mergeAdjacentAnonymousObjects(allOfMembers.slice(syntheticStart))],
|
|
1173
1276
|
...buildSchemaBase(schema, name, nullable, defaultValue)
|
|
1174
1277
|
});
|
|
1175
1278
|
}
|
|
@@ -1189,20 +1292,34 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1189
1292
|
};
|
|
1190
1293
|
if (schema.properties) {
|
|
1191
1294
|
const { oneOf: _oneOf, anyOf: _anyOf, ...schemaWithoutUnion } = schema;
|
|
1192
|
-
const
|
|
1295
|
+
const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
|
|
1296
|
+
const memberBaseSchema = discriminator ? Object.fromEntries(Object.entries(schemaWithoutUnion).filter(([key]) => key !== "discriminator")) : schemaWithoutUnion;
|
|
1193
1297
|
return (0, _kubb_ast.createSchema)({
|
|
1194
1298
|
type: "union",
|
|
1195
1299
|
...unionBase,
|
|
1196
|
-
members: unionMembers.map((s) =>
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1300
|
+
members: unionMembers.map((s) => {
|
|
1301
|
+
const ref = isReference(s) ? s.$ref : void 0;
|
|
1302
|
+
const discriminatorValue = discriminator?.mapping && ref ? Object.entries(discriminator.mapping).find(([, v]) => v === ref)?.[0] : void 0;
|
|
1303
|
+
let propertiesNode = convertSchema({
|
|
1304
|
+
schema: memberBaseSchema,
|
|
1305
|
+
name
|
|
1306
|
+
}, options);
|
|
1307
|
+
if (discriminatorValue && discriminator) propertiesNode = applyDiscriminatorEnum({
|
|
1308
|
+
node: propertiesNode,
|
|
1309
|
+
propertyName: discriminator.propertyName,
|
|
1310
|
+
values: [discriminatorValue]
|
|
1311
|
+
});
|
|
1312
|
+
return (0, _kubb_ast.createSchema)({
|
|
1313
|
+
type: "intersection",
|
|
1314
|
+
members: [convertSchema({ schema: s }, options), propertiesNode]
|
|
1315
|
+
});
|
|
1316
|
+
})
|
|
1200
1317
|
});
|
|
1201
1318
|
}
|
|
1202
1319
|
return (0, _kubb_ast.createSchema)({
|
|
1203
1320
|
type: "union",
|
|
1204
1321
|
...unionBase,
|
|
1205
|
-
members: unionMembers.map((s) => convertSchema({ schema: s }, options))
|
|
1322
|
+
members: simplifyUnionMembers(unionMembers.map((s) => convertSchema({ schema: s }, options)))
|
|
1206
1323
|
});
|
|
1207
1324
|
}
|
|
1208
1325
|
/**
|
|
@@ -1287,9 +1404,8 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1287
1404
|
*/
|
|
1288
1405
|
function convertEnum({ schema, name, nullable, type, options }) {
|
|
1289
1406
|
if (type === "array") {
|
|
1290
|
-
const rawSchema = schema;
|
|
1291
1407
|
const normalizedItems = {
|
|
1292
|
-
...typeof
|
|
1408
|
+
...typeof schema.items === "object" && !Array.isArray(schema.items) ? schema.items : {},
|
|
1293
1409
|
enum: schema.enum
|
|
1294
1410
|
};
|
|
1295
1411
|
const { enum: _enum, ...schemaWithoutEnum } = schema;
|
|
@@ -1369,22 +1485,28 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1369
1485
|
* - not required + nullable → `nullish: true`
|
|
1370
1486
|
*/
|
|
1371
1487
|
function convertObject({ schema, name, nullable, defaultValue, options, mergedOptions }) {
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
const required = Array.isArray(resolvedSchema.required) ? resolvedSchema.required.includes(propName) : !!resolvedSchema.required;
|
|
1488
|
+
const properties = schema.properties ? Object.entries(schema.properties).map(([propName, propSchema]) => {
|
|
1489
|
+
const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
|
|
1375
1490
|
const resolvedPropSchema = propSchema;
|
|
1376
1491
|
const propNullable = isNullable(resolvedPropSchema);
|
|
1492
|
+
const basePropName = name ? pascalCase([name, propName].join(" ")) : void 0;
|
|
1493
|
+
const propNode = convertSchema({
|
|
1494
|
+
schema: resolvedPropSchema,
|
|
1495
|
+
name: basePropName
|
|
1496
|
+
}, options);
|
|
1497
|
+
const isEnumNode = !!(0, _kubb_ast.narrowSchema)(propNode, "enum");
|
|
1498
|
+
const derivedPropName = isEnumNode && name ? pascalCase([
|
|
1499
|
+
name,
|
|
1500
|
+
propName,
|
|
1501
|
+
mergedOptions.enumSuffix
|
|
1502
|
+
].filter(Boolean).join(" ")) : basePropName;
|
|
1377
1503
|
return (0, _kubb_ast.createProperty)({
|
|
1378
1504
|
name: propName,
|
|
1379
1505
|
schema: {
|
|
1380
|
-
...
|
|
1381
|
-
|
|
1382
|
-
name:
|
|
1383
|
-
|
|
1384
|
-
propName,
|
|
1385
|
-
mergedOptions.enumSuffix
|
|
1386
|
-
].filter(Boolean).join(" ")) : void 0
|
|
1387
|
-
}, options),
|
|
1506
|
+
...isEnumNode && derivedPropName !== basePropName ? {
|
|
1507
|
+
...propNode,
|
|
1508
|
+
name: derivedPropName
|
|
1509
|
+
} : propNode,
|
|
1388
1510
|
nullable: propNullable || void 0,
|
|
1389
1511
|
optional: !required && !propNullable ? true : void 0,
|
|
1390
1512
|
nullish: !required && propNullable ? true : void 0
|
|
@@ -1392,15 +1514,15 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1392
1514
|
required
|
|
1393
1515
|
});
|
|
1394
1516
|
}) : [];
|
|
1395
|
-
const additionalProperties =
|
|
1517
|
+
const additionalProperties = schema.additionalProperties;
|
|
1396
1518
|
let additionalPropertiesNode;
|
|
1397
1519
|
if (additionalProperties === true) additionalPropertiesNode = true;
|
|
1398
1520
|
else if (additionalProperties && Object.keys(additionalProperties).length > 0) additionalPropertiesNode = convertSchema({ schema: additionalProperties }, options);
|
|
1399
1521
|
else if (additionalProperties === false) additionalPropertiesNode = void 0;
|
|
1400
1522
|
else if (additionalProperties) additionalPropertiesNode = (0, _kubb_ast.createSchema)({ type: resolveTypeOption(mergedOptions.unknownType) });
|
|
1401
|
-
const rawPatternProperties = "patternProperties" in
|
|
1402
|
-
const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || Object.keys(patternSchema).length === 0 ? (0, _kubb_ast.createSchema)({ type: resolveTypeOption(mergedOptions.unknownType) }) : convertSchema({ schema: patternSchema }, options)])) : void 0;
|
|
1403
|
-
|
|
1523
|
+
const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
|
|
1524
|
+
const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? (0, _kubb_ast.createSchema)({ type: resolveTypeOption(mergedOptions.unknownType) }) : convertSchema({ schema: patternSchema }, options)])) : void 0;
|
|
1525
|
+
const objectNode = (0, _kubb_ast.createSchema)({
|
|
1404
1526
|
type: "object",
|
|
1405
1527
|
primitive: "object",
|
|
1406
1528
|
properties,
|
|
@@ -1408,6 +1530,20 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1408
1530
|
patternProperties,
|
|
1409
1531
|
...buildSchemaBase(schema, name, nullable, defaultValue)
|
|
1410
1532
|
});
|
|
1533
|
+
if (isDiscriminator(schema) && schema.discriminator.mapping) {
|
|
1534
|
+
const discPropName = schema.discriminator.propertyName;
|
|
1535
|
+
return applyDiscriminatorEnum({
|
|
1536
|
+
node: objectNode,
|
|
1537
|
+
propertyName: discPropName,
|
|
1538
|
+
values: Object.keys(schema.discriminator.mapping),
|
|
1539
|
+
enumName: name ? pascalCase([
|
|
1540
|
+
name,
|
|
1541
|
+
discPropName,
|
|
1542
|
+
mergedOptions.enumSuffix
|
|
1543
|
+
].filter(Boolean).join(" ")) : void 0
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1546
|
+
return objectNode;
|
|
1411
1547
|
}
|
|
1412
1548
|
/**
|
|
1413
1549
|
* Converts an OAS 3.1 `prefixItems` tuple into a `TupleSchemaNode`.
|
|
@@ -1416,12 +1552,11 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1416
1552
|
* after the prefix items is mapped to the rest parameter of the tuple.
|
|
1417
1553
|
*/
|
|
1418
1554
|
function convertTuple({ schema, name, nullable, defaultValue, options }) {
|
|
1419
|
-
const rawSchema = schema;
|
|
1420
1555
|
return (0, _kubb_ast.createSchema)({
|
|
1421
1556
|
type: "tuple",
|
|
1422
1557
|
primitive: "array",
|
|
1423
|
-
items:
|
|
1424
|
-
rest:
|
|
1558
|
+
items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item }, options)),
|
|
1559
|
+
rest: schema.items ? convertSchema({ schema: schema.items }, options) : void 0,
|
|
1425
1560
|
min: schema.minItems,
|
|
1426
1561
|
max: schema.maxItems,
|
|
1427
1562
|
...buildSchemaBase(schema, name, nullable, defaultValue)
|
|
@@ -1434,13 +1569,13 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1434
1569
|
* `enumSuffix` is forwarded so generators can emit a named enum declaration.
|
|
1435
1570
|
*/
|
|
1436
1571
|
function convertArray({ schema, name, nullable, defaultValue, options, mergedOptions }) {
|
|
1437
|
-
const
|
|
1438
|
-
const itemName =
|
|
1572
|
+
const rawItems = schema.items;
|
|
1573
|
+
const itemName = rawItems?.enum?.length && name ? pascalCase([name, mergedOptions.enumSuffix].join(" ")) : void 0;
|
|
1439
1574
|
return (0, _kubb_ast.createSchema)({
|
|
1440
1575
|
type: "array",
|
|
1441
1576
|
primitive: "array",
|
|
1442
|
-
items:
|
|
1443
|
-
schema:
|
|
1577
|
+
items: rawItems ? [convertSchema({
|
|
1578
|
+
schema: rawItems,
|
|
1444
1579
|
name: itemName
|
|
1445
1580
|
}, options)] : [],
|
|
1446
1581
|
min: schema.minItems,
|
|
@@ -1556,10 +1691,13 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1556
1691
|
const arrayNullable = schema.type.includes("null") || nullable || void 0;
|
|
1557
1692
|
if (nonNullTypes.length > 1) return (0, _kubb_ast.createSchema)({
|
|
1558
1693
|
type: "union",
|
|
1559
|
-
members: nonNullTypes.map((t) => convertSchema({
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1694
|
+
members: nonNullTypes.map((t) => convertSchema({
|
|
1695
|
+
schema: {
|
|
1696
|
+
...schema,
|
|
1697
|
+
type: t
|
|
1698
|
+
},
|
|
1699
|
+
name
|
|
1700
|
+
}, options)),
|
|
1563
1701
|
...buildSchemaBase(schema, name, arrayNullable, defaultValue)
|
|
1564
1702
|
});
|
|
1565
1703
|
}
|
|
@@ -1588,12 +1726,16 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1588
1726
|
* When the parameter has no `schema` or its schema is a `$ref`, falls back to `unknownType`.
|
|
1589
1727
|
*/
|
|
1590
1728
|
function parseParameter(options, param) {
|
|
1729
|
+
const required = param["required"] ?? false;
|
|
1591
1730
|
const schema = param["schema"] && !isReference(param["schema"]) ? convertSchema({ schema: param["schema"] }, options) : (0, _kubb_ast.createSchema)({ type: resolveTypeOption(options.unknownType) });
|
|
1592
1731
|
return (0, _kubb_ast.createParameter)({
|
|
1593
1732
|
name: param["name"],
|
|
1594
1733
|
in: param["in"],
|
|
1595
|
-
schema
|
|
1596
|
-
|
|
1734
|
+
schema: {
|
|
1735
|
+
...schema,
|
|
1736
|
+
optional: !required || !!schema.optional ? true : void 0
|
|
1737
|
+
},
|
|
1738
|
+
required
|
|
1597
1739
|
});
|
|
1598
1740
|
}
|
|
1599
1741
|
/**
|
|
@@ -1622,7 +1764,7 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1622
1764
|
return (0, _kubb_ast.createOperation)({
|
|
1623
1765
|
operationId: operation.getOperationId(),
|
|
1624
1766
|
method: operation.method.toUpperCase(),
|
|
1625
|
-
path: operation.path,
|
|
1767
|
+
path: new URLPath(operation.path).URL,
|
|
1626
1768
|
tags: operation.getTags().map((tag) => tag.name),
|
|
1627
1769
|
summary: operation.getSummary() || void 0,
|
|
1628
1770
|
description: operation.getDescription() || void 0,
|
|
@@ -1679,31 +1821,11 @@ function createOasParser(oas, { contentType, collisionDetection } = {}) {
|
|
|
1679
1821
|
}
|
|
1680
1822
|
} });
|
|
1681
1823
|
}
|
|
1682
|
-
/**
|
|
1683
|
-
* Collects all `KubbFile.Import` descriptors needed by a `SchemaNode` tree.
|
|
1684
|
-
*
|
|
1685
|
-
* Walks the tree looking for `ref` nodes, verifies each `$ref` is resolvable in the spec,
|
|
1686
|
-
* applies collision-resolved names from `nameMapping`, and calls `resolve` to obtain the
|
|
1687
|
-
* import path and name. Returns an empty array for refs that cannot be resolved.
|
|
1688
|
-
*/
|
|
1689
|
-
function getImports(node, resolve) {
|
|
1690
|
-
return (0, _kubb_ast.collect)(node, { schema(schemaNode) {
|
|
1691
|
-
if (schemaNode.type !== "ref" || !schemaNode.ref) return;
|
|
1692
|
-
if (!oas.get(schemaNode.ref)) return;
|
|
1693
|
-
const rawName = extractRefName(schemaNode.ref);
|
|
1694
|
-
const result = resolve(nameMapping.get(rawName) ?? rawName);
|
|
1695
|
-
if (!result) return;
|
|
1696
|
-
return {
|
|
1697
|
-
name: [result.name],
|
|
1698
|
-
path: result.path
|
|
1699
|
-
};
|
|
1700
|
-
} });
|
|
1701
|
-
}
|
|
1702
1824
|
return {
|
|
1703
1825
|
parse,
|
|
1704
1826
|
convertSchema,
|
|
1705
1827
|
resolveRefs,
|
|
1706
|
-
|
|
1828
|
+
nameMapping
|
|
1707
1829
|
};
|
|
1708
1830
|
}
|
|
1709
1831
|
//#endregion
|
|
@@ -1729,6 +1851,7 @@ const adapterOasName = "oas";
|
|
|
1729
1851
|
*/
|
|
1730
1852
|
const adapterOas = (0, _kubb_core.defineAdapter)((options) => {
|
|
1731
1853
|
const { validate = true, oasClass, contentType, serverIndex, serverVariables, discriminator = "strict", collisionDetection = false, dateType = "string", integerType = "number", unknownType = "any", emptySchemaType = unknownType } = options;
|
|
1854
|
+
const nameMapping = /* @__PURE__ */ new Map();
|
|
1732
1855
|
return {
|
|
1733
1856
|
name: "oas",
|
|
1734
1857
|
options: {
|
|
@@ -1742,7 +1865,15 @@ const adapterOas = (0, _kubb_core.defineAdapter)((options) => {
|
|
|
1742
1865
|
dateType,
|
|
1743
1866
|
integerType,
|
|
1744
1867
|
unknownType,
|
|
1745
|
-
emptySchemaType
|
|
1868
|
+
emptySchemaType,
|
|
1869
|
+
nameMapping
|
|
1870
|
+
},
|
|
1871
|
+
getImports(node, resolve) {
|
|
1872
|
+
return getImports({
|
|
1873
|
+
node,
|
|
1874
|
+
nameMapping,
|
|
1875
|
+
resolve
|
|
1876
|
+
});
|
|
1746
1877
|
},
|
|
1747
1878
|
async parse(source) {
|
|
1748
1879
|
const oas = await parseFromConfig(sourceToFakeConfig(source), oasClass);
|
|
@@ -1756,11 +1887,14 @@ const adapterOas = (0, _kubb_core.defineAdapter)((options) => {
|
|
|
1756
1887
|
} catch (_err) {}
|
|
1757
1888
|
const server = serverIndex !== void 0 ? oas.api.servers?.at(serverIndex) : void 0;
|
|
1758
1889
|
const baseURL = server?.url ? resolveServerUrl(server, serverVariables) : void 0;
|
|
1890
|
+
const parser = createOasParser(oas, {
|
|
1891
|
+
contentType,
|
|
1892
|
+
collisionDetection
|
|
1893
|
+
});
|
|
1894
|
+
nameMapping.clear();
|
|
1895
|
+
for (const [key, value] of parser.nameMapping) nameMapping.set(key, value);
|
|
1759
1896
|
return (0, _kubb_ast.createRoot)({
|
|
1760
|
-
...
|
|
1761
|
-
contentType,
|
|
1762
|
-
collisionDetection
|
|
1763
|
-
}).parse({
|
|
1897
|
+
...parser.parse({
|
|
1764
1898
|
dateType,
|
|
1765
1899
|
integerType,
|
|
1766
1900
|
unknownType,
|