prisma-class-validator-generator
Version:
Prisma 2+ generator to emit typescript models of your database with class validator
249 lines • 10.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = generateClass;
const path_1 = __importDefault(require("path"));
const helpers_1 = require("./helpers");
async function generateClass(project, config, model) {
if (config.separateRelationFields) {
generateSeparateRelationClasses(project, config, model);
}
else {
generateSingleClass(project, config, model);
}
}
function generateSingleClass(project, config, model) {
const dirPath = path_1.default.resolve(config.outputDir, 'models');
const filePath = path_1.default.resolve(dirPath, `${model.name}.model.ts`);
const sourceFile = project.createSourceFile(filePath, undefined, {
overwrite: true,
});
const validatorImports = [
...new Set(model.fields
.map((field) => (0, helpers_1.getDecoratorsImportsByType)(field))
.flatMap((item) => item)),
];
if ((0, helpers_1.shouldImportPrisma)(model.fields)) {
(0, helpers_1.generatePrismaImport)(sourceFile);
}
(0, helpers_1.generateClassValidatorImport)(sourceFile, validatorImports);
// Add Swagger imports if enabled
if (config.swagger &&
(0, helpers_1.shouldImportSwagger)(model.fields)) {
const swaggerImports = (0, helpers_1.getSwaggerImportsByType)(model.fields);
(0, helpers_1.generateSwaggerImport)(sourceFile, swaggerImports);
}
const relationImports = new Set();
model.fields.forEach((field) => {
if (field.relationName && model.name !== field.type) {
relationImports.add(field.type);
}
});
(0, helpers_1.generateRelationImportsImport)(sourceFile, [
...relationImports,
]);
if ((0, helpers_1.shouldImportHelpers)(model.fields)) {
(0, helpers_1.generateHelpersImports)(sourceFile, ['getEnumValues']);
}
(0, helpers_1.generateEnumImports)(sourceFile, model.fields);
sourceFile.addClass({
name: model.name,
isExported: true,
properties: [
...model.fields.map((field) => {
return {
name: field.name,
type: (0, helpers_1.getTSDataTypeFromFieldType)(field),
hasExclamationToken: field.isRequired,
hasQuestionToken: !field.isRequired,
trailingTrivia: '\r\n',
decorators: (0, helpers_1.getDecoratorsByFieldType)(field, config.swagger),
};
}),
],
});
}
function generateSeparateRelationClasses(project, config, model) {
// Separate base fields from relation fields
const baseFields = model.fields.filter((field) => !field.relationName);
const relationFields = model.fields.filter((field) => field.relationName);
// Generate base class (without relations)
generateBaseClass(project, config, model, baseFields);
// Generate relation class (only relations)
if (relationFields.length > 0) {
generateRelationClass(project, config, model, relationFields);
}
// Generate combined class that extends base and includes relations
generateCombinedClass(project, config, model, baseFields, relationFields);
}
function generateBaseClass(project, config, model, fields) {
const dirPath = path_1.default.resolve(config.outputDir, 'models');
const filePath = path_1.default.resolve(dirPath, `${model.name}Base.model.ts`);
const sourceFile = project.createSourceFile(filePath, undefined, {
overwrite: true,
});
const validatorImports = [
...new Set(fields
.map((field) => (0, helpers_1.getDecoratorsImportsByType)(field))
.flatMap((item) => item)),
];
if ((0, helpers_1.shouldImportPrisma)(fields)) {
(0, helpers_1.generatePrismaImport)(sourceFile);
}
(0, helpers_1.generateClassValidatorImport)(sourceFile, validatorImports);
// Add Swagger imports if enabled
if (config.swagger && (0, helpers_1.shouldImportSwagger)(fields)) {
const swaggerImports = (0, helpers_1.getSwaggerImportsByType)(fields);
(0, helpers_1.generateSwaggerImport)(sourceFile, swaggerImports);
}
if ((0, helpers_1.shouldImportHelpers)(fields)) {
(0, helpers_1.generateHelpersImports)(sourceFile, ['getEnumValues']);
}
(0, helpers_1.generateEnumImports)(sourceFile, fields);
sourceFile.addClass({
name: `${model.name}Base`,
isExported: true,
properties: [
...fields.map((field) => {
return {
name: field.name,
type: (0, helpers_1.getTSDataTypeFromFieldType)(field),
hasExclamationToken: field.isRequired,
hasQuestionToken: !field.isRequired,
trailingTrivia: '\r\n',
decorators: (0, helpers_1.getDecoratorsByFieldType)(field, config.swagger),
};
}),
],
});
}
function generateRelationClass(project, config, model, relationFields) {
const dirPath = path_1.default.resolve(config.outputDir, 'models');
const filePath = path_1.default.resolve(dirPath, `${model.name}Relations.model.ts`);
const sourceFile = project.createSourceFile(filePath, undefined, {
overwrite: true,
});
const validatorImports = [
...new Set(relationFields
.map((field) => (0, helpers_1.getDecoratorsImportsByType)(field))
.flatMap((item) => item)),
];
(0, helpers_1.generateClassValidatorImport)(sourceFile, validatorImports);
// Add Swagger imports if enabled
if (config.swagger &&
(0, helpers_1.shouldImportSwagger)(relationFields)) {
const swaggerImports = (0, helpers_1.getSwaggerImportsByType)(relationFields);
(0, helpers_1.generateSwaggerImport)(sourceFile, swaggerImports);
}
const relationImports = new Set();
let hasSelfRelation = false;
relationFields.forEach((field) => {
if (field.relationName) {
if (model.name !== field.type) {
relationImports.add(field.type);
}
else {
hasSelfRelation = true;
}
}
});
// For self-relations in the Relations class, import the combined model class
if (hasSelfRelation) {
sourceFile.addImportDeclaration({
moduleSpecifier: `./${model.name}.model`,
namedImports: [model.name],
});
}
if (relationImports.size > 0) {
(0, helpers_1.generateRelationImportsImport)(sourceFile, [
...relationImports,
]);
}
sourceFile.addClass({
name: `${model.name}Relations`,
isExported: true,
properties: [
...relationFields.map((field) => {
return {
name: field.name,
type: (0, helpers_1.getTSDataTypeFromFieldType)(field),
hasExclamationToken: field.isRequired,
hasQuestionToken: !field.isRequired,
trailingTrivia: '\r\n',
decorators: (0, helpers_1.getDecoratorsByFieldType)(field, config.swagger),
};
}),
],
});
}
function generateCombinedClass(project, config, model, baseFields, relationFields) {
const dirPath = path_1.default.resolve(config.outputDir, 'models');
const filePath = path_1.default.resolve(dirPath, `${model.name}.model.ts`);
const sourceFile = project.createSourceFile(filePath, undefined, {
overwrite: true,
});
// Import base class
sourceFile.addImportDeclaration({
moduleSpecifier: `./${model.name}Base.model`,
namedImports: [`${model.name}Base`],
});
// Add class validator imports for relation fields
const validatorImports = [
...new Set(relationFields
.map((field) => (0, helpers_1.getDecoratorsImportsByType)(field))
.flatMap((item) => item)),
];
if (validatorImports.length > 0) {
(0, helpers_1.generateClassValidatorImport)(sourceFile, validatorImports);
}
// Add Swagger imports if enabled
if (config.swagger &&
relationFields.length > 0 &&
(0, helpers_1.shouldImportSwagger)(relationFields)) {
const swaggerImports = (0, helpers_1.getSwaggerImportsByType)(relationFields);
(0, helpers_1.generateSwaggerImport)(sourceFile, swaggerImports);
}
// Import relation types for the combined class
const relationImports = new Set();
relationFields.forEach((field) => {
if (field.relationName && model.name !== field.type) {
relationImports.add(field.type);
}
});
if (relationImports.size > 0) {
(0, helpers_1.generateRelationImportsImport)(sourceFile, [
...relationImports,
]);
}
// Combined class extends base and includes relations
if (relationFields.length > 0) {
sourceFile.addClass({
name: model.name,
isExported: true,
extends: `${model.name}Base`,
properties: [
...relationFields.map((field) => {
return {
name: field.name,
type: (0, helpers_1.getTSDataTypeFromFieldType)(field),
hasExclamationToken: field.isRequired,
hasQuestionToken: !field.isRequired,
trailingTrivia: '\r\n',
decorators: (0, helpers_1.getDecoratorsByFieldType)(field, config.swagger),
};
}),
],
});
}
else {
// If no relations, just extend base
sourceFile.addClass({
name: model.name,
isExported: true,
extends: `${model.name}Base`,
});
}
}
//# sourceMappingURL=generate-class.js.map