zod 3.24.2 → 3.24.4
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 +129 -107
- package/lib/helpers/util.d.ts +2 -2
- package/lib/index.mjs +5 -5
- package/lib/index.umd.js +5 -5
- package/lib/types.js +5 -5
- package/package.json +2 -2
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
|
-
|
|
6
|
-
|
|
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,29 +16,42 @@
|
|
|
17
16
|
</p>
|
|
18
17
|
|
|
19
18
|
<div align="center">
|
|
20
|
-
<a href="https://zod.dev">
|
|
19
|
+
<a href="https://zod.dev">Website</a>
|
|
21
20
|
<span> • </span>
|
|
22
21
|
<a href="https://discord.gg/RcG33DQJdf">Discord</a>
|
|
23
22
|
<span> • </span>
|
|
24
|
-
<a href="https://
|
|
25
|
-
<span> • </span>
|
|
26
|
-
<a href="https://deno.land/x/zod">deno</a>
|
|
27
|
-
<span> • </span>
|
|
28
|
-
<a href="https://github.com/colinhacks/zod/issues/new">Issues</a>
|
|
23
|
+
<a href="https://twitter.com/colinhacks">𝕏</a>
|
|
29
24
|
<span> • </span>
|
|
30
|
-
<a href="https://
|
|
31
|
-
<span> • </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
|
-
|
|
40
|
+
<h2 align="center">Featured sponsor: Stainless</h2>
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
<div align="center">
|
|
43
|
+
<a href="https://www.stainless.com/?utm_source=zod">
|
|
44
|
+
<picture width="95%" >
|
|
45
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://i.imgur.com/bjyoaHY.jpeg">
|
|
46
|
+
<img alt="stainless logo" src="https://i.imgur.com/bjyoaHY.jpeg" 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/> -->
|
|
54
|
+
<br/>
|
|
43
55
|
<br/>
|
|
44
56
|
|
|
45
57
|
## Table of contents
|
|
@@ -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,32 +195,12 @@ 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
|
|
|
184
|
-
## Sponsors
|
|
185
|
-
|
|
186
|
-
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
|
-
|
|
188
198
|
<br/>
|
|
189
|
-
<h3 align="center">Diamond</h3>
|
|
190
199
|
|
|
191
|
-
|
|
200
|
+
## Sponsors
|
|
192
201
|
|
|
193
|
-
|
|
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>
|
|
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).
|
|
208
203
|
|
|
209
|
-
<br/>
|
|
210
204
|
<br/>
|
|
211
205
|
|
|
212
206
|
<h3 align="center">Platinum</h3>
|
|
@@ -222,7 +216,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
|
|
|
222
216
|
<img alt="CodeRabbit logo" height="80px" src="https://github.com/user-attachments/assets/d791bc7d-dc60-4d55-9c31-97779839cb74">
|
|
223
217
|
</picture>
|
|
224
218
|
</a>
|
|
225
|
-
<br />
|
|
219
|
+
<br />
|
|
226
220
|
Cut code review time & bugs in half
|
|
227
221
|
<br/>
|
|
228
222
|
<a href="https://www.coderabbit.ai/" style="text-decoration:none;">coderabbit.ai</a>
|
|
@@ -247,7 +241,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
|
|
|
247
241
|
<img alt="Courier logo" height="62px" src="https://github.com/user-attachments/assets/6b09506a-78de-47e8-a8c1-792efe31910a">
|
|
248
242
|
</picture>
|
|
249
243
|
</a>
|
|
250
|
-
<br />
|
|
244
|
+
<br />
|
|
251
245
|
The API platform for sending notifications
|
|
252
246
|
<br/>
|
|
253
247
|
<a href="https://www.courier.com/?utm_source=zod&utm_campaign=osssponsors" style="text-decoration:none;">courier.com</a>
|
|
@@ -263,7 +257,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
|
|
|
263
257
|
<img alt="LibLab" height="62px" src="https://github.com/user-attachments/assets/3de0b617-5137-49c4-b72d-a033cbe602d8">
|
|
264
258
|
</picture>
|
|
265
259
|
</a>
|
|
266
|
-
<br />
|
|
260
|
+
<br />
|
|
267
261
|
Generate better SDKs for your APIs
|
|
268
262
|
<br/>
|
|
269
263
|
<a href="https://liblab.com/?utm_source=zod" style="text-decoration:none;">liblab.com</a>
|
|
@@ -281,7 +275,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
|
|
|
281
275
|
<img alt="Neon" height="68px" src="https://github.com/user-attachments/assets/b5799fc8-81ff-4053-a1c3-b29adf85e7a1">
|
|
282
276
|
</picture>
|
|
283
277
|
</a>
|
|
284
|
-
<br />
|
|
278
|
+
<br />
|
|
285
279
|
Serverless Postgres — Ship faster
|
|
286
280
|
<br/>
|
|
287
281
|
<a href="https://neon.tech" style="text-decoration:none;">neon.tech</a>
|
|
@@ -294,10 +288,10 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
|
|
|
294
288
|
<a href="https://retool.com/?utm_source=github&utm_medium=referral&utm_campaign=zod">
|
|
295
289
|
<picture height="45px">
|
|
296
290
|
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/ac65013f-aeb4-48dd-a2ee-41040b69cbe6">
|
|
297
|
-
<img alt="
|
|
291
|
+
<img alt="Retool" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/5ef4c11b-efeb-4495-90a8-41b83f798600">
|
|
298
292
|
</picture>
|
|
299
293
|
</a>
|
|
300
|
-
<br />
|
|
294
|
+
<br />
|
|
301
295
|
Build AI apps and workflows with <a href="https://retool.com/products/ai?utm_source=github&utm_medium=referral&utm_campaign=zod">Retool AI</a>
|
|
302
296
|
<br/>
|
|
303
297
|
<a href="https://retool.com/?utm_source=github&utm_medium=referral&utm_campaign=zod" style="text-decoration:none;">retool.com</a>
|
|
@@ -309,16 +303,16 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
|
|
|
309
303
|
<td align="center">
|
|
310
304
|
<p></p>
|
|
311
305
|
<p>
|
|
312
|
-
<a href="https://
|
|
306
|
+
<a href="https://stainless.com">
|
|
313
307
|
<picture height="45px">
|
|
314
308
|
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/f20759c1-3e51-49d0-a31e-bbc43abec665">
|
|
315
309
|
<img alt="stainless" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/e9444e44-d991-4bba-a697-dbcfad608e47">
|
|
316
310
|
</picture>
|
|
317
311
|
</a>
|
|
318
|
-
<br />
|
|
312
|
+
<br />
|
|
319
313
|
Generate best-in-class SDKs
|
|
320
314
|
<br/>
|
|
321
|
-
<a href="https://
|
|
315
|
+
<a href="https://stainless.com" style="text-decoration:none;">stainless.com</a>
|
|
322
316
|
</p>
|
|
323
317
|
<p></p>
|
|
324
318
|
</td>
|
|
@@ -331,7 +325,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
|
|
|
331
325
|
<img alt="speakeasy" height="40px" src="https://github.com/colinhacks/zod/assets/3084745/647524a4-22bb-4199-be70-404207a5a2b5">
|
|
332
326
|
</picture>
|
|
333
327
|
</a>
|
|
334
|
-
<br />
|
|
328
|
+
<br />
|
|
335
329
|
SDKs & Terraform providers for your API
|
|
336
330
|
<br/>
|
|
337
331
|
<a href="https://speakeasy.com/?utm_source=zod+docs" style="text-decoration:none;">speakeasy.com</a>
|
|
@@ -416,6 +410,11 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
|
|
|
416
410
|
<br />
|
|
417
411
|
<a style="text-decoration:none;" href="https://mux.link/zod" target="_blank">Mux</a>
|
|
418
412
|
</td>
|
|
413
|
+
<td align="center">
|
|
414
|
+
<img src="https://avatars.githubusercontent.com/u/76428554?s=200&v=4" height="50px;" alt="Cybozu logo" />
|
|
415
|
+
<br />
|
|
416
|
+
<a style="text-decoration:none;" href="https://cybozu.co.jp/index.html" target="_blank">Cybozu</a>
|
|
417
|
+
</td>
|
|
419
418
|
</tr>
|
|
420
419
|
</table>
|
|
421
420
|
|
|
@@ -536,10 +535,13 @@ There are a growing number of tools that are built atop or support Zod natively!
|
|
|
536
535
|
- [`koa-zod-router`](https://github.com/JakeFenley/koa-zod-router): Create typesafe routes in Koa with I/O validation using Zod.
|
|
537
536
|
- [`zod-sockets`](https://github.com/RobinTail/zod-sockets): Zod-powered Socket.IO microframework with I/O validation and built-in AsyncAPI specs
|
|
538
537
|
- [`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.
|
|
538
|
+
- [`GQLoom`](https://github.com/modevol-com/gqloom): Weave GraphQL schema and resolvers using Zod.
|
|
539
|
+
- [`oRPC`](https://github.com/unnoq/orpc): Typesafe APIs Made Simple
|
|
539
540
|
|
|
540
541
|
#### Form integrations
|
|
541
542
|
|
|
542
543
|
- [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form.
|
|
544
|
+
- [`TanStack Form`](https://github.com/TanStack/form): Headless, performant, and type-safe form state management for TS/JS, React, Vue, Angular, Solid, and Lit
|
|
543
545
|
- [`zod-validation-error`](https://github.com/causaly/zod-validation-error): Generate user-friendly error messages from `ZodError`s.
|
|
544
546
|
- [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod.
|
|
545
547
|
- [`react-zorm`](https://github.com/esamattis/react-zorm): Standalone `<form>` generation and validation for React using Zod.
|
|
@@ -612,6 +614,8 @@ There are a growing number of tools that are built atop or support Zod natively!
|
|
|
612
614
|
- [`zod-config`](https://github.com/alexmarqs/zod-config): Load configurations across multiple sources with flexible adapters, ensuring type safety with Zod.
|
|
613
615
|
- [`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.
|
|
614
616
|
- [`zod-struct`](https://codeberg.org/reesericci/zod-struct): Create runtime-checked structs with Zod.
|
|
617
|
+
- [`zod-csv`](https://github.com/bartoszgolebiowski/zod-csv): Validation helpers for zod for parsing CSV data.
|
|
618
|
+
- [`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.
|
|
615
619
|
|
|
616
620
|
#### Utilities for Zod
|
|
617
621
|
|
|
@@ -621,6 +625,8 @@ There are a growing number of tools that are built atop or support Zod natively!
|
|
|
621
625
|
- [`zod-dev`](https://github.com/schalkventer/zod-dev): Conditionally disables Zod runtime parsing in production.
|
|
622
626
|
- [`zod-accelerator`](https://github.com/duplojs/duplojs-zod-accelerator): Accelerates Zod's throughput up to ~100x.
|
|
623
627
|
|
|
628
|
+
<br/>
|
|
629
|
+
|
|
624
630
|
## Installation
|
|
625
631
|
|
|
626
632
|
### Requirements
|
|
@@ -661,6 +667,8 @@ pnpm add zod@canary # pnpm
|
|
|
661
667
|
|
|
662
668
|
> The rest of this README assumes you are using npm and importing directly from the `"zod"` package.
|
|
663
669
|
|
|
670
|
+
<br/>
|
|
671
|
+
|
|
664
672
|
## Basic usage
|
|
665
673
|
|
|
666
674
|
Creating a simple string schema
|
|
@@ -696,6 +704,8 @@ type User = z.infer<typeof User>;
|
|
|
696
704
|
// { username: string }
|
|
697
705
|
```
|
|
698
706
|
|
|
707
|
+
<br/>
|
|
708
|
+
|
|
699
709
|
## Primitives
|
|
700
710
|
|
|
701
711
|
```ts
|
|
@@ -724,6 +734,8 @@ z.unknown();
|
|
|
724
734
|
z.never();
|
|
725
735
|
```
|
|
726
736
|
|
|
737
|
+
<br/>
|
|
738
|
+
|
|
727
739
|
## Coercion for primitives
|
|
728
740
|
|
|
729
741
|
Zod now provides a more convenient way to coerce primitive values.
|
|
@@ -780,6 +792,8 @@ schema.parse(null); // => false
|
|
|
780
792
|
|
|
781
793
|
For more control over coercion logic, consider using [`z.preprocess`](#preprocess) or [`z.pipe()`](#pipe).
|
|
782
794
|
|
|
795
|
+
<br/>
|
|
796
|
+
|
|
783
797
|
## Literals
|
|
784
798
|
|
|
785
799
|
Literal schemas represent a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types), like `"hello world"` or `5`.
|
|
@@ -799,6 +813,8 @@ tuna.value; // "tuna"
|
|
|
799
813
|
|
|
800
814
|
> Currently there is no support for Date literals in Zod. If you have a use case for this feature, please file an issue.
|
|
801
815
|
|
|
816
|
+
<br/>
|
|
817
|
+
|
|
802
818
|
## Strings
|
|
803
819
|
|
|
804
820
|
Zod includes a handful of string-specific validations.
|
|
@@ -831,7 +847,7 @@ z.string().toUpperCase(); // toUpperCase
|
|
|
831
847
|
|
|
832
848
|
// added in Zod 3.23
|
|
833
849
|
z.string().date(); // ISO date format (YYYY-MM-DD)
|
|
834
|
-
z.string().time(); // ISO time format (HH:mm:ss[.SSSSSS])
|
|
850
|
+
z.string().time(); // ISO time format (HH:mm:ss[.SSSSSS] or HH:mm)
|
|
835
851
|
z.string().duration(); // ISO 8601 duration
|
|
836
852
|
z.string().base64();
|
|
837
853
|
```
|
|
@@ -871,7 +887,7 @@ z.string().cidr({ message: "Invalid CIDR" });
|
|
|
871
887
|
|
|
872
888
|
As you may have noticed, Zod string includes a few date/time related validations. These validations are regular expression based, so they are not as strict as a full date/time library. However, they are very convenient for validating user input.
|
|
873
889
|
|
|
874
|
-
The `z.string().datetime()` method enforces ISO 8601; default is no timezone offsets and arbitrary sub-second decimal precision.
|
|
890
|
+
The `z.string().datetime()` method enforces ISO 8601; default is no timezone offsets and arbitrary sub-second decimal precision. Seconds may be omitted if precision is not set.
|
|
875
891
|
|
|
876
892
|
```ts
|
|
877
893
|
const datetime = z.string().datetime();
|
|
@@ -879,6 +895,7 @@ const datetime = z.string().datetime();
|
|
|
879
895
|
datetime.parse("2020-01-01T00:00:00Z"); // pass
|
|
880
896
|
datetime.parse("2020-01-01T00:00:00.123Z"); // pass
|
|
881
897
|
datetime.parse("2020-01-01T00:00:00.123456Z"); // pass (arbitrary precision)
|
|
898
|
+
datetime.parse("2020-01-01T00:00Z"); // pass (hours and minutes only)
|
|
882
899
|
datetime.parse("2020-01-01T00:00:00+02:00"); // fail (no offsets allowed)
|
|
883
900
|
```
|
|
884
901
|
|
|
@@ -888,6 +905,7 @@ Timezone offsets can be allowed by setting the `offset` option to `true`.
|
|
|
888
905
|
const datetime = z.string().datetime({ offset: true });
|
|
889
906
|
|
|
890
907
|
datetime.parse("2020-01-01T00:00:00+02:00"); // pass
|
|
908
|
+
datetime.parse("2020-01-01T00:00+02:00"); // pass
|
|
891
909
|
datetime.parse("2020-01-01T00:00:00.123+02:00"); // pass (millis optional)
|
|
892
910
|
datetime.parse("2020-01-01T00:00:00.123+0200"); // pass (millis optional)
|
|
893
911
|
datetime.parse("2020-01-01T00:00:00.123+02"); // pass (only offset hours)
|
|
@@ -899,6 +917,7 @@ Allow unqualified (timezone-less) datetimes with the `local` flag.
|
|
|
899
917
|
```ts
|
|
900
918
|
const schema = z.string().datetime({ local: true });
|
|
901
919
|
schema.parse("2020-01-01T00:00:00"); // pass
|
|
920
|
+
schema.parse("2020-01-01T00:00"); // pass
|
|
902
921
|
```
|
|
903
922
|
|
|
904
923
|
You can additionally constrain the allowable `precision`. By default, arbitrary sub-second precision is supported (but optional).
|
|
@@ -908,6 +927,7 @@ const datetime = z.string().datetime({ precision: 3 });
|
|
|
908
927
|
|
|
909
928
|
datetime.parse("2020-01-01T00:00:00.123Z"); // pass
|
|
910
929
|
datetime.parse("2020-01-01T00:00:00Z"); // fail
|
|
930
|
+
datetime.parse("2020-01-01T00:00Z"); // fail
|
|
911
931
|
datetime.parse("2020-01-01T00:00:00.123456Z"); // fail
|
|
912
932
|
```
|
|
913
933
|
|
|
@@ -929,13 +949,14 @@ date.parse("2020-01-32"); // fail
|
|
|
929
949
|
|
|
930
950
|
> Added in Zod 3.23
|
|
931
951
|
|
|
932
|
-
The `z.string().time()` method validates strings in the format `HH:MM:SS[.s+]`. The second can include arbitrary decimal precision. It does not allow timezone offsets of any kind.
|
|
952
|
+
The `z.string().time()` method validates strings in the format `HH:MM` or `HH:MM:SS[.s+]`. The second can include arbitrary decimal precision. It does not allow timezone offsets of any kind.
|
|
933
953
|
|
|
934
954
|
```ts
|
|
935
955
|
const time = z.string().time();
|
|
936
956
|
|
|
937
957
|
time.parse("00:00:00"); // pass
|
|
938
958
|
time.parse("09:52:31"); // pass
|
|
959
|
+
time.parse("09:52"); // pass
|
|
939
960
|
time.parse("23:59:59.9999999"); // pass (arbitrary precision)
|
|
940
961
|
|
|
941
962
|
time.parse("00:00:00.123Z"); // fail (no `Z` allowed)
|
|
@@ -950,6 +971,7 @@ const time = z.string().time({ precision: 3 });
|
|
|
950
971
|
time.parse("00:00:00.123"); // pass
|
|
951
972
|
time.parse("00:00:00.123456"); // fail
|
|
952
973
|
time.parse("00:00:00"); // fail
|
|
974
|
+
time.parse("00:00"); // fail
|
|
953
975
|
```
|
|
954
976
|
|
|
955
977
|
### IP addresses
|
|
@@ -997,6 +1019,8 @@ const ipv6Cidr = z.string().cidr({ version: "v6" });
|
|
|
997
1019
|
ipv6Cidr.parse("192.168.1.1"); // fail
|
|
998
1020
|
```
|
|
999
1021
|
|
|
1022
|
+
<br/>
|
|
1023
|
+
|
|
1000
1024
|
## Numbers
|
|
1001
1025
|
|
|
1002
1026
|
You can customize certain error messages when creating a number schema.
|
|
@@ -1035,6 +1059,8 @@ Optionally, you can pass in a second argument to provide a custom error message.
|
|
|
1035
1059
|
z.number().lte(5, { message: "this👏is👏too👏big" });
|
|
1036
1060
|
```
|
|
1037
1061
|
|
|
1062
|
+
<br/>
|
|
1063
|
+
|
|
1038
1064
|
## BigInts
|
|
1039
1065
|
|
|
1040
1066
|
Zod includes a handful of bigint-specific validations.
|
|
@@ -1053,6 +1079,8 @@ z.bigint().nonpositive(); // <= 0n
|
|
|
1053
1079
|
z.bigint().multipleOf(5n); // Evenly divisible by 5n.
|
|
1054
1080
|
```
|
|
1055
1081
|
|
|
1082
|
+
<br/>
|
|
1083
|
+
|
|
1056
1084
|
## NaNs
|
|
1057
1085
|
|
|
1058
1086
|
You can customize certain error messages when creating a nan schema.
|
|
@@ -1064,6 +1092,8 @@ const isNaN = z.nan({
|
|
|
1064
1092
|
});
|
|
1065
1093
|
```
|
|
1066
1094
|
|
|
1095
|
+
<br/>
|
|
1096
|
+
|
|
1067
1097
|
## Booleans
|
|
1068
1098
|
|
|
1069
1099
|
You can customize certain error messages when creating a boolean schema.
|
|
@@ -1075,6 +1105,8 @@ const isActive = z.boolean({
|
|
|
1075
1105
|
});
|
|
1076
1106
|
```
|
|
1077
1107
|
|
|
1108
|
+
<br/>
|
|
1109
|
+
|
|
1078
1110
|
## Dates
|
|
1079
1111
|
|
|
1080
1112
|
Use z.date() to validate `Date` instances.
|
|
@@ -1122,6 +1154,8 @@ console.log(dateSchema.safeParse("0000-00-00").success); // false
|
|
|
1122
1154
|
|
|
1123
1155
|
For older zod versions, use [`z.preprocess`](#preprocess) like [described in this thread](https://github.com/colinhacks/zod/discussions/879#discussioncomment-2036276).
|
|
1124
1156
|
|
|
1157
|
+
<br/>
|
|
1158
|
+
|
|
1125
1159
|
## Zod enums
|
|
1126
1160
|
|
|
1127
1161
|
```ts
|
|
@@ -1177,6 +1211,8 @@ const SalmonAndTrout = FishEnum.extract(["Salmon", "Trout"]);
|
|
|
1177
1211
|
const TunaOnly = FishEnum.exclude(["Salmon", "Trout"]);
|
|
1178
1212
|
```
|
|
1179
1213
|
|
|
1214
|
+
<br/>
|
|
1215
|
+
|
|
1180
1216
|
## Native enums
|
|
1181
1217
|
|
|
1182
1218
|
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()`.
|
|
@@ -1245,6 +1281,8 @@ You can access the underlying object with the `.enum` property:
|
|
|
1245
1281
|
FruitEnum.enum.Apple; // "apple"
|
|
1246
1282
|
```
|
|
1247
1283
|
|
|
1284
|
+
<br/>
|
|
1285
|
+
|
|
1248
1286
|
## Optionals
|
|
1249
1287
|
|
|
1250
1288
|
You can make any schema optional with `z.optional()`. This wraps the schema in a `ZodOptional` instance and returns the result.
|
|
@@ -1273,6 +1311,8 @@ const optionalString = stringSchema.optional();
|
|
|
1273
1311
|
optionalString.unwrap() === stringSchema; // true
|
|
1274
1312
|
```
|
|
1275
1313
|
|
|
1314
|
+
<br/>
|
|
1315
|
+
|
|
1276
1316
|
## Nullables
|
|
1277
1317
|
|
|
1278
1318
|
Similarly, you can create nullable types with `z.nullable()`.
|
|
@@ -1298,6 +1338,8 @@ const nullableString = stringSchema.nullable();
|
|
|
1298
1338
|
nullableString.unwrap() === stringSchema; // true
|
|
1299
1339
|
```
|
|
1300
1340
|
|
|
1341
|
+
<br/>
|
|
1342
|
+
|
|
1301
1343
|
## Objects
|
|
1302
1344
|
|
|
1303
1345
|
```ts
|
|
@@ -1566,6 +1608,8 @@ person.parse({
|
|
|
1566
1608
|
|
|
1567
1609
|
Using `.catchall()` obviates `.passthrough()` , `.strip()` , or `.strict()`. All keys are now considered "known".
|
|
1568
1610
|
|
|
1611
|
+
<br/>
|
|
1612
|
+
|
|
1569
1613
|
## Arrays
|
|
1570
1614
|
|
|
1571
1615
|
```ts
|
|
@@ -1622,6 +1666,8 @@ z.string().array().length(5); // must contain 5 items exactly
|
|
|
1622
1666
|
|
|
1623
1667
|
Unlike `.nonempty()` these methods do not change the inferred type.
|
|
1624
1668
|
|
|
1669
|
+
<br/>
|
|
1670
|
+
|
|
1625
1671
|
## Tuples
|
|
1626
1672
|
|
|
1627
1673
|
Unlike arrays, tuples have a fixed number of elements and each element can have a different type.
|
|
@@ -1647,6 +1693,8 @@ const result = variadicTuple.parse(["hello", 1, 2, 3]);
|
|
|
1647
1693
|
// => [string, ...number[]];
|
|
1648
1694
|
```
|
|
1649
1695
|
|
|
1696
|
+
<br/>
|
|
1697
|
+
|
|
1650
1698
|
## Unions
|
|
1651
1699
|
|
|
1652
1700
|
Zod includes a built-in `z.union` method for composing "OR" types.
|
|
@@ -1682,6 +1730,8 @@ console.log(optionalUrl.safeParse("https://zod.dev").success); // true
|
|
|
1682
1730
|
console.log(optionalUrl.safeParse("not a valid url").success); // false
|
|
1683
1731
|
```
|
|
1684
1732
|
|
|
1733
|
+
<br/>
|
|
1734
|
+
|
|
1685
1735
|
## Discriminated unions
|
|
1686
1736
|
|
|
1687
1737
|
A discriminated union is a union of object schemas that all share a particular key.
|
|
@@ -1724,6 +1774,8 @@ const B = z.discriminatedUnion("status", [
|
|
|
1724
1774
|
const AB = z.discriminatedUnion("status", [...A.options, ...B.options]);
|
|
1725
1775
|
```
|
|
1726
1776
|
|
|
1777
|
+
<br/>
|
|
1778
|
+
|
|
1727
1779
|
## Records
|
|
1728
1780
|
|
|
1729
1781
|
Record schemas are used to validate types such as `Record<string, number>`. This is particularly useful for storing or caching items by ID.
|
|
@@ -1778,6 +1830,8 @@ for (const key in testMap) {
|
|
|
1778
1830
|
|
|
1779
1831
|
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.
|
|
1780
1832
|
|
|
1833
|
+
<br/>
|
|
1834
|
+
|
|
1781
1835
|
## Maps
|
|
1782
1836
|
|
|
1783
1837
|
```ts
|
|
@@ -1787,6 +1841,8 @@ type StringNumberMap = z.infer<typeof stringNumberMap>;
|
|
|
1787
1841
|
// type StringNumberMap = Map<string, number>
|
|
1788
1842
|
```
|
|
1789
1843
|
|
|
1844
|
+
<br/>
|
|
1845
|
+
|
|
1790
1846
|
## Sets
|
|
1791
1847
|
|
|
1792
1848
|
```ts
|
|
@@ -1804,6 +1860,8 @@ z.set(z.string()).max(5); // must contain 5 or fewer items
|
|
|
1804
1860
|
z.set(z.string()).size(5); // must contain 5 items exactly
|
|
1805
1861
|
```
|
|
1806
1862
|
|
|
1863
|
+
<br/>
|
|
1864
|
+
|
|
1807
1865
|
## Intersections
|
|
1808
1866
|
|
|
1809
1867
|
Intersections are useful for creating "logical AND" types. This is useful for intersecting two object types.
|
|
@@ -1852,6 +1910,8 @@ type Teacher = z.infer<typeof Teacher>;
|
|
|
1852
1910
|
// { id:string; name:string };
|
|
1853
1911
|
``` -->
|
|
1854
1912
|
|
|
1913
|
+
<br/>
|
|
1914
|
+
|
|
1855
1915
|
## Recursive types
|
|
1856
1916
|
|
|
1857
1917
|
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".
|
|
@@ -1942,6 +2002,8 @@ Despite supporting recursive schemas, passing cyclical data into Zod will cause
|
|
|
1942
2002
|
|
|
1943
2003
|
> To detect cyclical objects before they cause problems, consider [this approach](https://gist.github.com/colinhacks/d35825e505e635df27cc950776c5500b).
|
|
1944
2004
|
|
|
2005
|
+
<br/>
|
|
2006
|
+
|
|
1945
2007
|
## Promises
|
|
1946
2008
|
|
|
1947
2009
|
```ts
|
|
@@ -1973,6 +2035,8 @@ const test = async () => {
|
|
|
1973
2035
|
|
|
1974
2036
|
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. -->
|
|
1975
2037
|
|
|
2038
|
+
<br/>
|
|
2039
|
+
|
|
1976
2040
|
## Instanceof
|
|
1977
2041
|
|
|
1978
2042
|
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.
|
|
@@ -1989,6 +2053,8 @@ TestSchema.parse(new Test()); // passes
|
|
|
1989
2053
|
TestSchema.parse(blob); // throws
|
|
1990
2054
|
```
|
|
1991
2055
|
|
|
2056
|
+
<br/>
|
|
2057
|
+
|
|
1992
2058
|
## Functions
|
|
1993
2059
|
|
|
1994
2060
|
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".
|
|
@@ -2072,6 +2138,8 @@ myFunction.returnType();
|
|
|
2072
2138
|
* `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([])`).
|
|
2073
2139
|
* `returnType: any Zod schema` The second argument is the function's return type. This can be any Zod schema. -->
|
|
2074
2140
|
|
|
2141
|
+
<br/>
|
|
2142
|
+
|
|
2075
2143
|
## Preprocess
|
|
2076
2144
|
|
|
2077
2145
|
> Zod now supports primitive coercion without the need for `.preprocess()`. See the [coercion docs](#coercion-for-primitives) for more information.
|
|
@@ -2086,6 +2154,8 @@ const castToString = z.preprocess((val) => String(val), z.string());
|
|
|
2086
2154
|
|
|
2087
2155
|
This returns a `ZodEffects` instance. `ZodEffects` is a wrapper class that contains all logic pertaining to preprocessing, refinements, and transforms.
|
|
2088
2156
|
|
|
2157
|
+
<br/>
|
|
2158
|
+
|
|
2089
2159
|
## Custom schemas
|
|
2090
2160
|
|
|
2091
2161
|
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.
|
|
@@ -2113,6 +2183,8 @@ You can customize the error message and other options by passing a second argume
|
|
|
2113
2183
|
z.custom<...>((val) => ..., "custom error message");
|
|
2114
2184
|
```
|
|
2115
2185
|
|
|
2186
|
+
<br/>
|
|
2187
|
+
|
|
2116
2188
|
## Schema methods
|
|
2117
2189
|
|
|
2118
2190
|
All Zod schemas contain certain methods.
|
|
@@ -2490,8 +2562,8 @@ numberWithRandomDefault.parse(undefined); // => 0.7223408162401552
|
|
|
2490
2562
|
|
|
2491
2563
|
Conceptually, this is how Zod processes default values:
|
|
2492
2564
|
|
|
2493
|
-
1. If the input is `undefined`, the default value is
|
|
2494
|
-
2.
|
|
2565
|
+
1. If the input is `undefined`, the default value is substituted
|
|
2566
|
+
2. Then the data is parsed using the base schema. Your default value will be parsed by the schema (including any potential transforms).
|
|
2495
2567
|
|
|
2496
2568
|
### `.describe`
|
|
2497
2569
|
|
|
@@ -2698,61 +2770,7 @@ z.string()
|
|
|
2698
2770
|
|
|
2699
2771
|
The `.pipe()` method returns a `ZodPipeline` instance.
|
|
2700
2772
|
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
You can constrain the input to types that work well with your chosen coercion. Then use `.pipe()` to apply the coercion.
|
|
2704
|
-
|
|
2705
|
-
without constrained input:
|
|
2706
|
-
|
|
2707
|
-
```ts
|
|
2708
|
-
const toDate = z.coerce.date();
|
|
2709
|
-
|
|
2710
|
-
// works intuitively
|
|
2711
|
-
console.log(toDate.safeParse("2023-01-01").success); // true
|
|
2712
|
-
|
|
2713
|
-
// might not be what you want
|
|
2714
|
-
console.log(toDate.safeParse(null).success); // true
|
|
2715
|
-
```
|
|
2716
|
-
|
|
2717
|
-
with constrained input:
|
|
2718
|
-
|
|
2719
|
-
```ts
|
|
2720
|
-
const datelike = z.union([z.number(), z.string(), z.date()]);
|
|
2721
|
-
const datelikeToDate = datelike.pipe(z.coerce.date());
|
|
2722
|
-
|
|
2723
|
-
// still works intuitively
|
|
2724
|
-
console.log(datelikeToDate.safeParse("2023-01-01").success); // true
|
|
2725
|
-
|
|
2726
|
-
// more likely what you want
|
|
2727
|
-
console.log(datelikeToDate.safeParse(null).success); // false
|
|
2728
|
-
```
|
|
2729
|
-
|
|
2730
|
-
You can also use this technique to avoid coercions that throw uncaught errors.
|
|
2731
|
-
|
|
2732
|
-
without constrained input:
|
|
2733
|
-
|
|
2734
|
-
```ts
|
|
2735
|
-
const toBigInt = z.coerce.bigint();
|
|
2736
|
-
|
|
2737
|
-
// works intuitively
|
|
2738
|
-
console.log(toBigInt.safeParse("42")); // true
|
|
2739
|
-
|
|
2740
|
-
// probably not what you want
|
|
2741
|
-
console.log(toBigInt.safeParse(null)); // throws uncaught error
|
|
2742
|
-
```
|
|
2743
|
-
|
|
2744
|
-
with constrained input:
|
|
2745
|
-
|
|
2746
|
-
```ts
|
|
2747
|
-
const toNumber = z.number().or(z.string()).pipe(z.coerce.number());
|
|
2748
|
-
const toBigInt = z.bigint().or(toNumber).pipe(z.coerce.bigint());
|
|
2749
|
-
|
|
2750
|
-
// still works intuitively
|
|
2751
|
-
console.log(toBigInt.safeParse("42").success); // true
|
|
2752
|
-
|
|
2753
|
-
// error handled by zod, more likely what you want
|
|
2754
|
-
console.log(toBigInt.safeParse(null).success); // false
|
|
2755
|
-
```
|
|
2773
|
+
<br/>
|
|
2756
2774
|
|
|
2757
2775
|
## Guides and concepts
|
|
2758
2776
|
|
|
@@ -2923,6 +2941,8 @@ if (!result.success) {
|
|
|
2923
2941
|
}
|
|
2924
2942
|
```
|
|
2925
2943
|
|
|
2944
|
+
<br/>
|
|
2945
|
+
|
|
2926
2946
|
## Comparison
|
|
2927
2947
|
|
|
2928
2948
|
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.
|
|
@@ -3069,6 +3089,8 @@ Ow is focused on function input validation. It's a library that makes it easy to
|
|
|
3069
3089
|
|
|
3070
3090
|
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.
|
|
3071
3091
|
|
|
3092
|
+
<br/>
|
|
3093
|
+
|
|
3072
3094
|
## Changelog
|
|
3073
3095
|
|
|
3074
3096
|
View the changelog at [CHANGELOG.md](CHANGELOG.md)
|
package/lib/helpers/util.d.ts
CHANGED
|
@@ -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
|
@@ -961,15 +961,15 @@ const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z
|
|
|
961
961
|
const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
|
|
962
962
|
const dateRegex = new RegExp(`^${dateRegexSource}$`);
|
|
963
963
|
function timeRegexSource(args) {
|
|
964
|
-
|
|
965
|
-
let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`;
|
|
964
|
+
let secondsRegexSource = `[0-5]\\d`;
|
|
966
965
|
if (args.precision) {
|
|
967
|
-
|
|
966
|
+
secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
|
|
968
967
|
}
|
|
969
968
|
else if (args.precision == null) {
|
|
970
|
-
|
|
969
|
+
secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
|
|
971
970
|
}
|
|
972
|
-
|
|
971
|
+
const secondsQuantifier = args.precision ? "+" : "?"; // require seconds if precision is nonzero
|
|
972
|
+
return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
|
|
973
973
|
}
|
|
974
974
|
function timeRegex(args) {
|
|
975
975
|
return new RegExp(`^${timeRegexSource(args)}$`);
|
package/lib/index.umd.js
CHANGED
|
@@ -967,15 +967,15 @@
|
|
|
967
967
|
const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
|
|
968
968
|
const dateRegex = new RegExp(`^${dateRegexSource}$`);
|
|
969
969
|
function timeRegexSource(args) {
|
|
970
|
-
|
|
971
|
-
let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`;
|
|
970
|
+
let secondsRegexSource = `[0-5]\\d`;
|
|
972
971
|
if (args.precision) {
|
|
973
|
-
|
|
972
|
+
secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
|
|
974
973
|
}
|
|
975
974
|
else if (args.precision == null) {
|
|
976
|
-
|
|
975
|
+
secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
|
|
977
976
|
}
|
|
978
|
-
|
|
977
|
+
const secondsQuantifier = args.precision ? "+" : "?"; // require seconds if precision is nonzero
|
|
978
|
+
return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
|
|
979
979
|
}
|
|
980
980
|
function timeRegex(args) {
|
|
981
981
|
return new RegExp(`^${timeRegexSource(args)}$`);
|
package/lib/types.js
CHANGED
|
@@ -432,15 +432,15 @@ const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z
|
|
|
432
432
|
const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
|
|
433
433
|
const dateRegex = new RegExp(`^${dateRegexSource}$`);
|
|
434
434
|
function timeRegexSource(args) {
|
|
435
|
-
|
|
436
|
-
let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`;
|
|
435
|
+
let secondsRegexSource = `[0-5]\\d`;
|
|
437
436
|
if (args.precision) {
|
|
438
|
-
|
|
437
|
+
secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
|
|
439
438
|
}
|
|
440
439
|
else if (args.precision == null) {
|
|
441
|
-
|
|
440
|
+
secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
|
|
442
441
|
}
|
|
443
|
-
|
|
442
|
+
const secondsQuantifier = args.precision ? "+" : "?"; // require seconds if precision is nonzero
|
|
443
|
+
return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
|
|
444
444
|
}
|
|
445
445
|
function timeRegex(args) {
|
|
446
446
|
return new RegExp(`^${timeRegexSource(args)}$`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zod",
|
|
3
|
-
"version": "3.24.
|
|
3
|
+
"version": "3.24.4",
|
|
4
4
|
"author": "Colin McDonnell <colin@colinhacks.com>",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"ts-morph": "^14.0.0",
|
|
44
44
|
"ts-node": "^10.9.1",
|
|
45
45
|
"tslib": "^2.3.1",
|
|
46
|
-
"tsx": "^
|
|
46
|
+
"tsx": "^4.19.4",
|
|
47
47
|
"typescript": "^5.0.0",
|
|
48
48
|
"vitest": "^0.32.2"
|
|
49
49
|
},
|