prisma-to-zod-v4 0.6.2 → 0.6.3
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/dist/index.js +49 -80
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -213183,13 +213183,17 @@ var getZodConstructor = (field, getRelatedModelName = (name) => name.toString(),
|
|
|
213183
213183
|
const match = nativeType.match(/Numeric\((\d+),(\d+)\)/);
|
|
213184
213184
|
if (match) {
|
|
213185
213185
|
const [, precision, scale] = match;
|
|
213186
|
-
extraModifiers.push(
|
|
213186
|
+
extraModifiers.push(
|
|
213187
|
+
`refine(x => /^\\d{1,${Number(precision) - parseInt(scale)}}(\\.\\d{1,${scale}})?$/.test(x.toString()))`
|
|
213188
|
+
);
|
|
213187
213189
|
}
|
|
213188
213190
|
} else if (nativeType == null ? void 0 : nativeType.match(/^Decimal\(\d+,\d+\)/)) {
|
|
213189
213191
|
const match = nativeType.match(/Decimal\((\d+),(\d+)\)/);
|
|
213190
213192
|
if (match) {
|
|
213191
213193
|
const [, precision, scale] = match;
|
|
213192
|
-
extraModifiers.push(
|
|
213194
|
+
extraModifiers.push(
|
|
213195
|
+
`refine(x => /^\\d{1,${Number(precision) - parseInt(scale)}}(\\.\\d{1,${scale}})?$/.test(x.toString()))`
|
|
213196
|
+
);
|
|
213193
213197
|
}
|
|
213194
213198
|
}
|
|
213195
213199
|
break;
|
|
@@ -213197,7 +213201,8 @@ var getZodConstructor = (field, getRelatedModelName = (name) => name.toString(),
|
|
|
213197
213201
|
zodType = "z.date()";
|
|
213198
213202
|
if (nativeType == null ? void 0 : nativeType.match(/^TimestampTz/)) zodType = "z.date()";
|
|
213199
213203
|
else if (nativeType == null ? void 0 : nativeType.match(/^Timestamp/)) zodType = "z.date()";
|
|
213200
|
-
else if (nativeType == null ? void 0 : nativeType.match(/^TimeTz/))
|
|
213204
|
+
else if (nativeType == null ? void 0 : nativeType.match(/^TimeTz/))
|
|
213205
|
+
zodType = "z.string().regex(/^\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:\\d{2}$/)";
|
|
213201
213206
|
else if (nativeType == null ? void 0 : nativeType.match(/^Time/)) zodType = "z.string().regex(/^\\d{2}:\\d{2}:\\d{2}$/)";
|
|
213202
213207
|
else if (nativeType == null ? void 0 : nativeType.match(/^Date/)) zodType = "z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/)";
|
|
213203
213208
|
else if (nativeType == null ? void 0 : nativeType.match(/^DateTime/)) zodType = "z.date()";
|
|
@@ -213233,7 +213238,7 @@ var getZodConstructor = (field, getRelatedModelName = (name) => name.toString(),
|
|
|
213233
213238
|
extraModifiers.push(...computeModifiers(field.documentation));
|
|
213234
213239
|
}
|
|
213235
213240
|
if (!field.isRequired && field.type !== "Json") extraModifiers.push("nullish()");
|
|
213236
|
-
const validModifiers = extraModifiers.filter((m) => m !== "");
|
|
213241
|
+
const validModifiers = extraModifiers.filter((m) => m !== "").filter((m, i, l) => l.indexOf(m) === i);
|
|
213237
213242
|
return validModifiers.length > 0 ? `${zodType}.${validModifiers.join(".")}` : zodType;
|
|
213238
213243
|
};
|
|
213239
213244
|
|
|
@@ -213242,60 +213247,41 @@ var parseNativeTypes = (schemaPath) => {
|
|
|
213242
213247
|
var _a;
|
|
213243
213248
|
let schemaContent = "";
|
|
213244
213249
|
let resolvedPath = schemaPath;
|
|
213245
|
-
|
|
213246
|
-
|
|
213247
|
-
|
|
213248
|
-
|
|
213249
|
-
|
|
213250
|
-
|
|
213251
|
-
} else if ((0, import_fs.existsSync)(parentDir)) {
|
|
213252
|
-
resolvedPath = parentDir;
|
|
213253
|
-
} else {
|
|
213254
|
-
console.warn(`Schema path not found: ${schemaPath}`);
|
|
213255
|
-
return /* @__PURE__ */ new Map();
|
|
213256
|
-
}
|
|
213257
|
-
}
|
|
213258
|
-
const stat = (0, import_fs.statSync)(resolvedPath);
|
|
213259
|
-
if (stat.isFile()) {
|
|
213260
|
-
schemaContent = (0, import_fs.readFileSync)(resolvedPath, "utf-8");
|
|
213261
|
-
} else if (stat.isDirectory()) {
|
|
213262
|
-
const prismaFiles = findPrismaFiles(resolvedPath);
|
|
213263
|
-
if (prismaFiles.length === 0) {
|
|
213264
|
-
console.warn(`No .prisma files found in ${resolvedPath}`);
|
|
213265
|
-
return /* @__PURE__ */ new Map();
|
|
213266
|
-
}
|
|
213267
|
-
prismaFiles.forEach((filePath) => {
|
|
213268
|
-
schemaContent += (0, import_fs.readFileSync)(filePath, "utf-8") + "\n";
|
|
213269
|
-
});
|
|
213270
|
-
}
|
|
213271
|
-
} catch (error) {
|
|
213272
|
-
console.error(`Error reading schema path: ${schemaPath}`, error);
|
|
213273
|
-
return /* @__PURE__ */ new Map();
|
|
213250
|
+
if (!(0, import_fs.existsSync)(resolvedPath)) {
|
|
213251
|
+
const withFile = import_path.default.join(schemaPath, "schema.prisma");
|
|
213252
|
+
const parentDir = import_path.default.dirname(schemaPath);
|
|
213253
|
+
if ((0, import_fs.existsSync)(withFile)) resolvedPath = withFile;
|
|
213254
|
+
else if ((0, import_fs.existsSync)(parentDir)) resolvedPath = parentDir;
|
|
213255
|
+
else return /* @__PURE__ */ new Map();
|
|
213274
213256
|
}
|
|
213275
|
-
|
|
213276
|
-
|
|
213277
|
-
|
|
213257
|
+
const stat = (0, import_fs.statSync)(resolvedPath);
|
|
213258
|
+
if (stat.isFile()) schemaContent = (0, import_fs.readFileSync)(resolvedPath, "utf-8");
|
|
213259
|
+
else if (stat.isDirectory()) {
|
|
213260
|
+
const prismaFiles = findPrismaFiles(resolvedPath);
|
|
213261
|
+
if (prismaFiles.length === 0) return /* @__PURE__ */ new Map();
|
|
213262
|
+
prismaFiles.forEach((filePath) => {
|
|
213263
|
+
schemaContent += (0, import_fs.readFileSync)(filePath, "utf-8") + "\n";
|
|
213264
|
+
});
|
|
213278
213265
|
}
|
|
213279
213266
|
const nativeTypes = /* @__PURE__ */ new Map();
|
|
213280
|
-
const modelRegex = /model\s+(\w+)\s*\{([
|
|
213281
|
-
const fieldRegex = /(\w+)\s+(\w+(?:\[\])?)\s+([^;\n]+)/g;
|
|
213267
|
+
const modelRegex = /model\s+(\w+)\s*\{([\s\S]*?)\}/g;
|
|
213282
213268
|
let modelMatch;
|
|
213283
213269
|
while ((modelMatch = modelRegex.exec(schemaContent)) !== null) {
|
|
213284
213270
|
const modelName = modelMatch[1];
|
|
213285
213271
|
const modelBody = modelMatch[2];
|
|
213286
213272
|
const fields = /* @__PURE__ */ new Map();
|
|
213287
|
-
|
|
213288
|
-
|
|
213289
|
-
const
|
|
213290
|
-
|
|
213291
|
-
const
|
|
213292
|
-
if (
|
|
213293
|
-
|
|
213294
|
-
|
|
213295
|
-
|
|
213296
|
-
|
|
213297
|
-
nativeTypes.set(modelName, fields);
|
|
213273
|
+
const lines = modelBody.split("\n");
|
|
213274
|
+
for (const line of lines) {
|
|
213275
|
+
const trimmed = line.trim();
|
|
213276
|
+
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
213277
|
+
const parts = trimmed.split(/\s+/);
|
|
213278
|
+
if (parts.length < 2) continue;
|
|
213279
|
+
const fieldName = parts[0];
|
|
213280
|
+
const attributes = parts.slice(2).join(" ");
|
|
213281
|
+
const dbMatch = (_a = attributes.match(/@db\.([A-Za-z0-9_()]+)/)) == null ? void 0 : _a[1];
|
|
213282
|
+
if (dbMatch) fields.set(fieldName, dbMatch);
|
|
213298
213283
|
}
|
|
213284
|
+
if (fields.size > 0) nativeTypes.set(modelName, fields);
|
|
213299
213285
|
}
|
|
213300
213286
|
return nativeTypes;
|
|
213301
213287
|
};
|
|
@@ -213335,9 +213321,7 @@ var writeImportsForModel = (model, sourceFile, config, { schemaPath, outputPath,
|
|
|
213335
213321
|
importList.push({
|
|
213336
213322
|
kind: import_ts_morph.StructureKind.ImportDeclaration,
|
|
213337
213323
|
namespaceImport: "imports",
|
|
213338
|
-
moduleSpecifier: dotSlash(
|
|
213339
|
-
import_path.default.relative(outputPath, import_path.default.resolve(baseDir, config.imports))
|
|
213340
|
-
)
|
|
213324
|
+
moduleSpecifier: dotSlash(import_path.default.relative(outputPath, import_path.default.resolve(baseDir, config.imports)))
|
|
213341
213325
|
});
|
|
213342
213326
|
}
|
|
213343
213327
|
const hasNonCustomDecimalFieldForImports = model.fields.some(
|
|
@@ -213368,12 +213352,7 @@ var writeImportsForModel = (model, sourceFile, config, { schemaPath, outputPath,
|
|
|
213368
213352
|
kind: import_ts_morph.StructureKind.ImportDeclaration,
|
|
213369
213353
|
moduleSpecifier: "./index",
|
|
213370
213354
|
namedImports: Array.from(
|
|
213371
|
-
new Set(
|
|
213372
|
-
filteredFields.flatMap((f) => [
|
|
213373
|
-
`Complete${f.type}`,
|
|
213374
|
-
relatedModelName(f.type)
|
|
213375
|
-
])
|
|
213376
|
-
)
|
|
213355
|
+
new Set(filteredFields.flatMap((f) => [`Complete${f.type}`, relatedModelName(f.type)]))
|
|
213377
213356
|
)
|
|
213378
213357
|
});
|
|
213379
213358
|
}
|
|
@@ -213389,7 +213368,9 @@ var writeTypeSpecificSchemas = (model, sourceFile, config, _prismaOptions) => {
|
|
|
213389
213368
|
`type Literal = boolean | number | string${config.prismaJsonNullability ? "" : "| null"}`,
|
|
213390
213369
|
"type Json = Literal | { [key: string]: Json } | Json[]",
|
|
213391
213370
|
`const literalSchema = z.union([z.string(), z.number(), z.boolean()${config.prismaJsonNullability ? "" : ", z.null()"}])`,
|
|
213392
|
-
"const jsonSchema: z.ZodSchema<Json> = z.lazy(() =>
|
|
213371
|
+
"const jsonSchema: z.ZodSchema<Json> = z.lazy(() =>",
|
|
213372
|
+
" z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)])",
|
|
213373
|
+
")"
|
|
213393
213374
|
]);
|
|
213394
213375
|
});
|
|
213395
213376
|
}
|
|
@@ -213401,8 +213382,7 @@ var writeTypeSpecificSchemas = (model, sourceFile, config, _prismaOptions) => {
|
|
|
213401
213382
|
writer.newLine();
|
|
213402
213383
|
writeArray(writer, [
|
|
213403
213384
|
"// Helper schema for Decimal fields",
|
|
213404
|
-
"z",
|
|
213405
|
-
".instanceof(Decimal)",
|
|
213385
|
+
"z.instanceof(Decimal)",
|
|
213406
213386
|
".or(z.string())",
|
|
213407
213387
|
".or(z.number())",
|
|
213408
213388
|
".refine((value) => {",
|
|
@@ -213433,13 +213413,7 @@ var generateSchemaForModel = (model, sourceFile, config, { schemaPath }) => {
|
|
|
213433
213413
|
model.fields.filter((f) => f.kind !== "object").forEach((field) => {
|
|
213434
213414
|
writeArray(writer, getJSDocs(field.documentation));
|
|
213435
213415
|
const nativeType = modelNativeTypes.get(field.name);
|
|
213436
|
-
writer.write(
|
|
213437
|
-
`${field.name}: ${getZodConstructor(
|
|
213438
|
-
field,
|
|
213439
|
-
void 0,
|
|
213440
|
-
nativeType
|
|
213441
|
-
)}`
|
|
213442
|
-
).write(",").newLine();
|
|
213416
|
+
writer.write(`${field.name}: ${getZodConstructor(field, void 0, nativeType)}`).write(",").newLine();
|
|
213443
213417
|
});
|
|
213444
213418
|
}).write(")");
|
|
213445
213419
|
}
|
|
@@ -213483,12 +213457,7 @@ var generateRelatedSchemaForModel = (model, sourceFile, config, _prismaOptions)
|
|
|
213483
213457
|
writer.write(`z.lazy(() => ${modelName(model.name)}.extend(`).inlineBlock(() => {
|
|
213484
213458
|
relationFields.forEach((field) => {
|
|
213485
213459
|
writeArray(writer, getJSDocs(field.documentation));
|
|
213486
|
-
writer.write(
|
|
213487
|
-
`${field.name}: ${getZodConstructor(
|
|
213488
|
-
field,
|
|
213489
|
-
relatedModelName
|
|
213490
|
-
)}`
|
|
213491
|
-
).write(",").newLine();
|
|
213460
|
+
writer.write(`${field.name}: ${getZodConstructor(field, relatedModelName)}`).write(",").newLine();
|
|
213492
213461
|
});
|
|
213493
213462
|
}).write("))");
|
|
213494
213463
|
}
|
|
@@ -213522,7 +213491,11 @@ var import_ts_morph2 = require("ts-morph");
|
|
|
213522
213491
|
};
|
|
213523
213492
|
},
|
|
213524
213493
|
onGenerate(options) {
|
|
213525
|
-
const project = new import_ts_morph2.Project(
|
|
213494
|
+
const project = new import_ts_morph2.Project({
|
|
213495
|
+
manipulationSettings: {
|
|
213496
|
+
quoteKind: import_ts_morph2.QuoteKind.Single
|
|
213497
|
+
}
|
|
213498
|
+
});
|
|
213526
213499
|
const models = [...options.dmmf.datamodel.models];
|
|
213527
213500
|
const schemaPath = options.schemaPath;
|
|
213528
213501
|
const schemaDir = import_path2.default.dirname(schemaPath);
|
|
@@ -213542,11 +213515,7 @@ var import_ts_morph2 = require("ts-morph");
|
|
|
213542
213515
|
schemaPath: schemaDir
|
|
213543
213516
|
// Pass the directory, not the file
|
|
213544
213517
|
};
|
|
213545
|
-
const indexFile = project.createSourceFile(
|
|
213546
|
-
`${outputPath}/index.ts`,
|
|
213547
|
-
{},
|
|
213548
|
-
{ overwrite: true }
|
|
213549
|
-
);
|
|
213518
|
+
const indexFile = project.createSourceFile(`${outputPath}/index.ts`, {}, { overwrite: true });
|
|
213550
213519
|
generateBarrelFile(models, indexFile);
|
|
213551
213520
|
indexFile.formatText({
|
|
213552
213521
|
indentSize: 2,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prisma-to-zod-v4",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "A Prisma generator that creates Zod schemas for all of your models",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "yassinrais",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"printWidth": 100,
|
|
38
38
|
"semi": false,
|
|
39
39
|
"singleQuote": true,
|
|
40
|
-
"tabWidth":
|
|
40
|
+
"tabWidth": 2,
|
|
41
41
|
"trailingComma": "es5",
|
|
42
42
|
"useTabs": true
|
|
43
43
|
},
|