@kubb/adapter-oas 5.16.0 → 5.16.1
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 +46 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +46 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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.16.
|
|
22
|
+
var version = "5.16.1";
|
|
23
23
|
// src/constants.ts
|
|
24
24
|
/**
|
|
25
25
|
* Default parser options applied when no explicit options are provided.
|
|
@@ -1378,7 +1378,7 @@ function flattenSchema(schema) {
|
|
|
1378
1378
|
/**
|
|
1379
1379
|
* Links one freshly converted schema and its nested schemas to their RFC 6901 pointers
|
|
1380
1380
|
* (`#/components/schemas/Pet/properties/owner/properties/name`), and reports the advisory
|
|
1381
|
-
* diagnostics (`KUBB_UNSUPPORTED_FORMAT`, `KUBB_DEPRECATED`) against them.
|
|
1381
|
+
* diagnostics (`KUBB_UNSUPPORTED_FORMAT`, `KUBB_DEPRECATED`, `KUBB_DUPLICATE_DISCRIMINATOR`) against them.
|
|
1382
1382
|
* Refs are not followed, so the resolved schema is handled under its own walk.
|
|
1383
1383
|
* Reports land in the active build run, are a no-op outside one, and repeats are deduped by the build.
|
|
1384
1384
|
*/
|
|
@@ -1423,11 +1423,55 @@ function visit(node, pointer) {
|
|
|
1423
1423
|
for (const member of node.members ?? []) visit(member, `${pointer}/not`);
|
|
1424
1424
|
return;
|
|
1425
1425
|
}
|
|
1426
|
+
if (node.type === "union" && node.discriminatorPropertyName) reportDuplicateDiscriminators(node, node.discriminatorPropertyName, pointer);
|
|
1426
1427
|
if (node.type === "union" || node.type === "intersection") {
|
|
1427
1428
|
const keyword = node.type === "intersection" ? "allOf" : node.strategy === "any" ? "anyOf" : "oneOf";
|
|
1428
1429
|
for (const [index, member] of (node.members ?? []).entries()) visit(member, `${pointer}/${keyword}/${index}`);
|
|
1429
1430
|
}
|
|
1430
1431
|
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Reports a declared discriminator whose value pins more than one member. The spec cannot tell
|
|
1434
|
+
* those members apart, and Zod's `z.discriminatedUnion` throws on the first parse.
|
|
1435
|
+
* One diagnostic per union, since the build dedupes by code and pointer.
|
|
1436
|
+
*/
|
|
1437
|
+
function reportDuplicateDiscriminators(node, propertyName, pointer) {
|
|
1438
|
+
const keyword = node.strategy === "any" ? "anyOf" : "oneOf";
|
|
1439
|
+
const membersByValue = /* @__PURE__ */ new Map();
|
|
1440
|
+
for (const [index, member] of (node.members ?? []).entries()) {
|
|
1441
|
+
const label = memberName(member) ?? `${keyword}/${index}`;
|
|
1442
|
+
for (const value of memberValues(member, propertyName)) membersByValue.set(value, [...membersByValue.get(value) ?? [], label]);
|
|
1443
|
+
}
|
|
1444
|
+
const duplicates = [...membersByValue].filter(([, members]) => members.length > 1);
|
|
1445
|
+
if (!duplicates.length) return;
|
|
1446
|
+
Diagnostics.report({
|
|
1447
|
+
code: Diagnostics.code.duplicateDiscriminator,
|
|
1448
|
+
severity: "warning",
|
|
1449
|
+
message: duplicates.map(([value, members]) => `Discriminator "${propertyName}" value ${JSON.stringify(value)} matches more than one member (${members.join(", ")}).`).join(" "),
|
|
1450
|
+
help: `Give each member its own "${propertyName}" value, or drop the discriminator. Zod's z.discriminatedUnion throws on the first parse of this union.`,
|
|
1451
|
+
location: {
|
|
1452
|
+
kind: "schema",
|
|
1453
|
+
pointer
|
|
1454
|
+
}
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
function memberValues(node, propertyName, seen = /* @__PURE__ */ new Set()) {
|
|
1458
|
+
if (seen.has(node)) return [];
|
|
1459
|
+
seen.add(node);
|
|
1460
|
+
const target = node.type === "ref" && node.schema ? node.schema : node;
|
|
1461
|
+
if (target.type === "union") return [...new Set(target.members?.flatMap((member) => memberValues(member, propertyName, seen)))];
|
|
1462
|
+
return intersect(ast.resolveSchemaProperties({
|
|
1463
|
+
node,
|
|
1464
|
+
propertyName
|
|
1465
|
+
}).map((property) => [...ast.getSchemaLiteralValues(property.schema)]));
|
|
1466
|
+
}
|
|
1467
|
+
function intersect(slices) {
|
|
1468
|
+
const pinned = slices.filter((values) => values.length > 0);
|
|
1469
|
+
return pinned.reduce((acc, values) => acc.filter((value) => values.includes(value)), pinned[0] ?? []);
|
|
1470
|
+
}
|
|
1471
|
+
function memberName(member) {
|
|
1472
|
+
if (member.type === "ref") return member.name ?? void 0;
|
|
1473
|
+
if (member.type === "intersection") return member.members?.map(memberName).find(Boolean);
|
|
1474
|
+
}
|
|
1431
1475
|
// src/operation.ts
|
|
1432
1476
|
function slugify(value) {
|
|
1433
1477
|
return value.replace(/[^a-zA-Z0-9]/g, "-").replace(/-{2,}/g, "-").replace(/^-|-$/g, "");
|