nestjs-reverse-engineering
Version:
A powerful TypeScript/NestJS library for database reverse engineering, entity generation, and CRUD operations
883 lines ⢠40 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CrudGenerator = void 0;
/* eslint-disable prettier/prettier */
const fs = require("fs");
const path = require("path");
const database_types_1 = require("../types/database.types");
const naming_utils_1 = require("../utils/naming-utils");
const type_mapper_1 = require("../utils/type-mapper");
class CrudGenerator {
constructor(options = {}) {
this.options = {
outputPath: './src',
dialect: database_types_1.DatabaseDialect.POSTGRES,
framework: 'nestjs',
includeValidation: true,
includeSwagger: true,
includePagination: true,
includeFiltering: true,
includeSorting: true,
includeRelations: true,
generateTests: false,
authGuards: false,
useTypeORM: true,
useDTO: true,
...options
};
}
/**
* Helper method to create a file with content
*/
async createFile(filePath, content) {
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(filePath, content, 'utf8');
}
/**
* Generate CRUD operations for all tables
*/
async generateCrudForTables(tables) {
const result = {
tablesProcessed: 0,
filesGenerated: 0,
outputPaths: [],
modules: []
};
console.log(`š Generating CRUD operations for ${tables.length} tables...`);
for (const table of tables) {
try {
console.log(`š Processing table: ${table.tableName}`);
const moduleInfo = await this.generateCrudForTable(table);
result.tablesProcessed++;
result.filesGenerated += Object.keys(moduleInfo.files).length;
result.outputPaths.push(...Object.values(moduleInfo.files).flat());
result.modules.push(moduleInfo);
console.log(` ā
Generated ${Object.keys(moduleInfo.files).length} files`);
}
catch (error) {
console.error(` ā Failed to process ${table.tableName}:`, error);
}
}
// Generate main app module with all CRUD modules
const appModulePath = await this.generateAppModule(result.modules);
result.outputPaths.push(appModulePath);
result.filesGenerated++;
console.log(`\nā
CRUD generation completed!`);
console.log(`š ${result.tablesProcessed} tables processed`);
console.log(`š ${result.filesGenerated} files generated`);
return result;
}
/**
* Generate CRUD operations for a single table
*/
async generateCrudForTable(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const moduleName = naming_utils_1.NamingUtils.toCamelCase(table.tableName);
const moduleDir = path.join(this.options.outputPath, moduleName);
// Ensure module directory exists
if (!fs.existsSync(moduleDir)) {
fs.mkdirSync(moduleDir, { recursive: true });
}
const moduleInfo = {
tableName: table.tableName,
entityName,
moduleName,
files: {
entity: '',
dto: [],
controller: '',
service: '',
repository: '',
module: '',
tests: []
}
};
// Generate entity file
moduleInfo.files.entity = await this.generateEntity(table, moduleDir);
// Generate DTOs
moduleInfo.files.dto = await this.generateDTOs(table, moduleDir);
// Generate repository
moduleInfo.files.repository = await this.generateRepository(table, moduleDir);
// Generate service
moduleInfo.files.service = await this.generateService(table, moduleDir);
// Generate controller
moduleInfo.files.controller = await this.generateController(table, moduleDir);
// Generate module
moduleInfo.files.module = await this.generateModule(table, moduleDir);
// Generate tests if requested
if (this.options.generateTests) {
moduleInfo.files.tests = await this.generateTests(table, moduleDir);
}
return moduleInfo;
}
/**
* Generate entity file
*/
async generateEntity(table, moduleDir) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const fileName = `${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.entity.ts`;
const filePath = path.join(moduleDir, 'entities', fileName);
// Generate entity content
const content = this.buildEntityContent(table);
// Write file
await this.createFile(filePath, content);
return filePath;
}
/**
* Build entity content
*/
buildEntityContent(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
// Imports
lines.push("import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';");
if (this.options.includeSwagger) {
lines.push("import { ApiProperty } from '@nestjs/swagger';");
}
if (this.options.includeValidation) {
lines.push("import { IsString, IsNumber, IsBoolean, IsOptional, IsDate } from 'class-validator';");
}
lines.push('');
// Entity decorator and class
lines.push(``);
lines.push(`export class ${entityName} {`);
// Generate columns
table.columns.forEach(column => {
lines.push('');
lines.push(...this.buildColumnDecorators(column));
lines.push(` ${this.buildColumnProperty(column)}`);
});
lines.push('}');
return lines.join('\n');
}
/**
* Build column decorators
*/
buildColumnDecorators(column) {
const decorators = [];
// TypeORM decorators
if (column.columnName === 'id' && column.isAutoIncrement) {
decorators.push(' @PrimaryGeneratedColumn()');
}
else if (column.columnName.includes('created_at') || column.columnName.includes('createdAt')) {
decorators.push(' @CreateDateColumn()');
}
else if (column.columnName.includes('updated_at') || column.columnName.includes('updatedAt')) {
decorators.push(' @UpdateDateColumn()');
}
else {
const columnOptions = [];
if (column.columnName !== naming_utils_1.NamingUtils.toCamelCase(column.columnName)) {
columnOptions.push(`name: '${column.columnName}'`);
}
if (column.characterMaximumLength) {
columnOptions.push(`length: ${column.characterMaximumLength}`);
}
if (column.defaultValue) {
columnOptions.push(`default: ${column.defaultValue}`);
}
if (column.isNullable) {
columnOptions.push('nullable: true');
}
const optionsStr = columnOptions.length > 0 ? `{ ${columnOptions.join(', ')} }` : '';
decorators.push(` `);
}
// Swagger decorators
if (this.options.includeSwagger) {
const swaggerOptions = [];
if (column.columnComment) {
swaggerOptions.push(`description: '${column.columnComment}'`);
}
if (column.isNullable) {
swaggerOptions.push('required: false');
}
const swaggerStr = swaggerOptions.length > 0 ? `{ ${swaggerOptions.join(', ')} }` : '';
decorators.push(` `);
}
// Validation decorators
if (this.options.includeValidation) {
const tsType = this.getTypeScriptType(column.dataType);
if (column.isNullable) {
decorators.push(' @IsOptional()');
}
switch (tsType) {
case 'string':
decorators.push(' @IsString()');
break;
case 'number':
decorators.push(' @IsNumber()');
break;
case 'boolean':
decorators.push(' @IsBoolean()');
break;
case 'Date':
decorators.push(' @IsDate()');
break;
}
}
return decorators;
}
/**
* Build column property
*/
buildColumnProperty(column) {
const propertyName = naming_utils_1.NamingUtils.toCamelCase(column.columnName);
const tsType = this.getTypeScriptType(column.dataType);
const nullable = column.isNullable ? '?' : '';
return `${propertyName}${nullable}: ${tsType}${column.isNullable ? ' | null' : ''};`;
}
/**
* Generate DTOs
*/
async generateDTOs(table, moduleDir) {
const dtoDir = path.join(moduleDir, 'dto');
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const filePaths = [];
// Create DTO
const createDtoPath = path.join(dtoDir, `create-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto.ts`);
const createDtoContent = this.buildCreateDtoContent(table);
await this.createFile(createDtoPath, createDtoContent);
filePaths.push(createDtoPath);
// Update DTO
const updateDtoPath = path.join(dtoDir, `update-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto.ts`);
const updateDtoContent = this.buildUpdateDtoContent(table);
await this.createFile(updateDtoPath, updateDtoContent);
filePaths.push(updateDtoPath);
// Query DTO (for filtering)
if (this.options.includeFiltering) {
const queryDtoPath = path.join(dtoDir, `query-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto.ts`);
const queryDtoContent = this.buildQueryDtoContent(table);
await this.createFile(queryDtoPath, queryDtoContent);
filePaths.push(queryDtoPath);
}
return filePaths;
}
/**
* Build Create DTO content
*/
buildCreateDtoContent(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
// Imports
if (this.options.includeSwagger) {
lines.push("import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';");
}
if (this.options.includeValidation) {
lines.push("import { IsString, IsNumber, IsBoolean, IsOptional, IsDate } from 'class-validator';");
}
lines.push('');
// Class
lines.push(`export class Create${entityName}Dto {`);
// Generate properties (exclude id, created_at, updated_at)
const createColumns = table.columns.filter(col => !col.isAutoIncrement &&
!col.columnName.includes('created_at') &&
!col.columnName.includes('updated_at'));
createColumns.forEach(column => {
lines.push('');
lines.push(...this.buildDtoPropertyDecorators(column));
lines.push(` ${this.buildDtoProperty(column)}`);
});
lines.push('}');
return lines.join('\n');
}
/**
* Build Update DTO content
*/
buildUpdateDtoContent(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
// Imports
lines.push(`import { PartialType } from '@nestjs/mapped-types';`);
lines.push(`import { Create${entityName}Dto } from './create-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
lines.push('');
// Class
lines.push(`export class Update${entityName}Dto extends PartialType(Create${entityName}Dto) {}`);
return lines.join('\n');
}
/**
* Build Query DTO content
*/
buildQueryDtoContent(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
// Imports
if (this.options.includeSwagger) {
lines.push("import { ApiPropertyOptional } from '@nestjs/swagger';");
}
if (this.options.includeValidation) {
lines.push("import { IsOptional, IsNumber, IsString } from 'class-validator';");
lines.push("import { Transform } from 'class-transformer';");
}
lines.push('');
// Class
lines.push(`export class Query${entityName}Dto {`);
// Pagination properties
if (this.options.includePagination) {
lines.push('');
if (this.options.includeSwagger) {
lines.push(" @ApiPropertyOptional({ description: 'Page number for pagination' })");
}
if (this.options.includeValidation) {
lines.push(' @IsOptional()');
lines.push(' @IsNumber()');
lines.push(' @Transform(({ value }) => parseInt(value))');
}
lines.push(' page?: number;');
lines.push('');
if (this.options.includeSwagger) {
lines.push(" @ApiPropertyOptional({ description: 'Number of items per page' })");
}
if (this.options.includeValidation) {
lines.push(' @IsOptional()');
lines.push(' @IsNumber()');
lines.push(' @Transform(({ value }) => parseInt(value))');
}
lines.push(' limit?: number;');
}
// Filtering properties for searchable columns
if (this.options.includeFiltering) {
const searchableColumns = table.columns.filter(col => col.dataType.includes('varchar') ||
col.dataType.includes('text') ||
col.dataType.includes('char'));
searchableColumns.forEach(column => {
const propertyName = naming_utils_1.NamingUtils.toCamelCase(column.columnName);
lines.push('');
if (this.options.includeSwagger) {
lines.push(` `);
}
if (this.options.includeValidation) {
lines.push(' @IsOptional()');
lines.push(' @IsString()');
}
lines.push(` ${propertyName}?: string;`);
});
}
// Sorting properties
if (this.options.includeSorting) {
lines.push('');
if (this.options.includeSwagger) {
lines.push(" @ApiPropertyOptional({ description: 'Field to sort by' })");
}
if (this.options.includeValidation) {
lines.push(' @IsOptional()');
lines.push(' @IsString()');
}
lines.push(' sortBy?: string;');
lines.push('');
if (this.options.includeSwagger) {
lines.push(" @ApiPropertyOptional({ description: 'Sort direction', enum: ['ASC', 'DESC'] })");
}
if (this.options.includeValidation) {
lines.push(' @IsOptional()');
lines.push(' @IsString()');
}
lines.push(" sortOrder?: 'ASC' | 'DESC';");
}
lines.push('}');
return lines.join('\n');
}
/**
* Build DTO property decorators
*/
buildDtoPropertyDecorators(column) {
const decorators = [];
const propertyName = naming_utils_1.NamingUtils.toCamelCase(column.columnName);
// Swagger decorators
if (this.options.includeSwagger) {
const swaggerOptions = [];
if (column.columnComment) {
swaggerOptions.push(`description: '${column.columnComment}'`);
}
const swaggerStr = swaggerOptions.length > 0 ? `{ ${swaggerOptions.join(', ')} }` : '';
if (column.isNullable) {
decorators.push(` `);
}
else {
decorators.push(` `);
}
}
// Validation decorators
if (this.options.includeValidation) {
const tsType = this.getTypeScriptType(column.dataType);
if (column.isNullable) {
decorators.push(' @IsOptional()');
}
switch (tsType) {
case 'string':
decorators.push(' @IsString()');
break;
case 'number':
decorators.push(' @IsNumber()');
break;
case 'boolean':
decorators.push(' @IsBoolean()');
break;
case 'Date':
decorators.push(' @IsDate()');
break;
}
}
return decorators;
}
/**
* Build DTO property
*/
buildDtoProperty(column) {
const propertyName = naming_utils_1.NamingUtils.toCamelCase(column.columnName);
const tsType = this.getTypeScriptType(column.dataType);
const nullable = column.isNullable ? '?' : '';
return `${propertyName}${nullable}: ${tsType}${column.isNullable ? ' | null' : ''};`;
}
/**
* Generate repository
*/
async generateRepository(table, moduleDir) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const fileName = `${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.repository.ts`;
const filePath = path.join(moduleDir, fileName);
const content = this.buildRepositoryContent(table);
await this.createFile(filePath, content);
return filePath;
}
/**
* Build repository content
*/
buildRepositoryContent(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
// Imports
lines.push("import { Injectable } from '@nestjs/common';");
lines.push("import { InjectRepository } from '@nestjs/typeorm';");
lines.push("import { Repository, FindManyOptions } from 'typeorm';");
lines.push(`import { ${entityName} } from './entities/${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.entity';`);
lines.push(`import { Create${entityName}Dto } from './dto/create-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
lines.push(`import { Update${entityName}Dto } from './dto/update-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
if (this.options.includeFiltering) {
lines.push(`import { Query${entityName}Dto } from './dto/query-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
}
lines.push('');
// Repository class
lines.push('@Injectable()');
lines.push(`export class ${entityName}Repository {`);
lines.push(` constructor(`);
lines.push(` `);
lines.push(` private readonly repository: Repository<${entityName}>,`);
lines.push(` ) {}`);
// Create method
lines.push('');
lines.push(` async create(create${entityName}Dto: Create${entityName}Dto): Promise<${entityName}> {`);
lines.push(` const entity = this.repository.create(create${entityName}Dto);`);
lines.push(` return await this.repository.save(entity);`);
lines.push(` }`);
// Find all method
lines.push('');
if (this.options.includeFiltering) {
lines.push(` async findAll(queryDto?: Query${entityName}Dto): Promise<{ data: ${entityName}[], total: number }> {`);
lines.push(` const { page = 1, limit = 10, sortBy = 'id', sortOrder = 'DESC', ...filters } = queryDto || {};`);
lines.push(` `);
lines.push(` const options: FindManyOptions<${entityName}> = {`);
lines.push(` where: this.buildWhereClause(filters),`);
lines.push(` order: { [sortBy]: sortOrder },`);
if (this.options.includePagination) {
lines.push(` skip: (page - 1) * limit,`);
lines.push(` take: limit,`);
}
lines.push(` };`);
lines.push(` `);
lines.push(` const [data, total] = await this.repository.findAndCount(options);`);
lines.push(` return { data, total };`);
}
else {
lines.push(` async findAll(): Promise<${entityName}[]> {`);
lines.push(` return await this.repository.find();`);
}
lines.push(` }`);
// Find one method
lines.push('');
lines.push(` async findOne(id: number): Promise<${entityName}> {`);
lines.push(` const entity = await this.repository.findOne({ where: { id } as any });`);
lines.push(` if (!entity) {`);
lines.push(` throw new Error(\`${entityName} with ID \${id} not found\`);`);
lines.push(` }`);
lines.push(` return entity;`);
lines.push(` }`);
// Update method
lines.push('');
lines.push(` async update(id: number, update${entityName}Dto: Update${entityName}Dto): Promise<${entityName}> {`);
lines.push(` const entity = await this.findOne(id);`);
lines.push(` Object.assign(entity, update${entityName}Dto);`);
lines.push(` return await this.repository.save(entity);`);
lines.push(` }`);
// Remove method
lines.push('');
lines.push(` async remove(id: number): Promise<void> {`);
lines.push(` const entity = await this.findOne(id);`);
lines.push(` await this.repository.remove(entity);`);
lines.push(` }`);
// Build where clause helper
if (this.options.includeFiltering) {
lines.push('');
lines.push(` private buildWhereClause(filters: any): any {`);
lines.push(` const where: any = {};`);
lines.push(` `);
lines.push(` // Add filter conditions`);
const searchableColumns = table.columns.filter(col => col.dataType.includes('varchar') ||
col.dataType.includes('text') ||
col.dataType.includes('char'));
searchableColumns.forEach(column => {
const propertyName = naming_utils_1.NamingUtils.toCamelCase(column.columnName);
lines.push(` if (filters.${propertyName}) {`);
lines.push(` where.${propertyName} = filters.${propertyName};`);
lines.push(` }`);
});
lines.push(` `);
lines.push(` return where;`);
lines.push(` }`);
}
lines.push('}');
return lines.join('\n');
}
/**
* Generate service
*/
async generateService(table, moduleDir) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const fileName = `${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.service.ts`;
const filePath = path.join(moduleDir, fileName);
const content = this.buildServiceContent(table);
await this.createFile(filePath, content);
return filePath;
}
/**
* Build service content
*/
buildServiceContent(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
// Imports
lines.push("import { Injectable } from '@nestjs/common';");
lines.push(`import { ${entityName}Repository } from './${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.repository';`);
lines.push(`import { Create${entityName}Dto } from './dto/create-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
lines.push(`import { Update${entityName}Dto } from './dto/update-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
if (this.options.includeFiltering) {
lines.push(`import { Query${entityName}Dto } from './dto/query-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
}
lines.push('');
// Service class
lines.push('@Injectable()');
lines.push(`export class ${entityName}Service {`);
lines.push(` constructor(private readonly ${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Repository: ${entityName}Repository) {}`);
// Create method
lines.push('');
lines.push(` async create(create${entityName}Dto: Create${entityName}Dto) {`);
lines.push(` return await this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Repository.create(create${entityName}Dto);`);
lines.push(` }`);
// Find all method
lines.push('');
lines.push(` async findAll(${this.options.includeFiltering ? `queryDto?: Query${entityName}Dto` : ''}) {`);
if (this.options.includeFiltering) {
lines.push(` return await this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Repository.findAll(queryDto);`);
}
else {
lines.push(` return await this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Repository.findAll();`);
}
lines.push(` }`);
// Find one method
lines.push('');
lines.push(` async findOne(id: number) {`);
lines.push(` const entity = await this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Repository.findOne(id);`);
lines.push(` if (!entity) {`);
lines.push(` throw new Error(\`${entityName} with ID \${id} not found\`);`);
lines.push(` }`);
lines.push(` return entity;`);
lines.push(` }`);
// Update method
lines.push('');
lines.push(` async update(id: number, update${entityName}Dto: Update${entityName}Dto) {`);
lines.push(` const entity = await this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Repository.update(id, update${entityName}Dto);`);
lines.push(` if (!entity) {`);
lines.push(` throw new Error(\`${entityName} with ID \${id} not found\`);`);
lines.push(` }`);
lines.push(` return entity;`);
lines.push(` }`);
// Remove method
lines.push('');
lines.push(` async remove(id: number) {`);
lines.push(` const deleted = await this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Repository.remove(id);`);
lines.push(` if (!deleted) {`);
lines.push(` throw new Error(\`${entityName} with ID \${id} not found\`);`);
lines.push(` }`);
lines.push(` return { message: \`${entityName} deleted successfully\` };`);
lines.push(` }`);
lines.push('}');
return lines.join('\n');
}
/**
* Generate controller
*/
async generateController(table, moduleDir) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const fileName = `${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.controller.ts`;
const filePath = path.join(moduleDir, fileName);
const content = this.buildControllerContent(table);
await this.createFile(filePath, content);
return filePath;
}
/**
* Build controller content
*/
buildControllerContent(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const controllerPath = naming_utils_1.NamingUtils.toKebabCase(table.tableName);
const lines = [];
// Imports
lines.push("import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common';");
if (this.options.includeSwagger) {
lines.push("import { ApiTags, ApiOperation, ApiResponse, ApiParam } from '@nestjs/swagger';");
}
if (this.options.includeValidation) {
lines.push("import { ParseIntPipe } from '@nestjs/common';");
}
if (this.options.authGuards) {
lines.push("import { UseGuards } from '@nestjs/common';");
lines.push("import { JwtAuthGuard } from '../auth/jwt-auth.guard';");
}
lines.push(`import { ${entityName}Service } from './${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.service';`);
lines.push(`import { Create${entityName}Dto } from './dto/create-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
lines.push(`import { Update${entityName}Dto } from './dto/update-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
if (this.options.includeFiltering) {
lines.push(`import { Query${entityName}Dto } from './dto/query-${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.dto';`);
}
lines.push('');
// Controller decorators
if (this.options.includeSwagger) {
lines.push(``);
}
if (this.options.authGuards) {
lines.push('@UseGuards(JwtAuthGuard)');
}
lines.push(``);
lines.push(`export class ${entityName}Controller {`);
lines.push(` constructor(private readonly ${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Service: ${entityName}Service) {}`);
// CREATE endpoint
lines.push('');
lines.push(...this.buildCreateEndpoint(table));
// FIND ALL endpoint
lines.push('');
lines.push(...this.buildFindAllEndpoint(table));
// FIND ONE endpoint
lines.push('');
lines.push(...this.buildFindOneEndpoint(table));
// UPDATE endpoint
lines.push('');
lines.push(...this.buildUpdateEndpoint(table));
// DELETE endpoint
lines.push('');
lines.push(...this.buildDeleteEndpoint(table));
lines.push('}');
return lines.join('\n');
}
/**
* Build CREATE endpoint
*/
buildCreateEndpoint(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
if (this.options.includeSwagger) {
lines.push(` `);
lines.push(` `);
lines.push(` `);
}
lines.push(` `);
lines.push(` create( create${entityName}Dto: Create${entityName}Dto) {`);
lines.push(` return this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Service.create(create${entityName}Dto);`);
lines.push(` }`);
return lines;
}
/**
* Build FIND ALL endpoint
*/
buildFindAllEndpoint(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
if (this.options.includeSwagger) {
lines.push(` `);
lines.push(` `);
}
lines.push(` `);
if (this.options.includeFiltering) {
lines.push(` findAll( queryDto: Query${entityName}Dto) {`);
lines.push(` return this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Service.findAll(queryDto);`);
}
else {
lines.push(` findAll() {`);
lines.push(` return this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Service.findAll();`);
}
lines.push(` }`);
return lines;
}
/**
* Build FIND ONE endpoint
*/
buildFindOneEndpoint(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
if (this.options.includeSwagger) {
lines.push(` `);
lines.push(` `);
lines.push(` `);
lines.push(` `);
}
lines.push(` `);
if (this.options.includeValidation) {
lines.push(` findOne( id: number) {`);
}
else {
lines.push(` findOne( id: string) {`);
}
lines.push(` return this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Service.findOne(${this.options.includeValidation ? 'id' : '+id'});`);
lines.push(` }`);
return lines;
}
/**
* Build UPDATE endpoint
*/
buildUpdateEndpoint(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
if (this.options.includeSwagger) {
lines.push(` `);
lines.push(` `);
lines.push(` `);
lines.push(` `);
}
lines.push(` `);
if (this.options.includeValidation) {
lines.push(` update( id: number, update${entityName}Dto: Update${entityName}Dto) {`);
}
else {
lines.push(` update( id: string, update${entityName}Dto: Update${entityName}Dto) {`);
}
lines.push(` return this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Service.update(${this.options.includeValidation ? 'id' : '+id'}, update${entityName}Dto);`);
lines.push(` }`);
return lines;
}
/**
* Build DELETE endpoint
*/
buildDeleteEndpoint(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const lines = [];
if (this.options.includeSwagger) {
lines.push(` `);
lines.push(` `);
lines.push(` `);
lines.push(` `);
}
lines.push(` `);
if (this.options.includeValidation) {
lines.push(` remove( id: number) {`);
}
else {
lines.push(` remove( id: string) {`);
}
lines.push(` return this.${naming_utils_1.NamingUtils.toCamelCase(table.tableName)}Service.remove(${this.options.includeValidation ? 'id' : '+id'});`);
lines.push(` }`);
return lines;
}
/**
* Generate module
*/
async generateModule(table, moduleDir) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const fileName = `${naming_utils_1.NamingUtils.toKebabCase(table.tableName)}.module.ts`;
const filePath = path.join(moduleDir, fileName);
const content = this.buildModuleContent(table);
await this.createFile(filePath, content);
return filePath;
}
/**
* Build module content
*/
buildModuleContent(table) {
const entityName = naming_utils_1.NamingUtils.toPascalCase(table.tableName);
const kebabName = naming_utils_1.NamingUtils.toKebabCase(table.tableName);
const lines = [];
// Imports
lines.push("import { Module } from '@nestjs/common';");
lines.push("import { TypeOrmModule } from '@nestjs/typeorm';");
lines.push(`import { ${entityName}Controller } from './${kebabName}.controller';`);
lines.push(`import { ${entityName}Service } from './${kebabName}.service';`);
lines.push(`import { ${entityName}Repository } from './${kebabName}.repository';`);
lines.push(`import { ${entityName} } from './entities/${kebabName}.entity';`);
lines.push('');
// Module decorator
lines.push('@Module({');
lines.push(' imports: [');
lines.push(` TypeOrmModule.forFeature([${entityName}]),`);
lines.push(' ],');
lines.push(` controllers: [${entityName}Controller],`);
lines.push(` providers: [${entityName}Service, ${entityName}Repository],`);
lines.push(` exports: [${entityName}Service, ${entityName}Repository],`);
lines.push('})');
lines.push(`export class ${entityName}Module {}`);
return lines.join('\n');
}
/**
* Generate tests
*/
async generateTests(table, moduleDir) {
const filePaths = [];
// Test generation implementation would go here
// For now, return empty array
return filePaths;
}
/**
* Generate app module with all CRUD modules
*/
async generateAppModule(modules) {
const filePath = path.join(this.options.outputPath, 'app.module.ts');
const lines = [];
// Imports
lines.push("import { Module } from '@nestjs/common';");
lines.push("import { TypeOrmModule } from '@nestjs/typeorm';");
modules.forEach(module => {
lines.push(`import { ${module.entityName}Module } from './${module.moduleName}/${naming_utils_1.NamingUtils.toKebabCase(module.tableName)}.module';`);
});
lines.push('');
// App Module
lines.push('@Module({');
lines.push(' imports: [');
lines.push(' TypeOrmModule.forRoot({');
lines.push(' // Database configuration goes here');
lines.push(' // type: \'postgres\',');
lines.push(' // host: \'localhost\',');
lines.push(' // port: 5432,');
lines.push(' // username: \'your-username\',');
lines.push(' // password: \'your-password\',');
lines.push(' // database: \'your-database\',');
lines.push(' // entities: [__dirname + \'/**/*.entity{.ts,.js}\'],');
lines.push(' // synchronize: true,');
lines.push(' }),');
modules.forEach(module => {
lines.push(` ${module.entityName}Module,`);
});
lines.push(' ],');
lines.push('})');
lines.push('export class AppModule {}');
await this.createFile(filePath, lines.join('\n'));
return filePath;
}
/**
* Get TypeScript type from database type
*/
getTypeScriptType(dataType) {
const mapping = type_mapper_1.TypeMapper.mapType(dataType, this.options.dialect);
return mapping.tsType;
}
}
exports.CrudGenerator = CrudGenerator;
//# sourceMappingURL=crud-generator-fixed.js.map