prisma-extension-autozod 1.0.3 → 1.0.5

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.
Files changed (2) hide show
  1. package/README.md +87 -12
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -7,14 +7,26 @@
7
7
  > Contract-aware compile-time linting and runtime Zod validation for the new Prisma ORM (@prisma/orm-postgres).
8
8
 
9
9
  `prisma-extension-autozod` connects **Zod 4** and **Prisma ORM 8**. It provides two layers of safety:
10
+
10
11
  1. **Compile-time Linting**: TypeScript flags any field in your Zod schema that does not exist in your Prisma data contract.
11
12
  2. **Runtime Middleware**: Automatically intercepts write operations (`create`, `update`, `insert`) via Prisma 8's `beforeCompile` hook, validates payloads, normalizes column naming conventions, and blocks invalid mutations before SQL reaches your database.
12
13
 
13
14
  ---
14
15
 
16
+ ## Why prisma-extension-autozod?
17
+
18
+ | Feature | Manual Controller Validation | Schema Generators (zod-prisma) | prisma-extension-autozod |
19
+ | :--- | :--- | :--- | :--- |
20
+ | **Zero Controller Boilerplate** | No (Manual `.parse()`) | No (Manual `.parse()`) | Yes (Auto-intercepted) |
21
+ | **Prisma 8 Native Architecture** | No | No | Yes (`beforeCompile` / Contract) |
22
+ | **Compile-Time Typo Linter** | No | No | Yes (Immediate IDE feedback) |
23
+ | **Casing Normalization** | No | No | Yes (`first_name` <-> `firstName`) |
24
+
25
+ ---
26
+
15
27
  ## Requirements
16
28
 
17
- - **Node.js**: `>= 24.0.0`
29
+ - **Node.js**: `>= 22.0.0`
18
30
  - **Prisma ORM**: `@prisma/orm-postgres >= 8.0.0`
19
31
  - **Zod**: `^4.0.0`
20
32
 
@@ -64,18 +76,30 @@ export const userValidator = defineModel(
64
76
  "User",
65
77
  z.object({
66
78
  email: z.string().email("Invalid email address"),
67
- username: z.string().min(2, "Username must be at least 2 characters").nullable().optional(),
68
- name: z.string().min(2, "Name must be at least 2 characters").nullable().optional(),
69
- })
79
+ username: z
80
+ .string()
81
+ .min(2, "Username must be at least 2 characters")
82
+ .nullable()
83
+ .optional(),
84
+ name: z
85
+ .string()
86
+ .min(2, "Name must be at least 2 characters")
87
+ .nullable()
88
+ .optional(),
89
+ }),
70
90
  );
71
91
  ```
72
92
 
73
93
  > **Compile-Time Safety in Action:**
74
94
  > If you add a field that does not exist in the contract:
95
+ >
75
96
  > ```typescript
76
- > defineModel("User", z.object({
77
- > nonExistentColumn: z.string() // Error: Field 'nonExistentColumn' does not exist in table contract
78
- > }));
97
+ > defineModel(
98
+ > "User",
99
+ > z.object({
100
+ > nonExistentColumn: z.string(), // Error: Field 'nonExistentColumn' does not exist in table contract
101
+ > }),
102
+ > );
79
103
  > ```
80
104
 
81
105
  ---
@@ -128,11 +152,43 @@ await db.orm.public.User.create({
128
152
  });
129
153
 
130
154
  // Update: Only supplied fields are validated
131
- await db.orm.public.User
132
- .where({ email: "alice@prisma.io" })
133
- .update({
134
- name: "Alice Wonder", // Valid; other fields are not required on updates
135
- });
155
+ await db.orm.public.User.where({ email: "alice@prisma.io" }).update({
156
+ name: "Alice Wonder", // Valid; other fields are not required on updates
157
+ });
158
+ ```
159
+
160
+ ---
161
+
162
+ ### 4. Column Normalization in Action
163
+
164
+ Incoming payloads from frontend forms or REST APIs often use `snake_case`. The middleware automatically remaps them to match your contract columns:
165
+
166
+ ```typescript
167
+ // Incoming frontend payload uses snake_case:
168
+ await db.orm.public.User.create({
169
+ first_name: "Alice", // Automatically remapped to `firstName` in Postgres
170
+ email: "alice@prisma.io",
171
+ });
172
+ ```
173
+
174
+ ---
175
+
176
+ ### 5. Error Handling DX
177
+
178
+ Because validation throws standard `ZodError` instances, you can easily catch and format errors for HTTP responses in Express, NestJS, Fastify, or Hono:
179
+
180
+ ```typescript
181
+ import { ZodError } from "zod";
182
+
183
+ try {
184
+ await db.orm.public.User.create(req.body);
185
+ } catch (error) {
186
+ if (error instanceof ZodError) {
187
+ // Clean flattened validation errors directly back to the client
188
+ return res.status(400).json({ errors: error.flatten().fieldErrors });
189
+ }
190
+ throw error;
191
+ }
136
192
  ```
137
193
 
138
194
  ---
@@ -140,28 +196,36 @@ await db.orm.public.User
140
196
  ## API Reference
141
197
 
142
198
  ### `createZodRegistry<TModels>()`
199
+
143
200
  Creates a model validator factory bound to your contract models. Validates that all fields in the schema exist in the contract table, allowing omission of auto-generated or optional fields.
201
+
144
202
  ```typescript
145
203
  const defineModel = createZodRegistry<typeof models.public>();
146
204
  const userValidator = defineModel("User", zodSchema);
147
205
  ```
148
206
 
149
207
  ### `createStrictZodRegistry<TModels>()`
208
+
150
209
  Creates a strict validator factory that requires all columns in the contract table to be declared in the schema, while also rejecting unknown fields.
210
+
151
211
  ```typescript
152
212
  const defineStrict = createStrictZodRegistry<typeof models.public>();
153
213
  const userValidator = defineStrict("User", zodSchema);
154
214
  ```
155
215
 
156
216
  ### `autoZodPrisma8(options)` (alias: `autoZod`)
217
+
157
218
  Prisma ORM 8 middleware factory:
219
+
158
220
  - `options.contract`: The raw `contract.json` object.
159
221
  - `options.validators`: Array of validator entries returned by `createZodRegistry` or `createStrictZodRegistry`.
160
222
 
161
223
  ### `extractColumns(contractJson)`
224
+
162
225
  Helper function that inspects storage namespaces inside `contract.json` and returns a normalized dictionary of table column names.
163
226
 
164
227
  ### `normalizeKey(key: string)`
228
+
165
229
  Normalizes strings to lowercase alphanumeric format for reliable case- and separator-insensitive mapping.
166
230
 
167
231
  ---
@@ -184,6 +248,17 @@ pnpm run build
184
248
 
185
249
  ---
186
250
 
251
+ ## Contributing
252
+
253
+ Contributions, bug reports, and feature requests are welcome!
254
+ Feel free to check the [issues page](https://github.com/abzr0o/prisma-extension-autozod/issues).
255
+
256
+ ## Support
257
+
258
+ If this library saves you time or prevents schema bugs in production, consider giving it a star on [GitHub](https://github.com/abzr0o/prisma-extension-autozod)!
259
+
260
+ ---
261
+
187
262
  ## License
188
263
 
189
264
  [MIT](LICENSE) (c) [Mohammed Thamer](https://github.com/abzr0o)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-extension-autozod",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Contract-aware compile-time linting and runtime Zod validation for Prisma ORM 8 (@prisma/orm-postgres)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",