prisma-zod-generator 1.9.0 β 1.9.2
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 +63 -1689
- package/lib/prisma-generator.js +28 -19
- package/lib/prisma-generator.js.map +1 -1
- package/lib/transformer.js +29 -20
- package/lib/transformer.js.map +1 -1
- package/lib/utils/singleFileAggregator.js +1 -1
- package/lib/utils/singleFileAggregator.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,1733 +1,107 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<a href="https://www.npmjs.com/package/prisma-zod-generator">
|
|
15
|
-
<img src="https://img.shields.io/npm/dt/prisma-zod-generator.svg?style=for-the-badge&logo=npm&color=green" alt="Downloads">
|
|
16
|
-
</a>
|
|
17
|
-
<a href="https://github.com/omar-dulaimi/prisma-zod-generator/actions">
|
|
18
|
-
<img src="https://img.shields.io/github/actions/workflow/status/omar-dulaimi/prisma-zod-generator/ci.yml?style=for-the-badge&logo=github" alt="CI Status">
|
|
19
|
-
</a>
|
|
20
|
-
<a href="https://omar-dulaimi.github.io/prisma-zod-generator/">
|
|
21
|
-
<img src="https://img.shields.io/badge/docs-website-blue?style=for-the-badge&logo=readthedocs" alt="Docs">
|
|
22
|
-
</a>
|
|
23
|
-
<a href="LICENSE">
|
|
24
|
-
<img src="https://img.shields.io/npm/l/prisma-zod-generator.svg?style=for-the-badge&color=purple" alt="License">
|
|
25
|
-
</a>
|
|
26
|
-
</p>
|
|
27
|
-
|
|
28
|
-
<p>
|
|
29
|
-
<strong>:dart: Zero-config β’ :shield: Type-safe β’ :zap: Fast β’ :wrench: Customizable</strong>
|
|
30
|
-
</p>
|
|
31
|
-
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
<div align="center">
|
|
37
|
-
<h3>:bulb: Transform your Prisma schema into type-safe validation schemas</h3>
|
|
38
|
-
<p><em>Automatically generates Zod schemas for all Prisma operations with full TypeScript support</em></p>
|
|
39
|
-
</div>
|
|
40
|
-
|
|
41
|
-
<div align="center">
|
|
42
|
-
|
|
43
|
-
<a id="sponsor"></a>
|
|
44
|
-
## :sparkling_heart: Sponsor to Keep This Project Active
|
|
45
|
-
|
|
46
|
-
<p><strong>:rotating_light: Active maintenance depends on your sponsorship. If this generator saves you time, please consider sponsoring.</strong></p>
|
|
47
|
-
|
|
48
|
-
<a href="https://github.com/sponsors/omar-dulaimi">
|
|
49
|
-
<img src="https://img.shields.io/badge/π_Sponsor_on_GitHub-ea4aaa?style=for-the-badge&logo=github&logoColor=white" alt="GitHub Sponsors" height="45">
|
|
50
|
-
</a>
|
|
51
|
-
|
|
52
|
-
<p><em>Your support funds maintenance, issue triage, new features, documentation, and community help.</em></p>
|
|
53
|
-
|
|
2
|
+
<h1>Prisma Zod Generator</h1>
|
|
3
|
+
<p><strong>Prisma β Zod in one generate. Ship validated data everywhere.</strong></p>
|
|
4
|
+
<p>
|
|
5
|
+
<a href="https://www.npmjs.com/package/prisma-zod-generator"><img alt="npm version" src="https://img.shields.io/npm/v/prisma-zod-generator.svg?color=16C464&label=version"></a>
|
|
6
|
+
<a href="https://www.npmjs.com/package/prisma-zod-generator"><img alt="weekly downloads" src="https://img.shields.io/npm/dw/prisma-zod-generator.svg?color=8B5CF6&label=downloads"></a>
|
|
7
|
+
<a href="https://github.com/omar-dulaimi/prisma-zod-generator/actions"><img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/omar-dulaimi/prisma-zod-generator/ci.yml?branch=master&label=CI"></a>
|
|
8
|
+
<a href="https://github.com/omar-dulaimi/prisma-zod-generator/blob/master/LICENSE"><img alt="MIT license" src="https://img.shields.io/badge/license-MIT-0a0a0a.svg"></a>
|
|
9
|
+
<img alt="TypeScript" src="https://img.shields.io/badge/types-TypeScript-informational.svg">
|
|
10
|
+
<img alt="Module formats" src="https://img.shields.io/badge/modules-esm%20%2B%20cjs-444.svg">
|
|
11
|
+
<a href="https://omar-dulaimi.github.io/prisma-zod-generator/"><img alt="Docs" src="https://img.shields.io/badge/docs-website-blue.svg"></a>
|
|
12
|
+
</p>
|
|
13
|
+
<sub><code>input</code> Β· <code>result</code> Β· <code>pure</code> variants β’ comment rules β’ minimal mode β’ targeted filtering</sub>
|
|
54
14
|
</div>
|
|
55
15
|
|
|
56
16
|
---
|
|
57
17
|
|
|
18
|
+
> π Docs: https://omar-dulaimi.github.io/prisma-zod-generator/
|
|
58
19
|
|
|
20
|
+
## Prerequisites
|
|
59
21
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
<td><a href="#sponsor">:sparkling_heart: Sponsor</a></td>
|
|
65
|
-
<td><a href="#-quick-start">:rocket: Quick Start</a></td>
|
|
66
|
-
<td><a href="#-generated-output">:clipboard: Generated Output</a></td>
|
|
67
|
-
<td><a href="#-version-compatibility">:package: Compatibility</a></td>
|
|
68
|
-
<td><a href="#-core-examples">:books: Core Examples</a></td>
|
|
69
|
-
</tr>
|
|
70
|
-
<tr>
|
|
71
|
-
<td><a href="#-advanced-features">:wrench: Advanced Features</a></td>
|
|
72
|
-
<td><a href="#-configuration">:gear: Configuration</a></td>
|
|
73
|
-
<td><a href="#-api-reference">:book: API Reference</a></td>
|
|
74
|
-
<td><a href="#-framework-examples">:globe_with_meridians: Framework Examples</a></td>
|
|
75
|
-
</tr>
|
|
76
|
-
<td><a href="#-testing--development">:test_tube: Testing & Development</a></td>
|
|
77
|
-
<td><a href="#-troubleshooting">:mag: Troubleshooting</a></td>
|
|
78
|
-
<td><a href="#-contributing">:handshake: Contributing</a></td>
|
|
79
|
-
<td></td>
|
|
80
|
-
</tr>
|
|
81
|
-
</table>
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## :rocket: Quick Start
|
|
22
|
+
- Node.js 18+ (or Bun / Deno with Prisma compatibility layer)
|
|
23
|
+
- Prisma (installed & `npx prisma init` done)
|
|
24
|
+
- Zod (runtime dependency for the generated schemas)
|
|
25
|
+
- TypeScript recommended (strict mode ideal)
|
|
86
26
|
|
|
87
|
-
|
|
27
|
+
## Quick Start β‘
|
|
88
28
|
|
|
29
|
+
**1. Install (pick one)**
|
|
89
30
|
```bash
|
|
90
|
-
#
|
|
91
|
-
npm
|
|
92
|
-
|
|
93
|
-
# Yarn
|
|
94
|
-
yarn add prisma-zod-generator
|
|
95
|
-
|
|
96
|
-
# PNPM
|
|
97
|
-
pnpm add prisma-zod-generator
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### 2. Add generator block to your Prisma schema
|
|
101
|
-
|
|
102
|
-
Add the Prisma Zod Generator to your `schema.prisma` with inline options. You can also supply a JSON config via `config` for advanced/nested settings.
|
|
103
|
-
|
|
104
|
-
```prisma
|
|
105
|
-
generator zod {
|
|
106
|
-
provider = "prisma-zod-generator" // required: package id
|
|
107
|
-
output = "./generated" // required: where to write output
|
|
108
|
-
|
|
109
|
-
// File output mode
|
|
110
|
-
useMultipleFiles = true // true: multi-file (default), false: single-file bundle
|
|
111
|
-
singleFileName = "schemas.ts" // only when useMultipleFiles=false
|
|
112
|
-
placeSingleFileAtRoot = true // single-file at output root (true) or under schemas/ (false)
|
|
113
|
-
|
|
114
|
-
// Legacy select/include flags (override JSON config if both provided)
|
|
115
|
-
isGenerateSelect = false
|
|
116
|
-
isGenerateInclude = false
|
|
117
|
-
|
|
118
|
-
// Optional: external JSON config for nested options (models, variants, exclusions, etc.)
|
|
119
|
-
// When both sources specify the same simple option, this generator block wins.
|
|
120
|
-
config = "./zod-generator.config.json"
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Note on precedence: simple options declared in the Prisma generator block (like useMultipleFiles, singleFileName, placeSingleFileAtRoot, legacy isGenerateSelect/isGenerateInclude) override the same options from the JSON file. See the Precedence section for details.
|
|
125
|
-
|
|
126
|
-
### 3. Configure TypeScript (required)
|
|
127
|
-
|
|
128
|
-
```json
|
|
129
|
-
{
|
|
130
|
-
"compilerOptions": {
|
|
131
|
-
"strict": true
|
|
132
|
-
}
|
|
133
|
-
}
|
|
31
|
+
# npm
|
|
32
|
+
npm i -D prisma-zod-generator zod
|
|
134
33
|
```
|
|
135
|
-
|
|
136
|
-
### 4. Generate schemas
|
|
137
|
-
|
|
138
34
|
```bash
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
### π‘ Inline Custom Schema Override (@zod.custom.use)
|
|
143
|
-
|
|
144
|
-
Replace a field's generated schema directly via a doc comment:
|
|
145
|
-
|
|
146
|
-
```prisma
|
|
147
|
-
model AiChat {
|
|
148
|
-
id String @id @default(cuid())
|
|
149
|
-
/// @zod.custom.use(z.array(z.object({ role: z.enum(['user','assistant','system']), parts: z.array(z.object({ type: z.enum(['text','image']), text: z.string() })) })))
|
|
150
|
-
messages Json @default("[]")
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Output excerpt:
|
|
155
|
-
```ts
|
|
156
|
-
messages: z.array(z.object({ role: z.enum(['user','assistant','system']), parts: z.array(z.object({ type: z.enum(['text','image']), text: z.string() })) })).default("[]")
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Add the internal depth refinement if desired:
|
|
160
|
-
```ts
|
|
161
|
-
import { jsonMaxDepthRefinement } from 'prisma-zod-generator';
|
|
162
|
-
const ChatMessagesSchema = z.array(MessageSchema)${'${jsonMaxDepthRefinement(10)}'};
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
The override shortβcircuits further inline annotations for that field.
|
|
166
|
-
|
|
167
|
-
### π‘ Inline Custom Schema Override (@zod.custom.use)
|
|
168
|
-
|
|
169
|
-
You can replace a field's generated schema directly via a doc comment:
|
|
170
|
-
|
|
171
|
-
```prisma
|
|
172
|
-
model AiChat {
|
|
173
|
-
id String @id @default(cuid())
|
|
174
|
-
/// @zod.custom.use(z.array(z.object({ role: z.enum(['user','assistant','system']), parts: z.array(z.object({ type: z.enum(['text','image']), text: z.string() })) })))
|
|
175
|
-
messages Json @default("[]")
|
|
176
|
-
}
|
|
35
|
+
# pnpm
|
|
36
|
+
pnpm add -D prisma-zod-generator zod
|
|
177
37
|
```
|
|
178
|
-
|
|
179
|
-
Output excerpt:
|
|
180
|
-
```ts
|
|
181
|
-
messages: z.array(z.object({ role: z.enum(['user','assistant','system']), parts: z.array(z.object({ type: z.enum(['text','image']), text: z.string() })) })).default("[]")
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Add the internal depth refinement if desired:
|
|
185
|
-
```ts
|
|
186
|
-
import { jsonMaxDepthRefinement } from 'prisma-zod-generator';
|
|
187
|
-
const ChatMessagesSchema = z.array(MessageSchema)${'${jsonMaxDepthRefinement(10)}'};
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
The override shortβcircuits further inline annotations for that field.
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## π Logging and warnings
|
|
195
|
-
|
|
196
|
-
<details>
|
|
197
|
-
<summary><strong>Click to expand logging & warning details</strong></summary>
|
|
198
|
-
|
|
199
|
-
By default the generator prints minimal output. Critical warnings are surfaced as tagged info lines so you wonβt miss important context, while detailed diagnostics stay hidden unless you opt in.
|
|
200
|
-
|
|
201
|
-
What youβll see by default:
|
|
202
|
-
|
|
203
|
-
- [prisma-zod-generator] β οΈ File layout conflicts detected. The Prisma generator block takes precedence over JSON config.
|
|
204
|
-
- When generator block and JSON disagree on useMultipleFiles/singleFileName/placeSingleFileAtRoot, this header appears so you know why you got a bundle vs many files (or vice versa). Details are available in debug logs.
|
|
205
|
-
- [prisma-zod-generator] β οΈ Minimal mode active: Select/Include schemas will be disabled even if enabled by legacy flags or config.
|
|
206
|
-
- Minimal mode forces these helpers off to keep output lean. If you explicitly requested them, weβll tell you theyβre being ignored.
|
|
207
|
-
- [prisma-zod-generator] β οΈ Configuration loading failed, using defaults: β¦
|
|
208
|
-
- If a config file canβt be loaded, we fall back to safe defaults and tell you why.
|
|
209
|
-
|
|
210
|
-
Enable detailed debug output:
|
|
211
|
-
|
|
212
|
-
- One-off run (Linux/macOS):
|
|
213
|
-
- `DEBUG_PRISMA_ZOD=1 npx prisma generate`
|
|
214
|
-
- or use a namespace: `DEBUG=prisma-zod npx prisma generate`
|
|
215
|
-
- Via npm script in this repo: `npm run gen-example:debug`
|
|
216
|
-
|
|
217
|
-
Unset the env var to return to quiet mode.
|
|
218
|
-
|
|
219
|
-
</details>
|
|
220
|
-
|
|
221
|
-
---
|
|
222
|
-
|
|
223
|
-
## β¨ Why Choose Prisma Zod Generator?
|
|
224
|
-
|
|
225
|
-
<table>
|
|
226
|
-
<tr>
|
|
227
|
-
<td align="center" width="25%">
|
|
228
|
-
<img src="https://img.shields.io/badge/π-Zero_Config-blue?style=for-the-badge" alt="Zero Config"><br>
|
|
229
|
-
<strong>Works instantly</strong><br><em>Sensible defaults included</em>
|
|
230
|
-
</td>
|
|
231
|
-
<td align="center" width="25%">
|
|
232
|
-
<img src="https://img.shields.io/badge/π-Auto_Generated-green?style=for-the-badge" alt="Auto Generated"><br>
|
|
233
|
-
<strong>Always in sync</strong><br><em>Updates with schema changes</em>
|
|
234
|
-
</td>
|
|
235
|
-
<td align="center" width="25%">
|
|
236
|
-
<img src="https://img.shields.io/badge/π‘οΈ-Type_Safe-purple?style=for-the-badge" alt="Type Safe"><br>
|
|
237
|
-
<strong>100% TypeScript</strong><br><em>Catch errors at compile time</em>
|
|
238
|
-
</td>
|
|
239
|
-
<td align="center" width="25%">
|
|
240
|
-
<img src="https://img.shields.io/badge/π―-Comprehensive-orange?style=for-the-badge" alt="Comprehensive"><br>
|
|
241
|
-
<strong>Full CRUD coverage</strong><br><em>All Prisma operations included</em>
|
|
242
|
-
</td>
|
|
243
|
-
</tr>
|
|
244
|
-
<tr>
|
|
245
|
-
<td align="center">
|
|
246
|
-
<img src="https://img.shields.io/badge/βοΈ-Configurable-red?style=for-the-badge" alt="Configurable"><br>
|
|
247
|
-
<strong>Highly customizable</strong><br><em>Adapt to your needs</em>
|
|
248
|
-
</td>
|
|
249
|
-
<td align="center">
|
|
250
|
-
<img src="https://img.shields.io/badge/π¦-Lightweight-yellow?style=for-the-badge" alt="Lightweight"><br>
|
|
251
|
-
<strong>Minimal footprint</strong><br><em>Fast generation & runtime</em>
|
|
252
|
-
</td>
|
|
253
|
-
<td align="center">
|
|
254
|
-
<img src="https://img.shields.io/badge/ποΈ-Multi_DB-cyan?style=for-the-badge" alt="Multi Database"><br>
|
|
255
|
-
<strong>All databases</strong><br><em>PostgreSQL, MySQL, MongoDB+</em>
|
|
256
|
-
</td>
|
|
257
|
-
<td align="center">
|
|
258
|
-
<img src="https://img.shields.io/badge/π¨-Flexible-pink?style=for-the-badge" alt="Flexible"><br>
|
|
259
|
-
<strong>Your way</strong><br><em>Custom paths & options</em>
|
|
260
|
-
</td>
|
|
261
|
-
</tr>
|
|
262
|
-
</table>
|
|
263
|
-
|
|
264
|
-
### π Upgrading
|
|
265
|
-
|
|
266
|
-
The latest stable version maintains full API compatibility. Requirements:
|
|
267
|
-
- Node.js 18+
|
|
268
|
-
- Prisma 6.12.0+
|
|
269
|
-
- Zod 4.0.5+
|
|
270
|
-
|
|
271
|
-
Update and regenerate:
|
|
272
|
-
|
|
273
38
|
```bash
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
## π Generated Output
|
|
279
|
-
|
|
280
|
-
<details>
|
|
281
|
-
<summary><strong>π File Structure Overview</strong></summary>
|
|
282
|
-
|
|
283
|
-
For this Prisma schema:
|
|
284
|
-
|
|
285
|
-
```prisma
|
|
286
|
-
model User {
|
|
287
|
-
id Int @id @default(autoincrement())
|
|
288
|
-
email String @unique
|
|
289
|
-
name String?
|
|
290
|
-
posts Post[]
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
model Post {
|
|
294
|
-
id Int @id @default(autoincrement())
|
|
295
|
-
title String
|
|
296
|
-
content String?
|
|
297
|
-
author User? @relation(fields: [authorId], references: [id])
|
|
298
|
-
authorId Int?
|
|
299
|
-
}
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
The generator creates:
|
|
303
|
-
|
|
304
|
-
```
|
|
305
|
-
π generated/schemas/
|
|
306
|
-
βββ π enums/ # Enum validation schemas
|
|
307
|
-
βββ π objects/ # Input type schemas
|
|
308
|
-
βββ π findManyUser.schema.ts
|
|
309
|
-
βββ π findUniqueUser.schema.ts
|
|
310
|
-
βββ π createOneUser.schema.ts
|
|
311
|
-
βββ π updateOneUser.schema.ts
|
|
312
|
-
βββ π deleteOneUser.schema.ts
|
|
313
|
-
βββ π findManyPost.schema.ts
|
|
314
|
-
βββ π createOnePost.schema.ts
|
|
315
|
-
βββ π index.ts # Barrel exports
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
</details>
|
|
319
|
-
|
|
320
|
-
---
|
|
321
|
-
|
|
322
|
-
## :rocket: Dual Schema Export Strategy - Breakthrough Feature!
|
|
323
|
-
|
|
324
|
-
### π― Solving the Type Safety vs Method Availability Trade-off
|
|
325
|
-
|
|
326
|
-
This generator implements a dual export strategy that gives you both perfect Prisma typing and full Zod method support.
|
|
327
|
-
|
|
328
|
-
#### The Problem
|
|
329
|
-
With Zod schemas, you traditionally face a choice:
|
|
330
|
-
- Type-safe: `z.ZodType<Prisma.Type>` gives perfect inference but restricts Zod method chaining
|
|
331
|
-
- Method-friendly: Pure Zod schemas support all methods but lose perfect type binding
|
|
332
|
-
|
|
333
|
-
#### Our Solution: Export Both Versions
|
|
334
|
-
|
|
335
|
-
```ts
|
|
336
|
-
// Perfect type safety (no Zod method chaining)
|
|
337
|
-
export const PostFindManySchema: z.ZodType<Prisma.PostFindManyArgs> = schema;
|
|
338
|
-
|
|
339
|
-
// Full method availability (great inference)
|
|
340
|
-
export const PostFindManyZodSchema = schema;
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
Type-safe version (perfect Prisma integration):
|
|
344
|
-
|
|
345
|
-
```ts
|
|
346
|
-
import { PostFindManySchema } from './generated/schemas/findManyPost.schema';
|
|
347
|
-
|
|
348
|
-
type FindManyArgs = z.infer<typeof PostFindManySchema>; // Prisma.PostFindManyArgs
|
|
349
|
-
|
|
350
|
-
const validatedInput = PostFindManySchema.parse(queryParams);
|
|
351
|
-
const posts = await prisma.post.findMany(validatedInput);
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
Method-friendly version (full Zod capabilities):
|
|
355
|
-
|
|
356
|
-
```ts
|
|
357
|
-
import { PostFindManyZodSchema } from './generated/schemas/findManyPost.schema';
|
|
358
|
-
|
|
359
|
-
const customSchema = PostFindManyZodSchema
|
|
360
|
-
.extend({ customField: z.string() })
|
|
361
|
-
.omit({ take: true })
|
|
362
|
-
.merge(otherSchema);
|
|
363
|
-
|
|
364
|
-
const partialSchema = PostFindManyZodSchema.partial();
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
#### Configuration Options
|
|
368
|
-
|
|
369
|
-
```prisma
|
|
370
|
-
generator zod {
|
|
371
|
-
provider = "prisma-zod-generator"
|
|
372
|
-
output = "./generated/schemas"
|
|
373
|
-
exportTypedSchemas = true // Export z.ZodType<Prisma.Type> versions
|
|
374
|
-
exportZodSchemas = true // Export pure Zod versions
|
|
375
|
-
typedSchemaSuffix = "Schema" // Suffix for typed versions
|
|
376
|
-
zodSchemaSuffix = "ZodSchema" // Suffix for method-friendly versions
|
|
377
|
-
}
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
#### Configuration Scenarios
|
|
381
|
-
|
|
382
|
-
Type-safe only:
|
|
383
|
-
|
|
384
|
-
```prisma
|
|
385
|
-
generator zod {
|
|
386
|
-
provider = "prisma-zod-generator"
|
|
387
|
-
exportTypedSchemas = true
|
|
388
|
-
exportZodSchemas = false
|
|
389
|
-
}
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
Method-friendly only:
|
|
393
|
-
|
|
394
|
-
```prisma
|
|
395
|
-
generator zod {
|
|
396
|
-
provider = "prisma-zod-generator"
|
|
397
|
-
exportTypedSchemas = false
|
|
398
|
-
exportZodSchemas = true
|
|
399
|
-
}
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
Both versions:
|
|
403
|
-
|
|
404
|
-
```prisma
|
|
405
|
-
generator zod {
|
|
406
|
-
provider = "prisma-zod-generator"
|
|
407
|
-
exportTypedSchemas = true
|
|
408
|
-
exportZodSchemas = true
|
|
409
|
-
}
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
Custom naming:
|
|
413
|
-
|
|
414
|
-
```prisma
|
|
415
|
-
generator zod {
|
|
416
|
-
provider = "prisma-zod-generator"
|
|
417
|
-
exportTypedSchemas = true
|
|
418
|
-
exportZodSchemas = true
|
|
419
|
-
typedSchemaSuffix = "Args"
|
|
420
|
-
zodSchemaSuffix = "Validator"
|
|
421
|
-
}
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
Pro tips:
|
|
425
|
-
|
|
426
|
-
- Smaller bundles: use a single export mode
|
|
427
|
-
- Team consistency: choose one naming convention and stick with it
|
|
428
|
-
- Gradual adoption: start with type-safe schemas, add method-friendly as needed
|
|
429
|
-
- IDE performance: fewer exports -> faster IntelliSense in huge projects
|
|
430
|
-
|
|
431
|
-
---
|
|
432
|
-
|
|
433
|
-
## :package: Version Compatibility
|
|
434
|
-
|
|
435
|
-
<details>
|
|
436
|
-
<summary><strong>π Supported Versions & Migration Guide</strong></summary>
|
|
437
|
-
|
|
438
|
-
### Current Requirements
|
|
439
|
-
| **Prisma** | 6.12.0+ | β
Recommended |
|
|
440
|
-
| **Zod** | 4.0.5+ | β
Required |
|
|
441
|
-
| **TypeScript** | 5.8+ | β
Recommended |
|
|
442
|
-
### Prisma Client Generator Support
|
|
443
|
-
|
|
444
|
-
Both legacy and new ESM-compatible generators are supported:
|
|
445
|
-
|
|
446
|
-
#### Legacy Generator (Existing Projects)
|
|
447
|
-
```prisma
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
#### New ESM Generator (Prisma 6.12.0+)
|
|
451
|
-
```prisma
|
|
452
|
-
generator client {
|
|
453
|
-
provider = "prisma-client"
|
|
454
|
-
output = "./src/generated/client"
|
|
455
|
-
runtime = "nodejs"
|
|
456
|
-
moduleFormat = "esm"
|
|
457
|
-
generatedFileExtension = "ts"
|
|
458
|
-
importFileExtension = "ts"
|
|
459
|
-
}
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
### Migration Guide
|
|
463
|
-
|
|
464
|
-
**Existing Projects**: No changes needed - continue using `prisma-client-js`
|
|
465
|
-
|
|
466
|
-
**New Projects**: Consider the new `prisma-client` generator for ESM support
|
|
467
|
-
|
|
468
|
-
</details>
|
|
469
|
-
|
|
470
|
-
---
|
|
471
|
-
|
|
472
|
-
## π Core Examples
|
|
473
|
-
|
|
474
|
-
<details>
|
|
475
|
-
<summary><strong>π― Essential Usage Patterns</strong></summary>
|
|
476
|
-
|
|
477
|
-
### API Validation
|
|
478
|
-
|
|
479
|
-
```typescript
|
|
480
|
-
// Validate input data
|
|
481
|
-
const createUser = UserCreateInputObjectSchema.parse(requestData);
|
|
482
|
-
|
|
483
|
-
// Validate query parameters
|
|
484
|
-
const findUsers = UserFindManySchema.parse(queryParams);
|
|
485
|
-
|
|
486
|
-
// Validate update operations
|
|
487
|
-
const updateUser = UserUpdateOneSchema.parse(updateData);
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
### Form Validation with React Hook Form
|
|
491
|
-
|
|
492
|
-
```typescript
|
|
493
|
-
import { useForm } from 'react-hook-form';
|
|
494
|
-
import { zodResolver } from '@hookform/resolvers/zod';
|
|
495
|
-
import { UserCreateInputObjectSchema } from './generated/schemas';
|
|
496
|
-
|
|
497
|
-
function CreateUserForm() {
|
|
498
|
-
const { register, handleSubmit, formState: { errors } } = useForm({
|
|
499
|
-
resolver: zodResolver(UserCreateInputObjectSchema)
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
return (
|
|
503
|
-
<form onSubmit={handleSubmit(onSubmit)}>
|
|
504
|
-
<input {...register('email')} type="email" />
|
|
505
|
-
{errors.email && <span>{errors.email.message}</span>}
|
|
506
|
-
<button type="submit">Create User</button>
|
|
507
|
-
</form>
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
### Database Operations
|
|
513
|
-
|
|
514
|
-
```typescript
|
|
515
|
-
// Safe database queries with validation
|
|
516
|
-
const searchUsers = async (params: unknown) => {
|
|
517
|
-
const validatedParams = UserFindManySchema.parse(params);
|
|
518
|
-
return await prisma.user.findMany(validatedParams);
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
// Validated mutations
|
|
522
|
-
const createPost = async (data: unknown) => {
|
|
523
|
-
const validatedData = PostCreateOneSchema.parse(data);
|
|
524
|
-
return await prisma.post.create(validatedData);
|
|
525
|
-
};
|
|
526
|
-
```
|
|
527
|
-
|
|
528
|
-
</details>
|
|
529
|
-
|
|
530
|
-
---
|
|
531
|
-
|
|
532
|
-
## π§ Advanced Features
|
|
533
|
-
|
|
534
|
-
<details>
|
|
535
|
-
<summary><strong>π― Configuration System</strong></summary>
|
|
536
|
-
|
|
537
|
-
Looking for ready-made configs? See the new Recipes catalog in `recipes/` for common setups (single file, models-only, minimal CRUD, tRPC, API result schemas, hide fields, and more).
|
|
538
|
-
|
|
539
|
-
### JSON-Based Configuration
|
|
540
|
-
|
|
541
|
-
Create `zod-generator.config.json`:
|
|
542
|
-
|
|
543
|
-
```json
|
|
544
|
-
{
|
|
545
|
-
"mode": "custom",
|
|
546
|
-
"output": "./src/generated/zod",
|
|
547
|
-
"globalExclusions": {
|
|
548
|
-
"input": ["id", "createdAt", "updatedAt"],
|
|
549
|
-
"result": [],
|
|
550
|
-
"pure": ["password", "hashedPassword"]
|
|
551
|
-
},
|
|
552
|
-
"variants": {
|
|
553
|
-
"pure": {
|
|
554
|
-
"enabled": true,
|
|
555
|
-
"suffix": ".model",
|
|
556
|
-
"excludeFields": []
|
|
557
|
-
},
|
|
558
|
-
"input": {
|
|
559
|
-
"enabled": true,
|
|
560
|
-
"suffix": ".input",
|
|
561
|
-
"excludeFields": ["id"]
|
|
562
|
-
},
|
|
563
|
-
"result": {
|
|
564
|
-
"enabled": true,
|
|
565
|
-
"suffix": ".result",
|
|
566
|
-
"excludeFields": ["password"]
|
|
567
|
-
}
|
|
568
|
-
},
|
|
569
|
-
"models": {
|
|
570
|
-
"User": {
|
|
571
|
-
"enabled": true,
|
|
572
|
-
"operations": ["findMany", "findUnique", "create", "update"],
|
|
573
|
-
"variants": {
|
|
574
|
-
"input": {
|
|
575
|
-
"excludeFields": ["role", "permissions"]
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
### Configuration Modes
|
|
584
|
-
|
|
585
|
-
```typescript
|
|
586
|
-
// Minimal mode - essential operations only
|
|
587
|
-
const minimalConfig = {
|
|
588
|
-
mode: "minimal",
|
|
589
|
-
operations: ["findMany", "findUnique", "create", "update"]
|
|
590
|
-
};
|
|
591
|
-
|
|
592
|
-
// Full mode - all operations and features
|
|
593
|
-
const fullConfig = {
|
|
594
|
-
mode: "full",
|
|
595
|
-
includeAggregations: true,
|
|
596
|
-
includeGroupBy: true
|
|
597
|
-
};
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
</details>
|
|
601
|
-
|
|
602
|
-
<details>
|
|
603
|
-
<summary><strong>π¨ Schema Variants</strong></summary>
|
|
604
|
-
|
|
605
|
-
### Multiple Schema Types
|
|
606
|
-
|
|
607
|
-
Generate different schema variants for various use cases:
|
|
608
|
-
|
|
609
|
-
```typescript
|
|
610
|
-
// Pure model schemas - exact Prisma model structure
|
|
611
|
-
import { UserSchema } from './schemas/models/User.schema';
|
|
612
|
-
|
|
613
|
-
// Input schemas - for API endpoints and forms
|
|
614
|
-
import { UserInputSchema } from './schemas/User.input';
|
|
615
|
-
|
|
616
|
-
// Result schemas - for API responses
|
|
617
|
-
import { UserResultSchema } from './schemas/User.result';
|
|
618
|
-
|
|
619
|
-
// Usage examples
|
|
620
|
-
const createUser = UserInputSchema.parse(formData);
|
|
621
|
-
const userResponse = UserResultSchema.parse(dbResult);
|
|
622
|
-
const pureUser = UserSchema.parse(prismaModel);
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
### Variant Configuration
|
|
626
|
-
|
|
627
|
-
```json
|
|
628
|
-
{
|
|
629
|
-
"variants": [
|
|
630
|
-
{
|
|
631
|
-
"name": "input",
|
|
632
|
-
"suffix": "Input",
|
|
633
|
-
"exclude": ["id", "createdAt", "updatedAt"]
|
|
634
|
-
},
|
|
635
|
-
{
|
|
636
|
-
"name": "result",
|
|
637
|
-
"suffix": "Result",
|
|
638
|
-
"exclude": ["password"]
|
|
639
|
-
},
|
|
640
|
-
{
|
|
641
|
-
"name": "public",
|
|
642
|
-
"suffix": "Public",
|
|
643
|
-
"exclude": ["password", "email", "internalId"]
|
|
644
|
-
}
|
|
645
|
-
]
|
|
646
|
-
}
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
</details>
|
|
650
|
-
|
|
651
|
-
<details>
|
|
652
|
-
<summary><strong>π Field Exclusion System</strong></summary>
|
|
653
|
-
|
|
654
|
-
### Global and Model-Specific Exclusions
|
|
655
|
-
|
|
656
|
-
```typescript
|
|
657
|
-
// Configuration-based exclusion
|
|
658
|
-
const config = {
|
|
659
|
-
globalExclusions: {
|
|
660
|
-
input: ["id", "createdAt", "updatedAt"],
|
|
661
|
-
result: ["password", "hashedPassword"],
|
|
662
|
-
pure: []
|
|
663
|
-
},
|
|
664
|
-
models: {
|
|
665
|
-
User: {
|
|
666
|
-
variants: {
|
|
667
|
-
input: { excludeFields: ["role", "permissions"] },
|
|
668
|
-
result: { excludeFields: ["password", "sessionToken"] }
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
|
-
```
|
|
674
|
-
|
|
675
|
-
### Prisma Schema Exclusions
|
|
676
|
-
|
|
677
|
-
```prisma
|
|
678
|
-
model User {
|
|
679
|
-
id Int @id @default(autoincrement())
|
|
680
|
-
email String @unique
|
|
681
|
-
password String // Excluded from result schemas
|
|
682
|
-
role String // Excluded from input schemas
|
|
683
|
-
/// @@Gen.model(hide: true) // Hide entire model
|
|
684
|
-
posts Post[]
|
|
685
|
-
}
|
|
686
|
-
```
|
|
687
|
-
|
|
688
|
-
</details>
|
|
689
|
-
|
|
690
|
-
<details>
|
|
691
|
-
<summary><strong>π§ Create input strictness</strong></summary>
|
|
692
|
-
|
|
693
|
-
Control how Create-like inputs respect field exclusions.
|
|
694
|
-
|
|
695
|
-
- strictCreateInputs (boolean, default: true)
|
|
696
|
-
- true: Create-like inputs (CreateInput, UncheckedCreateInput, CreateMany*, CreateWithout*, CreateOrConnectWithout*, CreateNested*Without*) match Prisma exactly; exclusions do not apply.
|
|
697
|
-
- false: Apply exclusions to these Create-like inputs as well.
|
|
698
|
-
- preserveRequiredScalarsOnCreate (boolean, default: true)
|
|
699
|
-
- When strictCreateInputs is false, keep truly required scalar fields even if excluded. Set to false to omit them too (advanced use only).
|
|
700
|
-
|
|
701
|
-
Type parity with filtered Create inputs:
|
|
702
|
-
- When exclusions apply to Create-like inputs, the typed export binds to Omit<Prisma.Type, 'excluded' | ...> so TypeScript matches the Zod shape.
|
|
703
|
-
|
|
704
|
-
JSON config example:
|
|
705
|
-
|
|
706
|
-
```json
|
|
707
|
-
{
|
|
708
|
-
"globalExclusions": { "input": ["password", "internalId"] },
|
|
709
|
-
"strictCreateInputs": false,
|
|
710
|
-
"preserveRequiredScalarsOnCreate": true
|
|
711
|
-
}
|
|
712
|
-
```
|
|
713
|
-
|
|
714
|
-
</details>
|
|
715
|
-
|
|
716
|
-
<details>
|
|
717
|
-
<summary><strong>π @zod Comment Annotations</strong></summary>
|
|
718
|
-
|
|
719
|
-
### Inline Validation Rules
|
|
720
|
-
|
|
721
|
-
Add validation directly in your Prisma schema:
|
|
722
|
-
|
|
723
|
-
```prisma
|
|
724
|
-
model User {
|
|
725
|
-
id Int @id @default(autoincrement())
|
|
726
|
-
email String @unique /// @zod.email()
|
|
727
|
-
name String? /// @zod.min(2).max(50)
|
|
728
|
-
age Int? /// @zod.min(0).max(120)
|
|
729
|
-
username String @unique /// @zod.regex(/^[a-zA-Z0-9_]+$/)
|
|
730
|
-
website String? /// @zod.url().optional()
|
|
731
|
-
}
|
|
732
|
-
```
|
|
733
|
-
|
|
734
|
-
Generated schema with validations:
|
|
735
|
-
|
|
736
|
-
```typescript
|
|
737
|
-
export const UserCreateInputSchema = z.object({
|
|
738
|
-
email: z.string().email(),
|
|
739
|
-
name: z.string().min(2).max(50).optional(),
|
|
740
|
-
age: z.number().int().min(0).max(120).optional(),
|
|
741
|
-
username: z.string().regex(/^[a-zA-Z0-9_]+$/),
|
|
742
|
-
website: z.string().url().optional()
|
|
743
|
-
});
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
### Supported @zod Annotations
|
|
747
|
-
|
|
748
|
-
```prisma
|
|
749
|
-
// String validations
|
|
750
|
-
field String /// @zod.email()
|
|
751
|
-
field String /// @zod.url()
|
|
752
|
-
field String /// @zod.regex(/pattern/)
|
|
753
|
-
field String /// @zod.min(2).max(50)
|
|
754
|
-
|
|
755
|
-
// Number validations
|
|
756
|
-
field Int /// @zod.min(0).max(100)
|
|
757
|
-
field Float /// @zod.positive()
|
|
758
|
-
|
|
759
|
-
// Custom validations
|
|
760
|
-
field String /// @zod.custom(z.string().transform(s => s.toLowerCase()))
|
|
39
|
+
# yarn
|
|
40
|
+
yarn add -D prisma-zod-generator zod
|
|
761
41
|
```
|
|
762
|
-
|
|
763
|
-
</details>
|
|
764
|
-
|
|
765
|
-
<details>
|
|
766
|
-
<summary><strong>ποΈ Multi-Database Provider Support</strong></summary>
|
|
767
|
-
|
|
768
|
-
### Database-Specific Optimizations
|
|
769
|
-
|
|
770
|
-
```typescript
|
|
771
|
-
// PostgreSQL - Advanced types supported
|
|
772
|
-
const pgUser = z.object({
|
|
773
|
-
id: z.number().int(),
|
|
774
|
-
metadata: z.record(z.unknown()), // JSON type
|
|
775
|
-
tags: z.array(z.string()), // Array type
|
|
776
|
-
balance: z.number() // Decimal type
|
|
777
|
-
});
|
|
778
|
-
|
|
779
|
-
// MongoDB - Document structure
|
|
780
|
-
const mongoUser = z.object({
|
|
781
|
-
id: z.string(), // ObjectId as string
|
|
782
|
-
embedded: z.object({ // Embedded documents
|
|
783
|
-
profile: z.object({
|
|
784
|
-
bio: z.string().optional()
|
|
785
|
-
})
|
|
786
|
-
}).optional()
|
|
787
|
-
});
|
|
788
|
-
|
|
789
|
-
// MySQL - Optimized for relational data
|
|
790
|
-
const mysqlUser = z.object({
|
|
791
|
-
id: z.number().int(),
|
|
792
|
-
createdAt: z.date(),
|
|
793
|
-
updatedAt: z.date()
|
|
794
|
-
});
|
|
795
|
-
```
|
|
796
|
-
|
|
797
|
-
### Supported Providers
|
|
798
|
-
|
|
799
|
-
- **PostgreSQL** - Full advanced type support
|
|
800
|
-
- **MySQL** - Complete compatibility
|
|
801
|
-
- **MongoDB** - Native document schemas
|
|
802
|
-
- **SQLite** - Development & testing optimized
|
|
803
|
-
- **SQL Server** - Enterprise features
|
|
804
|
-
- **CockroachDB** - Distributed database support
|
|
805
|
-
|
|
806
|
-
</details>
|
|
807
|
-
|
|
808
|
-
<details>
|
|
809
|
-
<summary><strong>π§ ESM Import Handling</strong></summary>
|
|
810
|
-
|
|
811
|
-
### Modern ES Module Support
|
|
812
|
-
|
|
813
|
-
Full ESM compatibility with automatic file extension handling:
|
|
814
|
-
|
|
815
|
-
```prisma
|
|
816
|
-
generator client {
|
|
817
|
-
provider = "prisma-client"
|
|
818
|
-
output = "./src/generated/client"
|
|
819
|
-
moduleFormat = "esm"
|
|
820
|
-
importFileExtension = "js" # Auto-handled
|
|
821
|
-
}
|
|
822
|
-
```
|
|
823
|
-
|
|
824
|
-
Generated imports include proper extensions:
|
|
825
|
-
|
|
826
|
-
```typescript
|
|
827
|
-
import { User } from '../client/index.js'; // Auto-generated
|
|
828
|
-
import { z } from 'zod';
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
### Import Configuration
|
|
832
|
-
|
|
833
|
-
```json
|
|
834
|
-
{
|
|
835
|
-
"esm": {
|
|
836
|
-
"enabled": true,
|
|
837
|
-
"fileExtension": ".js",
|
|
838
|
-
"importExtension": ".js"
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
</details>
|
|
844
|
-
|
|
845
|
-
<details>
|
|
846
|
-
<summary><strong>β‘ Performance Optimization</strong></summary>
|
|
847
|
-
|
|
848
|
-
### Built-in Optimizations
|
|
849
|
-
|
|
850
|
-
```typescript
|
|
851
|
-
// Lazy loading for circular references
|
|
852
|
-
const UserSchema = z.lazy(() => z.object({
|
|
853
|
-
id: z.number().int(),
|
|
854
|
-
posts: z.array(PostSchema).optional()
|
|
855
|
-
}));
|
|
856
|
-
|
|
857
|
-
// Selective generation
|
|
858
|
-
const config = {
|
|
859
|
-
models: {
|
|
860
|
-
AuditLog: { enabled: false }, // Skip audit tables
|
|
861
|
-
Migration: { enabled: false }, // Skip migration tables
|
|
862
|
-
User: {
|
|
863
|
-
enabled: true,
|
|
864
|
-
operations: ["findMany", "create", "update"] // Only needed operations
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
};
|
|
868
|
-
```
|
|
869
|
-
|
|
870
|
-
### Performance Tips
|
|
871
|
-
|
|
872
|
-
- Use `minimal` mode for faster generation
|
|
873
|
-
- Exclude unused models and operations
|
|
874
|
-
- Enable lazy loading for complex relationships
|
|
875
|
-
- Cache generated schemas in production
|
|
876
|
-
|
|
877
|
-
</details>
|
|
878
|
-
|
|
879
|
-
<details>
|
|
880
|
-
<summary><strong>π API Security & Validation Patterns</strong></summary>
|
|
881
|
-
|
|
882
|
-
### Input Sanitization
|
|
883
|
-
|
|
884
|
-
```typescript
|
|
885
|
-
export const sanitizeUserInput = (data: unknown) => {
|
|
886
|
-
return UserCreateInputSchema
|
|
887
|
-
.omit({ id: true }) // Remove ID from input
|
|
888
|
-
.extend({
|
|
889
|
-
email: z.string().email().toLowerCase() // Normalize email
|
|
890
|
-
})
|
|
891
|
-
.parse(data);
|
|
892
|
-
};
|
|
893
|
-
```
|
|
894
|
-
|
|
895
|
-
### Role-Based Field Filtering
|
|
896
|
-
|
|
897
|
-
```typescript
|
|
898
|
-
export const getUserForRole = (user: User, role: 'admin' | 'user') => {
|
|
899
|
-
const baseSchema = UserResultSchema;
|
|
900
|
-
|
|
901
|
-
if (role === 'user') {
|
|
902
|
-
return baseSchema.omit({
|
|
903
|
-
email: true,
|
|
904
|
-
role: true,
|
|
905
|
-
permissions: true
|
|
906
|
-
}).parse(user);
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
return baseSchema.parse(user);
|
|
910
|
-
};
|
|
911
|
-
```
|
|
912
|
-
|
|
913
|
-
### Complete API Endpoint Validation
|
|
914
|
-
|
|
915
|
-
```typescript
|
|
916
|
-
app.post('/users', async (req, res) => {
|
|
917
|
-
try {
|
|
918
|
-
const userData = UserCreateInputSchema.parse(req.body);
|
|
919
|
-
const user = await prisma.user.create({ data: userData });
|
|
920
|
-
const response = UserResultSchema.parse(user);
|
|
921
|
-
res.json(response);
|
|
922
|
-
} catch (error) {
|
|
923
|
-
if (error instanceof z.ZodError) {
|
|
924
|
-
return res.status(400).json({
|
|
925
|
-
errors: error.errors.map(e => ({
|
|
926
|
-
field: e.path.join('.'),
|
|
927
|
-
message: e.message
|
|
928
|
-
}))
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
});
|
|
933
|
-
```
|
|
934
|
-
|
|
935
|
-
</details>
|
|
936
|
-
|
|
937
|
-
---
|
|
938
|
-
|
|
939
|
-
## βοΈ Configuration
|
|
940
|
-
|
|
941
|
-
<details>
|
|
942
|
-
<summary><strong>π§ Configuration Options</strong></summary>
|
|
943
|
-
|
|
944
|
-
> Looking for a complete, exhaustively documented list of every flag? See **[Full Configuration Reference](./CONFIG_REFERENCE.md)**.
|
|
945
|
-
|
|
946
|
-
### Basic Configuration
|
|
947
|
-
|
|
948
|
-
| Option | Description | Type | Default |
|
|
949
|
-
|--------|-------------|------|---------|
|
|
950
|
-
| `output` | Output directory for generated files | `string` | `"./generated"` |
|
|
951
|
-
| `isGenerateSelect` | Generate Select-related schemas | `boolean` | `false` |
|
|
952
|
-
| `isGenerateInclude` | Generate Include-related schemas | `boolean` | `false` |
|
|
953
|
-
| `exportTypedSchemas` | Export z.ZodType versions (type-safe) | `boolean` | `true` |
|
|
954
|
-
| `exportZodSchemas` | Export pure Zod versions (method-friendly) | `boolean` | `true` |
|
|
955
|
-
| `typedSchemaSuffix` | Suffix for typed schemas | `string` | `"Schema"` |
|
|
956
|
-
| `zodSchemaSuffix` | Suffix for Zod schemas | `string` | `"ZodSchema"` |
|
|
957
|
-
| `useMultipleFiles` | Output multiple files (true) or single bundle (false) | `boolean` | `true` |
|
|
958
|
-
| `singleFileName` | Name of the single-file bundle when `useMultipleFiles=false` | `string` | `"schemas.ts"` |
|
|
959
|
-
| `placeSingleFileAtRoot` | When `useMultipleFiles=false`, place the single file at the generator output root instead of a `schemas/` subfolder | `boolean` | `true` |
|
|
960
|
-
| `pureModels` | Emit plain model object schemas (no operation args wiring) | `boolean` | `false` (implicitly true in minimal mode) |
|
|
961
|
-
| `pureModelsLean` | When pure models are enabled, omit JSDoc/statistics & field doc blocks for minimal output | `boolean` | `true` |
|
|
962
|
-
| `pureModelsIncludeRelations` | When pureModels are enabled, include relation fields (lazy refs). Default excludes relations for slimmer objects | `boolean` | `false` |
|
|
963
|
-
| `dateTimeStrategy` | Mapping for Prisma `DateTime` ("date" | "coerce" | "isoString") | `string` | `"date"` |
|
|
964
|
-
| `emit.enums` | Explicitly emit enum schemas | `boolean` | `true` |
|
|
965
|
-
| `emit.objects` | Emit input/object schemas (`objects/`) | `boolean` | `true` |
|
|
966
|
-
| `emit.crud` | Emit CRUD operation arg schemas | `boolean` | `true` |
|
|
967
|
-
| `emit.results` | Emit result schemas (`results/`) | `boolean` | heuristic (off in minimal) |
|
|
968
|
-
| `emit.pureModels` | Emit pure model schemas (overrides heuristics) | `boolean` | mirrors `pureModels` |
|
|
969
|
-
| `emit.variants` | Emit variant wrapper/index | `boolean` | `true` if any variant enabled |
|
|
970
|
-
| `naming.pureModel.filePattern` | Pure model file name pattern (tokens) | `string` | `{Model}.schema.ts` |
|
|
971
|
-
| `naming.pureModel.schemaSuffix` | Suffix for schema const | `string` | `Schema` |
|
|
972
|
-
| `naming.pureModel.typeSuffix` | Suffix for inferred type export | `string` | `Type` |
|
|
973
|
-
| `naming.pureModel.exportNamePattern` | Pattern for schema export variable | `string` | `{Model}{SchemaSuffix}` |
|
|
974
|
-
| `naming.preset` | Apply preset naming (see below) | `string` | `default` |
|
|
975
|
-
|
|
976
|
-
### Advanced Configuration
|
|
977
|
-
|
|
978
|
-
```prisma
|
|
979
|
-
generator zod {
|
|
980
|
-
provider = "prisma-zod-generator"
|
|
981
|
-
output = "./src/schemas"
|
|
982
|
-
// File output mode
|
|
983
|
-
// true -> multiple files (default)
|
|
984
|
-
// false -> single file bundle (see singleFileName below)
|
|
985
|
-
useMultipleFiles = true
|
|
986
|
-
// Optional: name of the single-file bundle when useMultipleFiles = false
|
|
987
|
-
// Defaults to "schemas.ts"
|
|
988
|
-
singleFileName = "schemas.ts"
|
|
989
|
-
// Optional: when useMultipleFiles = false, place the single file at the
|
|
990
|
-
// generator output root (true) or inside a schemas/ subdir (false)
|
|
991
|
-
placeSingleFileAtRoot = true
|
|
992
|
-
isGenerateSelect = true
|
|
993
|
-
isGenerateInclude = true
|
|
994
|
-
// Pure model + DateTime handling examples
|
|
995
|
-
pureModels = true // enable pure model schemas (can also go in JSON)
|
|
996
|
-
pureModelsLean = true // default: lean (no doc banners)
|
|
997
|
-
pureModelsIncludeRelations = true // opt-in to emit relation fields (default false)
|
|
998
|
-
dateTimeStrategy = "coerce" // accept strings/numbers, coerce to Date
|
|
999
|
-
// Explicit emission overrides:
|
|
1000
|
-
// Example zod-generator.config.json:
|
|
1001
|
-
// {
|
|
1002
|
-
// "emit": {
|
|
1003
|
-
// "enums": true,
|
|
1004
|
-
// "objects": false,
|
|
1005
|
-
// "crud": false,
|
|
1006
|
-
// "results": false,
|
|
1007
|
-
// "pureModels": true,
|
|
1008
|
-
// "variants": true
|
|
1009
|
-
// }
|
|
1010
|
-
// }
|
|
1011
|
-
// Omit any key to fall back to legacy heuristics (e.g. minimal mode pruning).
|
|
1012
|
-
config = "./zod-config.json"
|
|
1013
|
-
}
|
|
1014
|
-
```
|
|
1015
|
-
|
|
1016
|
-
### Model Customizations
|
|
1017
|
-
|
|
1018
|
-
```prisma
|
|
1019
|
-
/// @@Gen.model(hide: true)
|
|
1020
|
-
model InternalLog {
|
|
1021
|
-
id Int @id @default(autoincrement())
|
|
1022
|
-
message String
|
|
1023
|
-
createdAt DateTime @default(now())
|
|
1024
|
-
}
|
|
1025
|
-
```
|
|
1026
|
-
|
|
1027
|
-
### JSON Configuration File
|
|
1028
|
-
|
|
1029
|
-
```json
|
|
1030
|
-
{
|
|
1031
|
-
"mode": "custom",
|
|
1032
|
-
"output": "./generated/schemas",
|
|
1033
|
-
"relationModel": true,
|
|
1034
|
-
"modelCase": "PascalCase",
|
|
1035
|
-
"modelSuffix": "Schema",
|
|
1036
|
-
"useMultipleFiles": true,
|
|
1037
|
-
"placeSingleFileAtRoot": true,
|
|
1038
|
-
"createInputTypes": true,
|
|
1039
|
-
"addIncludeType": true,
|
|
1040
|
-
"addSelectType": true,
|
|
1041
|
-
"validateWhereUniqueInput": true,
|
|
1042
|
-
"prismaClientPath": "@prisma/client"
|
|
1043
|
-
// Explicit emission
|
|
1044
|
-
// "emit": { "crud": false, "objects": false, "results": false, "variants": true, "enums": true }
|
|
1045
|
-
}
|
|
1046
|
-
```
|
|
1047
|
-
|
|
1048
|
-
### Naming Customization
|
|
1049
|
-
|
|
1050
|
-
Configure pure model naming:
|
|
1051
|
-
|
|
1052
|
-
```json
|
|
1053
|
-
{
|
|
1054
|
-
"pureModels": true,
|
|
1055
|
-
"naming": {
|
|
1056
|
-
"pureModel": {
|
|
1057
|
-
"filePattern": "{model}.zod.ts",
|
|
1058
|
-
"schemaSuffix": "Zod",
|
|
1059
|
-
"typeSuffix": "Shape",
|
|
1060
|
-
"exportNamePattern": "{Model}{SchemaSuffix}",
|
|
1061
|
-
"legacyAliases": false
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
```
|
|
1066
|
-
|
|
1067
|
-
Tokens:
|
|
1068
|
-
- `{Model}` PascalCase model name
|
|
1069
|
-
- `{model}` / `{camel}` camelCase
|
|
1070
|
-
- `{kebab}` kebab-case
|
|
1071
|
-
- `{SchemaSuffix}` / `{TypeSuffix}` resolved suffix values
|
|
1072
|
-
|
|
1073
|
-
Presets:
|
|
1074
|
-
- `zod-prisma` β keeps `ModelSchema`, adds legacy alias
|
|
1075
|
-
- `zod-prisma-types` β primary export without suffix + legacy alias
|
|
1076
|
-
- `legacy-model-suffix` β reintroduces `.model.ts` + `Model` suffix
|
|
1077
|
-
|
|
1078
|
-
Override any field after applying a preset.
|
|
1079
|
-
|
|
1080
|
-
Detailed preset behavior:
|
|
1081
|
-
|
|
1082
|
-
| Preset | File Pattern | Primary Const Export | Inferred Type Export | Legacy Aliases Emitted | Intended Use Case |
|
|
1083
|
-
|--------|--------------|----------------------|----------------------|------------------------|-------------------|
|
|
1084
|
-
| default | `{Model}.schema.ts` | `UserSchema` | `UserType` | No | Current builtβin style (no config needed) |
|
|
1085
|
-
| zod-prisma | `{Model}.schema.ts` | `UserSchema` | `UserType` | Yes (`UserModel`, `UserType`) | Migrate from prior community libs that used `ModelSchema` but also relied on `UserModel` name |
|
|
1086
|
-
| zod-prisma-types | `{Model}.schema.ts` | `User` | `User` (no suffix) | Yes (`UserSchema`, `UserType`) | Emulate style where primary export is unsuffixed but compatibility aliases are needed |
|
|
1087
|
-
| legacy-model-suffix | `{Model}.model.ts` | `UserModel` | `UserModelType` | No | Restore historical `.model.ts` file naming with `Model` suffix |
|
|
1088
|
-
|
|
1089
|
-
Examples:
|
|
1090
|
-
|
|
1091
|
-
```jsonc
|
|
1092
|
-
// zod-prisma
|
|
1093
|
-
{
|
|
1094
|
-
"pureModels": true,
|
|
1095
|
-
"naming": { "preset": "zod-prisma" }
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
// zod-prisma-types (empty suffix primary export + aliases)
|
|
1099
|
-
{
|
|
1100
|
-
"pureModels": true,
|
|
1101
|
-
"naming": { "preset": "zod-prisma-types" }
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
// legacy-model-suffix (.model.ts files + Model suffix, no aliases)
|
|
1105
|
-
{
|
|
1106
|
-
"pureModels": true,
|
|
1107
|
-
"naming": { "preset": "legacy-model-suffix" }
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
// Start from a preset then override just the file pattern
|
|
1111
|
-
{
|
|
1112
|
-
"pureModels": true,
|
|
1113
|
-
"naming": {
|
|
1114
|
-
"preset": "zod-prisma",
|
|
1115
|
-
"pureModel": { "filePattern": "{Model}.validation.ts" }
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
```
|
|
1119
|
-
|
|
1120
|
-
Override precedence notes:
|
|
1121
|
-
1. A `preset` seeds base values.
|
|
1122
|
-
2. Keys under `naming.pureModel` override only the ones you specify (others inherit from the preset).
|
|
1123
|
-
3. Leaving `pureModel` empty ( `{}` ) ensures the preset is applied untouched (this is what the generator defaults to internally).
|
|
1124
|
-
|
|
1125
|
-
Migration tips:
|
|
1126
|
-
- Coming from `.model.ts` style: set `preset` to `legacy-model-suffix` (no further changes needed).
|
|
1127
|
-
- Want to gradually adopt suffixless exports but keep old names available: use `zod-prisma-types` first; remove aliases later by disabling `legacyAliases`.
|
|
1128
|
-
- Need a custom pattern: supply `filePattern` (must end with `.ts`) and adjust `exportNamePattern` plus suffixes.
|
|
1129
|
-
|
|
1130
|
-
Validation rules:
|
|
1131
|
-
- `filePattern` must contain `{Model}` (or another token that yields a unique name) and end with `.ts`.
|
|
1132
|
-
- Empty `schemaSuffix` or `typeSuffix` is allowed; set explicit empty string `""` to clear the default.
|
|
1133
|
-
- Avoid producing duplicate file names after token replacement; the generator will overwrite silently if collisions occur.
|
|
1134
|
-
|
|
1135
|
-
#### DateTime Strategy Examples
|
|
1136
|
-
|
|
1137
|
-
Choose how Prisma `DateTime` fields are represented at validation boundaries:
|
|
1138
|
-
|
|
1139
|
-
```jsonc
|
|
1140
|
-
{ "dateTimeStrategy": "date" } // -> z.date() (default)
|
|
1141
|
-
{ "dateTimeStrategy": "coerce" } // -> z.coerce.date() (flexible input)
|
|
1142
|
-
{ "dateTimeStrategy": "isoString" } // -> z.string().regex(ISO).transform(v => new Date(v))
|
|
1143
|
-
```
|
|
1144
|
-
|
|
1145
|
-
#### pureModelsLean
|
|
1146
|
-
|
|
1147
|
-
When `pureModels` are enabled, the default `pureModelsLean: true` suppresses large JSDoc header banners, schema statistics, and field documentation comments for ultra-small output. Set `pureModelsLean: false` to restore verbose docs:
|
|
1148
|
-
|
|
1149
|
-
```jsonc
|
|
1150
|
-
{
|
|
1151
|
-
"pureModels": true,
|
|
1152
|
-
"pureModelsLean": false
|
|
1153
|
-
}
|
|
1154
|
-
```
|
|
1155
|
-
|
|
1156
|
-
Provides parity with popular βleanβ generators while still allowing an opt-in to rich docs for teams that want them.
|
|
1157
|
-
|
|
1158
|
-
</details>
|
|
1159
|
-
|
|
1160
|
-
---
|
|
1161
|
-
|
|
1162
|
-
## π API Reference
|
|
1163
|
-
|
|
1164
|
-
## βοΈ Configuration sources, precedence, and availability
|
|
1165
|
-
|
|
1166
|
-
This generator accepts configuration from two sources. When the same option is provided in multiple places, the value is resolved using a simple precedence.
|
|
1167
|
-
|
|
1168
|
-
### Sources
|
|
1169
|
-
|
|
1170
|
-
- Prisma generator block (schema.prisma)
|
|
1171
|
-
- Standard Prisma fields like `output`.
|
|
1172
|
-
- Simple override flags/strings (e.g., `useMultipleFiles`, `singleFileName`, etc.).
|
|
1173
|
-
- Optional `config = "./zod-generator.config.json"` to point to a JSON file.
|
|
1174
|
-
- JSON config file (recommended for complex/nested settings)
|
|
1175
|
-
- Full configuration surface, including nested structures like `models` and `variants`.
|
|
1176
|
-
- Can be provided explicitly via `config = "./path.json"` or auto-discovered (e.g., `zod-generator.config.json`, `.zod-generator.json`).
|
|
1177
|
-
|
|
1178
|
-
### Precedence (highest β lowest)
|
|
1179
|
-
|
|
1180
|
-
1) Prisma generator block options (direct attributes in `generator zod { ... }`)
|
|
1181
|
-
2) JSON config file (explicit or auto-discovered)
|
|
1182
|
-
3) Built-in defaults (computed based on `mode`, etc.)
|
|
1183
|
-
|
|
1184
|
-
Notes and special cases:
|
|
1185
|
-
- Output path: The Prisma generatorβs `output` always decides where files go. Any `output` set in the JSON config is ignored.
|
|
1186
|
-
- File layout: The Prisma generatorβs `useMultipleFiles` and `singleFileName` override the JSON. Keep them aligned with any recipe you copy.
|
|
1187
|
-
- Minimal mode: If `mode = "minimal"` (or legacy `minimal = true`), select/include schemas are forcibly disabled and many complex nested inputs are suppressed to speed up generation and shrink output.
|
|
1188
|
-
- Legacy flags: `isGenerateSelect` / `isGenerateInclude` (Prisma block) override the newer `addSelectType` / `addIncludeType` (config JSON). Minimal mode will still force them off.
|
|
1189
|
-
|
|
1190
|
-
Visibility of conflicts and overrides:
|
|
1191
|
-
- Critical cases (e.g., file layout conflicts; minimal mode overriding select/include) are surfaced as tagged info lines prefixed with `[prisma-zod-generator]`.
|
|
1192
|
-
- Detailed context and tips are printed only when debug logging is enabled.
|
|
1193
|
-
|
|
1194
|
-
### Option availability matrix
|
|
1195
|
-
|
|
1196
|
-
| Option | Prisma generator block | JSON config file | Notes |
|
|
1197
|
-
|---|---|---|---|
|
|
1198
|
-
| `output` | Yes (authoritative) | Ignored if present | Use the Prisma generator `output` only |
|
|
1199
|
-
| `useMultipleFiles` | Yes | Yes | `false` enables strict single-file mode |
|
|
1200
|
-
| `singleFileName` | Yes | Yes | File name for the single bundle (default `schemas.ts`) |
|
|
1201
|
-
| `placeSingleFileAtRoot` | Yes | Yes | Place single file at output root (true, default) or under `schemas/` (false) |
|
|
1202
|
-
| `placeArrayVariantsAtRoot` | Yes | Yes | For array-based variants placement (root vs `variants/`) |
|
|
1203
|
-
| `mode` (`full|minimal|custom`) | Yes | Yes | Minimal mode applies opinionated defaults |
|
|
1204
|
-
| `pureModels` | Yes | Yes | Generates `models/` set when multi-file; N/A in single-file (content is bundled) |
|
|
1205
|
-
| `globalExclusions` | β | Yes | Object keyed by variant (`input`, `result`, `pure`) |
|
|
1206
|
-
| `variants` (object-based) | β | Yes | Nested structure; configure `pure/input/result` |
|
|
1207
|
-
| `models.*` (per-model) | β | Yes | Nested per-model rules, operations, and variant overrides |
|
|
1208
|
-
| `addSelectType` / `addIncludeType` | Yes (as legacy `isGenerateSelect` / `isGenerateInclude`) | Yes | Prisma block flags override the JSON values; minimal mode forces off |
|
|
1209
|
-
| `formatGeneratedSchemas` | β | Yes | Formatting can be skipped for speed (default: false) |
|
|
1210
|
-
| `config` (path to JSON) | Yes | β | Points to the JSON file; not a config value itself |
|
|
1211
|
-
|
|
1212
|
-
Example: Prisma block overrides JSON file
|
|
1213
|
-
|
|
1214
|
-
```prisma
|
|
1215
|
-
generator zod {
|
|
1216
|
-
provider = "prisma-zod-generator"
|
|
1217
|
-
output = "./generated"
|
|
1218
|
-
// Overrides values from the JSON config below
|
|
1219
|
-
useMultipleFiles = false
|
|
1220
|
-
singleFileName = "bundle.ts"
|
|
1221
|
-
placeSingleFileAtRoot = true
|
|
1222
|
-
// Load additional (nested) settings from a JSON file
|
|
1223
|
-
config = "./zod-generator.config.json"
|
|
1224
|
-
}
|
|
1225
|
-
```
|
|
1226
|
-
|
|
1227
|
-
When both sources specify the same simple option (e.g., `useMultipleFiles`), the Prisma block wins. Nested settings (like `models` and `variants`) should live in the JSON file.
|
|
1228
|
-
|
|
1229
|
-
Tip when using recipes: If you want models-only (multi-file) but your generator block still has `useMultipleFiles = false` from a previous setup, you'll see extra files or a bundle you didn't expect. Open the matching recipe folder under `recipes/<name>/` and copy the generator block from its `schema.prisma`.
|
|
1230
|
-
|
|
1231
|
-
### How @zod schema comments fit into precedence
|
|
1232
|
-
|
|
1233
|
-
Inline `@zod` comments in your Prisma schema are not a separate βconfig source,β but they do affect field-level validation and are always respected when that field is generated.
|
|
1234
|
-
|
|
1235
|
-
- Scope: Applies only to the field where the comment appears, and only in schemas that include that field (subject to filtering, variants, minimal mode).
|
|
1236
|
-
- Merge behavior: Field validation is built by combining pieces. In practice, the chain is composed of the base Zod type plus any optional/nullable handling, any config-driven validations (e.g., variant `additionalValidation`), and your `@zod` comment directives. If multiple validations of the same kind are present, theyβre appended in order; the latter call wins when thereβs a conflict.
|
|
1237
|
-
- Not a global override: `@zod` comments do not override global settings like `output`, `mode`, or file layout; they only enrich the fieldβs Zod chain.
|
|
1238
|
-
- Filtering/minimal mode: If a field or schema is excluded by filters/variants/minimal mode, its comments simply wonβt apply because that schema isnβt emitted.
|
|
1239
|
-
|
|
1240
|
-
See the β@zod Comment Annotationsβ section for syntax and examples.
|
|
1241
|
-
|
|
1242
|
-
<details>
|
|
1243
|
-
<summary><strong>π Generated Schema Types</strong></summary>
|
|
1244
|
-
|
|
1245
|
-
### Operation Schemas
|
|
1246
|
-
|
|
1247
|
-
- **Create Operations**: `ModelCreateOneSchema`, `ModelCreateManySchema`
|
|
1248
|
-
- **Read Operations**: `ModelFindManySchema`, `ModelFindUniqueSchema`, `ModelFindFirstSchema`
|
|
1249
|
-
- **Update Operations**: `ModelUpdateOneSchema`, `ModelUpdateManySchema`, `ModelUpsertSchema`
|
|
1250
|
-
- **Delete Operations**: `ModelDeleteOneSchema`, `ModelDeleteManySchema`
|
|
1251
|
-
- **Aggregate Operations**: `ModelAggregateSchema`, `ModelGroupBySchema`
|
|
1252
|
-
|
|
1253
|
-
### Input Object Schemas
|
|
1254
|
-
|
|
1255
|
-
- **Create Inputs**: `ModelCreateInputObjectSchema`, `ModelCreateNestedInputObjectSchema`
|
|
1256
|
-
- **Update Inputs**: `ModelUpdateInputObjectSchema`, `ModelUpdateNestedInputObjectSchema`
|
|
1257
|
-
- **Where Inputs**: `ModelWhereInputObjectSchema`, `ModelWhereUniqueInputObjectSchema`
|
|
1258
|
-
- **Order Inputs**: `ModelOrderByInputObjectSchema`
|
|
1259
|
-
|
|
1260
|
-
### Select & Include Schemas
|
|
1261
|
-
|
|
1262
|
-
When enabled with `isGenerateSelect: true` and `isGenerateInclude: true`:
|
|
1263
|
-
- **Select Schemas**: `ModelSelectObjectSchema`
|
|
1264
|
-
- **Include Schemas**: `ModelIncludeObjectSchema`
|
|
1265
|
-
|
|
1266
|
-
### Schema Naming Convention
|
|
1267
|
-
|
|
1268
|
-
All generated schemas follow this pattern:
|
|
1269
|
-
```
|
|
1270
|
-
{ModelName}{Operation}{Type}Schema
|
|
1271
|
-
```
|
|
1272
|
-
|
|
1273
|
-
Examples:
|
|
1274
|
-
- `UserCreateOneSchema` - Schema for creating a single user
|
|
1275
|
-
- `PostFindManyArgsSchema` - Schema for finding multiple posts with arguments
|
|
1276
|
-
- `UserWhereInputObjectSchema` - Schema for user where conditions
|
|
1277
|
-
|
|
1278
|
-
</details>
|
|
1279
|
-
|
|
1280
|
-
---
|
|
1281
|
-
|
|
1282
|
-
## π Framework Examples
|
|
1283
|
-
|
|
1284
|
-
<details>
|
|
1285
|
-
<summary><strong>π Next.js Integration</strong></summary>
|
|
1286
|
-
|
|
1287
|
-
### API Routes
|
|
1288
|
-
|
|
1289
|
-
```typescript
|
|
1290
|
-
// pages/api/users.ts
|
|
1291
|
-
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
1292
|
-
import { UserCreateOneSchema } from '../../generated/schemas';
|
|
1293
|
-
|
|
1294
|
-
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
1295
|
-
if (req.method === 'POST') {
|
|
1296
|
-
try {
|
|
1297
|
-
const userData = UserCreateOneSchema.parse(req.body);
|
|
1298
|
-
const user = await prisma.user.create(userData);
|
|
1299
|
-
res.status(201).json(user);
|
|
1300
|
-
} catch (error) {
|
|
1301
|
-
res.status(400).json({ error: error.message });
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
```
|
|
1306
|
-
|
|
1307
|
-
### App Router (Next.js 13+)
|
|
1308
|
-
|
|
1309
|
-
```typescript
|
|
1310
|
-
// app/api/users/route.ts
|
|
1311
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
1312
|
-
import { UserCreateOneSchema } from '@/generated/schemas';
|
|
1313
|
-
|
|
1314
|
-
export async function POST(request: NextRequest) {
|
|
1315
|
-
try {
|
|
1316
|
-
const body = await request.json();
|
|
1317
|
-
const userData = UserCreateOneSchema.parse(body);
|
|
1318
|
-
const user = await prisma.user.create(userData);
|
|
1319
|
-
return NextResponse.json(user);
|
|
1320
|
-
} catch (error) {
|
|
1321
|
-
return NextResponse.json({ error: error.message }, { status: 400 });
|
|
1322
|
-
}
|
|
1323
|
-
}
|
|
1324
|
-
```
|
|
1325
|
-
|
|
1326
|
-
</details>
|
|
1327
|
-
|
|
1328
|
-
<details>
|
|
1329
|
-
<summary><strong>β‘ tRPC Integration</strong></summary>
|
|
1330
|
-
|
|
1331
|
-
```typescript
|
|
1332
|
-
import { z } from 'zod';
|
|
1333
|
-
import { PostCreateOneSchema, PostFindManySchema } from './generated/schemas';
|
|
1334
|
-
|
|
1335
|
-
export const postRouter = router({
|
|
1336
|
-
create: publicProcedure
|
|
1337
|
-
.input(PostCreateOneSchema)
|
|
1338
|
-
.mutation(({ input }) => {
|
|
1339
|
-
return prisma.post.create(input);
|
|
1340
|
-
}),
|
|
1341
|
-
|
|
1342
|
-
list: publicProcedure
|
|
1343
|
-
.input(PostFindManySchema)
|
|
1344
|
-
.query(({ input }) => {
|
|
1345
|
-
return prisma.post.findMany(input);
|
|
1346
|
-
}),
|
|
1347
|
-
});
|
|
1348
|
-
```
|
|
1349
|
-
|
|
1350
|
-
</details>
|
|
1351
|
-
|
|
1352
|
-
<details>
|
|
1353
|
-
<summary><strong>π οΈ Fastify Integration</strong></summary>
|
|
1354
|
-
|
|
1355
|
-
```typescript
|
|
1356
|
-
import fastify from 'fastify';
|
|
1357
|
-
import { UserCreateOneSchema } from './generated/schemas';
|
|
1358
|
-
|
|
1359
|
-
const server = fastify();
|
|
1360
|
-
|
|
1361
|
-
server.post('/users', {
|
|
1362
|
-
schema: {
|
|
1363
|
-
body: UserCreateOneSchema
|
|
1364
|
-
}
|
|
1365
|
-
}, async (request, reply) => {
|
|
1366
|
-
const user = await prisma.user.create(request.body);
|
|
1367
|
-
return user;
|
|
1368
|
-
});
|
|
1369
|
-
```
|
|
1370
|
-
|
|
1371
|
-
</details>
|
|
1372
|
-
|
|
1373
|
-
<details>
|
|
1374
|
-
<summary><strong>π Express.js Integration</strong></summary>
|
|
1375
|
-
|
|
1376
|
-
```typescript
|
|
1377
|
-
import express from 'express';
|
|
1378
|
-
import { UserCreateOneSchema, UserFindManySchema } from './generated/schemas';
|
|
1379
|
-
|
|
1380
|
-
const app = express();
|
|
1381
|
-
|
|
1382
|
-
// Create user with validation
|
|
1383
|
-
app.post('/users', async (req, res) => {
|
|
1384
|
-
try {
|
|
1385
|
-
const data = UserCreateOneSchema.parse(req.body);
|
|
1386
|
-
const user = await prisma.user.create(data);
|
|
1387
|
-
res.json(user);
|
|
1388
|
-
} catch (error) {
|
|
1389
|
-
if (error instanceof z.ZodError) {
|
|
1390
|
-
return res.status(400).json({ errors: error.errors });
|
|
1391
|
-
}
|
|
1392
|
-
res.status(500).json({ error: 'Internal server error' });
|
|
1393
|
-
}
|
|
1394
|
-
});
|
|
1395
|
-
|
|
1396
|
-
// Query with validation
|
|
1397
|
-
app.get('/users', async (req, res) => {
|
|
1398
|
-
const query = UserFindManySchema.parse(req.query);
|
|
1399
|
-
const users = await prisma.user.findMany(query);
|
|
1400
|
-
res.json(users);
|
|
1401
|
-
});
|
|
1402
|
-
```
|
|
1403
|
-
|
|
1404
|
-
</details>
|
|
1405
|
-
|
|
1406
|
-
---
|
|
1407
|
-
|
|
1408
|
-
## π§ͺ Testing & Development
|
|
1409
|
-
|
|
1410
|
-
<details>
|
|
1411
|
-
<summary><strong>π¬ Testing Infrastructure</strong></summary>
|
|
1412
|
-
|
|
1413
|
-
### Test Suite Overview
|
|
1414
|
-
|
|
1415
|
-
We maintain **enterprise-grade testing standards** with comprehensive coverage:
|
|
1416
|
-
|
|
1417
|
-
#### π **Test Statistics**
|
|
1418
|
-
- **π 80+ Tests Passing** - Comprehensive validation across all features
|
|
1419
|
-
- **π 5,239 Schemas Validated** - Massive multi-provider testing
|
|
1420
|
-
- **β
100% TypeScript Compilation** - Zero compilation errors guaranteed
|
|
1421
|
-
- **π‘οΈ Zero ESLint Issues** - Clean, maintainable code quality
|
|
1422
|
-
|
|
1423
|
-
#### π **Test Categories**
|
|
1424
|
-
|
|
1425
42
|
```bash
|
|
1426
|
-
#
|
|
1427
|
-
|
|
1428
|
-
npm run test:esm # ESM import handling tests
|
|
1429
|
-
npm run test:comprehensive # Multi-provider schema validation
|
|
1430
|
-
|
|
1431
|
-
# Feature-specific tests
|
|
1432
|
-
npm run test:config # Configuration system validation
|
|
1433
|
-
npm run test:variants # Schema variant generation
|
|
1434
|
-
npm run test:filtering # Model/field filtering logic
|
|
1435
|
-
npm run test:pure-models # Pure model schema generation
|
|
1436
|
-
npm run test:result-schemas # Result schema validation
|
|
1437
|
-
npm run test:zod-comments # @zod comment parsing
|
|
1438
|
-
npm run test:field-exclusion # Field exclusion system
|
|
1439
|
-
|
|
1440
|
-
# Advanced testing
|
|
1441
|
-
npm run test:integration # Full generation pipeline tests
|
|
1442
|
-
npm run test:multi-provider # All database provider validation
|
|
1443
|
-
npm run test:performance # Schema generation performance
|
|
1444
|
-
npm run test:coverage # Code coverage analysis
|
|
1445
|
-
```
|
|
1446
|
-
|
|
1447
|
-
</details>
|
|
1448
|
-
|
|
1449
|
-
<details>
|
|
1450
|
-
<summary><strong>π§ͺ Testing Integration</strong></summary>
|
|
1451
|
-
|
|
1452
|
-
### Schema Testing Utilities
|
|
1453
|
-
|
|
1454
|
-
```typescript
|
|
1455
|
-
import { SchemaTestUtils } from './test-utils';
|
|
1456
|
-
|
|
1457
|
-
// Validate schema structure
|
|
1458
|
-
SchemaTestUtils.testValidData(UserCreateInputSchema, {
|
|
1459
|
-
email: 'test@example.com',
|
|
1460
|
-
name: 'Test User'
|
|
1461
|
-
});
|
|
1462
|
-
|
|
1463
|
-
// Test boundary conditions
|
|
1464
|
-
SchemaTestUtils.testBoundaryValues(UserCreateInputSchema, [
|
|
1465
|
-
{ value: { email: 'invalid-email' }, shouldPass: false },
|
|
1466
|
-
{ value: { name: 'x'.repeat(51) }, shouldPass: false },
|
|
1467
|
-
{ value: { name: 'Valid Name' }, shouldPass: true }
|
|
1468
|
-
]);
|
|
1469
|
-
|
|
1470
|
-
// Performance testing
|
|
1471
|
-
const performance = SchemaTestUtils.performanceTest(
|
|
1472
|
-
UserCreateInputSchema,
|
|
1473
|
-
validUserData,
|
|
1474
|
-
1000 // iterations
|
|
1475
|
-
);
|
|
1476
|
-
console.log(`Avg validation time: ${performance.avgTime}ms`);
|
|
43
|
+
# bun
|
|
44
|
+
bun add -d prisma-zod-generator zod
|
|
1477
45
|
```
|
|
1478
46
|
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
```bash
|
|
1482
|
-
# Clone and setup
|
|
1483
|
-
git clone https://github.com/your-username/prisma-zod-generator.git
|
|
1484
|
-
cd prisma-zod-generator
|
|
1485
|
-
npm install
|
|
1486
|
-
|
|
1487
|
-
# Development build
|
|
1488
|
-
npm run gen-example
|
|
1489
|
-
|
|
1490
|
-
# Run tests
|
|
1491
|
-
npm test
|
|
1492
|
-
|
|
1493
|
-
# Code quality
|
|
1494
|
-
npm run lint # Check and fix linting issues
|
|
1495
|
-
npm run format # Format code with Prettier
|
|
1496
|
-
```
|
|
1497
|
-
|
|
1498
|
-
</details>
|
|
1499
|
-
|
|
1500
|
-
<details>
|
|
1501
|
-
<summary><strong>π Multi-Database Provider Validation</strong></summary>
|
|
1502
|
-
|
|
1503
|
-
Our test suite validates schemas across **6 database providers**:
|
|
1504
|
-
|
|
1505
|
-
| Provider | Schemas Validated | Status |
|
|
1506
|
-
|----------|------------------|---------|
|
|
1507
|
-
| **PostgreSQL** | 1,020 schemas | β
|
|
|
1508
|
-
| **MySQL** | 1,326 schemas | β
|
|
|
1509
|
-
| **MongoDB** | 855 schemas | β
|
|
|
1510
|
-
| **SQLite** | 1,409 schemas | β
|
|
|
1511
|
-
| **SQL Server** | 622 schemas | β
|
|
|
1512
|
-
| **Default** | Additional schemas | β
|
|
|
1513
|
-
|
|
1514
|
-
</details>
|
|
1515
|
-
|
|
1516
|
-
---
|
|
1517
|
-
|
|
1518
|
-
## π Troubleshooting
|
|
1519
|
-
|
|
1520
|
-
<details>
|
|
1521
|
-
<summary><strong>π¨ Common Issues & Solutions</strong></summary>
|
|
1522
|
-
|
|
1523
|
-
### Generator Compatibility Errors
|
|
1524
|
-
|
|
1525
|
-
**Issue**: Cannot find compatible Prisma generator
|
|
1526
|
-
```bash
|
|
1527
|
-
Error: No compatible Prisma client generator found
|
|
1528
|
-
```
|
|
1529
|
-
|
|
1530
|
-
**Solution**: Ensure you have a supported generator in your schema:
|
|
47
|
+
**2. Add to schema.prisma**
|
|
1531
48
|
```prisma
|
|
1532
|
-
generator client {
|
|
1533
|
-
provider = "prisma-client-js" // or "prisma-client"
|
|
1534
|
-
}
|
|
1535
|
-
|
|
1536
49
|
generator zod {
|
|
1537
|
-
|
|
1538
|
-
output = "./generated/schemas"
|
|
1539
|
-
}
|
|
1540
|
-
```
|
|
1541
|
-
|
|
1542
|
-
### Module Resolution Errors
|
|
1543
|
-
|
|
1544
|
-
**Issue**: `Cannot find module './generated/schemas'`
|
|
1545
|
-
|
|
1546
|
-
**Solutions**:
|
|
1547
|
-
1. Run `npx prisma generate` after adding the generator
|
|
1548
|
-
2. Check that your output path is correct
|
|
1549
|
-
3. Verify the generator completed successfully
|
|
1550
|
-
|
|
1551
|
-
### TypeScript Compilation Errors
|
|
1552
|
-
|
|
1553
|
-
**Issue**: Generated schemas have TypeScript errors
|
|
1554
|
-
|
|
1555
|
-
**Solutions**:
|
|
1556
|
-
1. Enable strict mode in `tsconfig.json`:
|
|
1557
|
-
```json
|
|
1558
|
-
{
|
|
1559
|
-
"compilerOptions": {
|
|
1560
|
-
"strict": true,
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
```
|
|
1564
|
-
2. Update dependencies: `npm update prisma-zod-generator prisma zod`
|
|
1565
|
-
3. Clear build cache and regenerate
|
|
1566
|
-
|
|
1567
|
-
### Generation Performance Issues
|
|
1568
|
-
|
|
1569
|
-
**Issue**: Slow generation for large schemas
|
|
1570
|
-
|
|
1571
|
-
**Solutions**:
|
|
1572
|
-
1. Use minimal mode:
|
|
1573
|
-
```json
|
|
1574
|
-
{
|
|
1575
|
-
"mode": "minimal",
|
|
1576
|
-
"models": {
|
|
1577
|
-
"AuditLog": { "enabled": false },
|
|
1578
|
-
"Migration": { "enabled": false }
|
|
1579
|
-
}
|
|
50
|
+
provider = "prisma-zod-generator"
|
|
1580
51
|
}
|
|
1581
52
|
```
|
|
1582
|
-
2. Exclude unnecessary operations
|
|
1583
|
-
3. Enable selective model generation
|
|
1584
|
-
|
|
1585
|
-
</details>
|
|
1586
|
-
|
|
1587
|
-
<details>
|
|
1588
|
-
<summary><strong>π‘ Performance Optimization Tips</strong></summary>
|
|
1589
53
|
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
- Use selective generation with model hiding
|
|
1594
|
-
- Split schemas into multiple files
|
|
1595
|
-
- Implement lazy loading for schemas
|
|
1596
|
-
- Consider minimal mode for faster builds
|
|
1597
|
-
|
|
1598
|
-
### Build Time Optimization
|
|
1599
|
-
|
|
1600
|
-
```json
|
|
1601
|
-
{
|
|
1602
|
-
"mode": "minimal",
|
|
1603
|
-
"models": {
|
|
1604
|
-
"User": {
|
|
1605
|
-
"operations": ["findMany", "create", "update"]
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
54
|
+
**3. Generate**
|
|
55
|
+
```bash
|
|
56
|
+
npx prisma generate
|
|
1609
57
|
```
|
|
1610
58
|
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
// Environment-specific configuration
|
|
1615
|
-
const productionConfig = {
|
|
1616
|
-
mode: 'minimal',
|
|
1617
|
-
globalExclusions: {
|
|
1618
|
-
result: ['password', 'sessionToken', 'internalNotes']
|
|
1619
|
-
}
|
|
1620
|
-
};
|
|
59
|
+
**4. Use**
|
|
60
|
+
```ts
|
|
61
|
+
import { UserSchema } from './prisma/generated/zod';
|
|
1621
62
|
```
|
|
1622
63
|
|
|
1623
|
-
|
|
64
|
+
Optional config: add `prisma/zod-generator.config.json` only if you need tweaks.
|
|
1624
65
|
|
|
1625
|
-
<details>
|
|
1626
|
-
<summary><strong>β Frequently Asked Questions</strong></summary>
|
|
1627
66
|
|
|
1628
|
-
|
|
1629
|
-
A: Modify your Prisma schema with `@zod` comments or use configuration options to customize validation.
|
|
67
|
+
## β€οΈ Sponsor
|
|
1630
68
|
|
|
1631
|
-
|
|
1632
|
-
A: Yes, generated schemas are compatible with Prisma Edge Runtime.
|
|
69
|
+
If this generator saves you engineering hours or reduces production risk, sponsoring keeps it fast, stable, and evolving.
|
|
1633
70
|
|
|
1634
|
-
|
|
1635
|
-
A: The generator automatically uses lazy loading for circular relationships.
|
|
71
|
+
Your support helps:
|
|
1636
72
|
|
|
1637
|
-
|
|
1638
|
-
|
|
73
|
+
- Prioritized issue triage & regression fixes
|
|
74
|
+
- New variant / edgeβcase coverage (providers, previews)
|
|
75
|
+
- Performance & DX improvements (leaner outputs, smarter filtering)
|
|
76
|
+
- Continued compatibility as Prisma & Zod evolve
|
|
1639
77
|
|
|
1640
|
-
|
|
1641
|
-
A: Enums are automatically converted to Zod enum schemas in the `enums/` directory.
|
|
78
|
+
Monthly tiers (GitHub Sponsors) unlock:
|
|
1642
79
|
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
<details>
|
|
1650
|
-
<summary><strong>π οΈ Development Guidelines</strong></summary>
|
|
80
|
+
| Tier | Intended For | Perks |
|
|
81
|
+
| ---- | ------------- | ----- |
|
|
82
|
+
| Solo | Indie devs | π Listed in README (optβin) |
|
|
83
|
+
| Team | Startups | Priority issues + roadmap influence |
|
|
84
|
+
| Scale | Companies | Early feature previews + escalation channel |
|
|
1651
85
|
|
|
86
|
+
β‘οΈ Sponsor here: https://github.com/sponsors/omar-dulaimi
|
|
1652
87
|
|
|
1653
|
-
|
|
1654
|
-
<summary><strong>π Release Process</strong></summary>
|
|
88
|
+
Oneβoff support also welcome (GitHub custom amount).
|
|
1655
89
|
|
|
1656
|
-
This project uses semantic versioning and automated releases:
|
|
1657
90
|
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
- Major: Breaking changes
|
|
91
|
+
## Contribute
|
|
92
|
+
PRs welcome. Keep diffs small; no unrelated refactors.
|
|
1661
93
|
|
|
1662
|
-
|
|
94
|
+
Before starting a feature or significant refactor: **open an issue / feature request first** (or discuss in an existing one) so we can:
|
|
95
|
+
- Confirm scope & fit
|
|
96
|
+
- Avoid duplicate / misaligned work
|
|
97
|
+
- Point you to internal patterns or existing WIP
|
|
1663
98
|
|
|
1664
|
-
|
|
1665
|
-
npm run prerelease # Build, type-check, lint
|
|
1666
|
-
npm run release:dry # Preview the next release
|
|
1667
|
-
```
|
|
99
|
+
Okay to skip issue for: typo fixes, tiny docs tweaks, test flake isolation.
|
|
1668
100
|
|
|
1669
|
-
|
|
1670
|
-
### Contribution Process
|
|
101
|
+
See tests for coverage expectations.
|
|
1671
102
|
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
3. **Follow existing code style** (ESLint + Prettier)
|
|
1675
|
-
4. **Add comprehensive tests** for new functionality
|
|
1676
|
-
5. **Update documentation** as needed
|
|
1677
|
-
6. **Submit a pull request** with clear description
|
|
103
|
+
## License
|
|
104
|
+
Released under the MIT License β see [LICENSE](./LICENSE) for full text.
|
|
1678
105
|
|
|
1679
|
-
|
|
106
|
+
Built & maintained by [Omar Dulaimi](https://github.com/omar-dulaimi) with community contributors.
|
|
1680
107
|
|
|
1681
|
-
```bash
|
|
1682
|
-
npm run lint # Check and fix linting issues
|
|
1683
|
-
npm run format # Format code with Prettier
|
|
1684
|
-
npm test # Run comprehensive test suite
|
|
1685
|
-
```
|
|
1686
|
-
|
|
1687
|
-
### Testing Requirements
|
|
1688
|
-
|
|
1689
|
-
When contributing new features:
|
|
1690
|
-
1. **Write tests first** - TDD approach
|
|
1691
|
-
2. **Test all edge cases** - Comprehensive scenarios
|
|
1692
|
-
3. **Validate across providers** - Multi-database compatibility
|
|
1693
|
-
4. **Performance testing** - Ensure scalability
|
|
1694
|
-
5. **Integration testing** - End-to-end validation
|
|
1695
|
-
|
|
1696
|
-
</details>
|
|
1697
|
-
|
|
1698
|
-
---
|
|
1699
|
-
|
|
1700
|
-
## π License
|
|
1701
|
-
|
|
1702
|
-
This project is licensed under the [MIT License](LICENSE).
|
|
1703
|
-
|
|
1704
|
-
---
|
|
1705
|
-
|
|
1706
|
-
## π Related Projects
|
|
1707
|
-
|
|
1708
|
-
- [prisma-trpc-generator](https://github.com/omar-dulaimi/prisma-trpc-generator) - Generate tRPC routers from Prisma schema
|
|
1709
|
-
- [Prisma](https://github.com/prisma/prisma) - Database toolkit and ORM
|
|
1710
|
-
- [Zod](https://github.com/colinhacks/zod) - TypeScript-first schema validation
|
|
1711
|
-
|
|
1712
|
-
---
|
|
1713
|
-
|
|
1714
|
-
<div align="center">
|
|
1715
|
-
|
|
1716
|
-
<h3>π **Show Your Support** π</h3>
|
|
1717
|
-
|
|
1718
|
-
<a href="https://github.com/omar-dulaimi/prisma-zod-generator">
|
|
1719
|
-
<img src="https://img.shields.io/github/stars/omar-dulaimi/prisma-zod-generator?style=for-the-badge&logo=github&color=yellow" alt="GitHub Stars">
|
|
1720
|
-
</a>
|
|
1721
|
-
|
|
1722
|
-
<br><br>
|
|
1723
|
-
|
|
1724
|
-
<p>
|
|
1725
|
-
<strong>Made with β€οΈ by</strong>
|
|
1726
|
-
<a href="https://github.com/omar-dulaimi">
|
|
1727
|
-
<img src="https://img.shields.io/badge/Omar_Dulaimi-100000?style=for-the-badge&logo=github&logoColor=white" alt="Omar Dulaimi">
|
|
1728
|
-
</a>
|
|
1729
|
-
</p>
|
|
1730
|
-
|
|
1731
|
-
<p><em>β‘ Accelerating Prisma development, one schema at a time</em></p>
|
|
1732
|
-
|
|
1733
|
-
</div>
|