@aws-amplify/graphql-api-construct 1.1.3 → 1.1.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/.jsii +34 -34
- package/CHANGELOG.md +8 -0
- package/README.md +9 -3
- package/lib/amplify-graphql-api.d.ts +9 -3
- package/lib/amplify-graphql-api.js +11 -5
- package/lib/amplify-graphql-definition.js +1 -1
- package/lib/internal/codegen-assets.js +6 -1
- package/node_modules/@aws-amplify/graphql-auth-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-auth-transformer/package.json +8 -8
- package/node_modules/@aws-amplify/graphql-default-value-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-default-value-transformer/package.json +5 -5
- package/node_modules/@aws-amplify/graphql-function-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-function-transformer/package.json +4 -4
- package/node_modules/@aws-amplify/graphql-http-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-http-transformer/package.json +4 -4
- package/node_modules/@aws-amplify/graphql-index-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-index-transformer/package.json +5 -5
- package/node_modules/@aws-amplify/graphql-maps-to-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-maps-to-transformer/lib/assets/mapping-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-maps-to-transformer/package.json +8 -8
- package/node_modules/@aws-amplify/graphql-model-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-notification-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-patching-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-model-transformer/package.json +4 -4
- package/node_modules/@aws-amplify/graphql-predictions-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-predictions-transformer/lib/predictionsLambdaFunction.zip +0 -0
- package/node_modules/@aws-amplify/graphql-predictions-transformer/package.json +4 -4
- package/node_modules/@aws-amplify/graphql-relational-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-relational-transformer/package.json +6 -6
- package/node_modules/@aws-amplify/graphql-searchable-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-searchable-transformer/lib/streaming-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-searchable-transformer/package.json +5 -5
- package/node_modules/@aws-amplify/graphql-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-transformer/package.json +13 -13
- package/node_modules/@aws-amplify/graphql-transformer-core/API.md +1 -0
- package/node_modules/@aws-amplify/graphql-transformer-core/CHANGELOG.md +6 -0
- package/node_modules/@aws-amplify/graphql-transformer-core/lib/transformer-context/output.d.ts +8 -1
- package/node_modules/@aws-amplify/graphql-transformer-core/lib/transformer-context/output.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-transformer-core/lib/transformer-context/output.js +60 -23
- package/node_modules/@aws-amplify/graphql-transformer-core/lib/transformer-context/output.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-transformer-core/lib/utils/defaultSchema.d.ts +4 -1
- package/node_modules/@aws-amplify/graphql-transformer-core/lib/utils/defaultSchema.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-transformer-core/lib/utils/defaultSchema.js +35 -36
- package/node_modules/@aws-amplify/graphql-transformer-core/lib/utils/defaultSchema.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-transformer-core/package.json +2 -2
- package/node_modules/@aws-amplify/graphql-transformer-interfaces/package.json +1 -2
- package/node_modules/zod/README.md +215 -120
- package/node_modules/zod/lib/ZodError.js +8 -0
- package/node_modules/zod/lib/helpers/parseUtil.js +3 -2
- package/node_modules/zod/lib/helpers/util.js +4 -4
- package/node_modules/zod/lib/index.mjs +121 -57
- package/node_modules/zod/lib/index.umd.js +121 -56
- package/node_modules/zod/lib/types.d.ts +55 -10
- package/node_modules/zod/lib/types.js +301 -58
- package/node_modules/zod/package.json +29 -15
- package/package.json +15 -15
- package/src/amplify-graphql-api.ts +9 -3
- package/src/internal/codegen-assets.ts +5 -0
- package/node_modules/@aws-amplify/graphql-transformer-interfaces/LICENSE +0 -201
@@ -45,20 +45,32 @@
|
|
45
45
|
|
46
46
|
#### Go to [zod.js.org](https://zod.js.org) >> -->
|
47
47
|
|
48
|
+
- [Table of contents](#table-of-contents)
|
48
49
|
- [Introduction](#introduction)
|
49
50
|
- [Sponsors](#sponsors)
|
51
|
+
- [Gold](#gold)
|
52
|
+
- [Silver](#silver)
|
53
|
+
- [Bronze](#bronze)
|
50
54
|
- [Ecosystem](#ecosystem)
|
55
|
+
- [Resources](#resources)
|
56
|
+
- [API libraries](#api-libraries)
|
57
|
+
- [Form integrations](#form-integrations)
|
58
|
+
- [Zod to X](#zod-to-x)
|
59
|
+
- [X to Zod](#x-to-zod)
|
60
|
+
- [Mocking](#mocking)
|
61
|
+
- [Powered by Zod](#powered-by-zod)
|
62
|
+
- [Utilities for Zod](#utilities-for-zod)
|
51
63
|
- [Installation](#installation)
|
52
64
|
- [Requirements](#requirements)
|
53
|
-
- [Node/
|
54
|
-
- [Deno](#from-denolandx-deno)
|
65
|
+
- [From `npm` (Node/Bun)](#from-npm-nodebun)
|
66
|
+
- [From `deno.land/x` (Deno)](#from-denolandx-deno)
|
55
67
|
- [Basic usage](#basic-usage)
|
56
68
|
- [Primitives](#primitives)
|
57
69
|
- [Coercion for primitives](#coercion-for-primitives)
|
58
70
|
- [Literals](#literals)
|
59
71
|
- [Strings](#strings)
|
60
|
-
- [
|
61
|
-
- [IP](#ip-
|
72
|
+
- [ISO datetimes](#iso-datetimes)
|
73
|
+
- [IP addresses](#ip-addresses)
|
62
74
|
- [Numbers](#numbers)
|
63
75
|
- [BigInts](#bigints)
|
64
76
|
- [NaNs](#nans)
|
@@ -69,59 +81,75 @@
|
|
69
81
|
- [Optionals](#optionals)
|
70
82
|
- [Nullables](#nullables)
|
71
83
|
- [Objects](#objects)
|
72
|
-
- [
|
73
|
-
- [
|
74
|
-
- [
|
75
|
-
- [
|
76
|
-
- [
|
77
|
-
- [
|
78
|
-
- [
|
79
|
-
- [
|
80
|
-
- [
|
81
|
-
- [
|
82
|
-
- [
|
84
|
+
- [`.shape`](#shape)
|
85
|
+
- [`.keyof`](#keyof)
|
86
|
+
- [`.extend`](#extend)
|
87
|
+
- [`.merge`](#merge)
|
88
|
+
- [`.pick/.omit`](#pickomit)
|
89
|
+
- [`.partial`](#partial)
|
90
|
+
- [`.deepPartial`](#deeppartial)
|
91
|
+
- [`.required`](#required)
|
92
|
+
- [`.passthrough`](#passthrough)
|
93
|
+
- [`.strict`](#strict)
|
94
|
+
- [`.strip`](#strip)
|
95
|
+
- [`.catchall`](#catchall)
|
83
96
|
- [Arrays](#arrays)
|
84
|
-
- [
|
85
|
-
- [
|
86
|
-
- [
|
97
|
+
- [`.element`](#element)
|
98
|
+
- [`.nonempty`](#nonempty)
|
99
|
+
- [`.min/.max/.length`](#minmaxlength)
|
87
100
|
- [Tuples](#tuples)
|
88
101
|
- [Unions](#unions)
|
89
|
-
- [Discriminated
|
102
|
+
- [Discriminated unions](#discriminated-unions)
|
90
103
|
- [Records](#records)
|
104
|
+
- [Record key type](#record-key-type)
|
91
105
|
- [Maps](#maps)
|
92
106
|
- [Sets](#sets)
|
93
107
|
- [Intersections](#intersections)
|
94
108
|
- [Recursive types](#recursive-types)
|
109
|
+
- [ZodType with ZodEffects](#zodtype-with-zodeffects)
|
95
110
|
- [JSON type](#json-type)
|
96
|
-
- [Cyclical
|
111
|
+
- [Cyclical objects](#cyclical-objects)
|
97
112
|
- [Promises](#promises)
|
98
113
|
- [Instanceof](#instanceof)
|
99
114
|
- [Functions](#functions)
|
100
115
|
- [Preprocess](#preprocess)
|
101
|
-
- [Custom](#custom-schemas)
|
116
|
+
- [Custom schemas](#custom-schemas)
|
102
117
|
- [Schema methods](#schema-methods)
|
103
|
-
- [
|
104
|
-
- [
|
105
|
-
- [
|
106
|
-
- [
|
107
|
-
- [
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
- [
|
113
|
-
|
114
|
-
|
115
|
-
- [
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
- [
|
121
|
-
- [
|
118
|
+
- [`.parse`](#parse)
|
119
|
+
- [`.parseAsync`](#parseasync)
|
120
|
+
- [`.safeParse`](#safeparse)
|
121
|
+
- [`.safeParseAsync`](#safeparseasync)
|
122
|
+
- [`.refine`](#refine)
|
123
|
+
- [Arguments](#arguments)
|
124
|
+
- [Customize error path](#customize-error-path)
|
125
|
+
- [Asynchronous refinements](#asynchronous-refinements)
|
126
|
+
- [Relationship to transforms](#relationship-to-transforms)
|
127
|
+
- [`.superRefine`](#superrefine)
|
128
|
+
- [Abort early](#abort-early)
|
129
|
+
- [Type refinements](#type-refinements)
|
130
|
+
- [`.transform`](#transform)
|
131
|
+
- [Chaining order](#chaining-order)
|
132
|
+
- [Validating during transform](#validating-during-transform)
|
133
|
+
- [Relationship to refinements](#relationship-to-refinements)
|
134
|
+
- [Async transforms](#async-transforms)
|
135
|
+
- [`.default`](#default)
|
136
|
+
- [`.describe`](#describe)
|
137
|
+
- [`.catch`](#catch)
|
138
|
+
- [`.optional`](#optional)
|
139
|
+
- [`.nullable`](#nullable)
|
140
|
+
- [`.nullish`](#nullish)
|
141
|
+
- [`.array`](#array)
|
142
|
+
- [`.promise`](#promise)
|
143
|
+
- [`.or`](#or)
|
144
|
+
- [`.and`](#and)
|
145
|
+
- [`.brand`](#brand)
|
146
|
+
- [`.readonly`](#readonly)
|
147
|
+
- [`.pipe`](#pipe)
|
148
|
+
- [You can use `.pipe()` to fix common issues with `z.coerce`.](#you-can-use-pipe-to-fix-common-issues-with-zcoerce)
|
122
149
|
- [Guides and concepts](#guides-and-concepts)
|
123
150
|
- [Type inference](#type-inference)
|
124
151
|
- [Writing generic functions](#writing-generic-functions)
|
152
|
+
- [Constraining allowable inputs](#constraining-allowable-inputs)
|
125
153
|
- [Error handling](#error-handling)
|
126
154
|
- [Error formatting](#error-formatting)
|
127
155
|
- [Comparison](#comparison)
|
@@ -129,10 +157,9 @@
|
|
129
157
|
- [Yup](#yup)
|
130
158
|
- [io-ts](#io-ts)
|
131
159
|
- [Runtypes](#runtypes)
|
160
|
+
- [Ow](#ow)
|
132
161
|
- [Changelog](#changelog)
|
133
162
|
|
134
|
-
<!-- **Zod 2 is coming! Follow [@colinhacks](https://twitter.com/colinhacks) to stay updated and discuss the future of Zod.** -->
|
135
|
-
|
136
163
|
## Introduction
|
137
164
|
|
138
165
|
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.
|
@@ -158,23 +185,19 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
|
|
158
185
|
<table>
|
159
186
|
<tr>
|
160
187
|
<td align="center">
|
161
|
-
<a href="https://
|
162
|
-
<img src="https://avatars.githubusercontent.com/u/
|
188
|
+
<a href="https://speakeasyapi.dev/">
|
189
|
+
<img src="https://avatars.githubusercontent.com/u/91446104?s=200&v=4" width="200px;" alt="Speakeasy API" />
|
163
190
|
</a>
|
164
191
|
<br />
|
165
|
-
<b>
|
192
|
+
<b>Speakeasy</b>
|
166
193
|
<br />
|
167
|
-
<a href="https://
|
194
|
+
<a href="https://speakeasyapi.dev/">speakeasyapi.dev</a>
|
168
195
|
<br />
|
169
|
-
<p width="200px">
|
170
|
-
Astro is a new kind of static <br/>
|
171
|
-
site builder for the modern web. <br/>
|
172
|
-
Powerful developer experience meets <br/>
|
173
|
-
lightweight output.</p>
|
196
|
+
<p width="200px">SDKs, Terraform, Docs.<br/>Your API made enterprise-ready.</p>
|
174
197
|
</td>
|
175
198
|
<td align="center">
|
176
199
|
<a href="https://glow.app/">
|
177
|
-
<img src="https://i.imgur.com/R0R43S2.jpg" width="200px;" alt="" />
|
200
|
+
<img src="https://i.imgur.com/R0R43S2.jpg" width="200px;" alt="Glow Wallet" />
|
178
201
|
</a>
|
179
202
|
<br />
|
180
203
|
<b>Glow Wallet</b>
|
@@ -197,42 +220,60 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
|
|
197
220
|
<a href="https://deletype.com">deletype.com</a>
|
198
221
|
</td>
|
199
222
|
<td align="center">
|
200
|
-
<a href="https://
|
201
|
-
<img src="https://avatars.githubusercontent.com/u/
|
223
|
+
<a href="https://trigger.dev/">
|
224
|
+
<img src="https://avatars.githubusercontent.com/u/95297378?s=200&v=4" width="200px;" alt="Trigger.dev logo" />
|
202
225
|
</a>
|
203
226
|
<br />
|
204
|
-
<b>
|
227
|
+
<b>Trigger.dev</b>
|
205
228
|
<br />
|
206
|
-
<a href="https://
|
229
|
+
<a href="https://trigger.dev">trigger.dev</a>
|
230
|
+
<br/>
|
231
|
+
<p>Effortless automation for developers.</p>
|
207
232
|
</td>
|
208
233
|
</tr>
|
209
|
-
|
234
|
+
<tr>
|
210
235
|
<td align="center">
|
211
|
-
<a href="https://
|
212
|
-
<img src="https://avatars.githubusercontent.com/u/
|
236
|
+
<a href="https://transloadit.com/?utm_source=zod&utm_medium=referral&utm_campaign=sponsorship&utm_content=github">
|
237
|
+
<img src="https://avatars.githubusercontent.com/u/125754?s=200&v=4" width="200px;" alt="Transloadit logo" />
|
213
238
|
</a>
|
214
239
|
<br />
|
215
|
-
<b>
|
240
|
+
<b>Transloadit</b>
|
216
241
|
<br />
|
217
|
-
<a href="https://
|
242
|
+
<a href="https://transloadit.com/?utm_source=zod&utm_medium=referral&utm_campaign=sponsorship&utm_content=github">transloadit.com</a>
|
243
|
+
<br/>
|
244
|
+
<p>Simple file processing for developers.</p>
|
218
245
|
</td>
|
219
|
-
|
220
|
-
<a href="https://
|
221
|
-
<img src="https://avatars.githubusercontent.com/u/
|
246
|
+
<td align="center">
|
247
|
+
<a href="https://infisical.com">
|
248
|
+
<img src="https://avatars.githubusercontent.com/u/107880645?s=200&v=4" width="200px;" alt="Infisical logo" />
|
222
249
|
</a>
|
223
250
|
<br />
|
224
|
-
<b>
|
251
|
+
<b>Infisical</b>
|
225
252
|
<br />
|
226
|
-
<a href="https://
|
227
|
-
|
253
|
+
<a href="https://infisical.com">infisical.com</a>
|
254
|
+
<br/>
|
255
|
+
<p>Open-source platform for secret<br/>management: sync secrets across your<br/>team/infrastructure and prevent secret leaks.</p>
|
256
|
+
</td>
|
228
257
|
</tr>
|
258
|
+
<tr>
|
259
|
+
<td align="center">
|
260
|
+
<a href="https://whop.com/">
|
261
|
+
<img src="https://avatars.githubusercontent.com/u/91036480?s=200&v=4" width="200px;" alt="Whop logo" />
|
262
|
+
</a>
|
263
|
+
<br />
|
264
|
+
<b>Whop</b>
|
265
|
+
<br />
|
266
|
+
<a href="https://whop.com/">whop.com</a>
|
267
|
+
<br />
|
268
|
+
<p width="200px">A marketplace for really cool internet products.</p>
|
269
|
+
</td>
|
229
270
|
</table>
|
230
271
|
|
231
272
|
#### Silver
|
232
273
|
|
233
274
|
<table>
|
234
275
|
<tr>
|
235
|
-
|
276
|
+
<td align="center" colspan="2">
|
236
277
|
<a href="https://www.numeric.io">
|
237
278
|
<img src="https://i.imgur.com/kTiLtZt.png" width="250px;" alt="Numeric logo" />
|
238
279
|
</a>
|
@@ -242,17 +283,6 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
|
|
242
283
|
<a href="https://www.numeric.io">numeric.io</a>
|
243
284
|
</td>
|
244
285
|
<td align="center">
|
245
|
-
<a href="https://snaplet.dev">
|
246
|
-
<img src="https://avatars.githubusercontent.com/u/69029941?s=200&v=4" width="150px;" alt="Snaplet logo" />
|
247
|
-
</a>
|
248
|
-
<br />
|
249
|
-
<b>Snaplet</b>
|
250
|
-
<br />
|
251
|
-
<a href="https://snaplet.dev">snaplet.dev</a>
|
252
|
-
</td>
|
253
|
-
</tr>
|
254
|
-
<tr>
|
255
|
-
<td align="center">
|
256
286
|
<a href="https://marcatopartners.com/">
|
257
287
|
<img src="https://avatars.githubusercontent.com/u/84106192?s=200&v=4" width="150px;" alt="Marcato Partners" />
|
258
288
|
</a>
|
@@ -261,7 +291,9 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
|
|
261
291
|
<br />
|
262
292
|
<a href="https://marcatopartners.com/">marcatopartners.com</a>
|
263
293
|
</td>
|
264
|
-
|
294
|
+
</tr>
|
295
|
+
<tr>
|
296
|
+
<td align="center">
|
265
297
|
<a href="https://interval.com">
|
266
298
|
<img src="https://avatars.githubusercontent.com/u/67802063?s=200&v=4" width="150px;" alt="" />
|
267
299
|
</a>
|
@@ -279,8 +311,6 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
|
|
279
311
|
<br />
|
280
312
|
<a href="https://seasoned.cc">seasoned.cc</a>
|
281
313
|
</td>
|
282
|
-
</tr>
|
283
|
-
<tr>
|
284
314
|
<td align="center">
|
285
315
|
<a href="https://www.bamboocreative.nz/">
|
286
316
|
<img src="https://avatars.githubusercontent.com/u/41406870?v=4" width="150px;" alt="Bamboo Creative logo" />
|
@@ -362,7 +392,7 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
|
|
362
392
|
</td>
|
363
393
|
</tr>
|
364
394
|
<tr>
|
365
|
-
|
395
|
+
<td align="center">
|
366
396
|
<a href="https://learnwithjason.dev">
|
367
397
|
<img src="https://avatars.githubusercontent.com/u/66575486?s=200&v=4" width="100px;" alt="Learn with Jason logo"/>
|
368
398
|
</a>
|
@@ -382,17 +412,16 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
|
|
382
412
|
<a href="https://ill.inc/">ill.inc</a>
|
383
413
|
<br />
|
384
414
|
</td>
|
385
|
-
|
386
|
-
<a href="https://www.
|
387
|
-
<img src="https://avatars.githubusercontent.com/u/
|
415
|
+
<td align="center">
|
416
|
+
<a href="https://www.masterborn.com/career?utm_source=github&utm_medium=referral&utm_campaign=zodsponsoring">
|
417
|
+
<img src="https://avatars.githubusercontent.com/u/48984031?s=200&v=4" width="100px;" alt="MasterBorn logo"/>
|
388
418
|
</a>
|
389
419
|
<br />
|
390
|
-
<b>
|
420
|
+
<b>MasterBorn</b>
|
391
421
|
<br/>
|
392
|
-
<a href="https://www.
|
393
|
-
<span>Solana non-custodial wallet</span>
|
422
|
+
<a href="https://www.masterborn.com/career?utm_source=github&utm_medium=referral&utm_campaign=zodsponsoring">masterborn.com</a>
|
394
423
|
<br />
|
395
|
-
</td>
|
424
|
+
</td>
|
396
425
|
</tr>
|
397
426
|
</table>
|
398
427
|
|
@@ -413,9 +442,12 @@ There are a growing number of tools that are built atop or support Zod natively!
|
|
413
442
|
- [`domain-functions`](https://github.com/SeasonedSoftware/domain-functions/): Decouple your business logic from your framework using composable functions. With first-class type inference from end to end powered by Zod schemas.
|
414
443
|
- [`@zodios/core`](https://github.com/ecyrbe/zodios): A typescript API client with runtime and compile time validation backed by axios and zod.
|
415
444
|
- [`express-zod-api`](https://github.com/RobinTail/express-zod-api): Build Express-based APIs with I/O schema validation and custom middlewares.
|
445
|
+
- [`tapiduck`](https://github.com/sumukhbarve/monoduck/blob/main/src/tapiduck/README.md): End-to-end typesafe JSON APIs with Zod and Express; a bit like tRPC, but simpler.
|
446
|
+
- [`koa-zod-router`](https://github.com/JakeFenley/koa-zod-router): Create typesafe routes in Koa with I/O validation using Zod.
|
416
447
|
|
417
448
|
#### Form integrations
|
418
449
|
|
450
|
+
- [`conform`](https://conform.guide/api/zod): A progressive enhancement first form validation library for Remix and React Router
|
419
451
|
- [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form.
|
420
452
|
- [`zod-validation-error`](https://github.com/causaly/zod-validation-error): Generate user-friendly error messages from `ZodError`s.
|
421
453
|
- [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod.
|
@@ -426,6 +458,9 @@ There are a growing number of tools that are built atop or support Zod natively!
|
|
426
458
|
- [`zod-i18n-map`](https://github.com/aiji42/zod-i18n): Useful for translating Zod error messages.
|
427
459
|
- [`@modular-forms/solid`](https://github.com/fabian-hiller/modular-forms): Modular form library for SolidJS that supports Zod for validation.
|
428
460
|
- [`houseform`](https://github.com/crutchcorn/houseform/): A React form library that uses Zod for validation.
|
461
|
+
- [`sveltekit-superforms`](https://github.com/ciscoheat/sveltekit-superforms): Supercharged form library for SvelteKit with Zod validation.
|
462
|
+
- [`mobx-zod-form`](https://github.com/MonoidDev/mobx-zod-form): Data-first form builder based on MobX & Zod.
|
463
|
+
- [`@vee-validate/zod`](https://github.com/logaretm/vee-validate/tree/main/packages/zod): Form library for Vue.js with Zod schema validation.
|
429
464
|
|
430
465
|
#### Zod to X
|
431
466
|
|
@@ -437,6 +472,9 @@ There are a growing number of tools that are built atop or support Zod natively!
|
|
437
472
|
- [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod): Create Fastify type providers from Zod schemas.
|
438
473
|
- [`zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi): Generate full OpenAPI (Swagger) docs from Zod, including schemas, endpoints & parameters.
|
439
474
|
- [`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.
|
475
|
+
- [`zod-openapi`](https://github.com/samchungy/zod-openapi): Create full OpenAPI v3.x documentation from Zod schemas.
|
476
|
+
- [`fastify-zod-openapi`](https://github.com/samchungy/fastify-zod-openapi): Fastify type provider, validation, serialization and @fastify/swagger support for Zod schemas.
|
477
|
+
- [`typeschema`](https://typeschema.com/): Universal adapter for schema validation.
|
440
478
|
|
441
479
|
#### X to Zod
|
442
480
|
|
@@ -450,14 +488,20 @@ There are a growing number of tools that are built atop or support Zod natively!
|
|
450
488
|
- [`prisma-zod-generator`](https://github.com/omar-dulaimi/prisma-zod-generator): Emit Zod schemas from your Prisma schema.
|
451
489
|
- [`prisma-trpc-generator`](https://github.com/omar-dulaimi/prisma-trpc-generator): Emit fully implemented tRPC routers and their validation schemas using Zod.
|
452
490
|
- [`zod-prisma-types`](https://github.com/chrishoermann/zod-prisma-types) Create Zod types from your Prisma models.
|
491
|
+
- [`quicktype`](https://app.quicktype.io/): Convert JSON objects and JSON schemas into Zod schemas.
|
492
|
+
- [`@sanity-typed/zod`](https://github.com/saiichihashimoto/sanity-typed/tree/main/packages/zod): Generate Zod Schemas from [Sanity Schemas](https://www.sanity.io/docs/schema-types).
|
453
493
|
|
454
494
|
#### Mocking
|
455
495
|
|
456
496
|
- [`@anatine/zod-mock`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-mock): Generate mock data from a Zod schema. Powered by [faker.js](https://github.com/faker-js/faker).
|
457
497
|
- [`zod-mocking`](https://github.com/dipasqualew/zod-mocking): Generate mock data from your Zod schemas.
|
498
|
+
- [`zod-fixture`](https://github.com/timdeschryver/zod-fixture): Use your zod schemas to automate the generation of non-relevant test fixtures in a deterministic way.
|
499
|
+
- [`zocker`](https://zocker.sigrist.dev): Generate plausible mock-data from your schemas.
|
500
|
+
- [`zodock`](https://github.com/ItMaga/zodock) Generate mock data based on Zod schemas.
|
458
501
|
|
459
502
|
#### Powered by Zod
|
460
503
|
|
504
|
+
- [`freerstore`](https://github.com/JacobWeisenburger/freerstore): Firestore cost optimizer.
|
461
505
|
- [`slonik`](https://github.com/gajus/slonik/tree/gajus/add-zod-validation-backwards-compatible#runtime-validation-and-static-type-inference): Node.js Postgres client with strong Zod integration.
|
462
506
|
- [`soly`](https://github.com/mdbetancourt/soly): Create CLI applications with zod.
|
463
507
|
- [`zod-xlsx`](https://github.com/sidwebworks/zod-xlsx): A xlsx based resource validator using Zod schemas.
|
@@ -466,6 +510,7 @@ There are a growing number of tools that are built atop or support Zod natively!
|
|
466
510
|
#### Utilities for Zod
|
467
511
|
|
468
512
|
- [`zod_utilz`](https://github.com/JacobWeisenburger/zod_utilz): Framework agnostic utilities for Zod.
|
513
|
+
- [`zod-sandbox`](https://github.com/nereumelo/zod-sandbox): Controlled environment for testing zod schemas. [Live demo](https://zod-sandbox.vercel.app/).
|
469
514
|
|
470
515
|
## Installation
|
471
516
|
|
@@ -494,6 +539,15 @@ bun add zod # bun
|
|
494
539
|
pnpm add zod # pnpm
|
495
540
|
```
|
496
541
|
|
542
|
+
Zod also publishes a canary version on every commit. To install the canary:
|
543
|
+
|
544
|
+
```sh
|
545
|
+
npm install zod@canary # npm
|
546
|
+
yarn add zod@canary # yarn
|
547
|
+
bun add zod@canary # bun
|
548
|
+
pnpm add zod@canary # pnpm
|
549
|
+
```
|
550
|
+
|
497
551
|
### From `deno.land/x` (Deno)
|
498
552
|
|
499
553
|
Unlike Node, Deno relies on direct URL imports instead of a package manager like NPM. Zod is available on [deno.land/x](https://deno.land/x). The latest version can be imported like so:
|
@@ -618,7 +672,7 @@ z.coerce.boolean().parse(null); // => false
|
|
618
672
|
|
619
673
|
## Literals
|
620
674
|
|
621
|
-
Literal schemas represent a [literal type](https://www.typescriptlang.org/docs/handbook/
|
675
|
+
Literal schemas represent a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types), like `"hello world"` or `5`.
|
622
676
|
|
623
677
|
```ts
|
624
678
|
const tuna = z.literal("tuna");
|
@@ -655,7 +709,7 @@ z.string().regex(regex);
|
|
655
709
|
z.string().includes(string);
|
656
710
|
z.string().startsWith(string);
|
657
711
|
z.string().endsWith(string);
|
658
|
-
z.string().datetime(); //
|
712
|
+
z.string().datetime(); // ISO 8601; default is without UTC offset, see below for options
|
659
713
|
z.string().ip(); // defaults to IPv4 and IPv6, see below for options
|
660
714
|
|
661
715
|
// transformations
|
@@ -694,7 +748,7 @@ z.string().ip({ message: "Invalid IP address" });
|
|
694
748
|
|
695
749
|
### ISO datetimes
|
696
750
|
|
697
|
-
The `z.string().datetime()` method
|
751
|
+
The `z.string().datetime()` method enforces ISO 8601; default is no timezone offsets and arbitrary sub-second decimal precision.
|
698
752
|
|
699
753
|
```ts
|
700
754
|
const datetime = z.string().datetime();
|
@@ -966,7 +1020,7 @@ FruitEnum.parse("Cantaloupe"); // fails
|
|
966
1020
|
|
967
1021
|
**Const enums**
|
968
1022
|
|
969
|
-
The `.nativeEnum()` function works for `as const` objects as well. ⚠️ `as const`
|
1023
|
+
The `.nativeEnum()` function works for `as const` objects as well. ⚠️ `as const` requires TypeScript 3.4+!
|
970
1024
|
|
971
1025
|
```ts
|
972
1026
|
const Fruits = {
|
@@ -1137,13 +1191,13 @@ type NoIDRecipe = z.infer<typeof NoIDRecipe>;
|
|
1137
1191
|
|
1138
1192
|
### `.partial`
|
1139
1193
|
|
1140
|
-
Inspired by the built-in TypeScript utility type [Partial](https://www.typescriptlang.org/docs/handbook/utility-types.html#
|
1194
|
+
Inspired by the built-in TypeScript utility type [Partial](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype), the `.partial` method makes all properties optional.
|
1141
1195
|
|
1142
1196
|
Starting from this object:
|
1143
1197
|
|
1144
1198
|
```ts
|
1145
1199
|
const user = z.object({
|
1146
|
-
email: z.string()
|
1200
|
+
email: z.string(),
|
1147
1201
|
username: z.string(),
|
1148
1202
|
});
|
1149
1203
|
// { email: string; username: string }
|
@@ -1207,10 +1261,12 @@ Contrary to the `.partial` method, the `.required` method makes all properties r
|
|
1207
1261
|
Starting from this object:
|
1208
1262
|
|
1209
1263
|
```ts
|
1210
|
-
const user = z
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1264
|
+
const user = z
|
1265
|
+
.object({
|
1266
|
+
email: z.string(),
|
1267
|
+
username: z.string(),
|
1268
|
+
})
|
1269
|
+
.partial();
|
1214
1270
|
// { email?: string | undefined; username?: string | undefined }
|
1215
1271
|
```
|
1216
1272
|
|
@@ -1464,6 +1520,12 @@ type NumberCache = z.infer<typeof NumberCache>;
|
|
1464
1520
|
This is particularly useful for storing or caching items by ID.
|
1465
1521
|
|
1466
1522
|
```ts
|
1523
|
+
const userSchema = z.object({ name: z.string() });
|
1524
|
+
const userStoreSchema = z.record(userSchema);
|
1525
|
+
|
1526
|
+
type UserStore = z.infer<typeof userStoreSchema>;
|
1527
|
+
// => type UserStore = { [ x: string ]: { name: string } }
|
1528
|
+
|
1467
1529
|
const userStore: UserStore = {};
|
1468
1530
|
|
1469
1531
|
userStore["77d2586b-9e8e-4ecf-8b21-ea7e0530eadd"] = {
|
@@ -1819,7 +1881,7 @@ You can create a Zod schema for any TypeScript type by using `z.custom()`. This
|
|
1819
1881
|
|
1820
1882
|
```ts
|
1821
1883
|
const px = z.custom<`${number}px`>((val) => {
|
1822
|
-
return /^\d+px$/.test(val
|
1884
|
+
return typeof val === "string" ? /^\d+px$/.test(val) : false;
|
1823
1885
|
});
|
1824
1886
|
|
1825
1887
|
type px = z.infer<typeof px>; // `${number}px`
|
@@ -2292,7 +2354,7 @@ A convenience method that returns a "nullish" version of a schema. Nullish schem
|
|
2292
2354
|
const nullishString = z.string().nullish(); // string | null | undefined
|
2293
2355
|
|
2294
2356
|
// equivalent to
|
2295
|
-
z.string().
|
2357
|
+
z.string().nullable().optional();
|
2296
2358
|
```
|
2297
2359
|
|
2298
2360
|
### `.array`
|
@@ -2382,7 +2444,38 @@ type Cat = z.infer<typeof Cat>;
|
|
2382
2444
|
|
2383
2445
|
Note that branded types do not affect the runtime result of `.parse`. It is a static-only construct.
|
2384
2446
|
|
2385
|
-
### `.
|
2447
|
+
### `.readonly`
|
2448
|
+
|
2449
|
+
`.readonly() => ZodReadonly<this>`
|
2450
|
+
|
2451
|
+
This method returns a `ZodReadonly` schema instance that parses the input using the base schema, then calls `Object.freeze()` on the result. The inferred type is also marked as `readonly`.
|
2452
|
+
|
2453
|
+
```ts
|
2454
|
+
const schema = z.object({ name: string }).readonly();
|
2455
|
+
type schema = z.infer<typeof schema>;
|
2456
|
+
// Readonly<{name: string}>
|
2457
|
+
|
2458
|
+
const result = schema.parse({ name: "fido" });
|
2459
|
+
result.name = "simba"; // error
|
2460
|
+
```
|
2461
|
+
|
2462
|
+
The inferred type uses TypeScript's built-in readonly types when relevant.
|
2463
|
+
|
2464
|
+
```ts
|
2465
|
+
z.array(z.string()).readonly();
|
2466
|
+
// readonly string[]
|
2467
|
+
|
2468
|
+
z.tuple([z.string(), z.number()]).readonly();
|
2469
|
+
// readonly [string, number]
|
2470
|
+
|
2471
|
+
z.map(z.string(), z.date()).readonly();
|
2472
|
+
// ReadonlyMap<string, Date>
|
2473
|
+
|
2474
|
+
z.set(z.string()).readonly();
|
2475
|
+
// ReadonlySet<Promise<string>>
|
2476
|
+
```
|
2477
|
+
|
2478
|
+
### `.pipe`
|
2386
2479
|
|
2387
2480
|
Schemas can be chained into validation "pipelines". It's useful for easily validating the result after a `.transform()`:
|
2388
2481
|
|
@@ -2399,51 +2492,55 @@ The `.pipe()` method returns a `ZodPipeline` instance.
|
|
2399
2492
|
You can constrain the input to types that work well with your chosen coercion. Then use `.pipe()` to apply the coercion.
|
2400
2493
|
|
2401
2494
|
without constrained input:
|
2495
|
+
|
2402
2496
|
```ts
|
2403
|
-
const toDate = z.coerce.date()
|
2497
|
+
const toDate = z.coerce.date();
|
2404
2498
|
|
2405
2499
|
// works intuitively
|
2406
|
-
console.log(toDate.safeParse(
|
2500
|
+
console.log(toDate.safeParse("2023-01-01").success); // true
|
2407
2501
|
|
2408
2502
|
// might not be what you want
|
2409
|
-
console.log(toDate.safeParse(null).success) // true
|
2503
|
+
console.log(toDate.safeParse(null).success); // true
|
2410
2504
|
```
|
2411
2505
|
|
2412
2506
|
with constrained input:
|
2507
|
+
|
2413
2508
|
```ts
|
2414
|
-
const datelike = z.union([z.number(), z.string(), z.date()])
|
2415
|
-
const datelikeToDate = datelike.pipe(z.coerce.date())
|
2509
|
+
const datelike = z.union([z.number(), z.string(), z.date()]);
|
2510
|
+
const datelikeToDate = datelike.pipe(z.coerce.date());
|
2416
2511
|
|
2417
2512
|
// still works intuitively
|
2418
|
-
console.log(datelikeToDate.safeParse(
|
2513
|
+
console.log(datelikeToDate.safeParse("2023-01-01").success); // true
|
2419
2514
|
|
2420
2515
|
// more likely what you want
|
2421
|
-
console.log(datelikeToDate.safeParse(null).success) // false
|
2516
|
+
console.log(datelikeToDate.safeParse(null).success); // false
|
2422
2517
|
```
|
2423
2518
|
|
2424
2519
|
You can also use this technique to avoid coercions that throw uncaught errors.
|
2425
2520
|
|
2426
2521
|
without constrained input:
|
2522
|
+
|
2427
2523
|
```ts
|
2428
|
-
const toBigInt = z.coerce.bigint()
|
2524
|
+
const toBigInt = z.coerce.bigint();
|
2429
2525
|
|
2430
2526
|
// works intuitively
|
2431
|
-
console.log(
|
2527
|
+
console.log(toBigInt.safeParse("42")); // true
|
2432
2528
|
|
2433
2529
|
// probably not what you want
|
2434
|
-
console.log(
|
2530
|
+
console.log(toBigInt.safeParse(null)); // throws uncaught error
|
2435
2531
|
```
|
2436
2532
|
|
2437
2533
|
with constrained input:
|
2534
|
+
|
2438
2535
|
```ts
|
2439
|
-
const toNumber = z.number().or(
|
2440
|
-
const toBigInt = z.bigint().or(
|
2536
|
+
const toNumber = z.number().or(z.string()).pipe(z.coerce.number());
|
2537
|
+
const toBigInt = z.bigint().or(toNumber).pipe(z.coerce.bigint());
|
2441
2538
|
|
2442
2539
|
// still works intuitively
|
2443
|
-
console.log(
|
2540
|
+
console.log(toBigInt.safeParse("42").success); // true
|
2444
2541
|
|
2445
2542
|
// error handled by zod, more likely what you want
|
2446
|
-
console.log(
|
2543
|
+
console.log(toBigInt.safeParse(null).success); // false
|
2447
2544
|
```
|
2448
2545
|
|
2449
2546
|
## Guides and concepts
|
@@ -2654,7 +2751,6 @@ Yup is a full-featured library that was implemented first in vanilla JS, and lat
|
|
2654
2751
|
|
2655
2752
|
- Supports casting and transforms
|
2656
2753
|
- All object fields are optional by default
|
2657
|
-
- Missing object methods: (partial, deepPartial)
|
2658
2754
|
<!-- - Missing nonempty arrays with proper typing (`[T, ...T[]]`) -->
|
2659
2755
|
- Missing promise schemas
|
2660
2756
|
- Missing function schemas
|
@@ -2717,10 +2813,9 @@ This more declarative API makes schema definitions vastly more concise.
|
|
2717
2813
|
|
2718
2814
|
[https://github.com/pelotom/runtypes](https://github.com/pelotom/runtypes)
|
2719
2815
|
|
2720
|
-
Good type inference support
|
2816
|
+
Good type inference support.
|
2721
2817
|
|
2722
2818
|
- Supports "pattern matching": computed properties that distribute over unions
|
2723
|
-
- Supports readonly types
|
2724
2819
|
- Missing object methods: (deepPartial, merge)
|
2725
2820
|
- Missing nonempty arrays with proper typing (`[T, ...T[]]`)
|
2726
2821
|
- Missing promise schemas
|
@@ -37,6 +37,7 @@ class ZodError extends Error {
|
|
37
37
|
};
|
38
38
|
const actualProto = new.target.prototype;
|
39
39
|
if (Object.setPrototypeOf) {
|
40
|
+
// eslint-disable-next-line ban/ban
|
40
41
|
Object.setPrototypeOf(this, actualProto);
|
41
42
|
}
|
42
43
|
else {
|
@@ -76,6 +77,13 @@ class ZodError extends Error {
|
|
76
77
|
const terminal = i === issue.path.length - 1;
|
77
78
|
if (!terminal) {
|
78
79
|
curr[el] = curr[el] || { _errors: [] };
|
80
|
+
// if (typeof el === "string") {
|
81
|
+
// curr[el] = curr[el] || { _errors: [] };
|
82
|
+
// } else if (typeof el === "number") {
|
83
|
+
// const errorArray: any = [];
|
84
|
+
// errorArray._errors = [];
|
85
|
+
// curr[el] = curr[el] || errorArray;
|
86
|
+
// }
|
79
87
|
}
|
80
88
|
else {
|
81
89
|
curr[el] = curr[el] || { _errors: [] };
|