@conte-ltd/prisma-zod-generator
Version:
Prisma 2+ generator to emit Zod schemas from your Prisma schema
231 lines • 11.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generate = void 0;
const internals_1 = require("@prisma/internals");
const removeDir_1 = __importDefault(require("./utils/removeDir"));
const fs_1 = require("fs");
const transformer_1 = __importDefault(require("./transformer"));
const project_1 = require("./project");
const path_1 = __importDefault(require("path"));
const capitalizeFirstLetter_1 = require("./utils/capitalizeFirstLetter");
const formatFile_1 = require("./utils/formatFile");
async function generate(options) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
const outputDir = (0, internals_1.parseEnvValue)(options.generator.output);
await fs_1.promises.mkdir(outputDir, { recursive: true });
await (0, removeDir_1.default)(outputDir, true);
const prismaClientProvider = options.otherGenerators.find((it) => (0, internals_1.parseEnvValue)(it.provider) === 'prisma-client-js');
const prismaClientDmmf = await (0, internals_1.getDMMF)({
datamodel: options.datamodel,
previewFeatures: prismaClientProvider === null || prismaClientProvider === void 0 ? void 0 : prismaClientProvider.previewFeatures,
});
transformer_1.default.isDefaultPrismaClientOutput =
(_a = prismaClientProvider === null || prismaClientProvider === void 0 ? void 0 : prismaClientProvider.isCustomOutput) !== null && _a !== void 0 ? _a : false;
if (prismaClientProvider === null || prismaClientProvider === void 0 ? void 0 : prismaClientProvider.isCustomOutput) {
transformer_1.default.prismaClientOutputPath =
(_c = (_b = prismaClientProvider === null || prismaClientProvider === void 0 ? void 0 : prismaClientProvider.output) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : '';
}
transformer_1.default.setOutputPath(outputDir);
const routeFile = project_1.project.createSourceFile(path_1.default.resolve(outputDir, 'index.ts'));
const enumRouteFile = project_1.project.createSourceFile(path_1.default.resolve(outputDir, 'enums/index.ts'), undefined, {
overwrite: true,
});
const enumTypes = [
...prismaClientDmmf.schema.enumTypes.prisma,
...((_d = prismaClientDmmf.schema.enumTypes.model) !== null && _d !== void 0 ? _d : []),
];
const enumNames = enumTypes.map((enumItem) => enumItem.name);
transformer_1.default.enumNames = enumNames !== null && enumNames !== void 0 ? enumNames : [];
for (const enumType of enumTypes) {
const enumsObj = new transformer_1.default({
enumType,
sourceFile: project_1.project.createSourceFile(path_1.default.resolve(outputDir, `enums/${enumType.name}.schema.ts`), undefined, { overwrite: true }),
});
const sourceFile = enumsObj.printEnumSchemas();
const formattedText = await (0, formatFile_1.formatFile)(sourceFile.getFullText());
sourceFile.replaceWithText(formattedText);
enumRouteFile.addExportDeclaration({
moduleSpecifier: `./${enumType.name}.schema`,
});
}
const objectRouteFile = project_1.project.createSourceFile(path_1.default.resolve(outputDir, 'objects/index.ts'), undefined, {
overwrite: true,
});
for (let i = 0; i < prismaClientDmmf.schema.inputObjectTypes.prisma.length; i += 1) {
const fields = (_e = prismaClientDmmf.schema.inputObjectTypes.prisma[i]) === null || _e === void 0 ? void 0 : _e.fields.map((field) => ({
...field,
inputTypes: field.inputTypes.filter((inputType) => {
const exclusion = typeof inputType.type === 'string' &&
(inputType.type.endsWith('RefInput') ||
inputType.type.includes('Unchecked'));
return !exclusion;
}),
}));
const name = (_f = prismaClientDmmf.schema.inputObjectTypes.prisma[i]) === null || _f === void 0 ? void 0 : _f.name;
if (name.includes('Unchecked')) {
continue;
}
const obj = new transformer_1.default({
name,
fields,
sourceFile: project_1.project.createSourceFile(path_1.default.resolve(outputDir, `objects/${name}.schema.ts`), undefined, { overwrite: true }),
});
const sourceFile = obj.printObjectSchemas();
const formattedText = await (0, formatFile_1.formatFile)(sourceFile.getFullText());
sourceFile.replaceWithText(formattedText);
objectRouteFile.addExportDeclaration({
moduleSpecifier: `./${name}.schema`,
});
}
for (let i = 0; i < prismaClientDmmf.datamodel.models.length; i += 1) {
const fields = (_g = prismaClientDmmf.datamodel.models[i]) === null || _g === void 0 ? void 0 : _g.fields;
const modelName = (_h = prismaClientDmmf.datamodel.models[i]) === null || _h === void 0 ? void 0 : _h.name;
let name = `${modelName}Select`;
let obj = new transformer_1.default({
name,
fields,
sourceFile: project_1.project.createSourceFile(path_1.default.resolve(outputDir, `objects/${name}.schema.ts`), undefined, { overwrite: true }),
});
let sourceFile = obj.printSelectObjectSchemas();
let formattedText = await (0, formatFile_1.formatFile)(sourceFile.getFullText());
sourceFile.replaceWithText(formattedText);
objectRouteFile.addExportDeclaration({
moduleSpecifier: `./${name}.schema`,
});
const hasRelatedField = fields.some((field) => field.relationName);
if (hasRelatedField) {
name = `${modelName}Include`;
obj = new transformer_1.default({
name,
fields,
sourceFile: project_1.project.createSourceFile(path_1.default.resolve(outputDir, `objects/${name}.schema.ts`), undefined, { overwrite: true }),
});
sourceFile = obj.printSelectObjectSchemas(true);
formattedText = await (0, formatFile_1.formatFile)(sourceFile.getFullText());
sourceFile.replaceWithText(formattedText);
objectRouteFile.addExportDeclaration({
moduleSpecifier: `./${name}.schema`,
});
name = `${modelName}Args`;
obj = new transformer_1.default({
name,
fields,
sourceFile: project_1.project.createSourceFile(path_1.default.resolve(outputDir, `objects/${name}.schema.ts`), undefined, { overwrite: true }),
});
sourceFile = obj.printArgsObjectSchemas(modelName);
formattedText = await (0, formatFile_1.formatFile)(sourceFile.getFullText());
sourceFile.replaceWithText(formattedText);
objectRouteFile.addExportDeclaration({
moduleSpecifier: `./${name}.schema`,
});
}
}
const models = prismaClientDmmf.datamodel.models;
for (const outputType of prismaClientDmmf.schema.outputObjectTypes.prisma) {
if (outputType.name !== 'Query' && outputType.name !== 'Mutation') {
continue;
}
for (const field of outputType.fields) {
const name = field.name;
const modelName = (_j = getModelNameWithSelect(name)) === null || _j === void 0 ? void 0 : _j.replace('OrThrow', '');
const hasRelated = models
.filter((model) => model.name === modelName)
.some((model) => model.fields.some((field) => field.relationName));
const args = field.args.map((arg) => ({
...arg,
inputTypes: arg.inputTypes.filter((type) => !String(type.type).includes('Unchecked')),
}));
const fields = name.startsWith('groupBy')
? args.map((arg) => {
if (arg.name === 'orderBy') {
return {
...arg,
isRequired: true,
};
}
else if (arg.name === 'by') {
return {
...arg,
inputTypes: arg.inputTypes.filter((inputType) => inputType.isList),
};
}
else {
return arg;
}
})
: args;
if (modelName) {
fields.push({
name: 'select',
isRequired: false,
isNullable: false,
inputTypes: [
{
type: `${modelName}Select`,
namespace: 'prisma',
location: 'inputObjectTypes',
isList: false,
},
],
});
if (hasRelated) {
fields.push({
name: 'include',
isRequired: false,
isNullable: false,
inputTypes: [
{
type: `${modelName}Include`,
namespace: 'prisma',
location: 'inputObjectTypes',
isList: false,
},
],
});
}
}
if (name === 'executeRaw' || name === 'queryRaw') {
continue;
}
const obj = new transformer_1.default({
name,
fields,
sourceFile: project_1.project.createSourceFile(path_1.default.resolve(outputDir, `${(0, capitalizeFirstLetter_1.capitalizeFirstLetter)(name)}.schema.ts`), undefined, { overwrite: true }),
});
const sourceFile = obj.printModelSchema();
const formattedText = await (0, formatFile_1.formatFile)(sourceFile.getFullText());
sourceFile.replaceWithText(formattedText);
routeFile.addExportDeclaration({
moduleSpecifier: `./${(0, capitalizeFirstLetter_1.capitalizeFirstLetter)(name)}.schema`,
});
}
}
routeFile.addExportDeclaration({
moduleSpecifier: './enums',
});
routeFile.addExportDeclaration({
moduleSpecifier: './objects',
});
await project_1.project.save();
}
exports.generate = generate;
function getModelNameWithSelect(name) {
for (const method of [
'findUnique',
'findFirst',
'findMany',
'createOne',
'updateOne',
'upsertOne',
'deleteOne',
]) {
if (name.startsWith(method)) {
return name.replace(method, '');
}
}
return null;
}
//# sourceMappingURL=prisma-generator.js.map