zod 4.0.8 → 4.0.10

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.0.8",
3
+ "version": "4.0.10",
4
4
  "type": "module",
5
5
  "author": "Colin McDonnell <zod@colinhacks.com>",
6
6
  "description": "TypeScript-first schema declaration and validation library with static type inference",
@@ -157,6 +157,7 @@ test("invalid discriminator value", () => {
157
157
  "code": "invalid_union",
158
158
  "errors": [],
159
159
  "note": "No matching discriminator",
160
+ "discriminator": "type",
160
161
  "path": [
161
162
  "type"
162
163
  ],
@@ -1,7 +1,6 @@
1
- // @ts-ignore
2
1
  import { File as WebFile } from "@web-std/file";
3
2
 
4
- import { afterEach, beforeEach, expect, test } from "vitest";
3
+ import { afterEach, beforeEach, expect, expectTypeOf, test } from "vitest";
5
4
 
6
5
  import * as z from "zod/v4";
7
6
 
@@ -27,6 +26,10 @@ test("passing validations", () => {
27
26
  expect(() => mimeCheck.parse(new File([""], "test.txt", { type: "text/csv" }))).toThrow();
28
27
  });
29
28
 
29
+ test("types", () => {
30
+ expectTypeOf(z.file().parse(new File([], "test.txt"))).toEqualTypeOf(new File([], "test.txt"));
31
+ });
32
+
30
33
  test("failing validations", () => {
31
34
  expect(minCheck.safeParse(new File(["1234"], "test.txt"))).toMatchInlineSnapshot(`
32
35
  {
@@ -134,3 +134,48 @@ test("non-aborted errors", () => {
134
134
  }
135
135
  `);
136
136
  });
137
+
138
+ test("surface continuable errors only if they exist", () => {
139
+ const schema = z.union([z.boolean(), z.uuid(), z.jwt()]);
140
+
141
+ expect(schema.safeParse("asdf")).toMatchInlineSnapshot(`
142
+ {
143
+ "error": [ZodError: [
144
+ {
145
+ "code": "invalid_union",
146
+ "errors": [
147
+ [
148
+ {
149
+ "expected": "boolean",
150
+ "code": "invalid_type",
151
+ "path": [],
152
+ "message": "Invalid input: expected boolean, received string"
153
+ }
154
+ ],
155
+ [
156
+ {
157
+ "origin": "string",
158
+ "code": "invalid_format",
159
+ "format": "uuid",
160
+ "pattern": "/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$/",
161
+ "path": [],
162
+ "message": "Invalid UUID"
163
+ }
164
+ ],
165
+ [
166
+ {
167
+ "code": "invalid_format",
168
+ "format": "jwt",
169
+ "path": [],
170
+ "message": "Invalid JWT"
171
+ }
172
+ ]
173
+ ],
174
+ "path": [],
175
+ "message": "Invalid input"
176
+ }
177
+ ]],
178
+ "success": false,
179
+ }
180
+ `);
181
+ });
@@ -67,6 +67,7 @@ export interface $ZodIssueInvalidUnion extends $ZodIssueBase {
67
67
  readonly code: "invalid_union";
68
68
  readonly errors: $ZodIssue[][];
69
69
  readonly input: unknown;
70
+ readonly discriminator?: string | undefined;
70
71
  }
71
72
 
72
73
  export interface $ZodIssueInvalidKey<Input = unknown> extends $ZodIssueBase {
@@ -1911,7 +1911,7 @@ function handleUnionResults(results: ParsePayload[], final: ParsePayload, inst:
1911
1911
  }
1912
1912
 
1913
1913
  const nonaborted = results.filter((r) => !util.aborted(r));
1914
- if (nonaborted.length > 0) {
1914
+ if (nonaborted.length === 1) {
1915
1915
  final.value = nonaborted[0].value;
1916
1916
  return nonaborted[0];
1917
1917
  }
@@ -2069,6 +2069,7 @@ export const $ZodDiscriminatedUnion: core.$constructor<$ZodDiscriminatedUnion> =
2069
2069
  code: "invalid_union",
2070
2070
  errors: [],
2071
2071
  note: "No matching discriminator",
2072
+ discriminator: def.discriminator,
2072
2073
  input,
2073
2074
  path: [def.discriminator],
2074
2075
  inst,
@@ -2781,6 +2782,9 @@ export const $ZodLiteral: core.$constructor<$ZodLiteral> = /*@__PURE__*/ core.$c
2781
2782
  "$ZodLiteral",
2782
2783
  (inst, def) => {
2783
2784
  $ZodType.init(inst, def);
2785
+ if (def.values.length === 0) {
2786
+ throw new Error("Cannot create literal schema with no valid values");
2787
+ }
2784
2788
 
2785
2789
  inst._zod.values = new Set<util.Literal>(def.values);
2786
2790
  inst._zod.pattern = new RegExp(
@@ -2859,8 +2863,8 @@ export const $ZodLiteral: core.$constructor<$ZodLiteral> = /*@__PURE__*/ core.$c
2859
2863
  type _File = typeof globalThis extends { File: infer F extends new (...args: any[]) => any } ? InstanceType<F> : {};
2860
2864
  /** Do not reference this directly. */
2861
2865
  export interface File extends _File {
2862
- type: string;
2863
- size: number;
2866
+ readonly type: string;
2867
+ readonly size: number;
2864
2868
  }
2865
2869
 
2866
2870
  export interface $ZodFileDef extends $ZodTypeDef {
@@ -1,5 +1,5 @@
1
1
  export const version = {
2
2
  major: 4,
3
3
  minor: 0,
4
- patch: 8 as number,
4
+ patch: 10 as number,
5
5
  } as const;
@@ -52,6 +52,7 @@ export interface $ZodIssueInvalidUnion extends $ZodIssueBase {
52
52
  readonly code: "invalid_union";
53
53
  readonly errors: $ZodIssue[][];
54
54
  readonly input: unknown;
55
+ readonly discriminator?: string | undefined;
55
56
  }
56
57
  export interface $ZodIssueInvalidKey<Input = unknown> extends $ZodIssueBase {
57
58
  readonly code: "invalid_key";
@@ -52,6 +52,7 @@ export interface $ZodIssueInvalidUnion extends $ZodIssueBase {
52
52
  readonly code: "invalid_union";
53
53
  readonly errors: $ZodIssue[][];
54
54
  readonly input: unknown;
55
+ readonly discriminator?: string | undefined;
55
56
  }
56
57
  export interface $ZodIssueInvalidKey<Input = unknown> extends $ZodIssueBase {
57
58
  readonly code: "invalid_key";
@@ -863,7 +863,7 @@ function handleUnionResults(results, final, inst, ctx) {
863
863
  }
864
864
  }
865
865
  const nonaborted = results.filter((r) => !util.aborted(r));
866
- if (nonaborted.length > 0) {
866
+ if (nonaborted.length === 1) {
867
867
  final.value = nonaborted[0].value;
868
868
  return nonaborted[0];
869
869
  }
@@ -977,6 +977,7 @@ core.$constructor("$ZodDiscriminatedUnion", (inst, def) => {
977
977
  code: "invalid_union",
978
978
  errors: [],
979
979
  note: "No matching discriminator",
980
+ discriminator: def.discriminator,
980
981
  input,
981
982
  path: [def.discriminator],
982
983
  inst,
@@ -1354,6 +1355,9 @@ exports.$ZodEnum = core.$constructor("$ZodEnum", (inst, def) => {
1354
1355
  });
1355
1356
  exports.$ZodLiteral = core.$constructor("$ZodLiteral", (inst, def) => {
1356
1357
  exports.$ZodType.init(inst, def);
1358
+ if (def.values.length === 0) {
1359
+ throw new Error("Cannot create literal schema with no valid values");
1360
+ }
1357
1361
  inst._zod.values = new Set(def.values);
1358
1362
  inst._zod.pattern = new RegExp(`^(${def.values
1359
1363
  .map((o) => (typeof o === "string" ? util.escapeRegex(o) : o ? util.escapeRegex(o.toString()) : String(o)))
@@ -768,8 +768,8 @@ type _File = typeof globalThis extends {
768
768
  } ? InstanceType<F> : {};
769
769
  /** Do not reference this directly. */
770
770
  export interface File extends _File {
771
- type: string;
772
- size: number;
771
+ readonly type: string;
772
+ readonly size: number;
773
773
  }
774
774
  export interface $ZodFileDef extends $ZodTypeDef {
775
775
  type: "file";
@@ -768,8 +768,8 @@ type _File = typeof globalThis extends {
768
768
  } ? InstanceType<F> : {};
769
769
  /** Do not reference this directly. */
770
770
  export interface File extends _File {
771
- type: string;
772
- size: number;
771
+ readonly type: string;
772
+ readonly size: number;
773
773
  }
774
774
  export interface $ZodFileDef extends $ZodTypeDef {
775
775
  type: "file";
@@ -832,7 +832,7 @@ function handleUnionResults(results, final, inst, ctx) {
832
832
  }
833
833
  }
834
834
  const nonaborted = results.filter((r) => !util.aborted(r));
835
- if (nonaborted.length > 0) {
835
+ if (nonaborted.length === 1) {
836
836
  final.value = nonaborted[0].value;
837
837
  return nonaborted[0];
838
838
  }
@@ -946,6 +946,7 @@ core.$constructor("$ZodDiscriminatedUnion", (inst, def) => {
946
946
  code: "invalid_union",
947
947
  errors: [],
948
948
  note: "No matching discriminator",
949
+ discriminator: def.discriminator,
949
950
  input,
950
951
  path: [def.discriminator],
951
952
  inst,
@@ -1323,6 +1324,9 @@ export const $ZodEnum = /*@__PURE__*/ core.$constructor("$ZodEnum", (inst, def)
1323
1324
  });
1324
1325
  export const $ZodLiteral = /*@__PURE__*/ core.$constructor("$ZodLiteral", (inst, def) => {
1325
1326
  $ZodType.init(inst, def);
1327
+ if (def.values.length === 0) {
1328
+ throw new Error("Cannot create literal schema with no valid values");
1329
+ }
1326
1330
  inst._zod.values = new Set(def.values);
1327
1331
  inst._zod.pattern = new RegExp(`^(${def.values
1328
1332
  .map((o) => (typeof o === "string" ? util.escapeRegex(o) : o ? util.escapeRegex(o.toString()) : String(o)))
@@ -4,5 +4,5 @@ exports.version = void 0;
4
4
  exports.version = {
5
5
  major: 4,
6
6
  minor: 0,
7
- patch: 8,
7
+ patch: 10,
8
8
  };
@@ -1,5 +1,5 @@
1
1
  export const version = {
2
2
  major: 4,
3
3
  minor: 0,
4
- patch: 8,
4
+ patch: 10,
5
5
  };