@kubb/plugin-zod 5.4.0-canary.20260925T211808 → 5.4.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 +52 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +52 -6
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -821,13 +821,38 @@ function shouldCoerce(coercion, type) {
|
|
|
821
821
|
if (coercion === true) return true;
|
|
822
822
|
return !!coercion[type];
|
|
823
823
|
}
|
|
824
|
+
function hasPropertyNames(node) {
|
|
825
|
+
return "propertyNames" in node && Boolean(node.propertyNames);
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Whether the schema node represents a closed or finite set of keys (e.g. enum, literal,
|
|
829
|
+
* or union of enums/literals).
|
|
830
|
+
*
|
|
831
|
+
* In Zod v4, passing a closed key schema to `z.record()` enforces exhaustiveness (all keys
|
|
832
|
+
* must exist in the input). OpenAPI 3.1 `propertyNames` only validates present keys without
|
|
833
|
+
* requiring all keys to exist, so closed key schemas use `z.partialRecord()` instead.
|
|
834
|
+
*/
|
|
835
|
+
function isClosedKeySchema(node) {
|
|
836
|
+
if (!node) return false;
|
|
837
|
+
const resolved = (0, kubb_kit.syncSchemaRef)(node);
|
|
838
|
+
if (resolved.type === "enum") return true;
|
|
839
|
+
if (resolved.type === "union") {
|
|
840
|
+
const members = resolved.members ?? [];
|
|
841
|
+
return members.length > 0 && members.every(isClosedKeySchema);
|
|
842
|
+
}
|
|
843
|
+
return false;
|
|
844
|
+
}
|
|
824
845
|
/**
|
|
825
846
|
* Whether the node is a plain inline object whose shape can be lifted into an `.extend({ … })`
|
|
826
847
|
* argument. A catchall, `patternProperties`, or a nullable/optional wrapper cannot, so those stay
|
|
827
848
|
* on `.and(…)`.
|
|
828
849
|
*/
|
|
829
850
|
function isPlainInlineObject(node) {
|
|
830
|
-
|
|
851
|
+
if (node.type !== "object") return false;
|
|
852
|
+
if (node.nullable || node.optional || node.nullish) return false;
|
|
853
|
+
const hasAdditionalProperties = node.additionalProperties !== void 0;
|
|
854
|
+
const hasPatternProperties = Boolean(node.patternProperties);
|
|
855
|
+
return !hasAdditionalProperties && !hasPatternProperties && !hasPropertyNames(node);
|
|
831
856
|
}
|
|
832
857
|
/**
|
|
833
858
|
* Whether a node renders as a bare Zod object — one that accepts `.extend(…)` and can be a
|
|
@@ -838,7 +863,12 @@ function isPlainInlineObject(node) {
|
|
|
838
863
|
*/
|
|
839
864
|
function isObjectSchemaNode(node, cyclicSchemas) {
|
|
840
865
|
if (node.nullable || node.optional || node.nullish) return false;
|
|
841
|
-
if (node.type === "object")
|
|
866
|
+
if (node.type === "object") {
|
|
867
|
+
const hasProperties = Boolean(node.properties?.length);
|
|
868
|
+
const hasTypedAdditionalProperties = Boolean(node.additionalProperties && node.additionalProperties !== true);
|
|
869
|
+
const hasPatternProperties = Boolean(node.patternProperties);
|
|
870
|
+
return !(!hasProperties && (hasTypedAdditionalProperties || hasPatternProperties || hasPropertyNames(node)));
|
|
871
|
+
}
|
|
842
872
|
if (node.type === "ref") {
|
|
843
873
|
const refName = kubb_kit.ast.resolveRefName(node);
|
|
844
874
|
if (refName && cyclicSchemas?.has(refName)) return false;
|
|
@@ -1212,6 +1242,7 @@ function containsDirectionalNode({ node, printerOptions, seen = /* @__PURE__ */
|
|
|
1212
1242
|
if ("items" in node && node.items) children.push(...node.items);
|
|
1213
1243
|
if ("members" in node && node.members) children.push(...node.members);
|
|
1214
1244
|
if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) children.push(node.additionalProperties);
|
|
1245
|
+
if ("propertyNames" in node && node.propertyNames) children.push(node.propertyNames);
|
|
1215
1246
|
return children.some((child) => containsDirectionalNode({
|
|
1216
1247
|
node: child,
|
|
1217
1248
|
printerOptions,
|
|
@@ -1376,14 +1407,23 @@ const printerZod = kubb_kit.ast.createPrinter((options) => {
|
|
|
1376
1407
|
object(node) {
|
|
1377
1408
|
const entries = node.properties ?? [];
|
|
1378
1409
|
const patterns = node.patternProperties ? Object.entries(node.patternProperties) : [];
|
|
1410
|
+
const propertyNamesNode = "propertyNames" in node ? node.propertyNames : void 0;
|
|
1411
|
+
const propertyNamesKeySchema = propertyNamesNode ? this.transform(propertyNamesNode) : null;
|
|
1379
1412
|
const isStrict = node.additionalProperties === false && patterns.length === 0;
|
|
1380
|
-
const
|
|
1413
|
+
const isLoose = node.additionalProperties === true;
|
|
1414
|
+
const objectBase = `${isStrict ? "z.strictObject" : isLoose ? "z.looseObject" : "z.object"}(${buildZodObjectShape(this, node)})`;
|
|
1381
1415
|
return (() => {
|
|
1416
|
+
const recordFn = isClosedKeySchema(propertyNamesNode) ? "z.partialRecord" : "z.record";
|
|
1382
1417
|
if (node.additionalProperties && node.additionalProperties !== true) {
|
|
1383
1418
|
const catchallType = this.transform(node.additionalProperties);
|
|
1419
|
+
if (entries.length === 0) return catchallType ? `${recordFn}(${propertyNamesKeySchema || "z.string()"}, ${catchallType})` : objectBase;
|
|
1384
1420
|
return catchallType ? `${objectBase}.catchall(${catchallType})` : objectBase;
|
|
1385
1421
|
}
|
|
1386
|
-
if (
|
|
1422
|
+
if (entries.length === 0 && patterns.length === 0 && propertyNamesKeySchema && !isStrict) {
|
|
1423
|
+
const unknownType = this.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }));
|
|
1424
|
+
return `${recordFn}(${propertyNamesKeySchema}, ${unknownType})`;
|
|
1425
|
+
}
|
|
1426
|
+
if (node.additionalProperties === true) return objectBase;
|
|
1387
1427
|
if (isStrict) return objectBase;
|
|
1388
1428
|
if (patterns.length > 0) {
|
|
1389
1429
|
const values = patterns.map(([, valueSchema]) => {
|
|
@@ -1639,13 +1679,19 @@ const printerZodMini = kubb_kit.ast.createPrinter((options) => {
|
|
|
1639
1679
|
object(node) {
|
|
1640
1680
|
const entries = node.properties ?? [];
|
|
1641
1681
|
const patterns = node.patternProperties ? Object.entries(node.patternProperties) : [];
|
|
1682
|
+
const propertyNamesNode = "propertyNames" in node ? node.propertyNames : void 0;
|
|
1683
|
+
const propertyNamesKeySchema = propertyNamesNode ? this.transform(propertyNamesNode) : null;
|
|
1642
1684
|
const isStrict = node.additionalProperties === false && patterns.length === 0;
|
|
1643
|
-
const
|
|
1685
|
+
const isLoose = node.additionalProperties === true;
|
|
1686
|
+
const objectBase = `${isStrict ? "z.strictObject" : isLoose ? "z.looseObject" : "z.object"}(${buildZodMiniObjectShape(this, node)})`;
|
|
1687
|
+
const recordFn = isClosedKeySchema(propertyNamesNode) ? "z.partialRecord" : "z.record";
|
|
1644
1688
|
if (node.additionalProperties && node.additionalProperties !== true) {
|
|
1645
1689
|
const catchallType = this.transform(node.additionalProperties);
|
|
1690
|
+
if (entries.length === 0) return catchallType ? `${recordFn}(${propertyNamesKeySchema || "z.string()"}, ${catchallType})` : objectBase;
|
|
1646
1691
|
return catchallType ? `z.catchall(${objectBase}, ${catchallType})` : objectBase;
|
|
1647
1692
|
}
|
|
1648
|
-
if (
|
|
1693
|
+
if (entries.length === 0 && patterns.length === 0 && propertyNamesKeySchema && !isStrict) return `${recordFn}(${propertyNamesKeySchema}, ${this.transform(kubb_kit.ast.factory.createSchema({ type: "unknown" }))})`;
|
|
1694
|
+
if (node.additionalProperties === true) return objectBase;
|
|
1649
1695
|
if (isStrict) return objectBase;
|
|
1650
1696
|
if (patterns.length > 0) {
|
|
1651
1697
|
const values = patterns.map(([, valueSchema]) => {
|