zod 4.1.0 → 4.2.0-canary.20250824T204911

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "4.1.0",
3
+ "version": "4.2.0-canary.20250824T204911",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Colin McDonnell <zod@colinhacks.com>",
@@ -55,6 +55,28 @@ export interface ZodType<
55
55
  params?: core.ParseContext<core.$ZodIssue>
56
56
  ) => Promise<parse.ZodSafeParseResult<core.output<this>>>;
57
57
 
58
+ // encoding/decoding
59
+ encode(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): core.input<this>;
60
+ decode(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
61
+ encodeAsync(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<core.input<this>>;
62
+ decodeAsync(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
63
+ safeEncode(
64
+ data: core.output<this>,
65
+ params?: core.ParseContext<core.$ZodIssue>
66
+ ): parse.ZodSafeParseResult<core.input<this>>;
67
+ safeDecode(
68
+ data: core.input<this>,
69
+ params?: core.ParseContext<core.$ZodIssue>
70
+ ): parse.ZodSafeParseResult<core.output<this>>;
71
+ safeEncodeAsync(
72
+ data: core.output<this>,
73
+ params?: core.ParseContext<core.$ZodIssue>
74
+ ): Promise<parse.ZodSafeParseResult<core.input<this>>>;
75
+ safeDecodeAsync(
76
+ data: core.input<this>,
77
+ params?: core.ParseContext<core.$ZodIssue>
78
+ ): Promise<parse.ZodSafeParseResult<core.output<this>>>;
79
+
58
80
  // refinements
59
81
  refine(check: (arg: core.output<this>) => unknown | Promise<unknown>, params?: string | core.$ZodCustomParams): this;
60
82
  superRefine(
@@ -150,6 +172,16 @@ export const ZodType: core.$constructor<ZodType> = /*@__PURE__*/ core.$construct
150
172
  inst.safeParseAsync = async (data, params) => parse.safeParseAsync(inst, data, params);
151
173
  inst.spa = inst.safeParseAsync;
152
174
 
175
+ // encoding/decoding
176
+ inst.encode = (data, params) => parse.encode(inst, data, params);
177
+ inst.decode = (data, params) => parse.decode(inst, data, params);
178
+ inst.encodeAsync = async (data, params) => parse.encodeAsync(inst, data, params);
179
+ inst.decodeAsync = async (data, params) => parse.decodeAsync(inst, data, params);
180
+ inst.safeEncode = (data, params) => parse.safeEncode(inst, data, params);
181
+ inst.safeDecode = (data, params) => parse.safeDecode(inst, data, params);
182
+ inst.safeEncodeAsync = async (data, params) => parse.safeEncodeAsync(inst, data, params);
183
+ inst.safeDecodeAsync = async (data, params) => parse.safeDecodeAsync(inst, data, params);
184
+
153
185
  // refinements
154
186
  inst.refine = (check, params) => inst.check(refine(check, params));
155
187
  inst.superRefine = (refinement) => inst.check(superRefine(refinement));
@@ -653,6 +653,24 @@ describe("toJSONSchema", () => {
653
653
  });
654
654
 
655
655
  test("tuple", () => {
656
+ const schema = z.tuple([z.string(), z.number()]);
657
+ expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
658
+ {
659
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
660
+ "prefixItems": [
661
+ {
662
+ "type": "string",
663
+ },
664
+ {
665
+ "type": "number",
666
+ },
667
+ ],
668
+ "type": "array",
669
+ }
670
+ `);
671
+ });
672
+
673
+ test("tuple with rest", () => {
656
674
  const schema = z.tuple([z.string(), z.number()]).rest(z.boolean());
657
675
  expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
658
676
  {
@@ -673,6 +691,46 @@ describe("toJSONSchema", () => {
673
691
  `);
674
692
  });
675
693
 
694
+ test("tuple openapi", () => {
695
+ const schema = z.tuple([z.string(), z.number()]);
696
+ expect(z.toJSONSchema(schema, { target: "openapi-3.0" })).toMatchInlineSnapshot(`
697
+ {
698
+ "items": [
699
+ {
700
+ "type": "string",
701
+ },
702
+ {
703
+ "type": "number",
704
+ },
705
+ ],
706
+ "maxItems": 2,
707
+ "minItems": 2,
708
+ "type": "array",
709
+ }
710
+ `);
711
+ });
712
+
713
+ test("tuple with rest openapi", () => {
714
+ const schema = z.tuple([z.string(), z.number()]).rest(z.boolean());
715
+ expect(z.toJSONSchema(schema, { target: "openapi-3.0" })).toMatchInlineSnapshot(`
716
+ {
717
+ "items": [
718
+ {
719
+ "type": "string",
720
+ },
721
+ {
722
+ "type": "number",
723
+ },
724
+ {
725
+ "type": "boolean",
726
+ },
727
+ ],
728
+ "minItems": 2,
729
+ "type": "array",
730
+ }
731
+ `);
732
+ });
733
+
676
734
  test("promise", () => {
677
735
  const schema = z.promise(z.string());
678
736
  expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
@@ -371,32 +371,34 @@ export class JSONSchemaGenerator {
371
371
  const prefixItems = def.items.map((x, i) =>
372
372
  this.process(x, { ...params, path: [...params.path, "prefixItems", i] })
373
373
  );
374
+ const rest = def.rest
375
+ ? this.process(def.rest, {
376
+ ...params,
377
+ path: [...params.path, "items"],
378
+ })
379
+ : null;
380
+
374
381
  if (this.target === "draft-2020-12") {
375
382
  json.prefixItems = prefixItems;
383
+ if (rest) {
384
+ json.items = rest;
385
+ }
386
+ } else if (this.target === "openapi-3.0") {
387
+ json.items = [...prefixItems];
388
+ if (rest) {
389
+ json.items.push(rest);
390
+ }
391
+ json.minItems = prefixItems.length;
392
+ if (!rest) {
393
+ json.maxItems = prefixItems.length;
394
+ }
376
395
  } else {
377
396
  json.items = prefixItems;
378
- }
379
-
380
- if (def.rest) {
381
- const rest = this.process(def.rest, {
382
- ...params,
383
- path: [...params.path, "items"],
384
- });
385
- if (this.target === "draft-2020-12") {
386
- json.items = rest;
387
- } else {
397
+ if (rest) {
388
398
  json.additionalItems = rest;
389
399
  }
390
400
  }
391
401
 
392
- // additionalItems
393
- if (def.rest) {
394
- json.items = this.process(def.rest, {
395
- ...params,
396
- path: [...params.path, "items"],
397
- });
398
- }
399
-
400
402
  // length
401
403
  const { minimum, maximum } = schema._zod.bag as {
402
404
  minimum?: number;
@@ -1,5 +1,5 @@
1
1
  export const version = {
2
2
  major: 4,
3
3
  minor: 1,
4
- patch: 0 as number,
4
+ patch: 1 as number,
5
5
  } as const;
@@ -149,6 +149,15 @@ exports.ZodType = core.$constructor("ZodType", (inst, def) => {
149
149
  inst.parseAsync = async (data, params) => parse.parseAsync(inst, data, params, { callee: inst.parseAsync });
150
150
  inst.safeParseAsync = async (data, params) => parse.safeParseAsync(inst, data, params);
151
151
  inst.spa = inst.safeParseAsync;
152
+ // encoding/decoding
153
+ inst.encode = (data, params) => parse.encode(inst, data, params);
154
+ inst.decode = (data, params) => parse.decode(inst, data, params);
155
+ inst.encodeAsync = async (data, params) => parse.encodeAsync(inst, data, params);
156
+ inst.decodeAsync = async (data, params) => parse.decodeAsync(inst, data, params);
157
+ inst.safeEncode = (data, params) => parse.safeEncode(inst, data, params);
158
+ inst.safeDecode = (data, params) => parse.safeDecode(inst, data, params);
159
+ inst.safeEncodeAsync = async (data, params) => parse.safeEncodeAsync(inst, data, params);
160
+ inst.safeDecodeAsync = async (data, params) => parse.safeDecodeAsync(inst, data, params);
152
161
  // refinements
153
162
  inst.refine = (check, params) => inst.check(refine(check, params));
154
163
  inst.superRefine = (refinement) => inst.check(superRefine(refinement));
@@ -21,6 +21,14 @@ export interface ZodType<out Output = unknown, out Input = unknown, out Internal
21
21
  parseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
22
22
  safeParseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.output<this>>>;
23
23
  spa: (data: unknown, params?: core.ParseContext<core.$ZodIssue>) => Promise<parse.ZodSafeParseResult<core.output<this>>>;
24
+ encode(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): core.input<this>;
25
+ decode(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
26
+ encodeAsync(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<core.input<this>>;
27
+ decodeAsync(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
28
+ safeEncode(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.input<this>>;
29
+ safeDecode(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.output<this>>;
30
+ safeEncodeAsync(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.input<this>>>;
31
+ safeDecodeAsync(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.output<this>>>;
24
32
  refine(check: (arg: core.output<this>) => unknown | Promise<unknown>, params?: string | core.$ZodCustomParams): this;
25
33
  superRefine(refinement: (arg: core.output<this>, ctx: core.$RefinementCtx<core.output<this>>) => void | Promise<void>): this;
26
34
  overwrite(fn: (x: core.output<this>) => core.output<this>): this;
@@ -21,6 +21,14 @@ export interface ZodType<out Output = unknown, out Input = unknown, out Internal
21
21
  parseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
22
22
  safeParseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.output<this>>>;
23
23
  spa: (data: unknown, params?: core.ParseContext<core.$ZodIssue>) => Promise<parse.ZodSafeParseResult<core.output<this>>>;
24
+ encode(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): core.input<this>;
25
+ decode(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
26
+ encodeAsync(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<core.input<this>>;
27
+ decodeAsync(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
28
+ safeEncode(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.input<this>>;
29
+ safeDecode(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.output<this>>;
30
+ safeEncodeAsync(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.input<this>>>;
31
+ safeDecodeAsync(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.output<this>>>;
24
32
  refine(check: (arg: core.output<this>) => unknown | Promise<unknown>, params?: string | core.$ZodCustomParams): this;
25
33
  superRefine(refinement: (arg: core.output<this>, ctx: core.$RefinementCtx<core.output<this>>) => void | Promise<void>): this;
26
34
  overwrite(fn: (x: core.output<this>) => core.output<this>): this;
@@ -32,6 +32,15 @@ export const ZodType = /*@__PURE__*/ core.$constructor("ZodType", (inst, def) =>
32
32
  inst.parseAsync = async (data, params) => parse.parseAsync(inst, data, params, { callee: inst.parseAsync });
33
33
  inst.safeParseAsync = async (data, params) => parse.safeParseAsync(inst, data, params);
34
34
  inst.spa = inst.safeParseAsync;
35
+ // encoding/decoding
36
+ inst.encode = (data, params) => parse.encode(inst, data, params);
37
+ inst.decode = (data, params) => parse.decode(inst, data, params);
38
+ inst.encodeAsync = async (data, params) => parse.encodeAsync(inst, data, params);
39
+ inst.decodeAsync = async (data, params) => parse.decodeAsync(inst, data, params);
40
+ inst.safeEncode = (data, params) => parse.safeEncode(inst, data, params);
41
+ inst.safeDecode = (data, params) => parse.safeDecode(inst, data, params);
42
+ inst.safeEncodeAsync = async (data, params) => parse.safeEncodeAsync(inst, data, params);
43
+ inst.safeDecodeAsync = async (data, params) => parse.safeDecodeAsync(inst, data, params);
35
44
  // refinements
36
45
  inst.refine = (check, params) => inst.check(refine(check, params));
37
46
  inst.superRefine = (refinement) => inst.check(superRefine(refinement));
@@ -289,31 +289,34 @@ class JSONSchemaGenerator {
289
289
  const json = _json;
290
290
  json.type = "array";
291
291
  const prefixItems = def.items.map((x, i) => this.process(x, { ...params, path: [...params.path, "prefixItems", i] }));
292
+ const rest = def.rest
293
+ ? this.process(def.rest, {
294
+ ...params,
295
+ path: [...params.path, "items"],
296
+ })
297
+ : null;
292
298
  if (this.target === "draft-2020-12") {
293
299
  json.prefixItems = prefixItems;
300
+ if (rest) {
301
+ json.items = rest;
302
+ }
303
+ }
304
+ else if (this.target === "openapi-3.0") {
305
+ json.items = [...prefixItems];
306
+ if (rest) {
307
+ json.items.push(rest);
308
+ }
309
+ json.minItems = prefixItems.length;
310
+ if (!rest) {
311
+ json.maxItems = prefixItems.length;
312
+ }
294
313
  }
295
314
  else {
296
315
  json.items = prefixItems;
297
- }
298
- if (def.rest) {
299
- const rest = this.process(def.rest, {
300
- ...params,
301
- path: [...params.path, "items"],
302
- });
303
- if (this.target === "draft-2020-12") {
304
- json.items = rest;
305
- }
306
- else {
316
+ if (rest) {
307
317
  json.additionalItems = rest;
308
318
  }
309
319
  }
310
- // additionalItems
311
- if (def.rest) {
312
- json.items = this.process(def.rest, {
313
- ...params,
314
- path: [...params.path, "items"],
315
- });
316
- }
317
320
  // length
318
321
  const { minimum, maximum } = schema._zod.bag;
319
322
  if (typeof minimum === "number")
@@ -285,31 +285,34 @@ export class JSONSchemaGenerator {
285
285
  const json = _json;
286
286
  json.type = "array";
287
287
  const prefixItems = def.items.map((x, i) => this.process(x, { ...params, path: [...params.path, "prefixItems", i] }));
288
+ const rest = def.rest
289
+ ? this.process(def.rest, {
290
+ ...params,
291
+ path: [...params.path, "items"],
292
+ })
293
+ : null;
288
294
  if (this.target === "draft-2020-12") {
289
295
  json.prefixItems = prefixItems;
296
+ if (rest) {
297
+ json.items = rest;
298
+ }
299
+ }
300
+ else if (this.target === "openapi-3.0") {
301
+ json.items = [...prefixItems];
302
+ if (rest) {
303
+ json.items.push(rest);
304
+ }
305
+ json.minItems = prefixItems.length;
306
+ if (!rest) {
307
+ json.maxItems = prefixItems.length;
308
+ }
290
309
  }
291
310
  else {
292
311
  json.items = prefixItems;
293
- }
294
- if (def.rest) {
295
- const rest = this.process(def.rest, {
296
- ...params,
297
- path: [...params.path, "items"],
298
- });
299
- if (this.target === "draft-2020-12") {
300
- json.items = rest;
301
- }
302
- else {
312
+ if (rest) {
303
313
  json.additionalItems = rest;
304
314
  }
305
315
  }
306
- // additionalItems
307
- if (def.rest) {
308
- json.items = this.process(def.rest, {
309
- ...params,
310
- path: [...params.path, "items"],
311
- });
312
- }
313
316
  // length
314
317
  const { minimum, maximum } = schema._zod.bag;
315
318
  if (typeof minimum === "number")
@@ -4,5 +4,5 @@ exports.version = void 0;
4
4
  exports.version = {
5
5
  major: 4,
6
6
  minor: 1,
7
- patch: 0,
7
+ patch: 1,
8
8
  };
@@ -1,5 +1,5 @@
1
1
  export const version = {
2
2
  major: 4,
3
3
  minor: 1,
4
- patch: 0,
4
+ patch: 1,
5
5
  };