prisma-to-zod-v4 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +26 -15
  2. package/dist/index.js +54 -35
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -125,27 +125,38 @@ This project uses pnpm.
125
125
 
126
126
  ```prisma
127
127
  generator zod {
128
- provider = "prisma-to-zod-v4"
129
- output = "./zod" // (default) the directory where generated zod schemas will be saved
128
+ provider = "prisma-to-zod-v4"
130
129
 
131
- relationModel = true // (default) Create and export both plain and related models.
132
- // relationModel = "default" // Do not export model without relations.
133
- // relationModel = false // Do not generate related model
130
+ // Output directory for generated Zod schemas
131
+ output = "./zod" // default
134
132
 
135
- modelCase = "PascalCase" // (default) Output models using pascal case (ex. UserModel, PostModel)
136
- // modelCase = "camelCase" // Output models using camel case (ex. userModel, postModel)
133
+ // Relation model generation
134
+ relationModel = true // default: generate both plain and related models
135
+ // relationModel = "default" // generate only related models (no plain models)
136
+ // relationModel = false // disable related model generation
137
137
 
138
- modelSuffix = "Model" // (default) Suffix to apply to your prisma models when naming Zod schemas
138
+ // Naming conventions
139
+ modelCase = "PascalCase" // default: UserModel, PostModel
140
+ // modelCase = "camelCase" // userModel, postModel
139
141
 
140
- // useDecimalJs = false // (default) represent the prisma Decimal type using as a JS number
141
- useDecimalJs = true // represent the prisma Decimal type using Decimal.js (as Prisma does)
142
+ // Suffix appended to generated Zod schemas
143
+ modelSuffix = "Model" // default
142
144
 
143
- imports = null // (default) will import the referenced file in generated schemas to be used via imports.someExportedVariable
145
+ // Decimal handling
146
+ // useDecimalJs = false // default: represent Prisma Decimal as number
147
+ useDecimalJs = true // represent Prisma Decimal using Decimal.js (matches Prisma behavior)
144
148
 
145
- // https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-by-null-values
146
- prismaJsonNullability = true // (default) uses prisma's scheme for JSON field nullability
147
- // prismaJsonNullability = false // allows null assignment to optional JSON fields
148
- }
149
+ // Enable coercion for input schemas (e.g. strings → numbers, dates)
150
+ useCoerce = true
151
+
152
+ // Custom imports for generated schemas
153
+ imports = null // default: no additional imports
154
+
155
+ // JSON field nullability behavior
156
+ // See: https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-by-null-values
157
+ prismaJsonNullability = true // default: follow Prisma's JSON nullability rules
158
+ // prismaJsonNullability = false // allow null assignment to optional JSON fields
159
+ }
149
160
  ```
150
161
 
151
162
  3. Run `npx prisma generate` or `pnpm prisma generate` to generate your zod schemas
package/dist/index.js CHANGED
@@ -213047,7 +213047,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
213047
213047
  });
213048
213048
 
213049
213049
  // package.json
213050
- var version = "0.6.2";
213050
+ var version = "0.6.4";
213051
213051
 
213052
213052
  // src/index.ts
213053
213053
  var import_generator_helper = require("@prisma/generator-helper");
@@ -213063,6 +213063,7 @@ var configSchema = import_zod.z.object({
213063
213063
  modelSuffix: import_zod.z.string().default("Model"),
213064
213064
  modelCase: import_zod.z.enum(["PascalCase", "camelCase"]).default("PascalCase"),
213065
213065
  useDecimalJs: configBoolean,
213066
+ useCoerce: configBoolean.default(false),
213066
213067
  imports: import_zod.z.string().optional(),
213067
213068
  prismaJsonNullability: configBoolean
213068
213069
  });
@@ -213132,25 +213133,26 @@ var computeModifiers = (docString) => {
213132
213133
  };
213133
213134
 
213134
213135
  // src/types.ts
213135
- var getZodConstructor = (field, getRelatedModelName = (name) => name.toString(), nativeType) => {
213136
+ var getZodConstructor = (field, getRelatedModelName = (name) => name.toString(), nativeType, useCoerce) => {
213136
213137
  var _a, _b, _c, _d;
213137
213138
  let zodType = "z.unknown()";
213138
- let extraModifiers = [""];
213139
+ const zodVar = useCoerce ? "z.coerce" : "z";
213140
+ const extraModifiers = [""];
213139
213141
  if (field.kind === "scalar") {
213140
213142
  switch (field.type) {
213141
213143
  case "String":
213142
- zodType = "z.string()";
213144
+ zodType = zodVar + ".string()";
213143
213145
  if (nativeType == null ? void 0 : nativeType.match(/^Uuid/)) zodType = "z.uuid()";
213144
- else if (nativeType == null ? void 0 : nativeType.match(/^Citext/)) zodType = "z.string().toLowerCase()";
213146
+ else if (nativeType == null ? void 0 : nativeType.match(/^Citext/)) zodType = zodVar + ".string().toLowerCase()";
213145
213147
  else if (nativeType == null ? void 0 : nativeType.match(/^VarChar\(\d+\)/)) {
213146
213148
  const length = (_a = nativeType.match(/VarChar\((\d+)\)/)) == null ? void 0 : _a[1];
213147
213149
  if (length) extraModifiers.push(`max(${length})`);
213148
213150
  } else if (nativeType == null ? void 0 : nativeType.match(/^Char\(\d+\)/)) {
213149
213151
  const length = (_b = nativeType.match(/Char\((\d+)\)/)) == null ? void 0 : _b[1];
213150
213152
  if (length) extraModifiers.push(`max(${length})`);
213151
- } else if (nativeType == null ? void 0 : nativeType.match(/^Text/)) zodType = "z.string()";
213152
- else if (nativeType == null ? void 0 : nativeType.match(/^VarBit/)) zodType = "z.string()";
213153
- else if (nativeType == null ? void 0 : nativeType.match(/^Bit/)) zodType = "z.string()";
213153
+ } else if (nativeType == null ? void 0 : nativeType.match(/^Text/)) zodType = zodVar + ".string()";
213154
+ else if (nativeType == null ? void 0 : nativeType.match(/^VarBit/)) zodType = zodVar + ".string()";
213155
+ else if (nativeType == null ? void 0 : nativeType.match(/^Bit/)) zodType = zodVar + ".string()";
213154
213156
  else if (nativeType == null ? void 0 : nativeType.match(/^VarBinary/)) zodType = "z.unknown()";
213155
213157
  else if (nativeType == null ? void 0 : nativeType.match(/^Binary/)) zodType = "z.unknown()";
213156
213158
  else if (nativeType == null ? void 0 : nativeType.match(/^NVarChar\(\d+\)/)) {
@@ -213159,11 +213161,11 @@ var getZodConstructor = (field, getRelatedModelName = (name) => name.toString(),
213159
213161
  } else if (nativeType == null ? void 0 : nativeType.match(/^NChar\(\d+\)/)) {
213160
213162
  const length = (_d = nativeType.match(/NChar\((\d+)\)/)) == null ? void 0 : _d[1];
213161
213163
  if (length) extraModifiers.push(`max(${length})`);
213162
- } else if (nativeType == null ? void 0 : nativeType.match(/^NText/)) zodType = "z.string()";
213164
+ } else if (nativeType == null ? void 0 : nativeType.match(/^NText/)) zodType = zodVar + ".string()";
213163
213165
  else if (nativeType == null ? void 0 : nativeType.match(/^ObjectId/)) extraModifiers.push("regex(/^[0-9a-f]{24}$/i)");
213164
213166
  break;
213165
213167
  case "Int":
213166
- zodType = "z.number()";
213168
+ zodType = zodVar + ".number()";
213167
213169
  extraModifiers.push("int()");
213168
213170
  if (nativeType == null ? void 0 : nativeType.match(/^SmallInt/)) extraModifiers.push("min(-32768)", "max(32767)");
213169
213171
  else if (nativeType == null ? void 0 : nativeType.match(/^UnsignedInt/)) extraModifiers.push("min(0)");
@@ -213172,13 +213174,13 @@ var getZodConstructor = (field, getRelatedModelName = (name) => name.toString(),
213172
213174
  else if (nativeType == null ? void 0 : nativeType.match(/^TinyInt/)) extraModifiers.push("min(-128)", "max(127)");
213173
213175
  break;
213174
213176
  case "BigInt":
213175
- zodType = "z.bigint()";
213177
+ zodType = zodVar + ".bigint()";
213176
213178
  break;
213177
213179
  case "Float":
213178
- zodType = "z.coerce.number()";
213180
+ zodType = zodVar + ".number()";
213179
213181
  break;
213180
213182
  case "Decimal":
213181
- zodType = "z.coerce.number()";
213183
+ zodType = zodVar + ".number()";
213182
213184
  if (nativeType == null ? void 0 : nativeType.match(/^Numeric\(\d+,\d+\)/)) {
213183
213185
  const match = nativeType.match(/Numeric\((\d+),(\d+)\)/);
213184
213186
  if (match) {
@@ -213198,19 +213200,21 @@ var getZodConstructor = (field, getRelatedModelName = (name) => name.toString(),
213198
213200
  }
213199
213201
  break;
213200
213202
  case "DateTime":
213201
- zodType = "z.date()";
213202
- if (nativeType == null ? void 0 : nativeType.match(/^TimestampTz/)) zodType = "z.date()";
213203
- else if (nativeType == null ? void 0 : nativeType.match(/^Timestamp/)) zodType = "z.date()";
213203
+ zodType = zodVar + ".date()";
213204
+ if (nativeType == null ? void 0 : nativeType.match(/^TimestampTz/)) zodType = zodVar + ".date()";
213205
+ else if (nativeType == null ? void 0 : nativeType.match(/^Timestamp/)) zodType = zodVar + ".date()";
213204
213206
  else if (nativeType == null ? void 0 : nativeType.match(/^TimeTz/))
213205
- zodType = "z.string().regex(/^\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:\\d{2}$/)";
213206
- else if (nativeType == null ? void 0 : nativeType.match(/^Time/)) zodType = "z.string().regex(/^\\d{2}:\\d{2}:\\d{2}$/)";
213207
- else if (nativeType == null ? void 0 : nativeType.match(/^Date/)) zodType = "z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/)";
213208
- else if (nativeType == null ? void 0 : nativeType.match(/^DateTime/)) zodType = "z.date()";
213209
- else if (nativeType == null ? void 0 : nativeType.match(/^DateTimeOffset/)) zodType = "z.date()";
213210
- else if (nativeType == null ? void 0 : nativeType.match(/^DateTime2/)) zodType = "z.date()";
213207
+ zodType = zodVar + ".string().regex(/^\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:\\d{2}$/)";
213208
+ else if (nativeType == null ? void 0 : nativeType.match(/^Time/))
213209
+ zodType = zodVar + ".string().regex(/^\\d{2}:\\d{2}:\\d{2}$/)";
213210
+ else if (nativeType == null ? void 0 : nativeType.match(/^Date/))
213211
+ zodType = zodVar + ".string().regex(/^\\d{4}-\\d{2}-\\d{2}$/)";
213212
+ else if (nativeType == null ? void 0 : nativeType.match(/^DateTime/)) zodType = zodVar + ".date()";
213213
+ else if (nativeType == null ? void 0 : nativeType.match(/^DateTimeOffset/)) zodType = zodVar + ".date()";
213214
+ else if (nativeType == null ? void 0 : nativeType.match(/^DateTime2/)) zodType = zodVar + ".date()";
213211
213215
  break;
213212
213216
  case "Boolean":
213213
- zodType = "z.boolean()";
213217
+ zodType = zodVar + ".boolean()";
213214
213218
  break;
213215
213219
  case "Bytes":
213216
213220
  zodType = "z.instanceof(Buffer)";
@@ -213362,15 +213366,14 @@ var writeImportsForModel = (model, sourceFile, config, { schemaPath, outputPath,
213362
213366
  var writeTypeSpecificSchemas = (model, sourceFile, config, _prismaOptions) => {
213363
213367
  if (model.fields.some((f) => f.type === "Json")) {
213364
213368
  sourceFile.addStatements((writer) => {
213365
- writer.newLine();
213366
213369
  writeArray(writer, [
213370
+ "",
213367
213371
  "// Helper schema for JSON fields",
213368
- `type Literal = boolean | number | string${config.prismaJsonNullability ? "" : "| null"}`,
213372
+ `type Literal = boolean | number | string${config.prismaJsonNullability ? "" : " | null"}`,
213369
213373
  "type Json = Literal | { [key: string]: Json } | Json[]",
213370
213374
  `const literalSchema = z.union([z.string(), z.number(), z.boolean()${config.prismaJsonNullability ? "" : ", z.null()"}])`,
213371
- "const jsonSchema: z.ZodSchema<Json> = z.lazy(() =>",
213372
- " z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)])",
213373
- ")"
213375
+ // Keep jsonSchema initializer fully on one line
213376
+ "const jsonSchema: z.ZodSchema<Json> = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)]))"
213374
213377
  ]);
213375
213378
  });
213376
213379
  }
@@ -213413,7 +213416,14 @@ var generateSchemaForModel = (model, sourceFile, config, { schemaPath }) => {
213413
213416
  model.fields.filter((f) => f.kind !== "object").forEach((field) => {
213414
213417
  writeArray(writer, getJSDocs(field.documentation));
213415
213418
  const nativeType = modelNativeTypes.get(field.name);
213416
- writer.write(`${field.name}: ${getZodConstructor(field, void 0, nativeType)}`).write(",").newLine();
213419
+ writer.write(
213420
+ `${field.name}: ${getZodConstructor(
213421
+ field,
213422
+ void 0,
213423
+ nativeType,
213424
+ config.useCoerce
213425
+ )}`
213426
+ ).write(",").newLine();
213417
213427
  });
213418
213428
  }).write(")");
213419
213429
  }
@@ -213454,12 +213464,21 @@ var generateRelatedSchemaForModel = (model, sourceFile, config, _prismaOptions)
213454
213464
  name: relatedModelName(model.name),
213455
213465
  type: `z.ZodSchema<Complete${model.name}>`,
213456
213466
  initializer(writer) {
213457
- writer.write(`z.lazy(() => ${modelName(model.name)}.extend(`).inlineBlock(() => {
213458
- relationFields.forEach((field) => {
213459
- writeArray(writer, getJSDocs(field.documentation));
213460
- writer.write(`${field.name}: ${getZodConstructor(field, relatedModelName)}`).write(",").newLine();
213461
- });
213462
- }).write("))");
213467
+ writer.write("z.lazy(() =>").newLine().indent(() => {
213468
+ writer.write(`${modelName(model.name)}.extend({`).newLine().indent(() => {
213469
+ relationFields.forEach((field) => {
213470
+ writeArray(writer, getJSDocs(field.documentation));
213471
+ writer.write(
213472
+ `${field.name}: ${getZodConstructor(
213473
+ field,
213474
+ relatedModelName,
213475
+ null,
213476
+ config.useCoerce
213477
+ )},`
213478
+ ).newLine();
213479
+ });
213480
+ }).write("})");
213481
+ }).newLine().write(")");
213463
213482
  }
213464
213483
  }
213465
213484
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-to-zod-v4",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "A Prisma generator that creates Zod schemas for all of your models",
5
5
  "license": "MIT",
6
6
  "author": "yassinrais",