├── .gitignore ├── .npmignore ├── README.md ├── bin └── index.js ├── package.json └── templates ├── common ├── controller.template.ts ├── dto.template.ts ├── module.template.ts ├── service.template.ts └── update.dto.template.ts └── repositories ├── mikroorm ├── entity.template.ts └── repository.template.ts ├── mongoose ├── entity.template.ts └── repository.template.ts ├── prisma ├── entity.template.ts └── repository.template.ts ├── sequelize ├── entity.template.ts └── repository.template.ts └── typeorm ├── entity.template.ts └── repository.template.ts /.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # package json 15 | package-lock.json 16 | 17 | # OS 18 | .DS_Store 19 | # Tests 20 | /coverage 21 | /.nyc_output 22 | 23 | # IDEs and editors 24 | /.idea 25 | .project 26 | .classpath 27 | .c9/ 28 | *.launch 29 | .settings/ 30 | *.sublime-workspace 31 | 32 | # IDE - VSCode 33 | .vscode/* 34 | !.vscode/settings.json 35 | !.vscode/tasks.json 36 | !.vscode/launch.json 37 | !.vscode/extensions.json 38 | 39 | # Environments 40 | .env -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .git 3 | .gitignore 4 | .env 5 | .log 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NestJS CRUD Generator 🚀 2 | 3 | A powerful and user-friendly CLI tool that generates complete CRUD operations for NestJS applications with support for multiple ORMs. 4 | 5 | ## Features ✨ 6 | 7 | - 🛠️ Generates complete CRUD operations 8 | - 🔌 Supports multiple ORMs: 9 | - TypeORM 10 | - Prisma 11 | - Mongoose 12 | - Sequelize 13 | - MikroORM 14 | - 📁 Creates all necessary files: 15 | - Controller 16 | - Service 17 | - Repository 18 | - Entity 19 | - DTOs 20 | - Module 21 | - 🤖 Automatic dependency installation 22 | - 🎨 Clean and consistent code structure 23 | 24 | ## Installation 📦 25 | bash 26 | 27 | npm install -g nestjs-crud-generator 28 | 29 | 30 | ## Quick Start 🏃‍♂️ 31 | 32 | 1. Open your terminal 33 | 2. Navigate to your NestJS project: 34 | 35 | bash 36 | cd your-nestjs-project 37 | 3. Run the generator: 38 | 39 | 40 | bash 41 | nest-crud-gen generate 42 | or use the shorthand: 43 | 44 | bash 45 | nest-crud-gen g 46 | 47 | 48 | ## Step-by-Step Guide 📝 49 | 50 | ### 1. Enter Resource Name 51 | When prompted, enter the name of your resource (e.g., "user", "product", "order"). 52 | 53 | Example: 54 | 55 | bash 56 | ? Enter the resource name: user 57 | 58 | 59 | ### 2. Select ORM 60 | Choose your preferred ORM from the list: 61 | - TypeORM 62 | - Prisma 63 | - Mongoose 64 | - Sequelize 65 | - MikroORM 66 | 67 | Example: 68 | 69 | bash 70 | ? Which ORM would you like to use? 71 | ❯ TypeORM - Most popular ORM for TypeScript/Node.js 72 | Prisma - Modern DB toolkit with type safety 73 | Mongoose - Elegant MongoDB ODM 74 | Sequelize - Feature-rich ORM for SQL databases 75 | MikroORM - TypeScript ORM with Identity Map pattern 76 | 77 | 78 | ### 3. Wait for Generation 79 | The tool will: 80 | 1. Install required dependencies 81 | 2. Generate all necessary files 82 | 3. Set up proper configurations 83 | 84 | ## Generated Files Structure 📁 85 | 86 | src/ 87 | └── your-resource/ 88 | ├── dto/ 89 | │ ├── create-your-resource.dto.ts 90 | │ └── update-your-resource.dto.ts 91 | ├── entities/ 92 | │ └── your-resource.entity.ts 93 | ├── your-resource.controller.ts 94 | ├── your-resource.service.ts 95 | ├── your-resource.repository.ts 96 | └── your-resource.module.ts 97 | 98 | 99 | ## Example Usage 💡 100 | 101 | Let's create a complete CRUD for a "product" resource: 102 | 103 | 1. Run the generator: 104 | 105 | bash 106 | nest-crud-gen g 107 | 108 | 2. Enter details: 109 | 110 | bash 111 | ? Enter the resource name: product 112 | ? Which ORM would you like to use? TypeORM 113 | 114 | 115 | 3. The generator will create: 116 | - `ProductController` with all CRUD endpoints 117 | - `ProductService` with business logic 118 | - `ProductRepository` for database operations 119 | - `Product` entity with basic fields 120 | - DTOs for create and update operations 121 | - `ProductModule` with proper configurations 122 | 123 | 4. Your endpoints will be available at: 124 | - GET `/product` - Get all products 125 | - GET `/product/:id` - Get one product 126 | - POST `/product` - Create product 127 | - PATCH `/product/:id` - Update product 128 | - DELETE `/product/:id` - Delete product 129 | 130 | ## Customization 🎨 131 | 132 | After generation, you can: 133 | 1. Add more fields to the entity 134 | 2. Modify validation in DTOs 135 | 3. Add custom methods to the service 136 | 4. Extend controller functionality 137 | 138 | ## Troubleshooting 🔧 139 | 140 | ### Common Issues 141 | 142 | 1. **Dependencies Installation Failed** 143 | 144 | bash 145 | npm install --legacy-peer-deps [missing-dependencies] 146 | 147 | 148 | 2. **Type Errors** 149 | Make sure to install all type definitions: 150 | 151 | bash 152 | npm install @types/node -D 153 | 154 | 155 | 3. **Path Issues** 156 | Ensure you're running the command in your NestJS project root. 157 | 158 | ## Support 🤝 159 | 160 | If you encounter any issues or need help: 161 | 1. Check our [GitHub Issues](https://github.com/daniel3380rm/nest-crud-repository-pattern/issues) 162 | 3. Email us at: daniel.3380.rm@gmail.com 163 | 164 | ## Contributing 🌟 165 | 166 | We love contributions! To contribute: 167 | 1. Fork the repository 168 | 2. Create your feature branch 169 | 3. Commit your changes 170 | 4. Push to the branch 171 | 5. Create a Pull Request 172 | 173 | ## License 📄 174 | 175 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 176 | 177 | ## Author ✍️ 178 | 179 | [Your Name] 180 | - GitHub: [@daniel3380rm](https://github.com/daniel3380rm) 181 | - Twitter: [@daniel3380rm](https://twitter.com/daniel3380rm) 182 | 183 | ## Acknowledgments 👏 184 | 185 | Special thanks to: 186 | - NestJS team 187 | - All contributors 188 | - Our amazing community 189 | 190 | 191 | Made with ❤️ for the NestJS community -------------------------------------------------------------------------------- /bin/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { Command } from 'commander'; 4 | import inquirer from 'inquirer'; 5 | import fs from 'fs-extra'; 6 | import path from 'path'; 7 | import chalk from 'chalk'; 8 | import { pascalCase, camelCase, kebabCase } from 'change-case'; 9 | import { fileURLToPath } from 'url'; 10 | import { dirname } from 'path'; 11 | import { exec } from 'child_process'; 12 | import { promisify } from 'util'; 13 | 14 | const execAsync = promisify(exec); 15 | const __filename = fileURLToPath(import.meta.url); 16 | const __dirname = dirname(__filename); 17 | 18 | // Read package.json 19 | const packageJson = JSON.parse(await fs.readFile(new URL('../package.json', import.meta.url))); 20 | 21 | const program = new Command(); 22 | 23 | program 24 | .version(packageJson.version) 25 | .description('NestJS CRUD generator with Repository Pattern'); 26 | 27 | program 28 | .command('generate') 29 | .alias('g') 30 | .description('Generate CRUD components') 31 | .action(async () => { 32 | try { 33 | const answers = await inquirer.prompt([ 34 | { 35 | type: 'input', 36 | name: 'name', 37 | message: 'Enter the resource name:', 38 | validate: input => input.length > 0 39 | }, 40 | { 41 | type: 'list', 42 | name: 'orm', 43 | message: 'Which ORM would you like to use?', 44 | choices: [ 45 | { name: 'TypeORM - Most popular ORM for TypeScript/Node.js', value: 'typeorm' }, 46 | { name: 'Prisma - Modern DB toolkit with type safety', value: 'prisma' }, 47 | { name: 'Mongoose - Elegant MongoDB ODM', value: 'mongoose' }, 48 | { name: 'Sequelize - Feature-rich ORM for SQL databases', value: 'sequelize' }, 49 | { name: 'MikroORM - TypeScript ORM with Identity Map pattern', value: 'mikroorm' } 50 | ] 51 | } 52 | ]); 53 | 54 | const { name, orm } = answers; 55 | 56 | // Get dependencies from package.json 57 | const commonDeps = Object.entries(packageJson.optionalDependencies || {}) 58 | .map(([name, version]) => `${name}@${version}`); 59 | 60 | const ormDeps = Object.entries(packageJson.orm[orm].dependencies || {}) 61 | .map(([name, version]) => `${name}@${version}`); 62 | if (orm === 'typeorm') { 63 | ormDeps.push('@types/node'); 64 | } 65 | // Display dependencies information 66 | console.log(chalk.yellow('\nRequired dependencies:')); 67 | console.log(chalk.cyan('\nCommon dependencies:')); 68 | console.log(chalk.white(commonDeps.join('\n'))); 69 | 70 | console.log(chalk.cyan('\nORM-specific dependencies:')); 71 | console.log(chalk.white(ormDeps.join('\n'))); 72 | 73 | // Install dependencies automatically 74 | console.log(chalk.yellow('\nInstalling required dependencies...\n')); 75 | 76 | const dependencies = [...commonDeps, ...ormDeps]; 77 | const currentDir = process.cwd(); 78 | 79 | // Check if dependencies are already installed 80 | const nodeModulesPath = path.join(process.cwd(), 'node_modules'); 81 | const checkDependency = (dep) => { 82 | const [name] = dep.split('@'); 83 | return fs.existsSync(path.join(nodeModulesPath, name)); 84 | }; 85 | 86 | const missingDeps = dependencies.filter(dep => !checkDependency(dep)); 87 | 88 | if (missingDeps.length === 0) { 89 | console.log(chalk.green('\n✓ All dependencies are already installed!\n')); 90 | } else { 91 | // Install dependencies automatically 92 | console.log(chalk.yellow('\nInstalling missing dependencies...\n')); 93 | console.log(chalk.white('Missing packages:', missingDeps.join(', '))); 94 | 95 | const installCommand = `cd "${currentDir}" && npm install --legacy-peer-deps ${missingDeps.join(' ')}`; 96 | 97 | try { 98 | const { stdout, stderr } = await execAsync(installCommand, { shell: true }); 99 | if (stdout) console.log(chalk.green(stdout)); 100 | if (stderr) console.log(chalk.yellow(stderr)); 101 | console.log(chalk.green('\n✓ Dependencies installed successfully!\n')); 102 | } catch (error) { 103 | console.error(chalk.red('\n✗ Error installing dependencies:'), error.message); 104 | console.log(chalk.yellow('\nYou can install dependencies manually using:')); 105 | console.log(chalk.cyan('npm install --legacy-peer-deps'), chalk.white(missingDeps.join(' '))); 106 | console.log(chalk.yellow('\nOr using yarn:')); 107 | console.log(chalk.cyan('yarn add --ignore-peer-dependencies'), chalk.white(missingDeps.join(' '))); 108 | 109 | // Ask if user wants to continue without installing dependencies 110 | const { continueWithoutDeps } = await inquirer.prompt([ 111 | { 112 | type: 'confirm', 113 | name: 'continueWithoutDeps', 114 | message: 'Do you want to continue without installing dependencies?', 115 | default: false 116 | } 117 | ]); 118 | 119 | if (!continueWithoutDeps) { 120 | console.log(chalk.red('\nAborted: Dependencies installation failed.')); 121 | process.exit(1); 122 | } 123 | } 124 | } 125 | 126 | // ORM-specific configurations 127 | const ormConfigs = { 128 | typeorm: { 129 | import: `import { TypeOrmModule } from '@nestjs/typeorm';\nimport { ${pascalCase(name)} } from './entities/${kebabCase(name)}.entity';`, 130 | imports: `TypeOrmModule.forFeature([${pascalCase(name)}])`, 131 | }, 132 | prisma: { 133 | import: `import { PrismaModule } from '../prisma/prisma.module';`, 134 | imports: 'PrismaModule', 135 | }, 136 | mongoose: { 137 | import: `import { MongooseModule } from '@nestjs/mongoose';\nimport { ${pascalCase(name)}, ${pascalCase(name)}Schema } from './entities/${kebabCase(name)}.entity';`, 138 | imports: `MongooseModule.forFeature([{ name: ${pascalCase(name)}.name, schema: ${pascalCase(name)}Schema }])`, 139 | }, 140 | sequelize: { 141 | import: `import { SequelizeModule } from '@nestjs/sequelize';\nimport { ${pascalCase(name)} } from './entities/${kebabCase(name)}.entity';`, 142 | imports: `SequelizeModule.forFeature([${pascalCase(name)}])`, 143 | }, 144 | mikroorm: { 145 | import: `import { MikroOrmModule } from '@mikro-orm/nestjs';\nimport { ${pascalCase(name)} } from './entities/${kebabCase(name)}.entity';`, 146 | imports: `MikroOrmModule.forFeature([${pascalCase(name)}])`, 147 | }, 148 | }; 149 | 150 | // Component generation 151 | const components = ['controller', 'service', 'repository', 'module', 'entity', 'dto']; 152 | const templatesDir = path.join(dirname(__dirname), 'templates'); 153 | 154 | console.log(chalk.blue('\nGenerating CRUD components...\n')); 155 | 156 | for (const component of components) { 157 | try { 158 | const targetDir = path.join(process.cwd(), `src/${kebabCase(name)}`); 159 | let templatePath, targetPath, updateDtoPath; 160 | 161 | // Determine paths 162 | if (component === 'entity' || component === 'repository') { 163 | templatePath = path.join(templatesDir, 'repositories', orm, `${component}.template.ts`); 164 | } else { 165 | templatePath = path.join(templatesDir, 'common', `${component}.template.ts`); 166 | } 167 | 168 | if (component === 'dto') { 169 | await fs.ensureDir(path.join(targetDir, 'dto')); 170 | targetPath = path.join(targetDir, 'dto', `create-${kebabCase(name)}.dto.ts`); 171 | updateDtoPath = path.join(targetDir, 'dto', `update-${kebabCase(name)}.dto.ts`); 172 | } else if (component === 'entity') { 173 | await fs.ensureDir(path.join(targetDir, 'entities')); 174 | targetPath = path.join(targetDir, 'entities', `${kebabCase(name)}.entity.ts`); 175 | } else { 176 | targetPath = path.join(targetDir, `${kebabCase(name)}.${component}.ts`); 177 | } 178 | 179 | // Ensure directory exists 180 | await fs.ensureDir(path.dirname(targetPath)); 181 | 182 | // Process template 183 | let templateContent = await fs.readFile(templatePath, 'utf8'); 184 | templateContent = templateContent 185 | .replace(/{{pascalCase name}}/g, pascalCase(name)) 186 | .replace(/{{camelCase name}}/g, camelCase(name)) 187 | .replace(/{{kebabCase name}}/g, kebabCase(name)); 188 | 189 | if (component === 'module') { 190 | const ormConfig = ormConfigs[orm]; 191 | templateContent = templateContent 192 | .replace('{{importBlock}}', ormConfig.import) 193 | .replace('{{importsBlock}}', ormConfig.imports); 194 | } 195 | 196 | // Write files 197 | await fs.writeFile(targetPath, templateContent); 198 | console.log(chalk.green(`✓ Created ${component}: ${targetPath}`)); 199 | 200 | if (component === 'dto') { 201 | const updateDtoTemplatePath = path.join(templatesDir, 'common', 'update.dto.template.ts'); 202 | let updateDtoContent = await fs.readFile(updateDtoTemplatePath, 'utf8'); 203 | 204 | updateDtoContent = updateDtoContent 205 | .replace(/{{pascalCase name}}/g, pascalCase(name)) 206 | .replace(/{{camelCase name}}/g, camelCase(name)) 207 | .replace(/{{kebabCase name}}/g, kebabCase(name)); 208 | 209 | await fs.writeFile(updateDtoPath, updateDtoContent); 210 | console.log(chalk.green(`✓ Created update DTO: ${updateDtoPath}`)); 211 | } 212 | 213 | } catch (error) { 214 | console.error(chalk.red(`✗ Error creating ${component}:`), error.message); 215 | if (error.code === 'ENOENT') { 216 | console.error(chalk.yellow(` Make sure all template files exist in the correct location: ${templatePath}`)); 217 | } 218 | throw error; 219 | } 220 | } 221 | 222 | console.log(chalk.green('\n✨ CRUD generation completed successfully!\n')); 223 | 224 | } catch (error) { 225 | console.error(chalk.red('\n✗ An error occurred during generation:'), error); 226 | process.exit(1); 227 | } 228 | }); 229 | 230 | program.parse(process.argv); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nest-crud-repository-pattern", 3 | "version": "1.0.0", 4 | "main": "bin/index.js", 5 | "type": "module", 6 | "bin": { 7 | "ngen": "./bin/index.js" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/daniel3380rm/nest-crud-repository-pattern.git" 15 | }, 16 | "description": "A powerful NestJS CRUD generator implementing the Repository Pattern with support for multiple ORMs", 17 | "keywords": [ 18 | "nestjs", 19 | "crud", 20 | "generator", 21 | "repository-pattern", 22 | "typeorm", 23 | "prisma", 24 | "mongoose", 25 | "sequelize", 26 | "mikroorm", 27 | "cli" 28 | ], 29 | "author": "daniel3380", 30 | "license": "ISC", 31 | "dependencies": { 32 | "chalk": "^5.3.0", 33 | "change-case": "^5.4.4", 34 | "commander": "^13.1.0", 35 | "fs-extra": "^11.3.0", 36 | "inquirer": "^9.2.16" 37 | }, 38 | "optionalDependencies": { 39 | "@nestjs/common": "^10.3.3", 40 | "@nestjs/core": "^10.3.3", 41 | "@nestjs/mapped-types": "^2.0.5", 42 | "@nestjs/platform-express": "^10.3.3", 43 | "class-validator": "^0.14.1", 44 | "reflect-metadata": "^0.2.1", 45 | "rxjs": "^7.8.1", 46 | "@types/node": "^20.11.24", 47 | "typescript": "^5.3.3" 48 | }, 49 | "orm": { 50 | "typeorm": { 51 | "dependencies": { 52 | "@nestjs/typeorm": "^10.0.2", 53 | "typeorm": "^0.3.20" 54 | } 55 | }, 56 | "prisma": { 57 | "dependencies": { 58 | "@prisma/client": "^5.10.2", 59 | "prisma": "^5.10.2" 60 | } 61 | }, 62 | "mongoose": { 63 | "dependencies": { 64 | "@nestjs/mongoose": "^10.0.4", 65 | "mongoose": "^8.2.0", 66 | "@types/mongoose": "^5.11.97" 67 | } 68 | }, 69 | "sequelize": { 70 | "dependencies": { 71 | "@nestjs/sequelize": "^10.0.0", 72 | "sequelize": "^6.37.1", 73 | "sequelize-typescript": "^2.1.6" 74 | } 75 | }, 76 | "mikroorm": { 77 | "dependencies": { 78 | "@mikro-orm/core": "^6.1.5", 79 | "@mikro-orm/nestjs": "^6.1.5", 80 | "@mikro-orm/migrations": "^6.1.5", 81 | "@mikro-orm/cli": "^6.1.5" 82 | } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /templates/common/controller.template.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; 2 | import { {{pascalCase name}}Service } from './{{kebabCase name}}.service'; 3 | import { Create{{pascalCase name}}Dto } from './dto/create-{{kebabCase name}}.dto'; 4 | import { Update{{pascalCase name}}Dto } from './dto/update-{{kebabCase name}}.dto'; 5 | 6 | @Controller('{{kebabCase name}}') 7 | export class {{pascalCase name}}Controller { 8 | constructor(private readonly {{camelCase name}}Service: {{pascalCase name}}Service) {} 9 | 10 | @Post() 11 | create(@Body() create{{pascalCase name}}Dto: Create{{pascalCase name}}Dto) { 12 | return this.{{camelCase name}}Service.create(create{{pascalCase name}}Dto); 13 | } 14 | 15 | @Get() 16 | findAll() { 17 | return this.{{camelCase name}}Service.findAll(); 18 | } 19 | 20 | @Get(':id') 21 | findOne(@Param('id') id: string) { 22 | return this.{{camelCase name}}Service.findOne(+id); 23 | } 24 | 25 | @Patch(':id') 26 | update(@Param('id') id: string, @Body() update{{pascalCase name}}Dto: Update{{pascalCase name}}Dto) { 27 | return this.{{camelCase name}}Service.update(+id, update{{pascalCase name}}Dto); 28 | } 29 | 30 | @Delete(':id') 31 | remove(@Param('id') id: string) { 32 | return this.{{camelCase name}}Service.remove(+id); 33 | } 34 | } -------------------------------------------------------------------------------- /templates/common/dto.template.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsString } from 'class-validator'; 2 | 3 | export class Create{{pascalCase name}}Dto { 4 | @IsString() 5 | @IsNotEmpty() 6 | name: string; 7 | } -------------------------------------------------------------------------------- /templates/common/module.template.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { {{pascalCase name}}Service } from './{{kebabCase name}}.service'; 3 | import { {{pascalCase name}}Controller } from './{{kebabCase name}}.controller'; 4 | import { {{pascalCase name}}Repository } from './{{kebabCase name}}.repository'; 5 | {{importBlock}} 6 | 7 | @Module({ 8 | imports: [{{importsBlock}}], 9 | controllers: [{{pascalCase name}}Controller], 10 | providers: [{{pascalCase name}}Service, {{pascalCase name}}Repository], 11 | exports: [{{pascalCase name}}Service], 12 | }) 13 | export class {{pascalCase name}}Module {} -------------------------------------------------------------------------------- /templates/common/service.template.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { Create{{pascalCase name}}Dto } from './dto/create-{{kebabCase name}}.dto'; 3 | import { Update{{pascalCase name}}Dto } from './dto/update-{{kebabCase name}}.dto'; 4 | import { {{pascalCase name}}Repository } from './{{kebabCase name}}.repository'; 5 | 6 | @Injectable() 7 | export class {{pascalCase name}}Service { 8 | constructor(private readonly {{camelCase name}}Repository: {{pascalCase name}}Repository) {} 9 | 10 | create(create{{pascalCase name}}Dto: Create{{pascalCase name}}Dto) { 11 | return this.{{camelCase name}}Repository.create(create{{pascalCase name}}Dto); 12 | } 13 | 14 | findAll() { 15 | return this.{{camelCase name}}Repository.findAll(); 16 | } 17 | 18 | findOne(id: number) { 19 | return this.{{camelCase name}}Repository.findOne(id); 20 | } 21 | 22 | update(id: number, update{{pascalCase name}}Dto: Update{{pascalCase name}}Dto) { 23 | return this.{{camelCase name}}Repository.update(id, update{{pascalCase name}}Dto); 24 | } 25 | 26 | remove(id: number) { 27 | return this.{{camelCase name}}Repository.remove(id); 28 | } 29 | } -------------------------------------------------------------------------------- /templates/common/update.dto.template.ts: -------------------------------------------------------------------------------- 1 | import { PartialType } from '@nestjs/mapped-types'; 2 | import { Create{{pascalCase name}}Dto } from './create-{{kebabCase name}}.dto'; 3 | 4 | export class Update{{pascalCase name}}Dto extends PartialType(Create{{pascalCase name}}Dto) {} -------------------------------------------------------------------------------- /templates/repositories/mikroorm/entity.template.ts: -------------------------------------------------------------------------------- 1 | import { Entity, PrimaryKey, Property } from '@mikro-orm/core'; 2 | 3 | @Entity() 4 | export class {{pascalCase name}} { 5 | @PrimaryKey() 6 | id!: number; 7 | 8 | @Property() 9 | name!: string; 10 | 11 | @Property() 12 | createdAt: Date = new Date(); 13 | 14 | @Property({ onUpdate: () => new Date() }) 15 | updatedAt: Date = new Date(); 16 | } -------------------------------------------------------------------------------- /templates/repositories/mikroorm/repository.template.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { EntityRepository, EntityManager } from '@mikro-orm/core'; 3 | import { InjectRepository } from '@mikro-orm/nestjs'; 4 | import { {{pascalCase name}} } from './entities/{{kebabCase name}}.entity'; 5 | import { Create{{pascalCase name}}Dto } from './dto/create-{{kebabCase name}}.dto'; 6 | import { Update{{pascalCase name}}Dto } from './dto/update-{{kebabCase name}}.dto'; 7 | 8 | @Injectable() 9 | export class {{pascalCase name}}Repository { 10 | constructor( 11 | @InjectRepository({{pascalCase name}}) 12 | private readonly repository: EntityRepository<{{pascalCase name}}>, 13 | private readonly em: EntityManager, 14 | ) {} 15 | 16 | async create(create{{pascalCase name}}Dto: Create{{pascalCase name}}Dto): Promise<{{pascalCase name}}> { 17 | const entity = this.em.create({{pascalCase name}}, create{{pascalCase name}}Dto); 18 | await this.em.persistAndFlush(entity); 19 | return entity; 20 | } 21 | 22 | async findAll(): Promise<{{pascalCase name}}[]> { 23 | return this.repository.findAll(); 24 | } 25 | 26 | async findOne(id: number): Promise<{{pascalCase name}}> { 27 | return this.repository.findOne(id); 28 | } 29 | 30 | async update(id: number, update{{pascalCase name}}Dto: Update{{pascalCase name}}Dto): Promise<{{pascalCase name}}> { 31 | const entity = await this.repository.findOne(id); 32 | this.em.assign(entity, update{{pascalCase name}}Dto); 33 | await this.em.flush(); 34 | return entity; 35 | } 36 | 37 | async remove(id: number): Promise { 38 | const entity = await this.repository.findOne(id); 39 | await this.em.removeAndFlush(entity); 40 | } 41 | } -------------------------------------------------------------------------------- /templates/repositories/mongoose/entity.template.ts: -------------------------------------------------------------------------------- 1 | import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; 2 | import { HydratedDocument } from 'mongoose'; 3 | 4 | export type {{pascalCase name}}Document = HydratedDocument<{{pascalCase name}}>; 5 | 6 | @Schema({ timestamps: true }) 7 | export class {{pascalCase name}} { 8 | @Prop({ required: true }) 9 | name: string; 10 | 11 | // Add other properties as needed 12 | } 13 | 14 | export const {{pascalCase name}}Schema = SchemaFactory.createForClass({{pascalCase name}}); -------------------------------------------------------------------------------- /templates/repositories/mongoose/repository.template.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { InjectModel } from '@nestjs/mongoose'; 3 | import { Model } from 'mongoose'; 4 | import { {{pascalCase name}}, {{pascalCase name}}Document } from './entities/{{kebabCase name}}.entity'; 5 | import { Create{{pascalCase name}}Dto } from './dto/create-{{kebabCase name}}.dto'; 6 | import { Update{{pascalCase name}}Dto } from './dto/update-{{kebabCase name}}.dto'; 7 | 8 | @Injectable() 9 | export class {{pascalCase name}}Repository { 10 | constructor( 11 | @InjectModel({{pascalCase name}}.name) 12 | private readonly model: Model<{{pascalCase name}}Document> 13 | ) {} 14 | 15 | async create(create{{pascalCase name}}Dto: Create{{pascalCase name}}Dto): Promise<{{pascalCase name}}> { 16 | const created = new this.model(create{{pascalCase name}}Dto); 17 | return created.save(); 18 | } 19 | 20 | async findAll(): Promise<{{pascalCase name}}[]> { 21 | return this.model.find().exec(); 22 | } 23 | 24 | async findOne(id: string): Promise<{{pascalCase name}}> { 25 | return this.model.findById(id).exec(); 26 | } 27 | 28 | async update(id: string, update{{pascalCase name}}Dto: Update{{pascalCase name}}Dto): Promise<{{pascalCase name}}> { 29 | return this.model.findByIdAndUpdate(id, update{{pascalCase name}}Dto, { new: true }).exec(); 30 | } 31 | 32 | async remove(id: string): Promise<{{pascalCase name}}> { 33 | return this.model.findByIdAndDelete(id).exec(); 34 | } 35 | } -------------------------------------------------------------------------------- /templates/repositories/prisma/entity.template.ts: -------------------------------------------------------------------------------- 1 | // This will be used to generate Prisma schema 2 | model {{pascalCase name}} { 3 | id Int @id @default(autoincrement()) 4 | name String 5 | createdAt DateTime @default(now()) 6 | updatedAt DateTime @updatedAt 7 | } -------------------------------------------------------------------------------- /templates/repositories/prisma/repository.template.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { PrismaService } from '../prisma/prisma.service'; 3 | import { Create{{pascalCase name}}Dto } from './dto/create-{{kebabCase name}}.dto'; 4 | import { Update{{pascalCase name}}Dto } from './dto/update-{{kebabCase name}}.dto'; 5 | 6 | @Injectable() 7 | export class {{pascalCase name}}Repository { 8 | constructor(private readonly prisma: PrismaService) {} 9 | 10 | async create(create{{pascalCase name}}Dto: Create{{pascalCase name}}Dto) { 11 | return this.prisma.{{camelCase name}}.create({ 12 | data: create{{pascalCase name}}Dto, 13 | }); 14 | } 15 | 16 | async findAll() { 17 | return this.prisma.{{camelCase name}}.findMany(); 18 | } 19 | 20 | async findOne(id: number) { 21 | return this.prisma.{{camelCase name}}.findUnique({ 22 | where: { id }, 23 | }); 24 | } 25 | 26 | async update(id: number, update{{pascalCase name}}Dto: Update{{pascalCase name}}Dto) { 27 | return this.prisma.{{camelCase name}}.update({ 28 | where: { id }, 29 | data: update{{pascalCase name}}Dto, 30 | }); 31 | } 32 | 33 | async remove(id: number) { 34 | return this.prisma.{{camelCase name}}.delete({ 35 | where: { id }, 36 | }); 37 | } 38 | } -------------------------------------------------------------------------------- /templates/repositories/sequelize/entity.template.ts: -------------------------------------------------------------------------------- 1 | import { Table, Column, Model, DataType } from 'sequelize-typescript'; 2 | 3 | @Table({ tableName: '{{kebabCase name}}s' }) 4 | export class {{pascalCase name}} extends Model { 5 | @Column({ 6 | type: DataType.INTEGER, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | }) 10 | id: number; 11 | 12 | @Column 13 | name: string; 14 | 15 | @Column 16 | createdAt: Date; 17 | 18 | @Column 19 | updatedAt: Date; 20 | } -------------------------------------------------------------------------------- /templates/repositories/sequelize/repository.template.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { InjectModel } from '@nestjs/sequelize'; 3 | import { {{pascalCase name}} } from './entities/{{kebabCase name}}.entity'; 4 | import { Create{{pascalCase name}}Dto } from './dto/create-{{kebabCase name}}.dto'; 5 | import { Update{{pascalCase name}}Dto } from './dto/update-{{kebabCase name}}.dto'; 6 | 7 | @Injectable() 8 | export class {{pascalCase name}}Repository { 9 | constructor( 10 | @InjectModel({{pascalCase name}}) 11 | private {{camelCase name}}Model: typeof {{pascalCase name}}, 12 | ) {} 13 | 14 | async create(create{{pascalCase name}}Dto: Create{{pascalCase name}}Dto): Promise<{{pascalCase name}}> { 15 | return this.{{camelCase name}}Model.create({ ...create{{pascalCase name}}Dto } as any); 16 | } 17 | 18 | async findAll(): Promise<{{pascalCase name}}[]> { 19 | return this.{{camelCase name}}Model.findAll(); 20 | } 21 | 22 | async findOne(id: number): Promise<{{pascalCase name}}> { 23 | return this.{{camelCase name}}Model.findByPk(id); 24 | } 25 | 26 | async update(id: number, update{{pascalCase name}}Dto: Update{{pascalCase name}}Dto): Promise<[number, {{pascalCase name}}[]]> { 27 | const [affectedCount, affectedRows] = await this.{{camelCase name}}Model.update( 28 | { ...update{{pascalCase name}}Dto }, 29 | { where: { id }, returning: true } 30 | ); 31 | return [affectedCount, affectedRows]; 32 | } 33 | 34 | async remove(id: number): Promise { 35 | return this.{{camelCase name}}Model.destroy({ where: { id } }); 36 | } 37 | } -------------------------------------------------------------------------------- /templates/repositories/typeorm/entity.template.ts: -------------------------------------------------------------------------------- 1 | import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm'; 2 | 3 | @Entity('{{kebabCase name}}s') 4 | export class {{pascalCase name}} { 5 | @PrimaryGeneratedColumn() 6 | id: number; 7 | 8 | @Column({ 9 | type: DataType.STRING, 10 | allowNull: false 11 | }) 12 | name: string; 13 | 14 | @CreateDateColumn() 15 | createdAt: Date; 16 | 17 | @UpdateDateColumn() 18 | updatedAt: Date; 19 | } -------------------------------------------------------------------------------- /templates/repositories/typeorm/repository.template.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { Repository } from 'typeorm'; 4 | import { {{pascalCase name}} } from './entities/{{kebabCase name}}.entity'; 5 | import { Create{{pascalCase name}}Dto } from './dto/create-{{kebabCase name}}.dto'; 6 | import { Update{{pascalCase name}}Dto } from './dto/update-{{kebabCase name}}.dto'; 7 | 8 | @Injectable() 9 | export class {{pascalCase name}}Repository { 10 | constructor( 11 | @InjectRepository({{pascalCase name}}) 12 | private readonly repository: Repository<{{pascalCase name}}>, 13 | ) {} 14 | 15 | async create(create{{pascalCase name}}Dto: Create{{pascalCase name}}Dto): Promise<{{pascalCase name}}> { 16 | const entity = this.repository.create(create{{pascalCase name}}Dto); 17 | return this.repository.save(entity); 18 | } 19 | 20 | async findAll(): Promise<{{pascalCase name}}[]> { 21 | return this.repository.find(); 22 | } 23 | 24 | async findOne(id: number): Promise<{{pascalCase name}}> { 25 | return this.repository.findOneBy({ id }); 26 | } 27 | 28 | async update(id: number, update{{pascalCase name}}Dto: Update{{pascalCase name}}Dto): Promise { 29 | await this.repository.update(id, update{{pascalCase name}}Dto); 30 | } 31 | 32 | async remove(id: number): Promise { 33 | await this.repository.delete(id); 34 | } 35 | } --------------------------------------------------------------------------------