@kubb/plugin-zod 5.8.0 → 5.8.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 CHANGED
@@ -1263,6 +1263,37 @@ function printWithOmit(ctx, node, modify, mini = false) {
1263
1263
  }
1264
1264
  // src/printers/zodNodes.ts
1265
1265
  /**
1266
+ * Reads a union of bare single-value enums as one enum, except under `xor` or an enum override, which need each member.
1267
+ * Only a numeric union with a `format` coerces, because it printed as `z.coerce.number()` before the adapter kept its values.
1268
+ */
1269
+ function getLiteralUnion({ node, options }) {
1270
+ if (node.strategy === "one" && options.oneOfType === "xor" || options.nodes?.enum) return void 0;
1271
+ const values = (node.members ?? []).map((member) => {
1272
+ const enumNode = _kubb_kit.ast.narrowSchema(member, _kubb_kit.ast.schemaTypes.enum);
1273
+ return enumNode && !enumNode.name && !enumNode.nullable && !enumNode.namedEnumValues && enumNode.enumValues?.length === 1 ? enumNode.enumValues[0] : void 0;
1274
+ });
1275
+ if (!values.length || !values.every((value) => value !== void 0 && value !== null)) return void 0;
1276
+ return {
1277
+ values,
1278
+ coerce: !!node.format && values.every((value) => typeof value === "number") && shouldCoerce(options.coercion, "numbers")
1279
+ };
1280
+ }
1281
+ /**
1282
+ * Whether a discriminated union member's discriminator property prints as a coerced literal union.
1283
+ */
1284
+ function hasCoercedDiscriminator({ member, propertyName, options }) {
1285
+ return _kubb_kit.ast.resolveSchemaProperties({
1286
+ node: member,
1287
+ propertyName
1288
+ }).some(({ schema }) => {
1289
+ const resolved = (0, _kubb_kit.syncSchemaRef)(schema);
1290
+ return resolved.type === "union" && !!getLiteralUnion({
1291
+ node: resolved,
1292
+ options
1293
+ })?.coerce;
1294
+ });
1295
+ }
1296
+ /**
1266
1297
  * Builds the scalar handlers both dialects share. They never recurse into children. The temporal
1267
1298
  * scalars and `bigint` differ per dialect, so each printer adds its own.
1268
1299
  */
@@ -1401,8 +1432,21 @@ function buildZodNodes(dialect, cyclicSchemas) {
1401
1432
  return `z.tuple(${buildList(mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(Boolean))})`;
1402
1433
  },
1403
1434
  union(node) {
1435
+ const literalUnion = getLiteralUnion({
1436
+ node,
1437
+ options: this.options
1438
+ });
1439
+ if (literalUnion) {
1440
+ const schema = buildEnum(literalUnion.values);
1441
+ return literalUnion.coerce ? dialect.coercedNumber(schema) : schema;
1442
+ }
1404
1443
  const nodeMembers = node.members ?? [];
1405
- const isDiscriminated = !!node.discriminatorPropertyName && nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemas));
1444
+ const { discriminatorPropertyName } = node;
1445
+ const isDiscriminated = !!discriminatorPropertyName && nodeMembers.every((m) => isObjectSchemaNode(m, cyclicSchemas)) && !nodeMembers.some((m) => hasCoercedDiscriminator({
1446
+ member: m,
1447
+ propertyName: discriminatorPropertyName,
1448
+ options: this.options
1449
+ }));
1406
1450
  const isXor = node.strategy === "one" && !isDiscriminated && this.options.oneOfType === "xor";
1407
1451
  const isStrict = node.strategy === "one" && !isXor && !unionsWithSiblings.has(node);
1408
1452
  const members = mapSchemaMembers(node, (memberNode) => this.transform(isStrict ? strictOneOfNode(memberNode) : memberNode)).map(({ schema, output }) => output && isStrict && dialect.strictMember ? dialect.strictMember(output, schema, cyclicSchemas) : output).filter(Boolean);
@@ -1588,6 +1632,7 @@ const standardDialect = {
1588
1632
  patternKey: patternKeySchema,
1589
1633
  objectShape: buildZodObjectShape,
1590
1634
  coercedInt: "z.coerce.number().int()",
1635
+ coercedNumber: (schema) => `z.coerce.number().pipe(${schema})`,
1591
1636
  catchall: (object, value) => `${object}.catchall(${value})`,
1592
1637
  nullable: (value) => `${value}.nullable()`,
1593
1638
  unique: (array) => `${array}.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" })`,
@@ -1696,6 +1741,7 @@ const miniDialect = {
1696
1741
  patternKey: patternKeySchemaMini,
1697
1742
  objectShape: buildZodMiniObjectShape,
1698
1743
  coercedInt: "z.coerce.number().check(z.int())",
1744
+ coercedNumber: (schema) => `z.pipe(z.coerce.number(), ${schema})`,
1699
1745
  catchall: (object, value) => `z.catchall(${object}, ${value})`,
1700
1746
  nullable: (value) => `z.nullable(${value})`,
1701
1747
  unique: (array) => `${array}.check(z.refine(items => new Set(items).size === items.length, { message: "Array entries must be unique" }))`,
@@ -2126,7 +2172,7 @@ var compatibility = {
2126
2172
  "node": ">=22.22"
2127
2173
  };
2128
2174
  // package.json
2129
- var version = "5.8.0";
2175
+ var version = "5.8.1";
2130
2176
  // src/resolvers/resolverZod.ts
2131
2177
  /**
2132
2178
  * Default resolver used by `@kubb/plugin-zod`. Decides the names and file