zod 3.24.1 → 3.24.3

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/README.md CHANGED
@@ -1,13 +1,12 @@
1
1
  <p align="center">
2
- <img src="logo.svg" width="200px" align="center" alt="Zod logo" />
2
+ <img src="https://raw.githubusercontent.com/colinhacks/zod/main/logo.svg" width="200px" align="center" alt="Zod logo" />
3
3
  <h1 align="center">Zod</h1>
4
4
  <p align="center">
5
- <a href="https://zod.dev">https://zod.dev</a>
6
- <br/>
5
+ <a href="https://zod.dev">zod.dev</a>
6
+ <br/>
7
7
  TypeScript-first schema validation with static type inference
8
8
  </p>
9
9
  </p>
10
- <br/>
11
10
  <p align="center">
12
11
  <a href="https://github.com/colinhacks/zod/actions?query=branch%3Amain"><img src="https://github.com/colinhacks/zod/actions/workflows/test.yml/badge.svg?event=push&branch=main" alt="Zod CI status" /></a>
13
12
  <a href="https://twitter.com/colinhacks" rel="nofollow"><img src="https://img.shields.io/badge/created%20by-@colinhacks-4BBAAB.svg" alt="Created by Colin McDonnell"></a>
@@ -17,34 +16,47 @@
17
16
  </p>
18
17
 
19
18
  <div align="center">
20
- <a href="https://zod.dev">Documentation</a>
19
+ <a href="https://zod.dev">Website</a>
21
20
  <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
22
21
  <a href="https://discord.gg/RcG33DQJdf">Discord</a>
23
22
  <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
24
- <a href="https://www.npmjs.com/package/zod">npm</a>
25
- <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
26
- <a href="https://deno.land/x/zod">deno</a>
23
+ <a href="https://twitter.com/colinhacks">𝕏</a>
27
24
  <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
28
- <a href="https://github.com/colinhacks/zod/issues/new">Issues</a>
29
- <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
30
- <a href="https://twitter.com/colinhacks">@colinhacks</a>
31
- <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
32
- <a href="https://trpc.io">tRPC</a>
25
+ <a href="https://bsky.app/profile/zod.dev">Bluesky</a>
33
26
  <br />
34
27
  </div>
35
28
 
29
+ <br/><br/>
30
+
31
+ <table align="center" style="justify-content:center;align-items:center;display:flex;"><td>
32
+ <p align="center">Zod 4 is now in beta!
33
+ <br/>
34
+ <a target="_blank" rel="noopener noreferrer" href="https://v4.zod.dev/v4">Read the announcement 👉</a></p></td>
35
+ </table>
36
+
36
37
  <br/>
37
38
  <br/>
38
39
 
39
- <!-- <p><strong>Announcement ✨</strong> Zod has recieved the <a href="https://go.clerk.com/zod-clerk">Clerk</a> OSS Fellowship!<br/>Read the announcement post 👉 <a href="https://go.clerk.com/zod-clerk">clerk.com/blog/zod-fellowship</a></p> -->
40
+ <h2 align="center">Featured sponsor: Fern</h2>
40
41
 
41
- [![clerk announcement](https://github.com/colinhacks/zod/assets/3084745/6327cf99-8d82-4b44-a5b1-ba2b5c2ff6ad)](https://go.clerk.com/hqN4rp7)
42
+ <div align="center">
43
+ <a href="https://link.buildwithfern.com/zod-partnership">
44
+ <picture width="95%" >
45
+ <source media="(prefers-color-scheme: dark)" srcset="https://i.imgur.com/ntvK08h.png">
46
+ <img alt="fern logo" src="https://i.imgur.com/pqyEkg5.png" width="95%">
47
+ </picture>
48
+ </a>
49
+ <br/>
50
+ <p><sub>Learn more about <a target="_blank" rel="noopener noreferrer" href="mailto:sponsorship@colinhacks.com">featured sponsorships</a></sub></p>
51
+ </div>
42
52
 
53
+ <!-- <hr/> -->
43
54
  <br/>
44
-
55
+ <br/>
56
+
45
57
  ## Table of contents
46
58
 
47
- > These docs have been translated into [Chinese](./README_ZH.md).
59
+ > These docs have been translated into [Chinese](./README_ZH.md) and [Korean](./README_KO.md).
48
60
 
49
61
  - [Table of contents](#table-of-contents)
50
62
  - [Introduction](#introduction)
@@ -165,6 +177,8 @@
165
177
  - [Ow](#ow)
166
178
  - [Changelog](#changelog)
167
179
 
180
+ <br/>
181
+
168
182
  ## Introduction
169
183
 
170
184
  Zod is a TypeScript-first schema declaration and validation library. I'm using the term "schema" to broadly refer to any data type, from a simple `string` to a complex nested object.
@@ -181,38 +195,59 @@ Some other great aspects:
181
195
  - Functional approach: [parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
182
196
  - Works with plain JavaScript too! You don't need to use TypeScript.
183
197
 
198
+ <br/>
199
+
184
200
  ## Sponsors
185
201
 
186
202
  Sponsorship at any level is appreciated and encouraged. If you built a paid product using Zod, consider one of the [corporate tiers](https://github.com/sponsors/colinhacks).
187
203
 
188
204
  <br/>
189
- <h3 align="center">Diamond</h3>
190
205
 
191
- <br/>
206
+ <h3 align="center">Platinum</h3>
192
207
 
193
- <div align="center">
194
- <a href="https://go.clerk.com/PKHrcwh">
195
- <picture width="100%">
196
- <source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/15c8c8be-189d-44ed-b3db-59bf2a21cbe3">
197
- <img alt="clerk logo" src="https://github.com/colinhacks/zod/assets/3084745/15c8c8be-189d-44ed-b3db-59bf2a21cbe3">
198
- </picture>
199
- </a>
200
- <br/>
201
- <br/>
202
- <p>
203
- The most comprehensive User Management Platform
204
- <br/>
205
- <a style="text-decoration:none;" href="https://go.clerk.com/PKHrcwh" target="_blank">clerk.com</a>
206
- </p>
207
- </div>
208
+ <table align="center" style="justify-content: center;align-items: center;display: flex;">
209
+ <tr>
210
+ <td align="center">
211
+ <p></p>
212
+ <p>
213
+ <a href="https://www.coderabbit.ai/">
214
+ <picture height="80px">
215
+ <source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/eea24edb-ff20-4532-b57c-e8719f455d6d">
216
+ <img alt="CodeRabbit logo" height="80px" src="https://github.com/user-attachments/assets/d791bc7d-dc60-4d55-9c31-97779839cb74">
217
+ </picture>
218
+ </a>
219
+ <br />
220
+ Cut code review time & bugs in half
221
+ <br/>
222
+ <a href="https://www.coderabbit.ai/" style="text-decoration:none;">coderabbit.ai</a>
223
+ </p>
224
+ <p></p>
225
+ </td>
226
+ </tr>
227
+ </table>
208
228
 
209
- <br/>
210
229
  <br/>
211
230
 
212
- <h3 align="center">Platinum</h3>
231
+ <h3 align="center">Gold</h3>
213
232
 
214
233
  <table align="center" style="justify-content: center;align-items: center;display: flex;">
215
234
  <tr>
235
+ <td align="center">
236
+ <p></p>
237
+ <p>
238
+ <a href="https://www.courier.com/?utm_source=zod&utm_campaign=osssponsors">
239
+ <picture height="62px">
240
+ <source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/6b09506a-78de-47e8-a8c1-792efe31910a">
241
+ <img alt="Courier logo" height="62px" src="https://github.com/user-attachments/assets/6b09506a-78de-47e8-a8c1-792efe31910a">
242
+ </picture>
243
+ </a>
244
+ <br />
245
+ The API platform for sending notifications
246
+ <br/>
247
+ <a href="https://www.courier.com/?utm_source=zod&utm_campaign=osssponsors" style="text-decoration:none;">courier.com</a>
248
+ </p>
249
+ <p></p>
250
+ </td>
216
251
  <td align="center">
217
252
  <p></p>
218
253
  <p>
@@ -247,15 +282,13 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
247
282
  </p>
248
283
  <p></p>
249
284
  </td>
250
- </tr>
251
- <tr>
252
285
  <td align="center">
253
286
  <p></p>
254
287
  <p>
255
288
  <a href="https://retool.com/?utm_source=github&utm_medium=referral&utm_campaign=zod">
256
289
  <picture height="45px">
257
290
  <source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/ac65013f-aeb4-48dd-a2ee-41040b69cbe6">
258
- <img alt="stainless" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/5ef4c11b-efeb-4495-90a8-41b83f798600">
291
+ <img alt="Retool" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/5ef4c11b-efeb-4495-90a8-41b83f798600">
259
292
  </picture>
260
293
  </a>
261
294
  <br />
@@ -270,7 +303,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
270
303
  <td align="center">
271
304
  <p></p>
272
305
  <p>
273
- <a href="https://stainlessapi.com">
306
+ <a href="https://stainless.com">
274
307
  <picture height="45px">
275
308
  <source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/f20759c1-3e51-49d0-a31e-bbc43abec665">
276
309
  <img alt="stainless" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/e9444e44-d991-4bba-a697-dbcfad608e47">
@@ -279,12 +312,10 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
279
312
  <br />
280
313
  Generate best-in-class SDKs
281
314
  <br/>
282
- <a href="https://stainlessapi.com" style="text-decoration:none;">stainlessapi.com</a>
315
+ <a href="https://stainless.com" style="text-decoration:none;">stainless.com</a>
283
316
  </p>
284
317
  <p></p>
285
318
  </td>
286
- </tr>
287
- <tr>
288
319
  <td align="center">
289
320
  <p></p>
290
321
  <p>
@@ -306,10 +337,15 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
306
337
 
307
338
  <br/>
308
339
 
309
- <h3 align="center">Gold</h3>
340
+ <h3 align="center">Silver</h3>
310
341
 
311
342
  <table align="center" style="justify-content: center;align-items: center;display: flex;">
312
343
  <tr>
344
+ <td align="center">
345
+ <img src="https://avatars.githubusercontent.com/u/72055470?s=200&v=4" height="50px;" alt="Nitric" />
346
+ <br />
347
+ <a style="text-decoration:none;" href="https://nitric.io/" target="_blank">Nitric</a>
348
+ </td>
313
349
  <td align="center">
314
350
  <img src="https://avatars.githubusercontent.com/u/89474619?s=200&v=4" height="50px;" alt="PropelAuth" />
315
351
  <br />
@@ -325,12 +361,12 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
325
361
  <br />
326
362
  <a style="text-decoration:none;" href="https://scalar.com/" target="_blank">Scalar</a>
327
363
  </td>
364
+ </tr><tr>
328
365
  <td align="center">
329
366
  <img src="https://avatars.githubusercontent.com/u/95297378?s=200&v=4" height="50px;" alt="Trigger.dev logo" />
330
367
  <br />
331
368
  <a style="text-decoration:none;" href="https://trigger.dev" target="_blank">Trigger.dev</a>
332
369
  </td>
333
- </tr><tr>
334
370
  <td align="center">
335
371
  <img src="https://avatars.githubusercontent.com/u/125754?s=200&v=4" height="50px;" alt="Transloadit logo" />
336
372
  <br />
@@ -347,12 +383,12 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
347
383
  <br />
348
384
  <a style="text-decoration:none;" href="https://whop.com/" target="_blank">Whop</a>
349
385
  </td>
386
+ </tr><tr>
350
387
  <td align="center">
351
388
  <img src="https://avatars.githubusercontent.com/u/36402888?s=200&v=4" height="50px;" alt="CryptoJobsList logo" />
352
389
  <br />
353
390
  <a style="text-decoration:none;" href="https://cryptojobslist.com/" target="_blank">CryptoJobsList</a>
354
391
  </td>
355
- </tr><tr>
356
392
  <td align="center">
357
393
  <img src="https://avatars.githubusercontent.com/u/70170949?s=200&v=4" height="50px;" alt="Plain logo" />
358
394
  <br />
@@ -368,6 +404,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
368
404
  <br />
369
405
  <a style="text-decoration:none;" href="https://storyblok.com/" target="_blank">Storyblok</a>
370
406
  </td>
407
+ </tr><tr>
371
408
  <td align="center">
372
409
  <img src="https://avatars.githubusercontent.com/u/16199997?s=200&v=4" height="50px;" alt="Mux logo" />
373
410
  <br />
@@ -378,7 +415,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
378
415
 
379
416
  <br/>
380
417
 
381
- <h3 align="center">Silver</h3>
418
+ <h3 align="center">Bronze</h3>
382
419
 
383
420
  <table align="center" style="justify-content: center;align-items: center;display: flex;">
384
421
  <tr>
@@ -442,7 +479,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
442
479
  </tr>
443
480
  </table>
444
481
 
445
- <h3 align="center">Bronze</h3>
482
+ <!-- <h3 align="center">Bronze</h3>
446
483
 
447
484
  <table align="center" style="justify-content: center;align-items: center;display: flex;">
448
485
  <tr>
@@ -469,7 +506,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
469
506
  <td>Mohammad-Ali A'râbi</td>
470
507
  <td>Supatool</td>
471
508
  </tr>
472
- </table>
509
+ </table> -->
473
510
 
474
511
  ### Ecosystem
475
512
 
@@ -493,10 +530,13 @@ There are a growing number of tools that are built atop or support Zod natively!
493
530
  - [`koa-zod-router`](https://github.com/JakeFenley/koa-zod-router): Create typesafe routes in Koa with I/O validation using Zod.
494
531
  - [`zod-sockets`](https://github.com/RobinTail/zod-sockets): Zod-powered Socket.IO microframework with I/O validation and built-in AsyncAPI specs
495
532
  - [`oas-tszod-gen`](https://github.com/inkognitro/oas-tszod-gen): Client SDK code generator to convert OpenApi v3 specifications into TS endpoint caller functions with Zod types.
533
+ - [`GQLoom`](https://github.com/modevol-com/gqloom): Weave GraphQL schema and resolvers using Zod.
534
+ - [`oRPC`](https://github.com/unnoq/orpc): Typesafe APIs Made Simple
496
535
 
497
536
  #### Form integrations
498
537
 
499
538
  - [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form.
539
+ - [`TanStack Form`](https://github.com/TanStack/form): Headless, performant, and type-safe form state management for TS/JS, React, Vue, Angular, Solid, and Lit
500
540
  - [`zod-validation-error`](https://github.com/causaly/zod-validation-error): Generate user-friendly error messages from `ZodError`s.
501
541
  - [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod.
502
542
  - [`react-zorm`](https://github.com/esamattis/react-zorm): Standalone `<form>` generation and validation for React using Zod.
@@ -520,7 +560,7 @@ There are a growing number of tools that are built atop or support Zod natively!
520
560
  - [`zod-to-json-schema`](https://github.com/StefanTerdell/zod-to-json-schema): Convert your Zod schemas into [JSON Schemas](https://json-schema.org/).
521
561
  - [`@anatine/zod-openapi`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-openapi): Converts a Zod schema to an OpenAPI v3.x `SchemaObject`.
522
562
  - [`zod-fast-check`](https://github.com/DavidTimms/zod-fast-check): Generate `fast-check` arbitraries from Zod schemas.
523
- - [`zod-dto`](https://github.com/kbkk/abitia/tree/main/packages/zod-dto): Generate Nest.js DTOs from a Zod schema.
563
+ - [`zod-dto`](https://github.com/kbkk/abitia/tree/master/packages/zod-dto): Generate Nest.js DTOs from a Zod schema.
524
564
  - [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod): Create Fastify type providers from Zod schemas.
525
565
  - [`zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi): Generate full OpenAPI (Swagger) docs from Zod, including schemas, endpoints & parameters.
526
566
  - [`nestjs-graphql-zod`](https://github.com/incetarik/nestjs-graphql-zod): Generates NestJS GraphQL model classes from Zod schemas. Provides GraphQL method decorators working with Zod schemas.
@@ -532,7 +572,7 @@ There are a growing number of tools that are built atop or support Zod natively!
532
572
  #### X to Zod
533
573
 
534
574
  - [`ts-to-zod`](https://github.com/fabien0102/ts-to-zod): Convert TypeScript definitions into Zod schemas.
535
- - [`@runtyping/zod`](https://github.com/johngeorgewright/runtyping/tree/main/packages/zod): Generate Zod from static types & JSON schema.
575
+ - [`@runtyping/zod`](https://github.com/johngeorgewright/runtyping): Generate Zod from static types & JSON schema.
536
576
  - [`json-schema-to-zod`](https://github.com/StefanTerdell/json-schema-to-zod): Convert your [JSON Schemas](https://json-schema.org/) into Zod schemas. [Live demo](https://StefanTerdell.github.io/json-schema-to-zod-react/).
537
577
  - [`json-to-zod`](https://github.com/rsinohara/json-to-zod): Convert JSON objects into Zod schemas. [Live demo](https://rsinohara.github.io/json-to-zod-react/).
538
578
  - [`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.
@@ -568,6 +608,9 @@ There are a growing number of tools that are built atop or support Zod natively!
568
608
  - [`znv`](https://github.com/lostfictions/znv): Type-safe environment parsing and validation for Node.js with Zod schemas.
569
609
  - [`zod-config`](https://github.com/alexmarqs/zod-config): Load configurations across multiple sources with flexible adapters, ensuring type safety with Zod.
570
610
  - [`unplugin-environment`](https://github.com/r17x/js/tree/main/packages/unplugin-environment#readme): A plugin for loading enviroment variables safely with schema validation, simple with virtual module, type-safe with intellisense, and better DX 🔥 🚀 👷. Powered by Zod.
611
+ - [`zod-struct`](https://codeberg.org/reesericci/zod-struct): Create runtime-checked structs with Zod.
612
+ - [`zod-csv`](https://github.com/bartoszgolebiowski/zod-csv): Validation helpers for zod for parsing CSV data.
613
+ - [`fullproduct.dev`](https://fullproduct.dev?identity=freelancers&v=z3): Universal Expo + Next.js App Starter that uses Zod schemas as the single source of truth to keep generated MDX docs, GraphQL, database models, forms, and fetcher functions in sync.
571
614
 
572
615
  #### Utilities for Zod
573
616
 
@@ -577,6 +620,8 @@ There are a growing number of tools that are built atop or support Zod natively!
577
620
  - [`zod-dev`](https://github.com/schalkventer/zod-dev): Conditionally disables Zod runtime parsing in production.
578
621
  - [`zod-accelerator`](https://github.com/duplojs/duplojs-zod-accelerator): Accelerates Zod's throughput up to ~100x.
579
622
 
623
+ <br/>
624
+
580
625
  ## Installation
581
626
 
582
627
  ### Requirements
@@ -617,6 +662,8 @@ pnpm add zod@canary # pnpm
617
662
 
618
663
  > The rest of this README assumes you are using npm and importing directly from the `"zod"` package.
619
664
 
665
+ <br/>
666
+
620
667
  ## Basic usage
621
668
 
622
669
  Creating a simple string schema
@@ -652,6 +699,8 @@ type User = z.infer<typeof User>;
652
699
  // { username: string }
653
700
  ```
654
701
 
702
+ <br/>
703
+
655
704
  ## Primitives
656
705
 
657
706
  ```ts
@@ -680,6 +729,8 @@ z.unknown();
680
729
  z.never();
681
730
  ```
682
731
 
732
+ <br/>
733
+
683
734
  ## Coercion for primitives
684
735
 
685
736
  Zod now provides a more convenient way to coerce primitive values.
@@ -736,6 +787,8 @@ schema.parse(null); // => false
736
787
 
737
788
  For more control over coercion logic, consider using [`z.preprocess`](#preprocess) or [`z.pipe()`](#pipe).
738
789
 
790
+ <br/>
791
+
739
792
  ## Literals
740
793
 
741
794
  Literal schemas represent a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types), like `"hello world"` or `5`.
@@ -755,6 +808,8 @@ tuna.value; // "tuna"
755
808
 
756
809
  > Currently there is no support for Date literals in Zod. If you have a use case for this feature, please file an issue.
757
810
 
811
+ <br/>
812
+
758
813
  ## Strings
759
814
 
760
815
  Zod includes a handful of string-specific validations.
@@ -953,6 +1008,8 @@ const ipv6Cidr = z.string().cidr({ version: "v6" });
953
1008
  ipv6Cidr.parse("192.168.1.1"); // fail
954
1009
  ```
955
1010
 
1011
+ <br/>
1012
+
956
1013
  ## Numbers
957
1014
 
958
1015
  You can customize certain error messages when creating a number schema.
@@ -991,6 +1048,8 @@ Optionally, you can pass in a second argument to provide a custom error message.
991
1048
  z.number().lte(5, { message: "this👏is👏too👏big" });
992
1049
  ```
993
1050
 
1051
+ <br/>
1052
+
994
1053
  ## BigInts
995
1054
 
996
1055
  Zod includes a handful of bigint-specific validations.
@@ -1009,6 +1068,8 @@ z.bigint().nonpositive(); // <= 0n
1009
1068
  z.bigint().multipleOf(5n); // Evenly divisible by 5n.
1010
1069
  ```
1011
1070
 
1071
+ <br/>
1072
+
1012
1073
  ## NaNs
1013
1074
 
1014
1075
  You can customize certain error messages when creating a nan schema.
@@ -1020,6 +1081,8 @@ const isNaN = z.nan({
1020
1081
  });
1021
1082
  ```
1022
1083
 
1084
+ <br/>
1085
+
1023
1086
  ## Booleans
1024
1087
 
1025
1088
  You can customize certain error messages when creating a boolean schema.
@@ -1031,6 +1094,8 @@ const isActive = z.boolean({
1031
1094
  });
1032
1095
  ```
1033
1096
 
1097
+ <br/>
1098
+
1034
1099
  ## Dates
1035
1100
 
1036
1101
  Use z.date() to validate `Date` instances.
@@ -1078,6 +1143,8 @@ console.log(dateSchema.safeParse("0000-00-00").success); // false
1078
1143
 
1079
1144
  For older zod versions, use [`z.preprocess`](#preprocess) like [described in this thread](https://github.com/colinhacks/zod/discussions/879#discussioncomment-2036276).
1080
1145
 
1146
+ <br/>
1147
+
1081
1148
  ## Zod enums
1082
1149
 
1083
1150
  ```ts
@@ -1133,6 +1200,8 @@ const SalmonAndTrout = FishEnum.extract(["Salmon", "Trout"]);
1133
1200
  const TunaOnly = FishEnum.exclude(["Salmon", "Trout"]);
1134
1201
  ```
1135
1202
 
1203
+ <br/>
1204
+
1136
1205
  ## Native enums
1137
1206
 
1138
1207
  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()`.
@@ -1201,6 +1270,8 @@ You can access the underlying object with the `.enum` property:
1201
1270
  FruitEnum.enum.Apple; // "apple"
1202
1271
  ```
1203
1272
 
1273
+ <br/>
1274
+
1204
1275
  ## Optionals
1205
1276
 
1206
1277
  You can make any schema optional with `z.optional()`. This wraps the schema in a `ZodOptional` instance and returns the result.
@@ -1229,6 +1300,8 @@ const optionalString = stringSchema.optional();
1229
1300
  optionalString.unwrap() === stringSchema; // true
1230
1301
  ```
1231
1302
 
1303
+ <br/>
1304
+
1232
1305
  ## Nullables
1233
1306
 
1234
1307
  Similarly, you can create nullable types with `z.nullable()`.
@@ -1254,6 +1327,8 @@ const nullableString = stringSchema.nullable();
1254
1327
  nullableString.unwrap() === stringSchema; // true
1255
1328
  ```
1256
1329
 
1330
+ <br/>
1331
+
1257
1332
  ## Objects
1258
1333
 
1259
1334
  ```ts
@@ -1522,6 +1597,8 @@ person.parse({
1522
1597
 
1523
1598
  Using `.catchall()` obviates `.passthrough()` , `.strip()` , or `.strict()`. All keys are now considered "known".
1524
1599
 
1600
+ <br/>
1601
+
1525
1602
  ## Arrays
1526
1603
 
1527
1604
  ```ts
@@ -1578,6 +1655,8 @@ z.string().array().length(5); // must contain 5 items exactly
1578
1655
 
1579
1656
  Unlike `.nonempty()` these methods do not change the inferred type.
1580
1657
 
1658
+ <br/>
1659
+
1581
1660
  ## Tuples
1582
1661
 
1583
1662
  Unlike arrays, tuples have a fixed number of elements and each element can have a different type.
@@ -1603,6 +1682,8 @@ const result = variadicTuple.parse(["hello", 1, 2, 3]);
1603
1682
  // => [string, ...number[]];
1604
1683
  ```
1605
1684
 
1685
+ <br/>
1686
+
1606
1687
  ## Unions
1607
1688
 
1608
1689
  Zod includes a built-in `z.union` method for composing "OR" types.
@@ -1638,6 +1719,8 @@ console.log(optionalUrl.safeParse("https://zod.dev").success); // true
1638
1719
  console.log(optionalUrl.safeParse("not a valid url").success); // false
1639
1720
  ```
1640
1721
 
1722
+ <br/>
1723
+
1641
1724
  ## Discriminated unions
1642
1725
 
1643
1726
  A discriminated union is a union of object schemas that all share a particular key.
@@ -1680,6 +1763,8 @@ const B = z.discriminatedUnion("status", [
1680
1763
  const AB = z.discriminatedUnion("status", [...A.options, ...B.options]);
1681
1764
  ```
1682
1765
 
1766
+ <br/>
1767
+
1683
1768
  ## Records
1684
1769
 
1685
1770
  Record schemas are used to validate types such as `Record<string, number>`. This is particularly useful for storing or caching items by ID.
@@ -1734,6 +1819,8 @@ for (const key in testMap) {
1734
1819
 
1735
1820
  As you can see, JavaScript automatically casts all object keys to strings under the hood. Since Zod is trying to bridge the gap between static and runtime types, it doesn't make sense to provide a way of creating a record schema with numerical keys, since there's no such thing as a numerical key in runtime JavaScript.
1736
1821
 
1822
+ <br/>
1823
+
1737
1824
  ## Maps
1738
1825
 
1739
1826
  ```ts
@@ -1743,6 +1830,8 @@ type StringNumberMap = z.infer<typeof stringNumberMap>;
1743
1830
  // type StringNumberMap = Map<string, number>
1744
1831
  ```
1745
1832
 
1833
+ <br/>
1834
+
1746
1835
  ## Sets
1747
1836
 
1748
1837
  ```ts
@@ -1760,6 +1849,8 @@ z.set(z.string()).max(5); // must contain 5 or fewer items
1760
1849
  z.set(z.string()).size(5); // must contain 5 items exactly
1761
1850
  ```
1762
1851
 
1852
+ <br/>
1853
+
1763
1854
  ## Intersections
1764
1855
 
1765
1856
  Intersections are useful for creating "logical AND" types. This is useful for intersecting two object types.
@@ -1808,6 +1899,8 @@ type Teacher = z.infer<typeof Teacher>;
1808
1899
  // { id:string; name:string };
1809
1900
  ``` -->
1810
1901
 
1902
+ <br/>
1903
+
1811
1904
  ## Recursive types
1812
1905
 
1813
1906
  You can define a recursive schema in Zod, but because of a limitation of TypeScript, their type can't be statically inferred. Instead you'll need to define the type definition manually, and provide it to Zod as a "type hint".
@@ -1898,6 +1991,8 @@ Despite supporting recursive schemas, passing cyclical data into Zod will cause
1898
1991
 
1899
1992
  > To detect cyclical objects before they cause problems, consider [this approach](https://gist.github.com/colinhacks/d35825e505e635df27cc950776c5500b).
1900
1993
 
1994
+ <br/>
1995
+
1901
1996
  ## Promises
1902
1997
 
1903
1998
  ```ts
@@ -1929,6 +2024,8 @@ const test = async () => {
1929
2024
 
1930
2025
  When "parsing" a promise, Zod checks that the passed value is an object with `.then` and `.catch` methods — that's it. So you should be able to pass non-native Promises (Bluebird, etc) into `z.promise(...).parse` with no trouble. One gotcha: the return type of the parse function will be a _native_ `Promise` , so if you have downstream logic that uses non-standard Promise methods, this won't work. -->
1931
2026
 
2027
+ <br/>
2028
+
1932
2029
  ## Instanceof
1933
2030
 
1934
2031
  You can use `z.instanceof` to check that the input is an instance of a class. This is useful to validate inputs against classes that are exported from third-party libraries.
@@ -1945,6 +2042,8 @@ TestSchema.parse(new Test()); // passes
1945
2042
  TestSchema.parse(blob); // throws
1946
2043
  ```
1947
2044
 
2045
+ <br/>
2046
+
1948
2047
  ## Functions
1949
2048
 
1950
2049
  Zod also lets you define "function schemas". This makes it easy to validate the inputs and outputs of a function without intermixing your validation code and "business logic".
@@ -2028,6 +2127,8 @@ myFunction.returnType();
2028
2127
  * `args: ZodTuple` The first argument is a tuple (created with `z.tuple([...])` and defines the schema of the arguments to your function. If the function doesn't accept arguments, you can pass an empty tuple (`z.tuple([])`).
2029
2128
  * `returnType: any Zod schema` The second argument is the function's return type. This can be any Zod schema. -->
2030
2129
 
2130
+ <br/>
2131
+
2031
2132
  ## Preprocess
2032
2133
 
2033
2134
  > Zod now supports primitive coercion without the need for `.preprocess()`. See the [coercion docs](#coercion-for-primitives) for more information.
@@ -2042,6 +2143,8 @@ const castToString = z.preprocess((val) => String(val), z.string());
2042
2143
 
2043
2144
  This returns a `ZodEffects` instance. `ZodEffects` is a wrapper class that contains all logic pertaining to preprocessing, refinements, and transforms.
2044
2145
 
2146
+ <br/>
2147
+
2045
2148
  ## Custom schemas
2046
2149
 
2047
2150
  You can create a Zod schema for any TypeScript type by using `z.custom()`. This is useful for creating schemas for types that are not supported by Zod out of the box, such as template string literals.
@@ -2069,6 +2172,8 @@ You can customize the error message and other options by passing a second argume
2069
2172
  z.custom<...>((val) => ..., "custom error message");
2070
2173
  ```
2071
2174
 
2175
+ <br/>
2176
+
2072
2177
  ## Schema methods
2073
2178
 
2074
2179
  All Zod schemas contain certain methods.
@@ -2654,61 +2759,7 @@ z.string()
2654
2759
 
2655
2760
  The `.pipe()` method returns a `ZodPipeline` instance.
2656
2761
 
2657
- #### You can use `.pipe()` to fix common issues with `z.coerce`.
2658
-
2659
- You can constrain the input to types that work well with your chosen coercion. Then use `.pipe()` to apply the coercion.
2660
-
2661
- without constrained input:
2662
-
2663
- ```ts
2664
- const toDate = z.coerce.date();
2665
-
2666
- // works intuitively
2667
- console.log(toDate.safeParse("2023-01-01").success); // true
2668
-
2669
- // might not be what you want
2670
- console.log(toDate.safeParse(null).success); // true
2671
- ```
2672
-
2673
- with constrained input:
2674
-
2675
- ```ts
2676
- const datelike = z.union([z.number(), z.string(), z.date()]);
2677
- const datelikeToDate = datelike.pipe(z.coerce.date());
2678
-
2679
- // still works intuitively
2680
- console.log(datelikeToDate.safeParse("2023-01-01").success); // true
2681
-
2682
- // more likely what you want
2683
- console.log(datelikeToDate.safeParse(null).success); // false
2684
- ```
2685
-
2686
- You can also use this technique to avoid coercions that throw uncaught errors.
2687
-
2688
- without constrained input:
2689
-
2690
- ```ts
2691
- const toBigInt = z.coerce.bigint();
2692
-
2693
- // works intuitively
2694
- console.log(toBigInt.safeParse("42")); // true
2695
-
2696
- // probably not what you want
2697
- console.log(toBigInt.safeParse(null)); // throws uncaught error
2698
- ```
2699
-
2700
- with constrained input:
2701
-
2702
- ```ts
2703
- const toNumber = z.number().or(z.string()).pipe(z.coerce.number());
2704
- const toBigInt = z.bigint().or(toNumber).pipe(z.coerce.bigint());
2705
-
2706
- // still works intuitively
2707
- console.log(toBigInt.safeParse("42").success); // true
2708
-
2709
- // error handled by zod, more likely what you want
2710
- console.log(toBigInt.safeParse(null).success); // false
2711
- ```
2762
+ <br/>
2712
2763
 
2713
2764
  ## Guides and concepts
2714
2765
 
@@ -2879,6 +2930,8 @@ if (!result.success) {
2879
2930
  }
2880
2931
  ```
2881
2932
 
2933
+ <br/>
2934
+
2882
2935
  ## Comparison
2883
2936
 
2884
2937
  There are a handful of other widely-used validation libraries, but all of them have certain design limitations that make for a non-ideal developer experience.
@@ -3005,13 +3058,15 @@ This more declarative API makes schema definitions vastly more concise.
3005
3058
 
3006
3059
  ### Runtypes
3007
3060
 
3008
- [https://github.com/pelotom/runtypes](https://github.com/pelotom/runtypes)
3061
+ [https://github.com/runtypes/runtypes](https://github.com/runtypes/runtypes)
3009
3062
 
3010
- Good type inference support.
3063
+ Runtypes is focused on ergonomics, with good type inference support.
3011
3064
 
3012
3065
  - Supports "pattern matching": computed properties that distribute over unions
3066
+ - Supports branded types
3067
+ - Supports template literals
3068
+ - Supports conformance to predefined static types
3013
3069
  - Missing object methods: (deepPartial, merge)
3014
- - Missing nonempty arrays with proper typing (`[T, ...T[]]`)
3015
3070
  - Missing promise schemas
3016
3071
  - Missing error customization
3017
3072
 
@@ -3023,6 +3078,8 @@ Ow is focused on function input validation. It's a library that makes it easy to
3023
3078
 
3024
3079
  If you want to validate function inputs, use function schemas in Zod! It's a much simpler approach that lets you reuse a function type declaration without repeating yourself (namely, copy-pasting a bunch of ow assertions at the beginning of every function). Also Zod lets you validate your return types as well, so you can be sure there won't be any unexpected data passed downstream.
3025
3080
 
3081
+ <br/>
3082
+
3026
3083
  ## Changelog
3027
3084
 
3028
3085
  View the changelog at [CHANGELOG.md](CHANGELOG.md)
@@ -22,7 +22,7 @@ export declare namespace util {
22
22
  export {};
23
23
  }
24
24
  export declare namespace objectUtil {
25
- export type MergeShapes<U, V> = {
25
+ export type MergeShapes<U, V> = keyof U & keyof V extends never ? U & V : {
26
26
  [k in Exclude<keyof U, keyof V>]: U[k];
27
27
  } & V;
28
28
  type optionalKeys<T extends object> = {
@@ -49,7 +49,7 @@ export declare namespace objectUtil {
49
49
  [k in noNeverKeys<T>]: k extends keyof T ? T[k] : never;
50
50
  }>;
51
51
  export const mergeShapes: <U, T>(first: U, second: T) => T & U;
52
- export type extendShape<A extends object, B extends object> = {
52
+ export type extendShape<A extends object, B extends object> = keyof A & keyof B extends never ? A & B : {
53
53
  [K in keyof A as K extends keyof B ? never : K]: A[K];
54
54
  } & {
55
55
  [K in keyof B]: B[K];
package/lib/index.mjs CHANGED
@@ -4144,7 +4144,23 @@ ZodReadonly.create = (type, params) => {
4144
4144
  ...processCreateParams(params),
4145
4145
  });
4146
4146
  };
4147
- function custom(check, params = {},
4147
+ ////////////////////////////////////////
4148
+ ////////////////////////////////////////
4149
+ ////////// //////////
4150
+ ////////// z.custom //////////
4151
+ ////////// //////////
4152
+ ////////////////////////////////////////
4153
+ ////////////////////////////////////////
4154
+ function cleanParams(params, data) {
4155
+ const p = typeof params === "function"
4156
+ ? params(data)
4157
+ : typeof params === "string"
4158
+ ? { message: params }
4159
+ : params;
4160
+ const p2 = typeof p === "string" ? { message: p } : p;
4161
+ return p2;
4162
+ }
4163
+ function custom(check, _params = {},
4148
4164
  /**
4149
4165
  * @deprecated
4150
4166
  *
@@ -4159,16 +4175,23 @@ fatal) {
4159
4175
  if (check)
4160
4176
  return ZodAny.create().superRefine((data, ctx) => {
4161
4177
  var _a, _b;
4162
- if (!check(data)) {
4163
- const p = typeof params === "function"
4164
- ? params(data)
4165
- : typeof params === "string"
4166
- ? { message: params }
4167
- : params;
4168
- const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
4169
- const p2 = typeof p === "string" ? { message: p } : p;
4170
- ctx.addIssue({ code: "custom", ...p2, fatal: _fatal });
4178
+ const r = check(data);
4179
+ if (r instanceof Promise) {
4180
+ return r.then((r) => {
4181
+ var _a, _b;
4182
+ if (!r) {
4183
+ const params = cleanParams(_params, data);
4184
+ const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
4185
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
4186
+ }
4187
+ });
4188
+ }
4189
+ if (!r) {
4190
+ const params = cleanParams(_params, data);
4191
+ const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
4192
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
4171
4193
  }
4194
+ return;
4172
4195
  });
4173
4196
  return ZodAny.create();
4174
4197
  }
package/lib/index.umd.js CHANGED
@@ -4150,7 +4150,23 @@
4150
4150
  ...processCreateParams(params),
4151
4151
  });
4152
4152
  };
4153
- function custom(check, params = {},
4153
+ ////////////////////////////////////////
4154
+ ////////////////////////////////////////
4155
+ ////////// //////////
4156
+ ////////// z.custom //////////
4157
+ ////////// //////////
4158
+ ////////////////////////////////////////
4159
+ ////////////////////////////////////////
4160
+ function cleanParams(params, data) {
4161
+ const p = typeof params === "function"
4162
+ ? params(data)
4163
+ : typeof params === "string"
4164
+ ? { message: params }
4165
+ : params;
4166
+ const p2 = typeof p === "string" ? { message: p } : p;
4167
+ return p2;
4168
+ }
4169
+ function custom(check, _params = {},
4154
4170
  /**
4155
4171
  * @deprecated
4156
4172
  *
@@ -4165,16 +4181,23 @@
4165
4181
  if (check)
4166
4182
  return ZodAny.create().superRefine((data, ctx) => {
4167
4183
  var _a, _b;
4168
- if (!check(data)) {
4169
- const p = typeof params === "function"
4170
- ? params(data)
4171
- : typeof params === "string"
4172
- ? { message: params }
4173
- : params;
4174
- const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
4175
- const p2 = typeof p === "string" ? { message: p } : p;
4176
- ctx.addIssue({ code: "custom", ...p2, fatal: _fatal });
4184
+ const r = check(data);
4185
+ if (r instanceof Promise) {
4186
+ return r.then((r) => {
4187
+ var _a, _b;
4188
+ if (!r) {
4189
+ const params = cleanParams(_params, data);
4190
+ const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
4191
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
4192
+ }
4193
+ });
4194
+ }
4195
+ if (!r) {
4196
+ const params = cleanParams(_params, data);
4197
+ const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
4198
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
4177
4199
  }
4200
+ return;
4178
4201
  });
4179
4202
  return ZodAny.create();
4180
4203
  }
package/lib/types.d.ts CHANGED
@@ -935,7 +935,7 @@ export declare class ZodReadonly<T extends ZodTypeAny> extends ZodType<MakeReado
935
935
  type CustomParams = CustomErrorParams & {
936
936
  fatal?: boolean;
937
937
  };
938
- export declare function custom<T>(check?: (data: any) => any, params?: string | CustomParams | ((input: any) => CustomParams),
938
+ export declare function custom<T>(check?: (data: any) => any, _params?: string | CustomParams | ((input: any) => CustomParams),
939
939
  /**
940
940
  * @deprecated
941
941
  *
package/lib/types.js CHANGED
@@ -3654,7 +3654,23 @@ ZodReadonly.create = (type, params) => {
3654
3654
  ...processCreateParams(params),
3655
3655
  });
3656
3656
  };
3657
- function custom(check, params = {},
3657
+ ////////////////////////////////////////
3658
+ ////////////////////////////////////////
3659
+ ////////// //////////
3660
+ ////////// z.custom //////////
3661
+ ////////// //////////
3662
+ ////////////////////////////////////////
3663
+ ////////////////////////////////////////
3664
+ function cleanParams(params, data) {
3665
+ const p = typeof params === "function"
3666
+ ? params(data)
3667
+ : typeof params === "string"
3668
+ ? { message: params }
3669
+ : params;
3670
+ const p2 = typeof p === "string" ? { message: p } : p;
3671
+ return p2;
3672
+ }
3673
+ function custom(check, _params = {},
3658
3674
  /**
3659
3675
  * @deprecated
3660
3676
  *
@@ -3669,16 +3685,23 @@ fatal) {
3669
3685
  if (check)
3670
3686
  return ZodAny.create().superRefine((data, ctx) => {
3671
3687
  var _a, _b;
3672
- if (!check(data)) {
3673
- const p = typeof params === "function"
3674
- ? params(data)
3675
- : typeof params === "string"
3676
- ? { message: params }
3677
- : params;
3678
- const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
3679
- const p2 = typeof p === "string" ? { message: p } : p;
3680
- ctx.addIssue({ code: "custom", ...p2, fatal: _fatal });
3688
+ const r = check(data);
3689
+ if (r instanceof Promise) {
3690
+ return r.then((r) => {
3691
+ var _a, _b;
3692
+ if (!r) {
3693
+ const params = cleanParams(_params, data);
3694
+ const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
3695
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
3696
+ }
3697
+ });
3698
+ }
3699
+ if (!r) {
3700
+ const params = cleanParams(_params, data);
3701
+ const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
3702
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
3681
3703
  }
3704
+ return;
3682
3705
  });
3683
3706
  return ZodAny.create();
3684
3707
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.24.1",
3
+ "version": "3.24.3",
4
4
  "author": "Colin McDonnell <colin@colinhacks.com>",
5
5
  "repository": {
6
6
  "type": "git",