prisma-zod-generator 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1132 -434
- package/lib/config/defaults.d.ts +106 -0
- package/lib/config/defaults.js +493 -0
- package/lib/config/defaults.js.map +1 -0
- package/lib/config/errors.d.ts +164 -0
- package/lib/config/errors.js +399 -0
- package/lib/config/errors.js.map +1 -0
- package/lib/config/generator-options.d.ts +93 -0
- package/lib/config/generator-options.js +353 -0
- package/lib/config/generator-options.js.map +1 -0
- package/lib/config/parser.d.ts +139 -0
- package/lib/config/parser.js +227 -0
- package/lib/config/parser.js.map +1 -0
- package/lib/config/schema.d.ts +118 -0
- package/lib/config/schema.js +410 -0
- package/lib/config/schema.js.map +1 -0
- package/lib/config/validator.d.ts +79 -0
- package/lib/config/validator.js +357 -0
- package/lib/config/validator.js.map +1 -0
- package/lib/generators/model.d.ts +526 -0
- package/lib/generators/model.js +1719 -0
- package/lib/generators/model.js.map +1 -0
- package/lib/generators/results.d.ts +157 -0
- package/lib/generators/results.js +494 -0
- package/lib/generators/results.js.map +1 -0
- package/lib/helpers/aggregate-helpers.d.ts +8 -0
- package/lib/helpers/aggregate-helpers.js +80 -37
- package/lib/helpers/aggregate-helpers.js.map +1 -1
- package/lib/helpers/helpers.d.ts +4 -0
- package/lib/helpers/helpers.js +12 -4
- package/lib/helpers/helpers.js.map +1 -1
- package/lib/helpers/include-helpers.d.ts +4 -0
- package/lib/helpers/include-helpers.js +50 -26
- package/lib/helpers/include-helpers.js.map +1 -1
- package/lib/helpers/index.d.ts +1 -0
- package/lib/helpers/index.js +1 -0
- package/lib/helpers/index.js.map +1 -1
- package/lib/helpers/model-helpers.d.ts +35 -0
- package/lib/helpers/model-helpers.js +117 -0
- package/lib/helpers/model-helpers.js.map +1 -1
- package/lib/helpers/mongodb-helpers.d.ts +4 -0
- package/lib/helpers/mongodb-helpers.js +61 -3
- package/lib/helpers/mongodb-helpers.js.map +1 -1
- package/lib/helpers/select-helpers.js +42 -13
- package/lib/helpers/select-helpers.js.map +1 -1
- package/lib/helpers/zod-integration.d.ts +104 -0
- package/lib/helpers/zod-integration.js +317 -0
- package/lib/helpers/zod-integration.js.map +1 -0
- package/lib/parsers/zodComments.d.ts +198 -0
- package/lib/parsers/zodComments.js +1127 -0
- package/lib/parsers/zodComments.js.map +1 -0
- package/lib/prisma-generator.js +974 -18
- package/lib/prisma-generator.js.map +1 -1
- package/lib/transformer.d.ts +237 -5
- package/lib/transformer.js +1479 -214
- package/lib/transformer.js.map +1 -1
- package/lib/types/variants.d.ts +149 -0
- package/lib/types/variants.js +99 -0
- package/lib/types/variants.js.map +1 -0
- package/lib/utils/naming.d.ts +180 -0
- package/lib/utils/naming.js +364 -0
- package/lib/utils/naming.js.map +1 -0
- package/lib/utils/singleFileAggregator.d.ts +4 -0
- package/lib/utils/singleFileAggregator.js +165 -0
- package/lib/utils/singleFileAggregator.js.map +1 -0
- package/lib/utils/writeFileSafely.js +42 -6
- package/lib/utils/writeFileSafely.js.map +1 -1
- package/lib/utils/writeIndexFile.js +67 -1
- package/lib/utils/writeIndexFile.js.map +1 -1
- package/lib/variants/config.d.ts +150 -0
- package/lib/variants/config.js +439 -0
- package/lib/variants/config.js.map +1 -0
- package/lib/variants/exports.d.ts +130 -0
- package/lib/variants/exports.js +459 -0
- package/lib/variants/exports.js.map +1 -0
- package/lib/variants/generator.d.ts +135 -0
- package/lib/variants/generator.js +456 -0
- package/lib/variants/generator.js.map +1 -0
- package/package.json +25 -8
package/README.md
CHANGED
|
@@ -23,237 +23,357 @@
|
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
25
|
<p>
|
|
26
|
-
<strong
|
|
26
|
+
<strong>:dart: Zero-config • :shield: Type-safe • :zap: Fast • :wrench: Customizable</strong>
|
|
27
27
|
</p>
|
|
28
28
|
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
<br>
|
|
34
|
-
|
|
35
33
|
<div align="center">
|
|
36
|
-
<h3
|
|
34
|
+
<h3>:bulb: Transform your Prisma schema into type-safe validation schemas</h3>
|
|
37
35
|
<p><em>Automatically generates Zod schemas for all Prisma operations with full TypeScript support</em></p>
|
|
38
36
|
</div>
|
|
39
37
|
|
|
40
38
|
<div align="center">
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
<a id="sponsor"></a>
|
|
41
|
+
## :sparkling_heart: Sponsor to Keep This Project Active
|
|
43
42
|
|
|
44
|
-
<p><
|
|
43
|
+
<p><strong>:rotating_light: Active maintenance depends on your sponsorship. If this generator saves you time, please consider sponsoring.</strong></p>
|
|
45
44
|
|
|
46
45
|
<a href="https://github.com/sponsors/omar-dulaimi">
|
|
47
46
|
<img src="https://img.shields.io/badge/💝_Sponsor_on_GitHub-ea4aaa?style=for-the-badge&logo=github&logoColor=white" alt="GitHub Sponsors" height="45">
|
|
48
47
|
</a>
|
|
49
48
|
|
|
50
|
-
<p><
|
|
49
|
+
<p><em>Your support funds maintenance, issue triage, new features, documentation, and community help.</em></p>
|
|
51
50
|
|
|
52
51
|
</div>
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
## 🚀 **Latest Stable Release** - Now with Schema Compilation Fixes!
|
|
57
|
-
|
|
58
|
-
<table>
|
|
59
|
-
<tr>
|
|
60
|
-
<td align="center">
|
|
61
|
-
<img src="https://img.shields.io/badge/🎉_STABLE_RELEASE-green?style=for-the-badge&logo=checkmark" alt="Stable Release">
|
|
62
|
-
</td>
|
|
63
|
-
</tr>
|
|
64
|
-
<tr>
|
|
65
|
-
<td align="center">
|
|
66
|
-
<strong>🎉 Production Ready with New Prisma Client Generator Support!</strong>
|
|
67
|
-
</td>
|
|
68
|
-
</tr>
|
|
69
|
-
</table>
|
|
70
|
-
|
|
71
|
-
</div>
|
|
53
|
+
---
|
|
72
54
|
|
|
73
|
-
### ✨ **Latest Features**
|
|
74
55
|
|
|
75
|
-
🐛 **Schema Compilation Fixes** - Resolved critical schema compilation errors:
|
|
76
|
-
- **SortOrderInput schemas** now use direct enum references instead of unnecessary lazy loading
|
|
77
|
-
- **Args schemas** (UserArgs, ProfileArgs, etc.) no longer cause TypeScript compilation errors
|
|
78
|
-
- **All generated schemas** now compile cleanly without type constraint issues
|
|
79
56
|
|
|
80
|
-
|
|
57
|
+
## :clipboard: **Table of Contents**
|
|
81
58
|
|
|
82
|
-
|
|
59
|
+
<table>
|
|
60
|
+
<tr>
|
|
61
|
+
<td><a href="#sponsor">:sparkling_heart: Sponsor</a></td>
|
|
62
|
+
<td><a href="#-quick-start">:rocket: Quick Start</a></td>
|
|
63
|
+
<td><a href="#-generated-output">:clipboard: Generated Output</a></td>
|
|
64
|
+
<td><a href="#-version-compatibility">:package: Compatibility</a></td>
|
|
65
|
+
<td><a href="#-core-examples">:books: Core Examples</a></td>
|
|
66
|
+
</tr>
|
|
67
|
+
<tr>
|
|
68
|
+
<td><a href="#-advanced-features">:wrench: Advanced Features</a></td>
|
|
69
|
+
<td><a href="#-configuration">:gear: Configuration</a></td>
|
|
70
|
+
<td><a href="#-api-reference">:book: API Reference</a></td>
|
|
71
|
+
<td><a href="#-framework-examples">:globe_with_meridians: Framework Examples</a></td>
|
|
72
|
+
</tr>
|
|
73
|
+
<td><a href="#-testing--development">:test_tube: Testing & Development</a></td>
|
|
74
|
+
<td><a href="#-troubleshooting">:mag: Troubleshooting</a></td>
|
|
75
|
+
<td><a href="#-contributing">:handshake: Contributing</a></td>
|
|
76
|
+
<td></td>
|
|
77
|
+
</tr>
|
|
78
|
+
</table>
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
| 🚀 **Feature** | 📦 **Version** | 🎯 **Benefit** |
|
|
87
|
-
|----------------|----------------|------------------|
|
|
88
|
-
| **New Prisma Client** | `6.12.0+` | 🆕 ESM-compatible generator support |
|
|
89
|
-
| **Prisma** | `6.12.0+` | 🏃♂️ Latest features & performance |
|
|
90
|
-
| **Zod** | `4.0.5+` | 🛡️ Enhanced validation & type safety |
|
|
91
|
-
| **TypeScript** | `5.8+` | ⚡ Cutting-edge language features |
|
|
92
|
-
| **Testing** | `Vitest 3` | 🧪 Comprehensive coverage |
|
|
93
|
-
| **Tooling** | `ESLint 9` | 🔧 Modern dev experience |
|
|
94
|
-
| **Multi-DB** | `All Providers` | 🗄️ PostgreSQL, MySQL, MongoDB, SQLite+ |
|
|
95
|
-
|
|
96
|
-
</div>
|
|
80
|
+
---
|
|
97
81
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
</div>
|
|
82
|
+
## :rocket: Quick Start
|
|
83
|
+
|
|
84
|
+
### Installation
|
|
103
85
|
|
|
104
86
|
```bash
|
|
105
|
-
#
|
|
87
|
+
# NPM
|
|
106
88
|
npm install prisma-zod-generator
|
|
89
|
+
|
|
90
|
+
# Yarn
|
|
91
|
+
yarn add prisma-zod-generator
|
|
92
|
+
|
|
93
|
+
# PNPM
|
|
94
|
+
pnpm add prisma-zod-generator
|
|
107
95
|
```
|
|
108
96
|
|
|
109
|
-
###
|
|
97
|
+
### 2. Add generator block to your Prisma schema
|
|
110
98
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
99
|
+
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.
|
|
100
|
+
|
|
101
|
+
```prisma
|
|
102
|
+
generator zod {
|
|
103
|
+
provider = "prisma-zod-generator" // required: package id
|
|
104
|
+
output = "./generated" // required: where to write output
|
|
105
|
+
|
|
106
|
+
// File output mode
|
|
107
|
+
useMultipleFiles = true // true: multi-file (default), false: single-file bundle
|
|
108
|
+
singleFileName = "schemas.ts" // only when useMultipleFiles=false
|
|
109
|
+
placeSingleFileAtRoot = true // single-file at output root (true) or under schemas/ (false)
|
|
110
|
+
|
|
111
|
+
// Legacy select/include flags (override JSON config if both provided)
|
|
112
|
+
isGenerateSelect = false
|
|
113
|
+
isGenerateInclude = false
|
|
114
|
+
|
|
115
|
+
// Optional: external JSON config for nested options (models, variants, exclusions, etc.)
|
|
116
|
+
// When both sources specify the same simple option, this generator block wins.
|
|
117
|
+
config = "./zod-generator.config.json"
|
|
118
|
+
}
|
|
119
|
+
```
|
|
115
120
|
|
|
116
|
-
|
|
121
|
+
### 3. Configure TypeScript (required)
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"compilerOptions": {
|
|
126
|
+
"strict": true
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 4. Generate schemas
|
|
117
132
|
|
|
118
133
|
```bash
|
|
119
|
-
npm update prisma-zod-generator
|
|
120
134
|
npx prisma generate
|
|
121
135
|
```
|
|
122
136
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
## 📚 **Navigation**
|
|
126
|
-
|
|
127
|
-
<table>
|
|
128
|
-
<tr>
|
|
129
|
-
<td><a href="#-features">✨ Features</a></td>
|
|
130
|
-
<td><a href="#-quick-start">🚀 Quick Start</a></td>
|
|
131
|
-
<td><a href="#-generated-output">📋 Output</a></td>
|
|
132
|
-
<td><a href="#️-configuration-options">⚙️ Config</a></td>
|
|
133
|
-
</tr>
|
|
134
|
-
<tr>
|
|
135
|
-
<td><a href="#-advanced-usage">🔧 Advanced</a></td>
|
|
136
|
-
<td><a href="#-examples">📚 Examples</a></td>
|
|
137
|
-
<td><a href="#-troubleshooting">🔍 Troubleshooting</a></td>
|
|
138
|
-
<td><a href="#-contributing">🤝 Contributing</a></td>
|
|
139
|
-
</tr>
|
|
140
|
-
</table>
|
|
141
|
-
|
|
142
|
-
</div>
|
|
137
|
+
---
|
|
143
138
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
## ✨ **Why Choose Prisma Zod Generator?**
|
|
147
|
-
|
|
148
|
-
</div>
|
|
139
|
+
## ✨ Why Choose Prisma Zod Generator?
|
|
149
140
|
|
|
150
141
|
<table>
|
|
151
142
|
<tr>
|
|
152
143
|
<td align="center" width="25%">
|
|
153
|
-
<img src="https://img.shields.io/badge/🚀-Zero_Config-blue?style=for-the-badge" alt="Zero Config">
|
|
154
|
-
<
|
|
144
|
+
<img src="https://img.shields.io/badge/🚀-Zero_Config-blue?style=for-the-badge" alt="Zero Config"><br>
|
|
145
|
+
<strong>Works instantly</strong><br><em>Sensible defaults included</em>
|
|
155
146
|
</td>
|
|
156
147
|
<td align="center" width="25%">
|
|
157
|
-
<img src="https://img.shields.io/badge/🔄-Auto_Generated-green?style=for-the-badge" alt="Auto Generated">
|
|
158
|
-
<
|
|
148
|
+
<img src="https://img.shields.io/badge/🔄-Auto_Generated-green?style=for-the-badge" alt="Auto Generated"><br>
|
|
149
|
+
<strong>Always in sync</strong><br><em>Updates with schema changes</em>
|
|
159
150
|
</td>
|
|
160
151
|
<td align="center" width="25%">
|
|
161
|
-
<img src="https://img.shields.io/badge/🛡️-Type_Safe-purple?style=for-the-badge" alt="Type Safe">
|
|
162
|
-
<
|
|
152
|
+
<img src="https://img.shields.io/badge/🛡️-Type_Safe-purple?style=for-the-badge" alt="Type Safe"><br>
|
|
153
|
+
<strong>100% TypeScript</strong><br><em>Catch errors at compile time</em>
|
|
163
154
|
</td>
|
|
164
155
|
<td align="center" width="25%">
|
|
165
|
-
<img src="https://img.shields.io/badge/🎯-Comprehensive-orange?style=for-the-badge" alt="Comprehensive">
|
|
166
|
-
<
|
|
156
|
+
<img src="https://img.shields.io/badge/🎯-Comprehensive-orange?style=for-the-badge" alt="Comprehensive"><br>
|
|
157
|
+
<strong>Full CRUD coverage</strong><br><em>All Prisma operations included</em>
|
|
167
158
|
</td>
|
|
168
159
|
</tr>
|
|
169
160
|
<tr>
|
|
170
161
|
<td align="center">
|
|
171
|
-
<img src="https://img.shields.io/badge/⚙️-Configurable-red?style=for-the-badge" alt="Configurable">
|
|
172
|
-
<
|
|
162
|
+
<img src="https://img.shields.io/badge/⚙️-Configurable-red?style=for-the-badge" alt="Configurable"><br>
|
|
163
|
+
<strong>Highly customizable</strong><br><em>Adapt to your needs</em>
|
|
173
164
|
</td>
|
|
174
165
|
<td align="center">
|
|
175
|
-
<img src="https://img.shields.io/badge/📦-Lightweight-yellow?style=for-the-badge" alt="Lightweight">
|
|
176
|
-
<
|
|
166
|
+
<img src="https://img.shields.io/badge/📦-Lightweight-yellow?style=for-the-badge" alt="Lightweight"><br>
|
|
167
|
+
<strong>Minimal footprint</strong><br><em>Fast generation & runtime</em>
|
|
177
168
|
</td>
|
|
178
169
|
<td align="center">
|
|
179
|
-
<img src="https://img.shields.io/badge/🗄️-Multi_DB-cyan?style=for-the-badge" alt="Multi Database">
|
|
180
|
-
<
|
|
170
|
+
<img src="https://img.shields.io/badge/🗄️-Multi_DB-cyan?style=for-the-badge" alt="Multi Database"><br>
|
|
171
|
+
<strong>All databases</strong><br><em>PostgreSQL, MySQL, MongoDB+</em>
|
|
181
172
|
</td>
|
|
182
173
|
<td align="center">
|
|
183
|
-
<img src="https://img.shields.io/badge/🎨-Flexible-pink?style=for-the-badge" alt="Flexible">
|
|
184
|
-
<
|
|
174
|
+
<img src="https://img.shields.io/badge/🎨-Flexible-pink?style=for-the-badge" alt="Flexible"><br>
|
|
175
|
+
<strong>Your way</strong><br><em>Custom paths & options</em>
|
|
185
176
|
</td>
|
|
186
177
|
</tr>
|
|
187
178
|
</table>
|
|
188
179
|
|
|
189
|
-
|
|
180
|
+
### 🔄 Upgrading
|
|
190
181
|
|
|
191
|
-
|
|
182
|
+
The latest stable version maintains full API compatibility. Requirements:
|
|
183
|
+
- Node.js 18+
|
|
184
|
+
- Prisma 6.12.0+
|
|
185
|
+
- Zod 4.0.5+
|
|
186
|
+
|
|
187
|
+
Update and regenerate:
|
|
192
188
|
|
|
193
189
|
```bash
|
|
194
|
-
|
|
195
|
-
|
|
190
|
+
npm update prisma-zod-generator
|
|
191
|
+
npx prisma generate
|
|
192
|
+
```
|
|
196
193
|
|
|
197
|
-
|
|
198
|
-
yarn add prisma-zod-generator
|
|
194
|
+
## 📋 Generated Output
|
|
199
195
|
|
|
200
|
-
|
|
201
|
-
|
|
196
|
+
<details>
|
|
197
|
+
<summary><strong>📁 File Structure Overview</strong></summary>
|
|
198
|
+
|
|
199
|
+
For this Prisma schema:
|
|
200
|
+
|
|
201
|
+
```prisma
|
|
202
|
+
model User {
|
|
203
|
+
id Int @id @default(autoincrement())
|
|
204
|
+
email String @unique
|
|
205
|
+
name String?
|
|
206
|
+
posts Post[]
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
model Post {
|
|
210
|
+
id Int @id @default(autoincrement())
|
|
211
|
+
title String
|
|
212
|
+
content String?
|
|
213
|
+
author User? @relation(fields: [authorId], references: [id])
|
|
214
|
+
authorId Int?
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The generator creates:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
📁 generated/schemas/
|
|
222
|
+
├── 📁 enums/ # Enum validation schemas
|
|
223
|
+
├── 📁 objects/ # Input type schemas
|
|
224
|
+
├── 📄 findManyUser.schema.ts
|
|
225
|
+
├── 📄 findUniqueUser.schema.ts
|
|
226
|
+
├── 📄 createOneUser.schema.ts
|
|
227
|
+
├── 📄 updateOneUser.schema.ts
|
|
228
|
+
├── 📄 deleteOneUser.schema.ts
|
|
229
|
+
├── 📄 findManyPost.schema.ts
|
|
230
|
+
├── 📄 createOnePost.schema.ts
|
|
231
|
+
└── 📄 index.ts # Barrel exports
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
</details>
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## :rocket: Dual Schema Export Strategy - Breakthrough Feature!
|
|
239
|
+
|
|
240
|
+
### 🎯 Solving the Type Safety vs Method Availability Trade-off
|
|
241
|
+
|
|
242
|
+
This generator implements a dual export strategy that gives you both perfect Prisma typing and full Zod method support.
|
|
243
|
+
|
|
244
|
+
#### The Problem
|
|
245
|
+
With Zod schemas, you traditionally face a choice:
|
|
246
|
+
- Type-safe: `z.ZodType<Prisma.Type>` gives perfect inference but restricts Zod method chaining
|
|
247
|
+
- Method-friendly: Pure Zod schemas support all methods but lose perfect type binding
|
|
248
|
+
|
|
249
|
+
#### Our Solution: Export Both Versions
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
// Perfect type safety (no Zod method chaining)
|
|
253
|
+
export const PostFindManySchema: z.ZodType<Prisma.PostFindManyArgs> = schema;
|
|
254
|
+
|
|
255
|
+
// Full method availability (great inference)
|
|
256
|
+
export const PostFindManyZodSchema = schema;
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### Usage Examples
|
|
260
|
+
|
|
261
|
+
Type-safe version (perfect Prisma integration):
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
import { PostFindManySchema } from './generated/schemas/findManyPost.schema';
|
|
265
|
+
|
|
266
|
+
type FindManyArgs = z.infer<typeof PostFindManySchema>; // Prisma.PostFindManyArgs
|
|
267
|
+
|
|
268
|
+
const validatedInput = PostFindManySchema.parse(queryParams);
|
|
269
|
+
const posts = await prisma.post.findMany(validatedInput);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Method-friendly version (full Zod capabilities):
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
import { PostFindManyZodSchema } from './generated/schemas/findManyPost.schema';
|
|
276
|
+
|
|
277
|
+
const customSchema = PostFindManyZodSchema
|
|
278
|
+
.extend({ customField: z.string() })
|
|
279
|
+
.omit({ take: true })
|
|
280
|
+
.merge(otherSchema);
|
|
281
|
+
|
|
282
|
+
const partialSchema = PostFindManyZodSchema.partial();
|
|
202
283
|
```
|
|
203
284
|
|
|
204
|
-
|
|
285
|
+
#### Configuration Options
|
|
205
286
|
|
|
206
|
-
|
|
287
|
+
```prisma
|
|
288
|
+
generator zod {
|
|
289
|
+
provider = "prisma-zod-generator"
|
|
290
|
+
output = "./generated/schemas"
|
|
291
|
+
exportTypedSchemas = true // Export z.ZodType<Prisma.Type> versions
|
|
292
|
+
exportZodSchemas = true // Export pure Zod versions
|
|
293
|
+
typedSchemaSuffix = "Schema" // Suffix for typed versions
|
|
294
|
+
zodSchemaSuffix = "ZodSchema" // Suffix for method-friendly versions
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
#### Configuration Scenarios
|
|
207
299
|
|
|
208
|
-
|
|
300
|
+
Type-safe only:
|
|
209
301
|
|
|
210
302
|
```prisma
|
|
211
303
|
generator zod {
|
|
212
|
-
provider
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
isGenerateInclude = true
|
|
304
|
+
provider = "prisma-zod-generator"
|
|
305
|
+
exportTypedSchemas = true
|
|
306
|
+
exportZodSchemas = false
|
|
216
307
|
}
|
|
217
308
|
```
|
|
218
309
|
|
|
219
|
-
|
|
310
|
+
Method-friendly only:
|
|
220
311
|
|
|
221
|
-
```
|
|
222
|
-
{
|
|
223
|
-
"
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
312
|
+
```prisma
|
|
313
|
+
generator zod {
|
|
314
|
+
provider = "prisma-zod-generator"
|
|
315
|
+
exportTypedSchemas = false
|
|
316
|
+
exportZodSchemas = true
|
|
227
317
|
}
|
|
228
318
|
```
|
|
229
319
|
|
|
230
|
-
|
|
320
|
+
Both versions:
|
|
231
321
|
|
|
232
|
-
```
|
|
233
|
-
|
|
322
|
+
```prisma
|
|
323
|
+
generator zod {
|
|
324
|
+
provider = "prisma-zod-generator"
|
|
325
|
+
exportTypedSchemas = true
|
|
326
|
+
exportZodSchemas = true
|
|
327
|
+
}
|
|
234
328
|
```
|
|
235
329
|
|
|
236
|
-
|
|
330
|
+
Custom naming:
|
|
237
331
|
|
|
238
|
-
|
|
332
|
+
```prisma
|
|
333
|
+
generator zod {
|
|
334
|
+
provider = "prisma-zod-generator"
|
|
335
|
+
exportTypedSchemas = true
|
|
336
|
+
exportZodSchemas = true
|
|
337
|
+
typedSchemaSuffix = "Args"
|
|
338
|
+
zodSchemaSuffix = "Validator"
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Pro tips:
|
|
343
|
+
|
|
344
|
+
- Smaller bundles: use a single export mode
|
|
345
|
+
- Team consistency: choose one naming convention and stick with it
|
|
346
|
+
- Gradual adoption: start with type-safe schemas, add method-friendly as needed
|
|
347
|
+
- IDE performance: fewer exports -> faster IntelliSense in huge projects
|
|
348
|
+
|
|
349
|
+
---
|
|
239
350
|
|
|
240
|
-
|
|
351
|
+
## :package: Version Compatibility
|
|
241
352
|
|
|
242
|
-
|
|
353
|
+
<details>
|
|
354
|
+
<summary><strong>🔄 Supported Versions & Migration Guide</strong></summary>
|
|
355
|
+
|
|
356
|
+
### Current Requirements
|
|
357
|
+
|
|
358
|
+
| Component | Version | Status |
|
|
359
|
+
|-----------|---------|---------|
|
|
360
|
+
| **Node.js** | 18+ | ✅ Required |
|
|
361
|
+
| **Prisma** | 6.12.0+ | ✅ Recommended |
|
|
362
|
+
| **Zod** | 4.0.5+ | ✅ Required |
|
|
363
|
+
| **TypeScript** | 5.8+ | ✅ Recommended |
|
|
364
|
+
|
|
365
|
+
### Prisma Client Generator Support
|
|
366
|
+
|
|
367
|
+
Both legacy and new ESM-compatible generators are supported:
|
|
243
368
|
|
|
244
369
|
#### Legacy Generator (Existing Projects)
|
|
245
370
|
```prisma
|
|
246
371
|
generator client {
|
|
247
372
|
provider = "prisma-client-js"
|
|
248
373
|
}
|
|
249
|
-
|
|
250
|
-
generator zod {
|
|
251
|
-
provider = "prisma-zod-generator"
|
|
252
|
-
output = "./generated/schemas"
|
|
253
|
-
}
|
|
254
374
|
```
|
|
255
375
|
|
|
256
|
-
#### New ESM
|
|
376
|
+
#### New ESM Generator (Prisma 6.12.0+)
|
|
257
377
|
```prisma
|
|
258
378
|
generator client {
|
|
259
379
|
provider = "prisma-client"
|
|
@@ -263,140 +383,503 @@ generator client {
|
|
|
263
383
|
generatedFileExtension = "ts"
|
|
264
384
|
importFileExtension = "ts"
|
|
265
385
|
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Migration Guide
|
|
389
|
+
|
|
390
|
+
**Existing Projects**: No changes needed - continue using `prisma-client-js`
|
|
391
|
+
|
|
392
|
+
**New Projects**: Consider the new `prisma-client` generator for ESM support
|
|
393
|
+
|
|
394
|
+
</details>
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## 📚 Core Examples
|
|
399
|
+
|
|
400
|
+
<details>
|
|
401
|
+
<summary><strong>🎯 Essential Usage Patterns</strong></summary>
|
|
402
|
+
|
|
403
|
+
### API Validation
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
// Validate input data
|
|
407
|
+
const createUser = UserCreateInputObjectSchema.parse(requestData);
|
|
408
|
+
|
|
409
|
+
// Validate query parameters
|
|
410
|
+
const findUsers = UserFindManySchema.parse(queryParams);
|
|
411
|
+
|
|
412
|
+
// Validate update operations
|
|
413
|
+
const updateUser = UserUpdateOneSchema.parse(updateData);
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Form Validation with React Hook Form
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
import { useForm } from 'react-hook-form';
|
|
420
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
421
|
+
import { UserCreateInputObjectSchema } from './generated/schemas';
|
|
422
|
+
|
|
423
|
+
function CreateUserForm() {
|
|
424
|
+
const { register, handleSubmit, formState: { errors } } = useForm({
|
|
425
|
+
resolver: zodResolver(UserCreateInputObjectSchema)
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
return (
|
|
429
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
430
|
+
<input {...register('email')} type="email" />
|
|
431
|
+
{errors.email && <span>{errors.email.message}</span>}
|
|
432
|
+
<button type="submit">Create User</button>
|
|
433
|
+
</form>
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
```
|
|
266
437
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
438
|
+
### Database Operations
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
// Safe database queries with validation
|
|
442
|
+
const searchUsers = async (params: unknown) => {
|
|
443
|
+
const validatedParams = UserFindManySchema.parse(params);
|
|
444
|
+
return await prisma.user.findMany(validatedParams);
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
// Validated mutations
|
|
448
|
+
const createPost = async (data: unknown) => {
|
|
449
|
+
const validatedData = PostCreateOneSchema.parse(data);
|
|
450
|
+
return await prisma.post.create(validatedData);
|
|
451
|
+
};
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
</details>
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## 🔧 Advanced Features
|
|
459
|
+
|
|
460
|
+
<details>
|
|
461
|
+
<summary><strong>🎯 Configuration System</strong></summary>
|
|
462
|
+
|
|
463
|
+
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).
|
|
464
|
+
|
|
465
|
+
### JSON-Based Configuration
|
|
466
|
+
|
|
467
|
+
Create `zod-generator.config.json`:
|
|
468
|
+
|
|
469
|
+
```json
|
|
470
|
+
{
|
|
471
|
+
"mode": "custom",
|
|
472
|
+
"output": "./src/generated/zod",
|
|
473
|
+
"globalExclusions": {
|
|
474
|
+
"input": ["id", "createdAt", "updatedAt"],
|
|
475
|
+
"result": [],
|
|
476
|
+
"pure": ["password", "hashedPassword"]
|
|
477
|
+
},
|
|
478
|
+
"variants": {
|
|
479
|
+
"pure": {
|
|
480
|
+
"enabled": true,
|
|
481
|
+
"suffix": ".model",
|
|
482
|
+
"excludeFields": []
|
|
483
|
+
},
|
|
484
|
+
"input": {
|
|
485
|
+
"enabled": true,
|
|
486
|
+
"suffix": ".input",
|
|
487
|
+
"excludeFields": ["id"]
|
|
488
|
+
},
|
|
489
|
+
"result": {
|
|
490
|
+
"enabled": true,
|
|
491
|
+
"suffix": ".result",
|
|
492
|
+
"excludeFields": ["password"]
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
"models": {
|
|
496
|
+
"User": {
|
|
497
|
+
"enabled": true,
|
|
498
|
+
"operations": ["findMany", "findUnique", "create", "update"],
|
|
499
|
+
"variants": {
|
|
500
|
+
"input": {
|
|
501
|
+
"excludeFields": ["role", "permissions"]
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
270
506
|
}
|
|
271
507
|
```
|
|
272
508
|
|
|
273
|
-
###
|
|
509
|
+
### Configuration Modes
|
|
510
|
+
|
|
511
|
+
```typescript
|
|
512
|
+
// Minimal mode - essential operations only
|
|
513
|
+
const minimalConfig = {
|
|
514
|
+
mode: "minimal",
|
|
515
|
+
operations: ["findMany", "findUnique", "create", "update"]
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
// Full mode - all operations and features
|
|
519
|
+
const fullConfig = {
|
|
520
|
+
mode: "full",
|
|
521
|
+
includeAggregations: true,
|
|
522
|
+
includeGroupBy: true
|
|
523
|
+
};
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
</details>
|
|
274
527
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
- **🔧 Runtime Flexibility** - Support for Bun, Deno, Cloudflare Workers
|
|
278
|
-
- **⚡ Better Performance** - Optimized code generation
|
|
279
|
-
- **🔮 Future-Ready** - Will become the default in Prisma v7
|
|
528
|
+
<details>
|
|
529
|
+
<summary><strong>🎨 Schema Variants</strong></summary>
|
|
280
530
|
|
|
281
|
-
###
|
|
531
|
+
### Multiple Schema Types
|
|
282
532
|
|
|
283
|
-
|
|
533
|
+
Generate different schema variants for various use cases:
|
|
284
534
|
|
|
285
|
-
|
|
535
|
+
```typescript
|
|
536
|
+
// Pure model schemas - exact Prisma model structure
|
|
537
|
+
import { UserModelSchema } from './schemas/User.model';
|
|
286
538
|
|
|
287
|
-
|
|
539
|
+
// Input schemas - for API endpoints and forms
|
|
540
|
+
import { UserInputSchema } from './schemas/User.input';
|
|
288
541
|
|
|
289
|
-
|
|
542
|
+
// Result schemas - for API responses
|
|
543
|
+
import { UserResultSchema } from './schemas/User.result';
|
|
290
544
|
|
|
291
|
-
|
|
545
|
+
// Usage examples
|
|
546
|
+
const createUser = UserInputSchema.parse(formData);
|
|
547
|
+
const userResponse = UserResultSchema.parse(dbResult);
|
|
548
|
+
const pureUser = UserModelSchema.parse(prismaModel);
|
|
549
|
+
```
|
|
292
550
|
|
|
293
|
-
###
|
|
551
|
+
### Variant Configuration
|
|
294
552
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
553
|
+
```json
|
|
554
|
+
{
|
|
555
|
+
"variants": [
|
|
556
|
+
{
|
|
557
|
+
"name": "input",
|
|
558
|
+
"suffix": "Input",
|
|
559
|
+
"exclude": ["id", "createdAt", "updatedAt"]
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"name": "result",
|
|
563
|
+
"suffix": "Result",
|
|
564
|
+
"exclude": ["password"]
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
"name": "public",
|
|
568
|
+
"suffix": "Public",
|
|
569
|
+
"exclude": ["password", "email", "internalId"]
|
|
570
|
+
}
|
|
571
|
+
]
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
</details>
|
|
298
576
|
|
|
299
|
-
|
|
577
|
+
<details>
|
|
578
|
+
<summary><strong>🔍 Field Exclusion System</strong></summary>
|
|
300
579
|
|
|
301
|
-
|
|
580
|
+
### Global and Model-Specific Exclusions
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
// Configuration-based exclusion
|
|
584
|
+
const config = {
|
|
585
|
+
globalExclusions: {
|
|
586
|
+
input: ["id", "createdAt", "updatedAt"],
|
|
587
|
+
result: ["password", "hashedPassword"],
|
|
588
|
+
pure: []
|
|
589
|
+
},
|
|
590
|
+
models: {
|
|
591
|
+
User: {
|
|
592
|
+
variants: {
|
|
593
|
+
input: { excludeFields: ["role", "permissions"] },
|
|
594
|
+
result: { excludeFields: ["password", "sessionToken"] }
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Prisma Schema Exclusions
|
|
302
602
|
|
|
303
603
|
```prisma
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
604
|
+
model User {
|
|
605
|
+
id Int @id @default(autoincrement())
|
|
606
|
+
email String @unique
|
|
607
|
+
password String // Excluded from result schemas
|
|
608
|
+
role String // Excluded from input schemas
|
|
609
|
+
/// @@Gen.model(hide: true) // Hide entire model
|
|
610
|
+
posts Post[]
|
|
308
611
|
}
|
|
612
|
+
```
|
|
309
613
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
614
|
+
</details>
|
|
615
|
+
|
|
616
|
+
<details>
|
|
617
|
+
<summary><strong>📝 @zod Comment Annotations</strong></summary>
|
|
618
|
+
|
|
619
|
+
### Inline Validation Rules
|
|
620
|
+
|
|
621
|
+
Add validation directly in your Prisma schema:
|
|
622
|
+
|
|
623
|
+
```prisma
|
|
624
|
+
model User {
|
|
625
|
+
id Int @id @default(autoincrement())
|
|
626
|
+
email String @unique /// @zod.email()
|
|
627
|
+
name String? /// @zod.min(2).max(50)
|
|
628
|
+
age Int? /// @zod.min(0).max(120)
|
|
629
|
+
username String @unique /// @zod.regex(/^[a-zA-Z0-9_]+$/)
|
|
630
|
+
website String? /// @zod.url().optional()
|
|
313
631
|
}
|
|
314
632
|
```
|
|
315
633
|
|
|
316
|
-
|
|
634
|
+
Generated schema with validations:
|
|
317
635
|
|
|
318
|
-
|
|
636
|
+
```typescript
|
|
637
|
+
export const UserCreateInputSchema = z.object({
|
|
638
|
+
email: z.string().email(),
|
|
639
|
+
name: z.string().min(2).max(50).optional(),
|
|
640
|
+
age: z.number().int().min(0).max(120).optional(),
|
|
641
|
+
username: z.string().regex(/^[a-zA-Z0-9_]+$/),
|
|
642
|
+
website: z.string().url().optional()
|
|
643
|
+
});
|
|
644
|
+
```
|
|
319
645
|
|
|
320
|
-
|
|
321
|
-
- **Progressive Enhancement**: New features are additive and don't break existing functionality
|
|
322
|
-
- **Automatic Detection**: No additional configuration required - the generator detects enabled features automatically
|
|
646
|
+
### Supported @zod Annotations
|
|
323
647
|
|
|
324
|
-
|
|
648
|
+
```prisma
|
|
649
|
+
// String validations
|
|
650
|
+
field String /// @zod.email()
|
|
651
|
+
field String /// @zod.url()
|
|
652
|
+
field String /// @zod.regex(/pattern/)
|
|
653
|
+
field String /// @zod.min(2).max(50)
|
|
654
|
+
|
|
655
|
+
// Number validations
|
|
656
|
+
field Int /// @zod.min(0).max(100)
|
|
657
|
+
field Float /// @zod.positive()
|
|
658
|
+
|
|
659
|
+
// Custom validations
|
|
660
|
+
field String /// @zod.custom(z.string().transform(s => s.toLowerCase()))
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
</details>
|
|
664
|
+
|
|
665
|
+
<details>
|
|
666
|
+
<summary><strong>🗄️ Multi-Database Provider Support</strong></summary>
|
|
667
|
+
|
|
668
|
+
### Database-Specific Optimizations
|
|
669
|
+
|
|
670
|
+
```typescript
|
|
671
|
+
// PostgreSQL - Advanced types supported
|
|
672
|
+
const pgUser = z.object({
|
|
673
|
+
id: z.number().int(),
|
|
674
|
+
metadata: z.record(z.unknown()), // JSON type
|
|
675
|
+
tags: z.array(z.string()), // Array type
|
|
676
|
+
balance: z.number() // Decimal type
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
// MongoDB - Document structure
|
|
680
|
+
const mongoUser = z.object({
|
|
681
|
+
id: z.string(), // ObjectId as string
|
|
682
|
+
embedded: z.object({ // Embedded documents
|
|
683
|
+
profile: z.object({
|
|
684
|
+
bio: z.string().optional()
|
|
685
|
+
})
|
|
686
|
+
}).optional()
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
// MySQL - Optimized for relational data
|
|
690
|
+
const mysqlUser = z.object({
|
|
691
|
+
id: z.number().int(),
|
|
692
|
+
createdAt: z.date(),
|
|
693
|
+
updatedAt: z.date()
|
|
694
|
+
});
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
### Supported Providers
|
|
698
|
+
|
|
699
|
+
- **PostgreSQL** - Full advanced type support
|
|
700
|
+
- **MySQL** - Complete compatibility
|
|
701
|
+
- **MongoDB** - Native document schemas
|
|
702
|
+
- **SQLite** - Development & testing optimized
|
|
703
|
+
- **SQL Server** - Enterprise features
|
|
704
|
+
- **CockroachDB** - Distributed database support
|
|
705
|
+
|
|
706
|
+
</details>
|
|
325
707
|
|
|
326
|
-
|
|
708
|
+
<details>
|
|
709
|
+
<summary><strong>🔧 ESM Import Handling</strong></summary>
|
|
710
|
+
|
|
711
|
+
### Modern ES Module Support
|
|
712
|
+
|
|
713
|
+
Full ESM compatibility with automatic file extension handling:
|
|
327
714
|
|
|
328
715
|
```prisma
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
716
|
+
generator client {
|
|
717
|
+
provider = "prisma-client"
|
|
718
|
+
output = "./src/generated/client"
|
|
719
|
+
moduleFormat = "esm"
|
|
720
|
+
importFileExtension = "js" # Auto-handled
|
|
334
721
|
}
|
|
722
|
+
```
|
|
335
723
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
724
|
+
Generated imports include proper extensions:
|
|
725
|
+
|
|
726
|
+
```typescript
|
|
727
|
+
import { User } from '../client/index.js'; // Auto-generated
|
|
728
|
+
import { z } from 'zod';
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### Import Configuration
|
|
732
|
+
|
|
733
|
+
```json
|
|
734
|
+
{
|
|
735
|
+
"esm": {
|
|
736
|
+
"enabled": true,
|
|
737
|
+
"fileExtension": ".js",
|
|
738
|
+
"importExtension": ".js"
|
|
739
|
+
}
|
|
347
740
|
}
|
|
348
741
|
```
|
|
349
742
|
|
|
350
|
-
|
|
743
|
+
</details>
|
|
744
|
+
|
|
745
|
+
<details>
|
|
746
|
+
<summary><strong>⚡ Performance Optimization</strong></summary>
|
|
747
|
+
|
|
748
|
+
### Built-in Optimizations
|
|
351
749
|
|
|
750
|
+
```typescript
|
|
751
|
+
// Lazy loading for circular references
|
|
752
|
+
const UserSchema = z.lazy(() => z.object({
|
|
753
|
+
id: z.number().int(),
|
|
754
|
+
posts: z.array(PostSchema).optional()
|
|
755
|
+
}));
|
|
756
|
+
|
|
757
|
+
// Selective generation
|
|
758
|
+
const config = {
|
|
759
|
+
models: {
|
|
760
|
+
AuditLog: { enabled: false }, // Skip audit tables
|
|
761
|
+
Migration: { enabled: false }, // Skip migration tables
|
|
762
|
+
User: {
|
|
763
|
+
enabled: true,
|
|
764
|
+
operations: ["findMany", "create", "update"] // Only needed operations
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
};
|
|
352
768
|
```
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
769
|
+
|
|
770
|
+
### Performance Tips
|
|
771
|
+
|
|
772
|
+
- Use `minimal` mode for faster generation
|
|
773
|
+
- Exclude unused models and operations
|
|
774
|
+
- Enable lazy loading for complex relationships
|
|
775
|
+
- Cache generated schemas in production
|
|
776
|
+
|
|
777
|
+
</details>
|
|
778
|
+
|
|
779
|
+
<details>
|
|
780
|
+
<summary><strong>🔐 API Security & Validation Patterns</strong></summary>
|
|
781
|
+
|
|
782
|
+
### Input Sanitization
|
|
783
|
+
|
|
784
|
+
```typescript
|
|
785
|
+
export const sanitizeUserInput = (data: unknown) => {
|
|
786
|
+
return UserCreateInputSchema
|
|
787
|
+
.omit({ id: true }) // Remove ID from input
|
|
788
|
+
.extend({
|
|
789
|
+
email: z.string().email().toLowerCase() // Normalize email
|
|
790
|
+
})
|
|
791
|
+
.parse(data);
|
|
792
|
+
};
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
### Role-Based Field Filtering
|
|
796
|
+
|
|
797
|
+
```typescript
|
|
798
|
+
export const getUserForRole = (user: User, role: 'admin' | 'user') => {
|
|
799
|
+
const baseSchema = UserResultSchema;
|
|
800
|
+
|
|
801
|
+
if (role === 'user') {
|
|
802
|
+
return baseSchema.omit({
|
|
803
|
+
email: true,
|
|
804
|
+
role: true,
|
|
805
|
+
permissions: true
|
|
806
|
+
}).parse(user);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
return baseSchema.parse(user);
|
|
810
|
+
};
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
### Complete API Endpoint Validation
|
|
814
|
+
|
|
815
|
+
```typescript
|
|
816
|
+
app.post('/users', async (req, res) => {
|
|
817
|
+
try {
|
|
818
|
+
const userData = UserCreateInputSchema.parse(req.body);
|
|
819
|
+
const user = await prisma.user.create({ data: userData });
|
|
820
|
+
const response = UserResultSchema.parse(user);
|
|
821
|
+
res.json(response);
|
|
822
|
+
} catch (error) {
|
|
823
|
+
if (error instanceof z.ZodError) {
|
|
824
|
+
return res.status(400).json({
|
|
825
|
+
errors: error.errors.map(e => ({
|
|
826
|
+
field: e.path.join('.'),
|
|
827
|
+
message: e.message
|
|
828
|
+
}))
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
});
|
|
364
833
|
```
|
|
365
834
|
|
|
366
|
-
|
|
835
|
+
</details>
|
|
367
836
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
| **Legacy** | 4.8.0+ | 3.20+ | 4.9+ | 16+ | 📦 **Deprecated** - Limited Support |
|
|
837
|
+
---
|
|
838
|
+
|
|
839
|
+
## ⚙️ Configuration
|
|
372
840
|
|
|
373
|
-
>
|
|
841
|
+
<details>
|
|
842
|
+
<summary><strong>🔧 Configuration Options</strong></summary>
|
|
374
843
|
|
|
375
|
-
|
|
844
|
+
### Basic Configuration
|
|
376
845
|
|
|
377
846
|
| Option | Description | Type | Default |
|
|
378
847
|
|--------|-------------|------|---------|
|
|
379
848
|
| `output` | Output directory for generated files | `string` | `"./generated"` |
|
|
380
849
|
| `isGenerateSelect` | Generate Select-related schemas | `boolean` | `false` |
|
|
381
850
|
| `isGenerateInclude` | Generate Include-related schemas | `boolean` | `false` |
|
|
851
|
+
| `exportTypedSchemas` | Export z.ZodType versions (type-safe) | `boolean` | `true` |
|
|
852
|
+
| `exportZodSchemas` | Export pure Zod versions (method-friendly) | `boolean` | `true` |
|
|
853
|
+
| `typedSchemaSuffix` | Suffix for typed schemas | `string` | `"Schema"` |
|
|
854
|
+
| `zodSchemaSuffix` | Suffix for Zod schemas | `string` | `"ZodSchema"` |
|
|
855
|
+
| `useMultipleFiles` | Output multiple files (true) or single bundle (false) | `boolean` | `true` |
|
|
856
|
+
| `singleFileName` | Name of the single-file bundle when `useMultipleFiles=false` | `string` | `"schemas.ts"` |
|
|
857
|
+
| `placeSingleFileAtRoot` | When `useMultipleFiles=false`, place the single file at the generator output root instead of a `schemas/` subfolder | `boolean` | `true` |
|
|
382
858
|
|
|
383
|
-
###
|
|
859
|
+
### Advanced Configuration
|
|
384
860
|
|
|
385
861
|
```prisma
|
|
386
862
|
generator zod {
|
|
387
863
|
provider = "prisma-zod-generator"
|
|
388
864
|
output = "./src/schemas"
|
|
865
|
+
// File output mode
|
|
866
|
+
// true -> multiple files (default)
|
|
867
|
+
// false -> single file bundle (see singleFileName below)
|
|
868
|
+
useMultipleFiles = true
|
|
869
|
+
// Optional: name of the single-file bundle when useMultipleFiles = false
|
|
870
|
+
// Defaults to "schemas.ts"
|
|
871
|
+
singleFileName = "schemas.ts"
|
|
872
|
+
// Optional: when useMultipleFiles = false, place the single file at the
|
|
873
|
+
// generator output root (true) or inside a schemas/ subdir (false)
|
|
874
|
+
placeSingleFileAtRoot = true
|
|
389
875
|
isGenerateSelect = true
|
|
390
876
|
isGenerateInclude = true
|
|
877
|
+
config = "./zod-config.json"
|
|
391
878
|
}
|
|
392
879
|
```
|
|
393
880
|
|
|
394
|
-
## 🔧 Advanced Usage
|
|
395
|
-
|
|
396
881
|
### Model Customizations
|
|
397
882
|
|
|
398
|
-
Hide specific models from generation:
|
|
399
|
-
|
|
400
883
|
```prisma
|
|
401
884
|
/// @@Gen.model(hide: true)
|
|
402
885
|
model InternalLog {
|
|
@@ -406,50 +889,148 @@ model InternalLog {
|
|
|
406
889
|
}
|
|
407
890
|
```
|
|
408
891
|
|
|
409
|
-
###
|
|
892
|
+
### JSON Configuration File
|
|
410
893
|
|
|
411
|
-
|
|
894
|
+
```json
|
|
895
|
+
{
|
|
896
|
+
"mode": "custom",
|
|
897
|
+
"output": "./generated/schemas",
|
|
898
|
+
"relationModel": true,
|
|
899
|
+
"modelCase": "PascalCase",
|
|
900
|
+
"modelSuffix": "Schema",
|
|
901
|
+
"useMultipleFiles": true,
|
|
902
|
+
"placeSingleFileAtRoot": true,
|
|
903
|
+
"createInputTypes": true,
|
|
904
|
+
"addIncludeType": true,
|
|
905
|
+
"addSelectType": true,
|
|
906
|
+
"validateWhereUniqueInput": true,
|
|
907
|
+
"prismaClientPath": "@prisma/client"
|
|
908
|
+
}
|
|
909
|
+
```
|
|
412
910
|
|
|
413
|
-
|
|
414
|
-
- **MySQL** - Full compatibility with all MySQL features
|
|
415
|
-
- **MongoDB** - Native MongoDB schema generation
|
|
416
|
-
- **SQLite** - Perfect for development and testing
|
|
417
|
-
- **SQL Server** - Enterprise-grade support
|
|
418
|
-
- **CockroachDB** - Distributed database support
|
|
911
|
+
</details>
|
|
419
912
|
|
|
420
|
-
|
|
913
|
+
---
|
|
421
914
|
|
|
422
|
-
|
|
915
|
+
## 📖 API Reference
|
|
423
916
|
|
|
424
|
-
|
|
425
|
-
import express from 'express';
|
|
426
|
-
import { PostCreateOneSchema, UserFindManySchema } from './generated/schemas';
|
|
917
|
+
## ⚙️ Configuration sources, precedence, and availability
|
|
427
918
|
|
|
428
|
-
|
|
919
|
+
This generator accepts configuration from two sources. When the same option is provided in multiple places, the value is resolved using a simple precedence.
|
|
429
920
|
|
|
430
|
-
|
|
431
|
-
app.post('/posts', async (req, res) => {
|
|
432
|
-
try {
|
|
433
|
-
const data = PostCreateOneSchema.parse(req.body);
|
|
434
|
-
const post = await prisma.post.create(data);
|
|
435
|
-
res.json(post);
|
|
436
|
-
} catch (error) {
|
|
437
|
-
if (error instanceof z.ZodError) {
|
|
438
|
-
return res.status(400).json({ errors: error.errors });
|
|
439
|
-
}
|
|
440
|
-
res.status(500).json({ error: 'Internal server error' });
|
|
441
|
-
}
|
|
442
|
-
});
|
|
921
|
+
### Sources
|
|
443
922
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
923
|
+
- Prisma generator block (schema.prisma)
|
|
924
|
+
- Standard Prisma fields like `output`.
|
|
925
|
+
- Simple override flags/strings (e.g., `useMultipleFiles`, `singleFileName`, etc.).
|
|
926
|
+
- Optional `config = "./zod-generator.config.json"` to point to a JSON file.
|
|
927
|
+
- JSON config file (recommended for complex/nested settings)
|
|
928
|
+
- Full configuration surface, including nested structures like `models` and `variants`.
|
|
929
|
+
- Can be provided explicitly via `config = "./path.json"` or auto-discovered (e.g., `zod-generator.config.json`, `.zod-generator.json`).
|
|
930
|
+
|
|
931
|
+
### Precedence (highest → lowest)
|
|
932
|
+
|
|
933
|
+
1) Prisma generator block options (direct attributes in `generator zod { ... }`)
|
|
934
|
+
2) JSON config file (explicit or auto-discovered)
|
|
935
|
+
3) Built-in defaults (computed based on `mode`, etc.)
|
|
936
|
+
|
|
937
|
+
Notes and special cases:
|
|
938
|
+
- Output path: The Prisma generator’s `output` always decides where files go. Any `output` set in the JSON config is ignored.
|
|
939
|
+
- 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.
|
|
940
|
+
- Legacy flags: `isGenerateSelect` / `isGenerateInclude` (Prisma block) override the newer `addSelectType` / `addIncludeType` (config JSON). Minimal mode will still force them off.
|
|
941
|
+
|
|
942
|
+
### Option availability matrix
|
|
943
|
+
|
|
944
|
+
| Option | Prisma generator block | JSON config file | Notes |
|
|
945
|
+
|---|---|---|---|
|
|
946
|
+
| `output` | Yes (authoritative) | Ignored if present | Use the Prisma generator `output` only |
|
|
947
|
+
| `useMultipleFiles` | Yes | Yes | `false` enables strict single-file mode |
|
|
948
|
+
| `singleFileName` | Yes | Yes | File name for the single bundle (default `schemas.ts`) |
|
|
949
|
+
| `placeSingleFileAtRoot` | Yes | Yes | Place single file at output root (true, default) or under `schemas/` (false) |
|
|
950
|
+
| `placeArrayVariantsAtRoot` | Yes | Yes | For array-based variants placement (root vs `variants/`) |
|
|
951
|
+
| `mode` (`full|minimal|custom`) | Yes | Yes | Minimal mode applies opinionated defaults |
|
|
952
|
+
| `pureModels` | Yes | Yes | Generates `models/` set when multi-file; N/A in single-file (content is bundled) |
|
|
953
|
+
| `globalExclusions` | — | Yes | Object keyed by variant (`input`, `result`, `pure`) |
|
|
954
|
+
| `variants` (object-based) | — | Yes | Nested structure; configure `pure/input/result` |
|
|
955
|
+
| `models.*` (per-model) | — | Yes | Nested per-model rules, operations, and variant overrides |
|
|
956
|
+
| `addSelectType` / `addIncludeType` | Yes (as legacy `isGenerateSelect` / `isGenerateInclude`) | Yes | Prisma block flags override the JSON values; minimal mode forces off |
|
|
957
|
+
| `formatGeneratedSchemas` | — | Yes | Formatting can be skipped for speed (default: false) |
|
|
958
|
+
| `config` (path to JSON) | Yes | — | Points to the JSON file; not a config value itself |
|
|
959
|
+
|
|
960
|
+
Example: Prisma block overrides JSON file
|
|
961
|
+
|
|
962
|
+
```prisma
|
|
963
|
+
generator zod {
|
|
964
|
+
provider = "prisma-zod-generator"
|
|
965
|
+
output = "./generated"
|
|
966
|
+
// Overrides values from the JSON config below
|
|
967
|
+
useMultipleFiles = false
|
|
968
|
+
singleFileName = "bundle.ts"
|
|
969
|
+
placeSingleFileAtRoot = true
|
|
970
|
+
// Load additional (nested) settings from a JSON file
|
|
971
|
+
config = "./zod-generator.config.json"
|
|
972
|
+
}
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
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.
|
|
976
|
+
|
|
977
|
+
### How @zod schema comments fit into precedence
|
|
978
|
+
|
|
979
|
+
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.
|
|
980
|
+
|
|
981
|
+
- Scope: Applies only to the field where the comment appears, and only in schemas that include that field (subject to filtering, variants, minimal mode).
|
|
982
|
+
- 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.
|
|
983
|
+
- 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.
|
|
984
|
+
- 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.
|
|
985
|
+
|
|
986
|
+
See the “@zod Comment Annotations” section for syntax and examples.
|
|
987
|
+
|
|
988
|
+
<details>
|
|
989
|
+
<summary><strong>📚 Generated Schema Types</strong></summary>
|
|
990
|
+
|
|
991
|
+
### Operation Schemas
|
|
992
|
+
|
|
993
|
+
- **Create Operations**: `ModelCreateOneSchema`, `ModelCreateManySchema`
|
|
994
|
+
- **Read Operations**: `ModelFindManySchema`, `ModelFindUniqueSchema`, `ModelFindFirstSchema`
|
|
995
|
+
- **Update Operations**: `ModelUpdateOneSchema`, `ModelUpdateManySchema`, `ModelUpsertSchema`
|
|
996
|
+
- **Delete Operations**: `ModelDeleteOneSchema`, `ModelDeleteManySchema`
|
|
997
|
+
- **Aggregate Operations**: `ModelAggregateSchema`, `ModelGroupBySchema`
|
|
998
|
+
|
|
999
|
+
### Input Object Schemas
|
|
1000
|
+
|
|
1001
|
+
- **Create Inputs**: `ModelCreateInputObjectSchema`, `ModelCreateNestedInputObjectSchema`
|
|
1002
|
+
- **Update Inputs**: `ModelUpdateInputObjectSchema`, `ModelUpdateNestedInputObjectSchema`
|
|
1003
|
+
- **Where Inputs**: `ModelWhereInputObjectSchema`, `ModelWhereUniqueInputObjectSchema`
|
|
1004
|
+
- **Order Inputs**: `ModelOrderByInputObjectSchema`
|
|
1005
|
+
|
|
1006
|
+
### Select & Include Schemas
|
|
1007
|
+
|
|
1008
|
+
When enabled with `isGenerateSelect: true` and `isGenerateInclude: true`:
|
|
1009
|
+
- **Select Schemas**: `ModelSelectObjectSchema`
|
|
1010
|
+
- **Include Schemas**: `ModelIncludeObjectSchema`
|
|
1011
|
+
|
|
1012
|
+
### Schema Naming Convention
|
|
1013
|
+
|
|
1014
|
+
All generated schemas follow this pattern:
|
|
1015
|
+
```
|
|
1016
|
+
{ModelName}{Operation}{Type}Schema
|
|
450
1017
|
```
|
|
451
1018
|
|
|
452
|
-
|
|
1019
|
+
Examples:
|
|
1020
|
+
- `UserCreateOneSchema` - Schema for creating a single user
|
|
1021
|
+
- `PostFindManyArgsSchema` - Schema for finding multiple posts with arguments
|
|
1022
|
+
- `UserWhereInputObjectSchema` - Schema for user where conditions
|
|
1023
|
+
|
|
1024
|
+
</details>
|
|
1025
|
+
|
|
1026
|
+
---
|
|
1027
|
+
|
|
1028
|
+
## 🌐 Framework Examples
|
|
1029
|
+
|
|
1030
|
+
<details>
|
|
1031
|
+
<summary><strong>🚀 Next.js Integration</strong></summary>
|
|
1032
|
+
|
|
1033
|
+
### API Routes
|
|
453
1034
|
|
|
454
1035
|
```typescript
|
|
455
1036
|
// pages/api/users.ts
|
|
@@ -469,7 +1050,29 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|
|
469
1050
|
}
|
|
470
1051
|
```
|
|
471
1052
|
|
|
472
|
-
###
|
|
1053
|
+
### App Router (Next.js 13+)
|
|
1054
|
+
|
|
1055
|
+
```typescript
|
|
1056
|
+
// app/api/users/route.ts
|
|
1057
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
1058
|
+
import { UserCreateOneSchema } from '@/generated/schemas';
|
|
1059
|
+
|
|
1060
|
+
export async function POST(request: NextRequest) {
|
|
1061
|
+
try {
|
|
1062
|
+
const body = await request.json();
|
|
1063
|
+
const userData = UserCreateOneSchema.parse(body);
|
|
1064
|
+
const user = await prisma.user.create(userData);
|
|
1065
|
+
return NextResponse.json(user);
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
return NextResponse.json({ error: error.message }, { status: 400 });
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1072
|
+
</details>
|
|
1073
|
+
|
|
1074
|
+
<details>
|
|
1075
|
+
<summary><strong>⚡ tRPC Integration</strong></summary>
|
|
473
1076
|
|
|
474
1077
|
```typescript
|
|
475
1078
|
import { z } from 'zod';
|
|
@@ -490,256 +1093,368 @@ export const postRouter = router({
|
|
|
490
1093
|
});
|
|
491
1094
|
```
|
|
492
1095
|
|
|
493
|
-
|
|
1096
|
+
</details>
|
|
1097
|
+
|
|
1098
|
+
<details>
|
|
1099
|
+
<summary><strong>🛠️ Fastify Integration</strong></summary>
|
|
494
1100
|
|
|
495
1101
|
```typescript
|
|
496
|
-
import
|
|
497
|
-
import {
|
|
498
|
-
import { UserCreateInputObjectSchema } from './generated/schemas';
|
|
1102
|
+
import fastify from 'fastify';
|
|
1103
|
+
import { UserCreateOneSchema } from './generated/schemas';
|
|
499
1104
|
|
|
500
|
-
|
|
501
|
-
const { register, handleSubmit, formState: { errors } } = useForm({
|
|
502
|
-
resolver: zodResolver(UserCreateInputObjectSchema)
|
|
503
|
-
});
|
|
1105
|
+
const server = fastify();
|
|
504
1106
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
1107
|
+
server.post('/users', {
|
|
1108
|
+
schema: {
|
|
1109
|
+
body: UserCreateOneSchema
|
|
1110
|
+
}
|
|
1111
|
+
}, async (request, reply) => {
|
|
1112
|
+
const user = await prisma.user.create(request.body);
|
|
1113
|
+
return user;
|
|
1114
|
+
});
|
|
1115
|
+
```
|
|
512
1116
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
1117
|
+
</details>
|
|
1118
|
+
|
|
1119
|
+
<details>
|
|
1120
|
+
<summary><strong>🌐 Express.js Integration</strong></summary>
|
|
1121
|
+
|
|
1122
|
+
```typescript
|
|
1123
|
+
import express from 'express';
|
|
1124
|
+
import { UserCreateOneSchema, UserFindManySchema } from './generated/schemas';
|
|
1125
|
+
|
|
1126
|
+
const app = express();
|
|
1127
|
+
|
|
1128
|
+
// Create user with validation
|
|
1129
|
+
app.post('/users', async (req, res) => {
|
|
1130
|
+
try {
|
|
1131
|
+
const data = UserCreateOneSchema.parse(req.body);
|
|
1132
|
+
const user = await prisma.user.create(data);
|
|
1133
|
+
res.json(user);
|
|
1134
|
+
} catch (error) {
|
|
1135
|
+
if (error instanceof z.ZodError) {
|
|
1136
|
+
return res.status(400).json({ errors: error.errors });
|
|
1137
|
+
}
|
|
1138
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
|
|
1142
|
+
// Query with validation
|
|
1143
|
+
app.get('/users', async (req, res) => {
|
|
1144
|
+
const query = UserFindManySchema.parse(req.query);
|
|
1145
|
+
const users = await prisma.user.findMany(query);
|
|
1146
|
+
res.json(users);
|
|
1147
|
+
});
|
|
525
1148
|
```
|
|
526
1149
|
|
|
527
|
-
|
|
1150
|
+
</details>
|
|
528
1151
|
|
|
529
|
-
|
|
1152
|
+
---
|
|
530
1153
|
|
|
531
|
-
|
|
1154
|
+
## 🧪 Testing & Development
|
|
532
1155
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
- **Read Operations**: `ModelFindManySchema`, `ModelFindUniqueSchema`, `ModelFindFirstSchema`
|
|
536
|
-
- **Update Operations**: `ModelUpdateOneSchema`, `ModelUpdateManySchema`, `ModelUpsertSchema`
|
|
537
|
-
- **Delete Operations**: `ModelDeleteOneSchema`, `ModelDeleteManySchema`
|
|
538
|
-
- **Aggregate Operations**: `ModelAggregateSchema`, `ModelGroupBySchema`
|
|
1156
|
+
<details>
|
|
1157
|
+
<summary><strong>🔬 Testing Infrastructure</strong></summary>
|
|
539
1158
|
|
|
540
|
-
|
|
541
|
-
- **Create Inputs**: `ModelCreateInputObjectSchema`, `ModelCreateNestedInputObjectSchema`
|
|
542
|
-
- **Update Inputs**: `ModelUpdateInputObjectSchema`, `ModelUpdateNestedInputObjectSchema`
|
|
543
|
-
- **Where Inputs**: `ModelWhereInputObjectSchema`, `ModelWhereUniqueInputObjectSchema`
|
|
544
|
-
- **Order Inputs**: `ModelOrderByInputObjectSchema`
|
|
1159
|
+
### Test Suite Overview
|
|
545
1160
|
|
|
546
|
-
|
|
547
|
-
When enabled with `isGenerateSelect: true` and `isGenerateInclude: true`:
|
|
548
|
-
- **Select Schemas**: `ModelSelectObjectSchema`
|
|
549
|
-
- **Include Schemas**: `ModelIncludeObjectSchema`
|
|
1161
|
+
We maintain **enterprise-grade testing standards** with comprehensive coverage:
|
|
550
1162
|
|
|
551
|
-
|
|
1163
|
+
#### 📊 **Test Statistics**
|
|
1164
|
+
- **📊 80+ Tests Passing** - Comprehensive validation across all features
|
|
1165
|
+
- **🔍 5,239 Schemas Validated** - Massive multi-provider testing
|
|
1166
|
+
- **✅ 100% TypeScript Compilation** - Zero compilation errors guaranteed
|
|
1167
|
+
- **🛡️ Zero ESLint Issues** - Clean, maintainable code quality
|
|
552
1168
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
1169
|
+
#### 📋 **Test Categories**
|
|
1170
|
+
|
|
1171
|
+
```bash
|
|
1172
|
+
# Core infrastructure tests
|
|
1173
|
+
npm run test:core # Configuration & integration tests
|
|
1174
|
+
npm run test:esm # ESM import handling tests
|
|
1175
|
+
npm run test:comprehensive # Multi-provider schema validation
|
|
1176
|
+
|
|
1177
|
+
# Feature-specific tests
|
|
1178
|
+
npm run test:config # Configuration system validation
|
|
1179
|
+
npm run test:variants # Schema variant generation
|
|
1180
|
+
npm run test:filtering # Model/field filtering logic
|
|
1181
|
+
npm run test:pure-models # Pure model schema generation
|
|
1182
|
+
npm run test:result-schemas # Result schema validation
|
|
1183
|
+
npm run test:zod-comments # @zod comment parsing
|
|
1184
|
+
npm run test:field-exclusion # Field exclusion system
|
|
1185
|
+
|
|
1186
|
+
# Advanced testing
|
|
1187
|
+
npm run test:integration # Full generation pipeline tests
|
|
1188
|
+
npm run test:multi-provider # All database provider validation
|
|
1189
|
+
npm run test:performance # Schema generation performance
|
|
1190
|
+
npm run test:coverage # Code coverage analysis
|
|
556
1191
|
```
|
|
557
1192
|
|
|
558
|
-
|
|
559
|
-
- `UserCreateOneSchema` - Schema for creating a single user
|
|
560
|
-
- `PostFindManyArgsSchema` - Schema for finding multiple posts with arguments
|
|
561
|
-
- `UserWhereInputObjectSchema` - Schema for user where conditions
|
|
1193
|
+
</details>
|
|
562
1194
|
|
|
563
|
-
|
|
1195
|
+
<details>
|
|
1196
|
+
<summary><strong>🧪 Testing Integration</strong></summary>
|
|
564
1197
|
|
|
565
|
-
###
|
|
1198
|
+
### Schema Testing Utilities
|
|
566
1199
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
- **Args schemas**: Resolved TypeScript compilation errors for UserArgs, ProfileArgs, etc.
|
|
570
|
-
- **All schemas**: Now compile cleanly without type constraint issues
|
|
571
|
-
- **Full backward compatibility**: No code changes needed when upgrading
|
|
1200
|
+
```typescript
|
|
1201
|
+
import { SchemaTestUtils } from './test-utils';
|
|
572
1202
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
1203
|
+
// Validate schema structure
|
|
1204
|
+
SchemaTestUtils.testValidData(UserCreateInputSchema, {
|
|
1205
|
+
email: 'test@example.com',
|
|
1206
|
+
name: 'Test User'
|
|
1207
|
+
});
|
|
577
1208
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
1209
|
+
// Test boundary conditions
|
|
1210
|
+
SchemaTestUtils.testBoundaryValues(UserCreateInputSchema, [
|
|
1211
|
+
{ value: { email: 'invalid-email' }, shouldPass: false },
|
|
1212
|
+
{ value: { name: 'x'.repeat(51) }, shouldPass: false },
|
|
1213
|
+
{ value: { name: 'Valid Name' }, shouldPass: true }
|
|
1214
|
+
]);
|
|
1215
|
+
|
|
1216
|
+
// Performance testing
|
|
1217
|
+
const performance = SchemaTestUtils.performanceTest(
|
|
1218
|
+
UserCreateInputSchema,
|
|
1219
|
+
validUserData,
|
|
1220
|
+
1000 // iterations
|
|
1221
|
+
);
|
|
1222
|
+
console.log(`Avg validation time: ${performance.avgTime}ms`);
|
|
1223
|
+
```
|
|
582
1224
|
|
|
583
|
-
|
|
584
|
-
- Backup your project before upgrading
|
|
585
|
-
- Update all related dependencies (Prisma, Zod, TypeScript)
|
|
586
|
-
- Re-run `npx prisma generate` after upgrading
|
|
587
|
-
- Test thoroughly in development environment
|
|
1225
|
+
### Development Setup
|
|
588
1226
|
|
|
589
|
-
|
|
1227
|
+
```bash
|
|
1228
|
+
# Clone and setup
|
|
1229
|
+
git clone https://github.com/your-username/prisma-zod-generator.git
|
|
1230
|
+
cd prisma-zod-generator
|
|
1231
|
+
npm install
|
|
590
1232
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
- The Zod generator provides clear error messages with examples if no compatible generator is found
|
|
594
|
-
- Both legacy and new generators are supported simultaneously
|
|
1233
|
+
# Development build
|
|
1234
|
+
npm run gen-example
|
|
595
1235
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
- Check that your output path is correct
|
|
1236
|
+
# Run tests
|
|
1237
|
+
npm test
|
|
599
1238
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
1239
|
+
# Code quality
|
|
1240
|
+
npm run lint # Check and fix linting issues
|
|
1241
|
+
npm run format # Format code with Prettier
|
|
1242
|
+
```
|
|
604
1243
|
|
|
605
|
-
|
|
606
|
-
- Run `npx prisma generate` after modifying your schema
|
|
607
|
-
- Check that the generator is properly configured in `schema.prisma`
|
|
608
|
-
- Clear your build cache and regenerate
|
|
1244
|
+
</details>
|
|
609
1245
|
|
|
610
|
-
|
|
611
|
-
-
|
|
612
|
-
- Check that your input schemas match your Prisma model types
|
|
1246
|
+
<details>
|
|
1247
|
+
<summary><strong>📈 Multi-Database Provider Validation</strong></summary>
|
|
613
1248
|
|
|
614
|
-
|
|
615
|
-
- Ensure you have the correct version installed
|
|
616
|
-
- Check that your `schema.prisma` syntax is valid
|
|
617
|
-
- Verify Node.js version compatibility (18+)
|
|
618
|
-
- Clear node_modules and reinstall dependencies
|
|
1249
|
+
Our test suite validates schemas across **6 database providers**:
|
|
619
1250
|
|
|
620
|
-
|
|
1251
|
+
| Provider | Schemas Validated | Status |
|
|
1252
|
+
|----------|------------------|---------|
|
|
1253
|
+
| **PostgreSQL** | 1,020 schemas | ✅ |
|
|
1254
|
+
| **MySQL** | 1,326 schemas | ✅ |
|
|
1255
|
+
| **MongoDB** | 855 schemas | ✅ |
|
|
1256
|
+
| **SQLite** | 1,409 schemas | ✅ |
|
|
1257
|
+
| **SQL Server** | 622 schemas | ✅ |
|
|
1258
|
+
| **Default** | Additional schemas | ✅ |
|
|
621
1259
|
|
|
622
|
-
|
|
623
|
-
For projects with many models (50+), consider:
|
|
624
|
-
- Using selective generation with model hiding
|
|
625
|
-
- Splitting schemas into multiple files
|
|
626
|
-
- Implementing lazy loading for schemas
|
|
1260
|
+
</details>
|
|
627
1261
|
|
|
628
|
-
|
|
629
|
-
To optimize build performance:
|
|
630
|
-
- Add generated files to `.gitignore`
|
|
631
|
-
- Use parallel builds where possible
|
|
632
|
-
- Consider caching in CI/CD pipelines
|
|
1262
|
+
---
|
|
633
1263
|
|
|
634
|
-
|
|
1264
|
+
## 🔍 Troubleshooting
|
|
635
1265
|
|
|
636
|
-
|
|
637
|
-
|
|
1266
|
+
<details>
|
|
1267
|
+
<summary><strong>🚨 Common Issues & Solutions</strong></summary>
|
|
638
1268
|
|
|
639
|
-
|
|
640
|
-
A: Yes, the generated schemas are compatible with Prisma Edge Runtime.
|
|
1269
|
+
### Generator Compatibility Errors
|
|
641
1270
|
|
|
642
|
-
**
|
|
643
|
-
|
|
1271
|
+
**Issue**: Cannot find compatible Prisma generator
|
|
1272
|
+
```bash
|
|
1273
|
+
Error: No compatible Prisma client generator found
|
|
1274
|
+
```
|
|
644
1275
|
|
|
645
|
-
**
|
|
646
|
-
|
|
1276
|
+
**Solution**: Ensure you have a supported generator in your schema:
|
|
1277
|
+
```prisma
|
|
1278
|
+
generator client {
|
|
1279
|
+
provider = "prisma-client-js" // or "prisma-client"
|
|
1280
|
+
}
|
|
647
1281
|
|
|
648
|
-
|
|
649
|
-
|
|
1282
|
+
generator zod {
|
|
1283
|
+
provider = "prisma-zod-generator"
|
|
1284
|
+
output = "./generated/schemas"
|
|
1285
|
+
}
|
|
1286
|
+
```
|
|
650
1287
|
|
|
651
|
-
###
|
|
1288
|
+
### Module Resolution Errors
|
|
652
1289
|
|
|
653
|
-
|
|
654
|
-
- 💡 **Feature Requests**: [Request a feature](https://github.com/omar-dulaimi/prisma-zod-generator/issues/new)
|
|
655
|
-
- 💬 **Discussions**: [Join the discussion](https://github.com/omar-dulaimi/prisma-zod-generator/discussions)
|
|
1290
|
+
**Issue**: `Cannot find module './generated/schemas'`
|
|
656
1291
|
|
|
657
|
-
|
|
1292
|
+
**Solutions**:
|
|
1293
|
+
1. Run `npx prisma generate` after adding the generator
|
|
1294
|
+
2. Check that your output path is correct
|
|
1295
|
+
3. Verify the generator completed successfully
|
|
658
1296
|
|
|
659
|
-
|
|
1297
|
+
### TypeScript Compilation Errors
|
|
660
1298
|
|
|
661
|
-
|
|
1299
|
+
**Issue**: Generated schemas have TypeScript errors
|
|
662
1300
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
1301
|
+
**Solutions**:
|
|
1302
|
+
1. Enable strict mode in `tsconfig.json`:
|
|
1303
|
+
```json
|
|
1304
|
+
{
|
|
1305
|
+
"compilerOptions": {
|
|
1306
|
+
"strict": true,
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
667
1309
|
```
|
|
1310
|
+
2. Update dependencies: `npm update prisma-zod-generator prisma zod`
|
|
1311
|
+
3. Clear build cache and regenerate
|
|
668
1312
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
1313
|
+
### Generation Performance Issues
|
|
1314
|
+
|
|
1315
|
+
**Issue**: Slow generation for large schemas
|
|
1316
|
+
|
|
1317
|
+
**Solutions**:
|
|
1318
|
+
1. Use minimal mode:
|
|
1319
|
+
```json
|
|
1320
|
+
{
|
|
1321
|
+
"mode": "minimal",
|
|
1322
|
+
"models": {
|
|
1323
|
+
"AuditLog": { "enabled": false },
|
|
1324
|
+
"Migration": { "enabled": false }
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
672
1327
|
```
|
|
1328
|
+
2. Exclude unnecessary operations
|
|
1329
|
+
3. Enable selective model generation
|
|
673
1330
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
1331
|
+
</details>
|
|
1332
|
+
|
|
1333
|
+
<details>
|
|
1334
|
+
<summary><strong>💡 Performance Optimization Tips</strong></summary>
|
|
1335
|
+
|
|
1336
|
+
### Large Schema Optimization
|
|
1337
|
+
|
|
1338
|
+
For projects with 50+ models:
|
|
1339
|
+
- Use selective generation with model hiding
|
|
1340
|
+
- Split schemas into multiple files
|
|
1341
|
+
- Implement lazy loading for schemas
|
|
1342
|
+
- Consider minimal mode for faster builds
|
|
1343
|
+
|
|
1344
|
+
### Build Time Optimization
|
|
1345
|
+
|
|
1346
|
+
```json
|
|
1347
|
+
{
|
|
1348
|
+
"mode": "minimal",
|
|
1349
|
+
"models": {
|
|
1350
|
+
"User": {
|
|
1351
|
+
"operations": ["findMany", "create", "update"]
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
677
1355
|
```
|
|
678
1356
|
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
1357
|
+
### Production Deployment
|
|
1358
|
+
|
|
1359
|
+
```typescript
|
|
1360
|
+
// Environment-specific configuration
|
|
1361
|
+
const productionConfig = {
|
|
1362
|
+
mode: 'minimal',
|
|
1363
|
+
globalExclusions: {
|
|
1364
|
+
result: ['password', 'sessionToken', 'internalNotes']
|
|
1365
|
+
}
|
|
1366
|
+
};
|
|
682
1367
|
```
|
|
683
1368
|
|
|
684
|
-
|
|
1369
|
+
</details>
|
|
685
1370
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
1371
|
+
<details>
|
|
1372
|
+
<summary><strong>❓ Frequently Asked Questions</strong></summary>
|
|
1373
|
+
|
|
1374
|
+
**Q: Can I customize the generated validation rules?**
|
|
1375
|
+
A: Modify your Prisma schema with `@zod` comments or use configuration options to customize validation.
|
|
1376
|
+
|
|
1377
|
+
**Q: Does this work with Prisma Edge Runtime?**
|
|
1378
|
+
A: Yes, generated schemas are compatible with Prisma Edge Runtime.
|
|
1379
|
+
|
|
1380
|
+
**Q: How do I handle circular references?**
|
|
1381
|
+
A: The generator automatically uses lazy loading for circular relationships.
|
|
1382
|
+
|
|
1383
|
+
**Q: Can I exclude certain fields from validation?**
|
|
1384
|
+
A: Yes, use the `globalExclusions` or model-specific `excludeFields` configuration.
|
|
1385
|
+
|
|
1386
|
+
**Q: How do I handle enum validation?**
|
|
1387
|
+
A: Enums are automatically converted to Zod enum schemas in the `enums/` directory.
|
|
1388
|
+
|
|
1389
|
+
</details>
|
|
1390
|
+
|
|
1391
|
+
---
|
|
1392
|
+
|
|
1393
|
+
## 🤝 Contributing
|
|
1394
|
+
|
|
1395
|
+
<details>
|
|
1396
|
+
<summary><strong>🛠️ Development Guidelines</strong></summary>
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
<details>
|
|
1400
|
+
<summary><strong>🚀 Release Process</strong></summary>
|
|
1401
|
+
|
|
1402
|
+
This project uses semantic versioning and automated releases:
|
|
1403
|
+
|
|
1404
|
+
- Patch: Bug fixes and small improvements
|
|
1405
|
+
- Minor: New features and enhancements
|
|
1406
|
+
- Major: Breaking changes
|
|
1407
|
+
|
|
1408
|
+
Helpful commands:
|
|
691
1409
|
|
|
692
|
-
Run specific test suites:
|
|
693
1410
|
```bash
|
|
694
|
-
npm run
|
|
695
|
-
npm run
|
|
696
|
-
npm run test:coverage # Coverage reports
|
|
697
|
-
npm run test:comprehensive # Full test suite
|
|
1411
|
+
npm run prerelease # Build, type-check, lint
|
|
1412
|
+
npm run release:dry # Preview the next release
|
|
698
1413
|
```
|
|
699
1414
|
|
|
700
|
-
|
|
1415
|
+
</details>
|
|
1416
|
+
### Contribution Process
|
|
701
1417
|
|
|
702
1418
|
1. **Create an issue** for bugs or feature requests
|
|
703
|
-
2. **
|
|
704
|
-
3. **
|
|
705
|
-
4. **
|
|
706
|
-
5. **
|
|
1419
|
+
2. **Fork and clone** the repository
|
|
1420
|
+
3. **Follow existing code style** (ESLint + Prettier)
|
|
1421
|
+
4. **Add comprehensive tests** for new functionality
|
|
1422
|
+
5. **Update documentation** as needed
|
|
1423
|
+
6. **Submit a pull request** with clear description
|
|
707
1424
|
|
|
708
|
-
### Code
|
|
1425
|
+
### Code Quality Standards
|
|
709
1426
|
|
|
710
|
-
We use ESLint and Prettier for consistent code formatting:
|
|
711
1427
|
```bash
|
|
712
1428
|
npm run lint # Check and fix linting issues
|
|
713
1429
|
npm run format # Format code with Prettier
|
|
1430
|
+
npm test # Run comprehensive test suite
|
|
714
1431
|
```
|
|
715
1432
|
|
|
716
|
-
###
|
|
1433
|
+
### Testing Requirements
|
|
717
1434
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
1435
|
+
When contributing new features:
|
|
1436
|
+
1. **Write tests first** - TDD approach
|
|
1437
|
+
2. **Test all edge cases** - Comprehensive scenarios
|
|
1438
|
+
3. **Validate across providers** - Multi-database compatibility
|
|
1439
|
+
4. **Performance testing** - Ensure scalability
|
|
1440
|
+
5. **Integration testing** - End-to-end validation
|
|
1441
|
+
|
|
1442
|
+
</details>
|
|
1443
|
+
|
|
1444
|
+
---
|
|
722
1445
|
|
|
723
1446
|
## 📄 License
|
|
724
1447
|
|
|
725
1448
|
This project is licensed under the [MIT License](LICENSE).
|
|
726
1449
|
|
|
1450
|
+
---
|
|
1451
|
+
|
|
727
1452
|
## 🔗 Related Projects
|
|
728
1453
|
|
|
729
1454
|
- [prisma-trpc-generator](https://github.com/omar-dulaimi/prisma-trpc-generator) - Generate tRPC routers from Prisma schema
|
|
730
1455
|
- [Prisma](https://github.com/prisma/prisma) - Database toolkit and ORM
|
|
731
1456
|
- [Zod](https://github.com/colinhacks/zod) - TypeScript-first schema validation
|
|
732
1457
|
|
|
733
|
-
## 🙏 Acknowledgments
|
|
734
|
-
|
|
735
|
-
- [Prisma](https://github.com/prisma/prisma) - Modern database toolkit
|
|
736
|
-
- [Zod](https://github.com/colinhacks/zod) - TypeScript-first schema validation
|
|
737
|
-
- All our [contributors](https://github.com/omar-dulaimi/prisma-zod-generator/graphs/contributors)
|
|
738
|
-
|
|
739
|
-
---
|
|
740
|
-
|
|
741
|
-
<br>
|
|
742
|
-
|
|
743
1458
|
---
|
|
744
1459
|
|
|
745
1460
|
<div align="center">
|
|
@@ -752,23 +1467,6 @@ This project is licensed under the [MIT License](LICENSE).
|
|
|
752
1467
|
|
|
753
1468
|
<br><br>
|
|
754
1469
|
|
|
755
|
-
<table>
|
|
756
|
-
<tr>
|
|
757
|
-
<td align="center">
|
|
758
|
-
<img src="https://img.shields.io/badge/💎-Latest_Stable-success?style=for-the-badge&logo=npm" alt="Stable">
|
|
759
|
-
<br>
|
|
760
|
-
<code>v1.0.0</code>
|
|
761
|
-
</td>
|
|
762
|
-
<td align="center">
|
|
763
|
-
<img src="https://img.shields.io/badge/📦-Legacy_Version-lightgrey?style=for-the-badge&logo=archive" alt="Legacy">
|
|
764
|
-
<br>
|
|
765
|
-
<code>v0.8.13</code>
|
|
766
|
-
</td>
|
|
767
|
-
</tr>
|
|
768
|
-
</table>
|
|
769
|
-
|
|
770
|
-
<br>
|
|
771
|
-
|
|
772
1470
|
<p>
|
|
773
1471
|
<strong>Made with ❤️ by</strong>
|
|
774
1472
|
<a href="https://github.com/omar-dulaimi">
|
|
@@ -778,4 +1476,4 @@ This project is licensed under the [MIT License](LICENSE).
|
|
|
778
1476
|
|
|
779
1477
|
<p><em>⚡ Accelerating Prisma development, one schema at a time</em></p>
|
|
780
1478
|
|
|
781
|
-
</div>
|
|
1479
|
+
</div>
|