UNPKG

@arianaprojects/prisma-nestjs-crud-generator

Version:
192 lines (170 loc) 7.31 kB
import { DMMF } from '@prisma/generator-helper/dist/dmmf'; import { classGenerator, importGenerator } from '../templates'; import { defaultGenerator, tsTypes } from '../util'; import Model from './Model'; export default class Types { parent: Model; entity: string; dto: string; constructor(parent: Model) { this.parent = parent; this.generateDTO(); this.generateEntity(); } public get entityDTO(): string { return this.dto; } public get entityGetter(): string { return this.entity; } private generateDTO() { let res: string[] = []; res.push(this.dtoImport()); res.push(this.classGenerator(`Create${this.parent.namePascal}Dto`, this.parent.createFields, true, false, true, false)); res.push(this.classGenerator(`Update${this.parent.namePascal}Dto`, this.parent.updateFields, true, false, true, true)); res.push(this.classGenerator(`Find${this.parent.namePascal}Dto`, this.parent.findFields, true, false, true, true)); res.push(this.classGenerator(`Connect${this.parent.namePascal}Dto`, this.parent.connectFields, true, false, true, false)); res.push(this.classGenerator(`Access${this.parent.namePascal}Dto`, this.parent.accessField, false, false, false, false)); res.push(this.classGenerator(`Deleted${this.parent.namePascal}Dto`, this.parent.deletedField, false, false, false, false)); res.push(this.classGenerator(`Pseudonymisation${this.parent.namePascal}Dto`, this.parent.updateFieldsAdmin, false, false, false, true)); res.push(this.classGenerator(`Create${this.parent.namePascal}AdminDto`, this.parent.createFieldsAdmin, true, false, true, false)); res.push(this.classGenerator(`Update${this.parent.namePascal}AdminDto`, this.parent.updateFieldsAdmin, true, false, true, true)); res.push(this.classGenerator(`Find${this.parent.namePascal}AdminDto`, this.parent.findFieldsAdmin, true, false, true, true)); res.push(this.classGenerator(`Connect${this.parent.namePascal}AdminDto`, this.parent.connectFieldsAdmin, true, false, true, false)); this.dto = res.join('\n\n'); } private generateEntity() { let res: string[] = []; res.push(this.entityImport()); res.push(this.classGenerator(this.parent.namePascal, this.parent.entityFields, true, true, true, false, true)); this.entity = res.join('\n'); } private dtoImport(): string { let res: string[] = [ `import { Exclude, Expose, Type } from 'class-transformer';`, `import { IsArray, IsBoolean, IsDate, IsDecimal, IsEnum, IsNotEmpty, IsNumber, IsObject, IsOptional, IsJSON,IsInt, ValidateNested,IsString } from 'class-validator';`, "import { Decimal } from '@prisma/client/runtime';", "import { ApiProperty } from '@nestjs/swagger';", `import { Prisma, ${this.parent.enumFields .map((f) => { return f.type; }) .join(',')} } from '@prisma/client';`, ]; return res.join('\n'); } private entityImport() { let res: string[] = [ `import { Exclude, Expose, Type } from 'class-transformer';`, `import { IsArray, IsBoolean, IsDate, IsDecimal, IsEnum, IsNotEmpty, IsNumber, IsObject, IsOptional, IsJSON,IsInt, ValidateNested,IsString } from 'class-validator';`, "import { ApiProperty } from '@nestjs/swagger';", "import { Decimal } from '@prisma/client/runtime';", ]; const importPrisma = '{Prisma,' + this.parent.enumFields .map((f) => { return f.type; }) .join(',') + '}'; res.push(importGenerator(importPrisma, '"@prisma/client"')); this.parent.objectFields.map((f) => { res.push(importGenerator('{' + this.parent.toPascalCase(tsTypes(f.type)) + '}', `"../${this.parent.toCamelCase(tsTypes(f.type))}/${this.parent.toCamelCase(tsTypes(f.type))}.entity"`)); }); return res.join('\n'); } private classGenerator(name: string, fields: DMMF.Field[], classValidator: boolean = true, classTransformer: boolean = true, apiProperty: boolean = true, isOptional: boolean = true, entity: boolean = false) { const body = fields.map((f) => this.fieldDecoratorGenerator(f, classValidator, classTransformer, apiProperty, isOptional, entity)).join('\n\n'); return classGenerator(name, body); } private fieldDecoratorGenerator(f: DMMF.Field, classValidator: boolean = true, classTransformer: boolean = true, apiProperty: boolean = true, isOptional: boolean, entity: boolean = false) { let res: string[] = []; if (classTransformer) res.push(this.classTransformerDecorator(f, entity)); if (apiProperty) res.push(this.apiPropertyDecorator(f, isOptional, entity)); if (classValidator) res.push(this.classValidatorDecorator(f, isOptional, entity)); res.push(this.fieldGenerator(f, isOptional, entity)); return res.join('\n'); } private fieldGenerator(f: DMMF.Field, isOptional, entity: boolean = false) { let res: string[] = []; res.push(); res.push(f.name); if (isOptional || !f.isRequired || f.kind == 'object') res.push('?'); res.push(':'); res.push(tsTypes(f.type, entity)); if (f.isList) res.push('[]'); return res.join(' '); } private classTransformerDecorator(f: DMMF.Field, entity: boolean = false) { let res: string[] = []; if (this.parent.isExcludeList(f.name)) res.push('@Exclude()'); return res.join('\n'); } private apiPropertyDecorator(f: DMMF.Field, isOptional, entity: boolean = false) { let res: string[] = []; if (this.parent.isInBlackList(f.name)) return ''; res.push('@ApiProperty({'); // Array if (f.isList) res.push('isArray: true,'); // type if (f.kind == 'object') res.push(`type: ()=>${f.type},`); else if (f.kind == 'enum') res.push(`enum: ${f.type},`); else if (f.kind == 'unsupported') res.push(`// TODO`); if (f.type == 'Decimal' || f.type == 'Float') res.push('type: ()=>Decimal,'); // not required if (isOptional || !f.isRequired) res.push(`required:false,`); // default const d = defaultGenerator(f.name, tsTypes(f.type, entity)); if (!!d) res.push(`default:${d}`); res.push('})'); return res.join('\n'); } private classValidatorDecorator(f: DMMF.Field, isOptional: boolean, entity: boolean = false) { // console.log(f); let res: string[] = []; // array if (f.isList) res.push('@IsArray()'); // required if (!isOptional && f.isRequired && f.kind != 'object') res.push('@IsNotEmpty()'); else res.push('@IsOptional()'); // kind if (f.kind == 'enum') res.push(`@IsEnum( ${f.type} )`); else if (f.kind == 'object') res.push('@ValidateNested()'); //types if (f.type == 'Int' || f.type == 'BigInt') { res.push('@IsInt()'); if (f.isId) res.push('@Type(() => Number)'); } else if (f.type == 'String' || f.type == 'Text') res.push('@IsString()'); else if (f.type == 'DateTime') res.push('@IsDate()'); else if (f.type == 'Boolean') res.push('@IsBoolean()'); else if (f.type == 'Decimal' || f.type == 'Float') res.push('@IsDecimal()'); else if (f.type == 'Json') res.push('@IsJSON()'); else res.push('@IsObject()'); return res.join('\n'); } }