zod 3.11.6 โ†’ 3.13.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.
Files changed (56) hide show
  1. package/README.md +104 -45
  2. package/lib/ZodError.d.ts +16 -5
  3. package/lib/ZodError.js +47 -42
  4. package/lib/benchmarks/discriminatedUnion.d.ts +5 -0
  5. package/lib/benchmarks/discriminatedUnion.js +79 -0
  6. package/lib/benchmarks/index.d.ts +0 -1
  7. package/lib/benchmarks/index.js +2 -2
  8. package/lib/benchmarks/object.d.ts +0 -1
  9. package/lib/benchmarks/object.js +3 -4
  10. package/lib/benchmarks/string.d.ts +0 -1
  11. package/lib/benchmarks/string.js +1 -2
  12. package/lib/benchmarks/union.d.ts +0 -1
  13. package/lib/benchmarks/union.js +2 -3
  14. package/lib/external.d.ts +1 -1
  15. package/lib/external.js +1 -1
  16. package/lib/helpers/errorUtil.d.ts +0 -1
  17. package/lib/helpers/errorUtil.js +0 -1
  18. package/lib/helpers/parseUtil.d.ts +1 -2
  19. package/lib/helpers/parseUtil.js +6 -5
  20. package/lib/helpers/partialUtil.d.ts +0 -1
  21. package/lib/helpers/partialUtil.js +0 -1
  22. package/lib/helpers/typeAliases.d.ts +2 -0
  23. package/lib/helpers/typeAliases.js +2 -0
  24. package/lib/helpers/util.d.ts +0 -1
  25. package/lib/helpers/util.js +0 -1
  26. package/lib/index.d.ts +1 -1
  27. package/lib/index.js +1 -1
  28. package/lib/index.mjs +3390 -2
  29. package/lib/types.d.ts +63 -10
  30. package/lib/types.js +191 -22
  31. package/package.json +5 -5
  32. package/lib/ZodError.d.ts.map +0 -1
  33. package/lib/ZodError.js.map +0 -1
  34. package/lib/benchmarks/index.d.ts.map +0 -1
  35. package/lib/benchmarks/index.js.map +0 -1
  36. package/lib/benchmarks/object.d.ts.map +0 -1
  37. package/lib/benchmarks/object.js.map +0 -1
  38. package/lib/benchmarks/string.d.ts.map +0 -1
  39. package/lib/benchmarks/string.js.map +0 -1
  40. package/lib/benchmarks/union.d.ts.map +0 -1
  41. package/lib/benchmarks/union.js.map +0 -1
  42. package/lib/external.d.ts.map +0 -1
  43. package/lib/external.js.map +0 -1
  44. package/lib/helpers/errorUtil.d.ts.map +0 -1
  45. package/lib/helpers/errorUtil.js.map +0 -1
  46. package/lib/helpers/parseUtil.d.ts.map +0 -1
  47. package/lib/helpers/parseUtil.js.map +0 -1
  48. package/lib/helpers/partialUtil.d.ts.map +0 -1
  49. package/lib/helpers/partialUtil.js.map +0 -1
  50. package/lib/helpers/util.d.ts.map +0 -1
  51. package/lib/helpers/util.js.map +0 -1
  52. package/lib/index.d.ts.map +0 -1
  53. package/lib/index.js.map +0 -1
  54. package/lib/index.mjs.map +0 -1
  55. package/lib/types.d.ts.map +0 -1
  56. package/lib/types.js.map +0 -1
package/README.md CHANGED
@@ -8,21 +8,29 @@
8
8
  <a href="https://www.npmjs.com/package/zod" rel="nofollow"><img src="https://img.shields.io/npm/dw/zod.svg" alt="npm"></a>
9
9
  <a href="https://www.npmjs.com/package/zod" rel="nofollow"><img src="https://img.shields.io/github/stars/colinhacks/zod" alt="stars"></a>
10
10
  <a href="./src/__tests__" rel="nofollow"><img src="./coverage.svg" alt="coverage"></a>
11
-
11
+ <a href="https://discord.gg/KaSRdyX2vc" rel="nofollow"><img src="https://img.shields.io/discord/893487829802418277?label=Discord&logo=discord&logoColor=white" alt="discord server"></a>
12
12
  </p>
13
13
  <p align="center">
14
- by [@colinhacks](https://twitter.com/colinhacks)
14
+ by <a href="https://twitter.com/colinhacks">@colinhacks</a>
15
15
  </p>
16
16
 
17
- > Hi! Colin here, creator of Zod. I hope you find it easy to use and powerful enough for all your use cases. If you have any issues or suggestions, please [open an issue](https://github.com/colinhacks/zod/issues/new)!
17
+ > Hi! Colin here, creator of Zod. I hope you find it easy to use and powerful enough for all your use cases. If you have any issues or suggestions, please [open an issue](https://github.com/colinhacks/zod/issues/new)!
18
18
  >
19
19
  > If you like typesafety, check out my other library [tRPC](https://trpc.io). It works in concert with Zod to provide a seamless way to build end-to-end typesafe APIs without GraphQL or code generation โ€” just TypeScript.
20
20
  >
21
21
  > Colin (AKA [@colinhacks](https://twitter.com/colinhacks))
22
22
 
23
+ <h3 align="center">
24
+ <a href="https://discord.gg/RcG33DQJdf">๐Ÿ’ฌ Chat on Discord</a>
25
+ ยท
26
+ <a href="https://zod.js.org/">๐Ÿ“ Explore the Docs</a>
27
+ ยท
28
+ <a href="https://www.npmjs.com/package/zod">โœจ Install Zod</a>
29
+ </h3>
30
+
23
31
  <br/>
24
32
 
25
- This docs have been translated into [Chinese](./README_ZH.md).
33
+ These docs have been translated into [Chinese](./README_ZH.md).
26
34
 
27
35
  # Table of contents
28
36
 
@@ -36,9 +44,9 @@ This docs have been translated into [Chinese](./README_ZH.md).
36
44
  - [Strings](#strings)
37
45
  - [Numbers](#numbers)
38
46
  - [Booleans](#booleans)
39
- - [Enums](#enums)
40
- - [Zod enums](#zod-enums)
41
- - [Native enums](#native-enums)
47
+ - [Dates](#dates)
48
+ - [Zod enums](#zod-enums)
49
+ - [Native enums](#native-enums)
42
50
  - [Optionals](#optionals)
43
51
  - [Nullables](#nullables)
44
52
  - [Objects](#objects)
@@ -53,6 +61,7 @@ This docs have been translated into [Chinese](./README_ZH.md).
53
61
  - [.strip](#strip)
54
62
  - [.catchall](#catchall)
55
63
  - [Arrays](#arrays)
64
+ - [.element](#element)
56
65
  - [.nonempty](#nonempty)
57
66
  - [.min/.max/.length](#minmaxlength)
58
67
  - [Tuples](#tuples)
@@ -60,6 +69,7 @@ This docs have been translated into [Chinese](./README_ZH.md).
60
69
  - [Maps](#maps)
61
70
  - [Sets](#sets)
62
71
  - [Unions](#unions)
72
+ - [Discriminated Unions](#discriminated-unions)
63
73
  - [Recursive types](#recursive-types)
64
74
  - [JSON type](#json-type)
65
75
  - [Cyclical data](#cyclical-objects)
@@ -105,7 +115,7 @@ Some other great aspects:
105
115
  - Zero dependencies
106
116
  - Works in Node.js and browsers (including IE 11)
107
117
  - Tiny: 8kb minified + zipped
108
- - Immutable: methods (i.e. `.optional()` return a new instance
118
+ - Immutable: methods (i.e. `.optional()`) return a new instance
109
119
  - Concise, chainable interface
110
120
  - Functional approach: [parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
111
121
  - Works with plain JavaScript too! You don't need to use TypeScript.
@@ -147,7 +157,7 @@ Sponsorship at any level is appreciated and encouraged. Zod is maintained by a s
147
157
  <span>creator of <a href="https://blitzjs.com">Blitz.js</a></span>
148
158
  <br />
149
159
  </td>
150
-
160
+
151
161
  </tr>
152
162
  <tr>
153
163
  <td align="center">
@@ -215,6 +225,7 @@ There are a growing number of tools that are built atop or support Zod natively!
215
225
 
216
226
  - [`tRPC`](https://github.com/trpc/trpc): Build end-to-end typesafe APIs without GraphQL.
217
227
  - [`ts-to-zod`](https://github.com/fabien0102/ts-to-zod): Convert TypeScript definitions into Zod schemas.
228
+ - [`zod-to-ts`](https://github.com/sachinraja/zod-to-ts): Generate TypeScript definitions from Zod schemas.
218
229
  - [`@anatine/zod-openapi`](https://github.com/anatine/zod-plugins/tree/main/libs/zod-openapi): Converts a Zod schema to an OpenAPI v3.x `SchemaObject`.
219
230
  - [`@anatine/zod-mock`](https://github.com/anatine/zod-plugins/tree/main/libs/zod-mock): Generate mock data from a Zod schema. Powered by [faker.js](https://github.com/Marak/Faker.js).
220
231
  - [`@anatine/zod-nestjs`](https://github.com/anatine/zod-plugins/tree/main/libs/zod-nestjs): Helper methods for using Zod in a NestJS project.
@@ -223,13 +234,17 @@ There are a growing number of tools that are built atop or support Zod natively!
223
234
  - [`zod-endpoints`](https://github.com/flock-community/zod-endpoints): Contract-first strictly typed endpoints with Zod. OpenAPI compatible.
224
235
  - [`express-zod-api`](https://github.com/RobinTail/express-zod-api): Build Express-based APIs with I/O schema validation and custom middlewares.
225
236
  - [`zod-to-json-schema`](https://github.com/StefanTerdell/zod-to-json-schema): Convert your Zod schemas into [JSON Schemas](https://json-schema.org/).
237
+ - [`json-schema-to-zod`](https://github.com/StefanTerdell/json-schema-to-zod): Convert your [JSON Schemas](https://json-schema.org/) into Zod schemas. Use it live [here](https://StefanTerdell.github.io/json-schema-to-zod-react/).
226
238
  - [`json-to-zod`](https://github.com/rsinohara/json-to-zod): Convert JSON objects into Zod schemas. Use it live [here](https://rsinohara.github.io/json-to-zod-react/).
227
239
  - [`zod-dto`](https://github.com/kbkk/abitia/tree/master/packages/zod-dto): Generate Nest.js DTOs from a Zod schema.
240
+ - [`soly`](https://github.com/mdbetancourt/soly): Create CLI applications with zod.
241
+ - [`graphql-codegen-typescript-validation-schema`](https://github.com/Code-Hex/graphql-codegen-typescript-validation-schema): GraphQL Code Generator plugin to generate form validation schema from your GraphQL schema
242
+ - [`zod-prisma`](https://github.com/CarterGrimmeisen/zod-prisma): Generate Zod schemas from your Prisma schema.
228
243
 
229
244
  ### Form integrations
230
245
 
231
246
  - [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form
232
- - [`formik`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod
247
+ - [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod
233
248
 
234
249
  # Basic usage
235
250
 
@@ -310,15 +325,6 @@ tuna.value; // "tuna"
310
325
 
311
326
  ## Strings
312
327
 
313
- You can customize certain errors when creating a string schema.
314
-
315
- ```ts
316
- const name = z.string({
317
- required: "Name is required",
318
- invalid: "Invalid name",
319
- });
320
- ```
321
-
322
328
  Zod includes a handful of string-specific validations.
323
329
 
324
330
  ```ts
@@ -408,11 +414,30 @@ const isActive = z.boolean({
408
414
  });
409
415
  ```
410
416
 
411
- ## Enums
417
+ ## Dates
418
+ z.date() accepts a date, not a date string
419
+ ```ts
420
+ z.date().safeParse( new Date() ) // success: true
421
+ z.date().safeParse( '2022-01-12T00:00:00.000Z' ) // success: false
422
+ ```
412
423
 
413
- There are two ways to define enums in Zod.
424
+ To allow for dates or date strings, you can use preprocess
425
+ ```ts
426
+ const dateSchema = z.preprocess(
427
+ arg => {
428
+ if ( typeof arg == 'string' || arg instanceof Date )
429
+ return new Date( arg )
430
+ },
431
+ z.date()
432
+ )
433
+ type DateSchema = z.infer<typeof dateSchema>
434
+ // type DateSchema = Date
414
435
 
415
- ### Zod enums
436
+ dateSchema.safeParse( new Date( '1/12/22' ) ) // success: true
437
+ dateSchema.safeParse( '2022-01-12T00:00:00.000Z' ) // success: true
438
+ ```
439
+
440
+ ## Zod enums
416
441
 
417
442
  ```ts
418
443
  const FishEnum = z.enum(["Salmon", "Tuna", "Trout"]);
@@ -420,22 +445,20 @@ type FishEnum = z.infer<typeof FishEnum>;
420
445
  // 'Salmon' | 'Tuna' | 'Trout'
421
446
  ```
422
447
 
423
- You must pass the array of values directly into `z.enum()`. Alternatively, use `as const` to define your enum values as a tuple of strings. See the [const assertion docs](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) for details.
448
+ `z.enum` is a Zod-native way to declare a schema with a fixed set of allowable _string_ values. Pass the array of values directly into `z.enum()`. Alternatively, use `as const` to define your enum values as a tuple of strings. See the [const assertion docs](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) for details.
424
449
 
425
450
  ```ts
426
451
  const VALUES = ["Salmon", "Tuna", "Trout"] as const;
427
452
  const FishEnum = z.enum(VALUES);
428
453
  ```
429
454
 
430
- This is not allowed:
455
+ This is not allowed, since Zod isn't able to infer the exact values of each elements.
431
456
 
432
457
  ```ts
433
458
  const fish = ["Salmon", "Tuna", "Trout"];
434
459
  const FishEnum = z.enum(fish);
435
460
  ```
436
461
 
437
- In that case, the inferred type of `fish` is simply `string[]`, so Zod isn't able to infer the individual enum elements.
438
-
439
462
  **Autocompletion**
440
463
 
441
464
  To get autocompletion with a Zod enum, use the `.enum` property of your schema:
@@ -444,12 +467,12 @@ To get autocompletion with a Zod enum, use the `.enum` property of your schema:
444
467
  FishEnum.enum.Salmon; // => autocompletes
445
468
 
446
469
  FishEnum.enum;
447
- /*
470
+ /*
448
471
  => {
449
472
  Salmon: "Salmon",
450
473
  Tuna: "Tuna",
451
474
  Trout: "Trout",
452
- }
475
+ }
453
476
  */
454
477
  ```
455
478
 
@@ -459,7 +482,7 @@ You can also retrieve the list of options as a tuple with the `.options` propert
459
482
  FishEnum.options; // ["Salmon", "Tuna", "Trout"]);
460
483
  ```
461
484
 
462
- ### Native enums
485
+ ## Native enums
463
486
 
464
487
  Zod enums are the recommended approach to defining and validating enums. But if you need to validate against an enum from a third-party library (or you don't want to rewrite your existing enums) you can use `z.nativeEnum()` .
465
488
 
@@ -684,11 +707,11 @@ You can also specify which properties to make optional:
684
707
  const optionalEmail = user.partial({
685
708
  email: true,
686
709
  });
687
- /*
688
- {
689
- email?: string | undefined;
710
+ /*
711
+ {
712
+ email?: string | undefined;
690
713
  username: string
691
- }
714
+ }
692
715
  */
693
716
  ```
694
717
 
@@ -708,9 +731,9 @@ const user = z.object({
708
731
 
709
732
  const deepPartialUser = user.deepPartial();
710
733
 
711
- /*
734
+ /*
712
735
  {
713
- username?: string | undefined,
736
+ username?: string | undefined,
714
737
  location?: {
715
738
  latitude?: number | undefined;
716
739
  longitude?: number | undefined;
@@ -814,6 +837,14 @@ z.string().optional().array(); // (string | undefined)[]
814
837
  z.string().array().optional(); // string[] | undefined
815
838
  ```
816
839
 
840
+ ### `.element`
841
+
842
+ Use `.element` to access the schema for an element of the array.
843
+
844
+ ```ts
845
+ stringArray.element; // => string schema
846
+ ```
847
+
817
848
  ### `.nonempty`
818
849
 
819
850
  If you want to ensure that an array contains at least one element, use `.nonempty()`.
@@ -882,6 +913,25 @@ For convenience, you can also use the `.or` method:
882
913
  const stringOrNumber = z.string().or(z.number());
883
914
  ```
884
915
 
916
+ ### Discriminated unions
917
+
918
+ If the union consists of object schemas all identifiable by a common property, it is possible to use
919
+ the `z.discriminatedUnion` method.
920
+
921
+ The advantage is in more efficient evaluation and more human friendly errors. With the basic union method the input is
922
+ tested against each of the provided "options", and in the case of invalidity, issues for all the "options" are shown in
923
+ the zod error. On the other hand, the discriminated union allows for selecting just one of the "options", testing
924
+ against it, and showing only the issues related to this "option".
925
+
926
+ ```ts
927
+ const item = z
928
+ .discriminatedUnion("type", [
929
+ z.object({ type: z.literal("a"), a: z.string() }),
930
+ z.object({ type: z.literal("b"), b: z.string() }),
931
+ ])
932
+ .parse({ type: "a", a: "abc" });
933
+ ```
934
+
885
935
  ## Records
886
936
 
887
937
  Record schemas are used to validate types such as `{ [k: string]: number }`.
@@ -936,15 +986,24 @@ Since Zod is trying to bridge the gap between static and runtime types, it doesn
936
986
  const stringNumberMap = z.map(z.string(), z.number());
937
987
 
938
988
  type StringNumberMap = z.infer<typeof stringNumberMap>;
939
- // type StringNumber = Map<string, number>
989
+ // type StringNumberMap = Map<string, number>
940
990
  ```
941
991
 
942
992
  ## Sets
943
993
 
944
994
  ```ts
945
- const numberSet = z.set(z.string());
946
- type numberSet = z.infer<typeof numberSet>;
947
- // Set<number>
995
+ const numberSet = z.set(z.number());
996
+ type NumberSet = z.infer<typeof numberSet>;
997
+ // type NumberSet = Set<number>
998
+ ```
999
+
1000
+ ### `.nonempty/.min/.max/.size`
1001
+
1002
+ ```ts
1003
+ z.set(z.string()).nonempty(); // must contain at least one item
1004
+ z.set(z.string()).min(5); // must contain 5 or more items
1005
+ z.set(z.string()).max(5); // must contain 5 or fewer items
1006
+ z.set(z.string()).size(5); // must contain 5 items exactly
948
1007
  ```
949
1008
 
950
1009
  ## Intersections
@@ -1007,8 +1066,8 @@ interface Category {
1007
1066
  subcategories: Category[];
1008
1067
  }
1009
1068
 
1010
- // cast to z.ZodSchema<Category>
1011
- const Category: z.ZodSchema<Category> = z.lazy(() =>
1069
+ // cast to z.ZodType<Category>
1070
+ const Category: z.ZodType<Category> = z.lazy(() =>
1012
1071
  z.object({
1013
1072
  name: z.string(),
1014
1073
  subcategories: z.array(Category),
@@ -1045,7 +1104,7 @@ interface Category extends z.infer<typeof BaseCategory> {
1045
1104
 
1046
1105
  // merge the base schema with
1047
1106
  // a new Zod schema containing relations
1048
- const Category: z.ZodSchema<Category> = BaseCategory.merge(
1107
+ const Category: z.ZodType<Category> = BaseCategory.merge(
1049
1108
  z.object({
1050
1109
  subcategories: z.lazy(() => z.array(Category)),
1051
1110
  })
@@ -1060,7 +1119,7 @@ If you want to validate any JSON value, you can use the snippet below.
1060
1119
  type Literal = boolean | null | number | string;
1061
1120
  type Json = Literal | { [key: string]: Json } | Json[];
1062
1121
  const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
1063
- const jsonSchema: z.ZodSchema<Json> = z.lazy(() =>
1122
+ const jsonSchema: z.ZodType<Json> = z.lazy(() =>
1064
1123
  z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])
1065
1124
  );
1066
1125
 
@@ -1071,7 +1130,7 @@ Thanks to [ggoodman](https://github.com/ggoodman) for suggesting this.
1071
1130
 
1072
1131
  #### Cyclical objects
1073
1132
 
1074
- Despite supporting recursive schemas, passing an cyclical data into Zod will cause an infinite loop.
1133
+ Despite supporting recursive schemas, passing cyclical data into Zod will cause an infinite loop.
1075
1134
 
1076
1135
  ## Promises
1077
1136
 
@@ -1607,7 +1666,7 @@ A convenience method for creating intersection types.
1607
1666
  z.object({ name: z.string() }).and(z.object({ age: z.number() })); // { name: string } & { age: number }
1608
1667
 
1609
1668
  // equivalent to
1610
- z.intersection(z.string(), z.number());
1669
+ z.intersection(z.object({ name: z.string() }), z.object({ age: z.number() }));
1611
1670
  ```
1612
1671
 
1613
1672
  # Type inference
package/lib/ZodError.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { ZodParsedType } from "./helpers/parseUtil";
2
+ import { Primitive } from "./helpers/typeAliases";
2
3
  import { util } from "./helpers/util";
3
4
  export declare const ZodIssueCode: {
4
5
  invalid_type: "invalid_type";
5
6
  custom: "custom";
6
7
  invalid_union: "invalid_union";
8
+ invalid_union_discriminator: "invalid_union_discriminator";
7
9
  invalid_enum_value: "invalid_enum_value";
8
10
  unrecognized_keys: "unrecognized_keys";
9
11
  invalid_arguments: "invalid_arguments";
@@ -33,6 +35,10 @@ export interface ZodInvalidUnionIssue extends ZodIssueBase {
33
35
  code: typeof ZodIssueCode.invalid_union;
34
36
  unionErrors: ZodError[];
35
37
  }
38
+ export interface ZodInvalidUnionDiscriminatorIssue extends ZodIssueBase {
39
+ code: typeof ZodIssueCode.invalid_union_discriminator;
40
+ options: Primitive[];
41
+ }
36
42
  export interface ZodInvalidEnumValueIssue extends ZodIssueBase {
37
43
  code: typeof ZodIssueCode.invalid_enum_value;
38
44
  options: (string | number)[];
@@ -57,13 +63,13 @@ export interface ZodTooSmallIssue extends ZodIssueBase {
57
63
  code: typeof ZodIssueCode.too_small;
58
64
  minimum: number;
59
65
  inclusive: boolean;
60
- type: "array" | "string" | "number";
66
+ type: "array" | "string" | "number" | "set";
61
67
  }
62
68
  export interface ZodTooBigIssue extends ZodIssueBase {
63
69
  code: typeof ZodIssueCode.too_big;
64
70
  maximum: number;
65
71
  inclusive: boolean;
66
- type: "array" | "string" | "number";
72
+ type: "array" | "string" | "number" | "set";
67
73
  }
68
74
  export interface ZodInvalidIntersectionTypesIssue extends ZodIssueBase {
69
75
  code: typeof ZodIssueCode.invalid_intersection_types;
@@ -81,7 +87,7 @@ export interface ZodCustomIssue extends ZodIssueBase {
81
87
  export declare type DenormalizedError = {
82
88
  [k: string]: DenormalizedError | string[];
83
89
  };
84
- export declare type ZodIssueOptionalMessage = ZodInvalidTypeIssue | ZodUnrecognizedKeysIssue | ZodInvalidUnionIssue | ZodInvalidEnumValueIssue | ZodInvalidArgumentsIssue | ZodInvalidReturnTypeIssue | ZodInvalidDateIssue | ZodInvalidStringIssue | ZodTooSmallIssue | ZodTooBigIssue | ZodInvalidIntersectionTypesIssue | ZodNotMultipleOfIssue | ZodCustomIssue;
90
+ export declare type ZodIssueOptionalMessage = ZodInvalidTypeIssue | ZodUnrecognizedKeysIssue | ZodInvalidUnionIssue | ZodInvalidUnionDiscriminatorIssue | ZodInvalidEnumValueIssue | ZodInvalidArgumentsIssue | ZodInvalidReturnTypeIssue | ZodInvalidDateIssue | ZodInvalidStringIssue | ZodTooSmallIssue | ZodTooBigIssue | ZodInvalidIntersectionTypesIssue | ZodNotMultipleOfIssue | ZodCustomIssue;
85
91
  export declare type ZodIssue = ZodIssueOptionalMessage & {
86
92
  message: string;
87
93
  };
@@ -104,7 +110,13 @@ export declare class ZodError<T = any> extends Error {
104
110
  get isEmpty(): boolean;
105
111
  addIssue: (sub: ZodIssue) => void;
106
112
  addIssues: (subs?: ZodIssue[]) => void;
107
- flatten: <U = string>(mapper?: (issue: ZodIssue) => U) => {
113
+ flatten(mapper?: (issue: ZodIssue) => string): {
114
+ formErrors: string[];
115
+ fieldErrors: {
116
+ [k: string]: string[];
117
+ };
118
+ };
119
+ flatten<U>(mapper?: (issue: ZodIssue) => U): {
108
120
  formErrors: U[];
109
121
  fieldErrors: {
110
122
  [k: string]: U[];
@@ -136,4 +148,3 @@ export declare let overrideErrorMap: (issue: ZodIssueOptionalMessage, _ctx: Erro
136
148
  };
137
149
  export declare const setErrorMap: (map: ZodErrorMap) => void;
138
150
  export {};
139
- //# sourceMappingURL=ZodError.d.ts.map
package/lib/ZodError.js CHANGED
@@ -57,6 +57,7 @@ exports.ZodIssueCode = util_1.util.arrayToEnum([
57
57
  "invalid_type",
58
58
  "custom",
59
59
  "invalid_union",
60
+ "invalid_union_discriminator",
60
61
  "invalid_enum_value",
61
62
  "unrecognized_keys",
62
63
  "invalid_arguments",
@@ -142,32 +143,6 @@ var ZodError = /** @class */ (function (_super) {
142
143
  if (subs === void 0) { subs = []; }
143
144
  _this.issues = __spreadArray(__spreadArray([], __read(_this.issues), false), __read(subs), false);
144
145
  };
145
- _this.flatten = function (mapper) {
146
- var e_2, _a;
147
- if (mapper === void 0) { mapper = function (issue) { return issue.message; }; }
148
- var fieldErrors = {};
149
- var formErrors = [];
150
- try {
151
- for (var _b = __values(_this.issues), _c = _b.next(); !_c.done; _c = _b.next()) {
152
- var sub = _c.value;
153
- if (sub.path.length > 0) {
154
- fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
155
- fieldErrors[sub.path[0]].push(mapper(sub));
156
- }
157
- else {
158
- formErrors.push(mapper(sub));
159
- }
160
- }
161
- }
162
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
163
- finally {
164
- try {
165
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
166
- }
167
- finally { if (e_2) throw e_2.error; }
168
- }
169
- return { formErrors: formErrors, fieldErrors: fieldErrors };
170
- };
171
146
  var actualProto = _newTarget.prototype;
172
147
  if (Object.setPrototypeOf) {
173
148
  // eslint-disable-next-line ban/ban
@@ -204,6 +179,32 @@ var ZodError = /** @class */ (function (_super) {
204
179
  enumerable: false,
205
180
  configurable: true
206
181
  });
182
+ ZodError.prototype.flatten = function (mapper) {
183
+ var e_2, _a;
184
+ if (mapper === void 0) { mapper = function (issue) { return issue.message; }; }
185
+ var fieldErrors = {};
186
+ var formErrors = [];
187
+ try {
188
+ for (var _b = __values(this.issues), _c = _b.next(); !_c.done; _c = _b.next()) {
189
+ var sub = _c.value;
190
+ if (sub.path.length > 0) {
191
+ fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
192
+ fieldErrors[sub.path[0]].push(mapper(sub));
193
+ }
194
+ else {
195
+ formErrors.push(mapper(sub));
196
+ }
197
+ }
198
+ }
199
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
200
+ finally {
201
+ try {
202
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
203
+ }
204
+ finally { if (e_2) throw e_2.error; }
205
+ }
206
+ return { formErrors: formErrors, fieldErrors: fieldErrors };
207
+ };
207
208
  Object.defineProperty(ZodError.prototype, "formErrors", {
208
209
  get: function () {
209
210
  return this.flatten();
@@ -226,21 +227,26 @@ var defaultErrorMap = function (issue, _ctx) {
226
227
  message = "Required";
227
228
  }
228
229
  else {
229
- message = "Expected " + issue.expected + ", received " + issue.received;
230
+ message = "Expected ".concat(issue.expected, ", received ").concat(issue.received);
230
231
  }
231
232
  break;
232
233
  case exports.ZodIssueCode.unrecognized_keys:
233
- message = "Unrecognized key(s) in object: " + issue.keys
234
- .map(function (k) { return "'" + k + "'"; })
235
- .join(", ");
234
+ message = "Unrecognized key(s) in object: ".concat(issue.keys
235
+ .map(function (k) { return "'".concat(k, "'"); })
236
+ .join(", "));
236
237
  break;
237
238
  case exports.ZodIssueCode.invalid_union:
238
239
  message = "Invalid input";
239
240
  break;
241
+ case exports.ZodIssueCode.invalid_union_discriminator:
242
+ message = "Invalid discriminator value. Expected ".concat(issue.options
243
+ .map(function (val) { return (typeof val === "string" ? "'".concat(val, "'") : val); })
244
+ .join(" | "));
245
+ break;
240
246
  case exports.ZodIssueCode.invalid_enum_value:
241
- message = "Invalid enum value. Expected " + issue.options
242
- .map(function (val) { return (typeof val === "string" ? "'" + val + "'" : val); })
243
- .join(" | ") + ", received " + (typeof _ctx.data === "string" ? "'" + _ctx.data + "'" : _ctx.data);
247
+ message = "Invalid enum value. Expected ".concat(issue.options
248
+ .map(function (val) { return (typeof val === "string" ? "'".concat(val, "'") : val); })
249
+ .join(" | "));
244
250
  break;
245
251
  case exports.ZodIssueCode.invalid_arguments:
246
252
  message = "Invalid function arguments";
@@ -253,27 +259,27 @@ var defaultErrorMap = function (issue, _ctx) {
253
259
  break;
254
260
  case exports.ZodIssueCode.invalid_string:
255
261
  if (issue.validation !== "regex")
256
- message = "Invalid " + issue.validation;
262
+ message = "Invalid ".concat(issue.validation);
257
263
  else
258
264
  message = "Invalid";
259
265
  break;
260
266
  case exports.ZodIssueCode.too_small:
261
267
  if (issue.type === "array")
262
- message = "Should have " + (issue.inclusive ? "at least" : "more than") + " " + issue.minimum + " items";
268
+ message = "Array must contain ".concat(issue.inclusive ? "at least" : "more than", " ").concat(issue.minimum, " element(s)");
263
269
  else if (issue.type === "string")
264
- message = "Should be " + (issue.inclusive ? "at least" : "over") + " " + issue.minimum + " characters";
270
+ message = "String must contain ".concat(issue.inclusive ? "at least" : "over", " ").concat(issue.minimum, " character(s)");
265
271
  else if (issue.type === "number")
266
- message = "Value should be greater than " + (issue.inclusive ? "or equal to " : "") + issue.minimum;
272
+ message = "Number must be greater than ".concat(issue.inclusive ? "or equal to " : "").concat(issue.minimum);
267
273
  else
268
274
  message = "Invalid input";
269
275
  break;
270
276
  case exports.ZodIssueCode.too_big:
271
277
  if (issue.type === "array")
272
- message = "Should have " + (issue.inclusive ? "at most" : "less than") + " " + issue.maximum + " items";
278
+ message = "Array must contain ".concat(issue.inclusive ? "at most" : "less than", " ").concat(issue.maximum, " element(s)");
273
279
  else if (issue.type === "string")
274
- message = "Should be " + (issue.inclusive ? "at most" : "under") + " " + issue.maximum + " characters long";
280
+ message = "String must contain ".concat(issue.inclusive ? "at most" : "under", " ").concat(issue.maximum, " character(s)");
275
281
  else if (issue.type === "number")
276
- message = "Value should be less than " + (issue.inclusive ? "or equal to " : "") + issue.maximum;
282
+ message = "Number must be less than ".concat(issue.inclusive ? "or equal to " : "").concat(issue.maximum);
277
283
  else
278
284
  message = "Invalid input";
279
285
  break;
@@ -284,7 +290,7 @@ var defaultErrorMap = function (issue, _ctx) {
284
290
  message = "Intersection results could not be merged";
285
291
  break;
286
292
  case exports.ZodIssueCode.not_multiple_of:
287
- message = "Should be multiple of " + issue.multipleOf;
293
+ message = "Number must be a multiple of ".concat(issue.multipleOf);
288
294
  break;
289
295
  default:
290
296
  message = _ctx.defaultError;
@@ -298,4 +304,3 @@ var setErrorMap = function (map) {
298
304
  exports.overrideErrorMap = map;
299
305
  };
300
306
  exports.setErrorMap = setErrorMap;
301
- //# sourceMappingURL=ZodError.js.map
@@ -0,0 +1,5 @@
1
+ import Benchmark from "benchmark";
2
+ declare const _default: {
3
+ suites: Benchmark.Suite[];
4
+ };
5
+ export default _default;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var benchmark_1 = __importDefault(require("benchmark"));
7
+ var index_1 = require("../index");
8
+ var doubleSuite = new benchmark_1.default.Suite("z.discriminatedUnion: double");
9
+ var manySuite = new benchmark_1.default.Suite("z.discriminatedUnion: many");
10
+ var aSchema = index_1.z.object({
11
+ type: index_1.z.literal("a"),
12
+ });
13
+ var objA = {
14
+ type: "a",
15
+ };
16
+ var bSchema = index_1.z.object({
17
+ type: index_1.z.literal("b"),
18
+ });
19
+ var objB = {
20
+ type: "b",
21
+ };
22
+ var cSchema = index_1.z.object({
23
+ type: index_1.z.literal("c"),
24
+ });
25
+ var objC = {
26
+ type: "c",
27
+ };
28
+ var dSchema = index_1.z.object({
29
+ type: index_1.z.literal("d"),
30
+ });
31
+ var double = index_1.z.discriminatedUnion("type", [aSchema, bSchema]);
32
+ var many = index_1.z.discriminatedUnion("type", [aSchema, bSchema, cSchema, dSchema]);
33
+ doubleSuite
34
+ .add("valid: a", function () {
35
+ double.parse(objA);
36
+ })
37
+ .add("valid: b", function () {
38
+ double.parse(objB);
39
+ })
40
+ .add("invalid: null", function () {
41
+ try {
42
+ double.parse(null);
43
+ }
44
+ catch (err) { }
45
+ })
46
+ .add("invalid: wrong shape", function () {
47
+ try {
48
+ double.parse(objC);
49
+ }
50
+ catch (err) { }
51
+ })
52
+ .on("cycle", function (e) {
53
+ console.log("".concat(doubleSuite.name, ": ").concat(e.target));
54
+ });
55
+ manySuite
56
+ .add("valid: a", function () {
57
+ many.parse(objA);
58
+ })
59
+ .add("valid: c", function () {
60
+ many.parse(objC);
61
+ })
62
+ .add("invalid: null", function () {
63
+ try {
64
+ many.parse(null);
65
+ }
66
+ catch (err) { }
67
+ })
68
+ .add("invalid: wrong shape", function () {
69
+ try {
70
+ many.parse({ type: "unknown" });
71
+ }
72
+ catch (err) { }
73
+ })
74
+ .on("cycle", function (e) {
75
+ console.log("".concat(manySuite.name, ": ").concat(e.target));
76
+ });
77
+ exports.default = {
78
+ suites: [doubleSuite, manySuite],
79
+ };
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=index.d.ts.map