@kubb/adapter-oas 5.16.0 → 5.17.0
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 +74 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +74 -22
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var compatibility = {
|
|
|
19
19
|
"node": ">=22.22"
|
|
20
20
|
};
|
|
21
21
|
// package.json
|
|
22
|
-
var version = "5.
|
|
22
|
+
var version = "5.17.0";
|
|
23
23
|
// src/constants.ts
|
|
24
24
|
/**
|
|
25
25
|
* Default parser options applied when no explicit options are provided.
|
|
@@ -1204,6 +1204,30 @@ function resolveServerUrl(server, overrides) {
|
|
|
1204
1204
|
}
|
|
1205
1205
|
return url;
|
|
1206
1206
|
}
|
|
1207
|
+
/**
|
|
1208
|
+
* Maps OpenAPI servers to `InputServer` entries: drops entries without a `url` and fills `{variable}` defaults.
|
|
1209
|
+
*/
|
|
1210
|
+
function toInputServers(servers) {
|
|
1211
|
+
return servers.filter((entry) => entry.url).map(({ url, description, variables }) => {
|
|
1212
|
+
const declared = variables && Object.keys(variables).length > 0 ? { variables } : {};
|
|
1213
|
+
try {
|
|
1214
|
+
return {
|
|
1215
|
+
url: resolveServerUrl({
|
|
1216
|
+
url,
|
|
1217
|
+
variables
|
|
1218
|
+
}),
|
|
1219
|
+
description,
|
|
1220
|
+
...declared
|
|
1221
|
+
};
|
|
1222
|
+
} catch {
|
|
1223
|
+
return {
|
|
1224
|
+
url,
|
|
1225
|
+
description,
|
|
1226
|
+
...declared
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1207
1231
|
// src/model/mediaType.ts
|
|
1208
1232
|
/**
|
|
1209
1233
|
* The media type without its parameters, so `text/event-stream; charset=utf-8` matches the bare name.
|
|
@@ -1378,7 +1402,7 @@ function flattenSchema(schema) {
|
|
|
1378
1402
|
/**
|
|
1379
1403
|
* Links one freshly converted schema and its nested schemas to their RFC 6901 pointers
|
|
1380
1404
|
* (`#/components/schemas/Pet/properties/owner/properties/name`), and reports the advisory
|
|
1381
|
-
* diagnostics (`KUBB_UNSUPPORTED_FORMAT`, `KUBB_DEPRECATED`) against them.
|
|
1405
|
+
* diagnostics (`KUBB_UNSUPPORTED_FORMAT`, `KUBB_DEPRECATED`, `KUBB_DUPLICATE_DISCRIMINATOR`) against them.
|
|
1382
1406
|
* Refs are not followed, so the resolved schema is handled under its own walk.
|
|
1383
1407
|
* Reports land in the active build run, are a no-op outside one, and repeats are deduped by the build.
|
|
1384
1408
|
*/
|
|
@@ -1423,11 +1447,55 @@ function visit(node, pointer) {
|
|
|
1423
1447
|
for (const member of node.members ?? []) visit(member, `${pointer}/not`);
|
|
1424
1448
|
return;
|
|
1425
1449
|
}
|
|
1450
|
+
if (node.type === "union" && node.discriminatorPropertyName) reportDuplicateDiscriminators(node, node.discriminatorPropertyName, pointer);
|
|
1426
1451
|
if (node.type === "union" || node.type === "intersection") {
|
|
1427
1452
|
const keyword = node.type === "intersection" ? "allOf" : node.strategy === "any" ? "anyOf" : "oneOf";
|
|
1428
1453
|
for (const [index, member] of (node.members ?? []).entries()) visit(member, `${pointer}/${keyword}/${index}`);
|
|
1429
1454
|
}
|
|
1430
1455
|
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Reports a declared discriminator whose value pins more than one member. The spec cannot tell
|
|
1458
|
+
* those members apart, and Zod's `z.discriminatedUnion` throws on the first parse.
|
|
1459
|
+
* One diagnostic per union, since the build dedupes by code and pointer.
|
|
1460
|
+
*/
|
|
1461
|
+
function reportDuplicateDiscriminators(node, propertyName, pointer) {
|
|
1462
|
+
const keyword = node.strategy === "any" ? "anyOf" : "oneOf";
|
|
1463
|
+
const membersByValue = /* @__PURE__ */ new Map();
|
|
1464
|
+
for (const [index, member] of (node.members ?? []).entries()) {
|
|
1465
|
+
const label = memberName(member) ?? `${keyword}/${index}`;
|
|
1466
|
+
for (const value of memberValues(member, propertyName)) membersByValue.set(value, [...membersByValue.get(value) ?? [], label]);
|
|
1467
|
+
}
|
|
1468
|
+
const duplicates = [...membersByValue].filter(([, members]) => members.length > 1);
|
|
1469
|
+
if (!duplicates.length) return;
|
|
1470
|
+
Diagnostics.report({
|
|
1471
|
+
code: Diagnostics.code.duplicateDiscriminator,
|
|
1472
|
+
severity: "warning",
|
|
1473
|
+
message: duplicates.map(([value, members]) => `Discriminator "${propertyName}" value ${JSON.stringify(value)} matches more than one member (${members.join(", ")}).`).join(" "),
|
|
1474
|
+
help: `Give each member its own "${propertyName}" value, or drop the discriminator. Zod's z.discriminatedUnion throws on the first parse of this union.`,
|
|
1475
|
+
location: {
|
|
1476
|
+
kind: "schema",
|
|
1477
|
+
pointer
|
|
1478
|
+
}
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1481
|
+
function memberValues(node, propertyName, seen = /* @__PURE__ */ new Set()) {
|
|
1482
|
+
if (seen.has(node)) return [];
|
|
1483
|
+
seen.add(node);
|
|
1484
|
+
const target = node.type === "ref" && node.schema ? node.schema : node;
|
|
1485
|
+
if (target.type === "union") return [...new Set(target.members?.flatMap((member) => memberValues(member, propertyName, seen)))];
|
|
1486
|
+
return intersect(ast.resolveSchemaProperties({
|
|
1487
|
+
node,
|
|
1488
|
+
propertyName
|
|
1489
|
+
}).map((property) => [...ast.getSchemaLiteralValues(property.schema)]));
|
|
1490
|
+
}
|
|
1491
|
+
function intersect(slices) {
|
|
1492
|
+
const pinned = slices.filter((values) => values.length > 0);
|
|
1493
|
+
return pinned.reduce((acc, values) => acc.filter((value) => values.includes(value)), pinned[0] ?? []);
|
|
1494
|
+
}
|
|
1495
|
+
function memberName(member) {
|
|
1496
|
+
if (member.type === "ref") return member.name ?? void 0;
|
|
1497
|
+
if (member.type === "intersection") return member.members?.map(memberName).find(Boolean);
|
|
1498
|
+
}
|
|
1431
1499
|
// src/operation.ts
|
|
1432
1500
|
function slugify(value) {
|
|
1433
1501
|
return value.replace(/[^a-zA-Z0-9]/g, "-").replace(/-{2,}/g, "-").replace(/^-|-$/g, "");
|
|
@@ -1768,6 +1836,7 @@ function parseOperation({ operation, ...ctx }) {
|
|
|
1768
1836
|
const fallback = operation.pathItem[key];
|
|
1769
1837
|
return typeof fallback === "string" ? fallback : void 0;
|
|
1770
1838
|
};
|
|
1839
|
+
const servers = operation.schema.servers ?? operation.pathItem.servers;
|
|
1771
1840
|
return ast.factory.createOperation({
|
|
1772
1841
|
pointer,
|
|
1773
1842
|
operationId,
|
|
@@ -1781,7 +1850,8 @@ function parseOperation({ operation, ...ctx }) {
|
|
|
1781
1850
|
parameters,
|
|
1782
1851
|
requestBody,
|
|
1783
1852
|
responses,
|
|
1784
|
-
extensions: pickExtensions(operation.schema)
|
|
1853
|
+
extensions: pickExtensions(operation.schema),
|
|
1854
|
+
...servers && { servers: toInputServers(servers) }
|
|
1785
1855
|
});
|
|
1786
1856
|
}
|
|
1787
1857
|
// src/emit/createNode.ts
|
|
@@ -3340,25 +3410,7 @@ const adapterOas = defineExtension({
|
|
|
3340
3410
|
document,
|
|
3341
3411
|
server
|
|
3342
3412
|
}),
|
|
3343
|
-
servers: (document.servers ?? [])
|
|
3344
|
-
const declared = variables && Object.keys(variables).length > 0 ? { variables } : {};
|
|
3345
|
-
try {
|
|
3346
|
-
return {
|
|
3347
|
-
url: resolveServerUrl({
|
|
3348
|
-
url,
|
|
3349
|
-
variables
|
|
3350
|
-
}),
|
|
3351
|
-
description,
|
|
3352
|
-
...declared
|
|
3353
|
-
};
|
|
3354
|
-
} catch {
|
|
3355
|
-
return {
|
|
3356
|
-
url,
|
|
3357
|
-
description,
|
|
3358
|
-
...declared
|
|
3359
|
-
};
|
|
3360
|
-
}
|
|
3361
|
-
}),
|
|
3413
|
+
servers: toInputServers(document.servers ?? []),
|
|
3362
3414
|
securitySchemes: Object.entries(document.components?.securitySchemes ?? {}).flatMap(([name, value]) => {
|
|
3363
3415
|
const scheme = refs.deref(value);
|
|
3364
3416
|
return scheme?.type ? [{
|