UNPKG

nestjs-ddd-cli

Version:

CLI for generating NestJS DDD boilerplate code

459 lines (366 loc) โ€ข 16.9 kB
# NestJS DDD CLI ๐Ÿ—๏ธ **An opinionated CLI for pragmatic Domain-Driven Design with NestJS** Stop writing boilerplate. Start building business logic. Generate production-ready NestJS code following proven DDD/CQRS patterns with consistent structure and immutable architecture principles. ## Installation **From NPM (Recommended):** ```bash npm install -g nestjs-ddd-cli ``` **From Source:** ```bash git clone https://github.com/eshe-huli/nestjs-ddd-cli cd nestjs-ddd-cli npm install npm run build npm link ``` ## Usage ### Generate Complete Scaffolding Generate all files for a new entity (entity, repository, mapper, use cases, controller, etc.): ```bash ddd scaffold Product -m inventory ``` ### Generate Individual Components ```bash # Generate a module ddd generate module user-management # Generate an entity ddd generate entity User -m user-management # Generate a use case ddd generate usecase CreateUser -m user-management # Generate a domain service ddd generate service UserValidation -m user-management # Generate a domain event ddd generate event UserCreated -m user-management # Generate a query handler ddd generate query GetUser -m user-management # Generate everything for an entity within existing module ddd generate all User -m user-management ``` ### Options - `-m, --module <name>`: Specify the module name - `-p, --path <path>`: Base path for generation (defaults to current directory) - `--skip-orm`: Skip ORM entity generation - `--skip-mapper`: Skip mapper generation - `--skip-repo`: Skip repository generation - `--with-events`: Include domain events - `--with-queries`: Include query handlers ## Available Generators | Generator | Command | Description | |-----------|---------|-------------| | **Module** | `ddd generate module <name>` | Creates complete DDD module structure | | **Entity** | `ddd generate entity <name> -m <module>` | Domain entity with ORM mapping | | **Use Case** | `ddd generate usecase <name> -m <module>` | CQRS command handler | | **Domain Service** | `ddd generate service <name> -m <module>` | Domain service for business logic | | **Domain Event** | `ddd generate event <name> -m <module>` | Domain event for CQRS | | **Query Handler** | `ddd generate query <name> -m <module>` | CQRS query handler | | **Complete CRUD** | `ddd scaffold <name> -m <module>` | All files for an entity | | **All Entity Files** | `ddd generate all <name> -m <module>` | Entity + related files | ## Quick Start ### ๐Ÿš€ **Generate Your First Feature** ```bash # 1. Create complete scaffolding for a User management feature ddd scaffold User -m user-management # 2. Add business logic to the generated files # 3. Update index.ts exports # 4. Run migrations # 5. Import module in app.module.ts ``` **What you get in seconds:** ``` ๐Ÿ“ modules/user-management/ โ”œโ”€โ”€ ๐Ÿ“„ user-management.module.ts โœ… NestJS module configured โ”œโ”€โ”€ ๐Ÿ“ application/ โ”‚ โ”œโ”€โ”€ ๐Ÿ“ controllers/ โ”‚ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ user.controller.ts โœ… REST endpoints (GET, POST, PUT, DELETE) โ”‚ โ”œโ”€โ”€ ๐Ÿ“ domain/ โ”‚ โ”‚ โ”œโ”€โ”€ ๐Ÿ“ entities/ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ user.entity.ts โœ… Domain entity with interfaces โ”‚ โ”‚ โ””โ”€โ”€ ๐Ÿ“ usecases/ โ”‚ โ”‚ โ”œโ”€โ”€ ๐Ÿ“„ create-user.usecase.ts โœ… Business logic for creation โ”‚ โ”‚ โ”œโ”€โ”€ ๐Ÿ“„ update-user.usecase.ts โœ… Business logic for updates โ”‚ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ delete-user.usecase.ts โœ… Business logic for deletion โ”‚ โ””โ”€โ”€ ๐Ÿ“ dto/ โ”‚ โ”œโ”€โ”€ ๐Ÿ“ requests/ โ”‚ โ”‚ โ”œโ”€โ”€ ๐Ÿ“„ create-user.dto.ts โœ… Request validation schemas โ”‚ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ update-user.dto.ts โœ… Update validation schemas โ”‚ โ””โ”€โ”€ ๐Ÿ“ responses/ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ user.response.ts โœ… Response data contracts โ””โ”€โ”€ ๐Ÿ“ infrastructure/ โ”œโ”€โ”€ ๐Ÿ“ repositories/ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ user.repository.ts โœ… CRUD operations + custom queries โ”œโ”€โ”€ ๐Ÿ“ orm-entities/ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ user.orm-entity.ts โœ… Database schema (TypeORM) โ””โ”€โ”€ ๐Ÿ“ mappers/ โ””โ”€โ”€ ๐Ÿ“„ user.mapper.ts โœ… Domain โ†” Database mapping ``` > **๐Ÿš€ From zero to production-ready in under 30 seconds** ## Real-World Examples ### ๐Ÿข **E-commerce Platform** ```bash # Generate order management ddd scaffold Order -m orders # Add payment processing ddd generate service PaymentProcessor -m orders ddd generate event OrderPaid -m orders # Add inventory checking ddd generate query CheckStock -m inventory ddd generate service StockValidator -m inventory ``` **Result:** Complete order system with payment processing and inventory management ``` ๐Ÿ“ modules/orders/ โ”œโ”€โ”€ ๐Ÿ“„ orders.module.ts โ”œโ”€โ”€ ๐Ÿ“ application/domain/services/ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ payment-processor.service.ts ๐Ÿ†• Payment business logic โ”œโ”€โ”€ ๐Ÿ“ application/domain/events/ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ order-paid.event.ts ๐Ÿ†• Order payment event โ””โ”€โ”€ ... (all CRUD operations) ๐Ÿ“ modules/inventory/ โ”œโ”€โ”€ ๐Ÿ“ application/queries/ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ check-stock.handler.ts ๐Ÿ†• Stock checking query โ”œโ”€โ”€ ๐Ÿ“ application/domain/services/ โ”‚ โ””โ”€โ”€ ๐Ÿ“„ stock-validator.service.ts ๐Ÿ†• Stock validation logic โ””โ”€โ”€ ... (all CRUD operations) ``` ### ๐Ÿฅ **Healthcare System** ```bash # Patient management ddd scaffold Patient -m patients # Medical records with events ddd scaffold MedicalRecord -m medical-records ddd generate event RecordCreated -m medical-records ddd generate event RecordUpdated -m medical-records # Appointment scheduling ddd generate query FindAvailableSlots -m appointments ddd generate service AppointmentScheduler -m appointments ``` ### ๐ŸŽ“ **Learning Management System** ```bash # Course management ddd scaffold Course -m courses ddd generate service CourseEnrollment -m courses ddd generate event StudentEnrolled -m courses # Progress tracking ddd generate query GetStudentProgress -m progress ddd generate service ProgressCalculator -m progress ``` > **๐ŸŽฏ Each example follows identical patterns** - Learn once, apply everywhere. ## Philosophy & Principles This CLI embodies **pragmatic Domain-Driven Design** with unwavering consistency: ### ๐Ÿ”’ **Immutable Architecture** - **"Code once, never touch"** - Each generated component remains unchanged after creation - **Evolution over modification** - New requirements create new use cases, never modify existing ones - **Predictable structure** - Every project follows identical patterns, enabling instant developer onboarding ### ๐ŸŽฏ **Opinionated by Design** - **Zero configuration fatigue** - One way to do things, the right way - **Consistent naming** - PascalCase entities, kebab-case modules, predictable file names - **Proven patterns** - Battle-tested DDD/CQRS structure from real-world enterprise applications ### ๐Ÿš€ **Developer Experience First** - **No bikeshedding** - Spend time on business logic, not folder structure debates - **IDE-friendly** - Barrel exports, clear interfaces, TypeScript-first approach - **Team consistency** - Every developer generates identical code structure ### ๐Ÿ—๏ธ **Enterprise Ready** - **Separation of concerns** - Domain logic isolated from infrastructure - **CQRS compliance** - Commands for writes, queries for reads - **Testable by default** - Clean interfaces enable easy unit testing ## What Makes This Different? ### ๐ŸŽจ **Structure That Scales** Every module follows this **identical, battle-tested structure**: ``` modules/ โ””โ”€โ”€ [feature-name]/ # ๐Ÿ  Feature boundary โ”œโ”€โ”€ [feature-name].module.ts # ๐Ÿ”ง NestJS module wiring โ”œโ”€โ”€ application/ # ๐Ÿ“‹ Application layer โ”‚ โ”œโ”€โ”€ commands/ # โœ๏ธ CQRS commands (writes) โ”‚ โ”‚ โ”œโ”€โ”€ create-[entity].command.ts # โ””โ”€ Create operations โ”‚ โ”‚ โ”œโ”€โ”€ update-[entity].command.ts # โ””โ”€ Update operations โ”‚ โ”‚ โ”œโ”€โ”€ delete-[entity].command.ts # โ””โ”€ Delete operations โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ”œโ”€โ”€ controllers/ # ๐ŸŒ HTTP/GraphQL endpoints โ”‚ โ”‚ โ”œโ”€โ”€ [entity].controller.ts # โ””โ”€ REST API endpoints โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ”œโ”€โ”€ domain/ # ๐Ÿง  Pure business logic โ”‚ โ”‚ โ”œโ”€โ”€ entities/ # ๐Ÿ“ฆ Business objects โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [entity].entity.ts # โ””โ”€ Domain entity โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ”‚ โ”œโ”€โ”€ events/ # ๐ŸŽฏ Domain events โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [entity]-created.event.ts # โ””โ”€ Event definitions โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ”‚ โ”œโ”€โ”€ services/ # โš™๏ธ Domain services โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [entity].service.ts # โ””โ”€ Business rules โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ”‚ โ””โ”€โ”€ usecases/ # ๐ŸŽฌ Use case operations โ”‚ โ”‚ โ”œโ”€โ”€ create-[entity].usecase.ts# โ””โ”€ Create business logic โ”‚ โ”‚ โ”œโ”€โ”€ update-[entity].usecase.ts# โ””โ”€ Update business logic โ”‚ โ”‚ โ”œโ”€โ”€ delete-[entity].usecase.ts# โ””โ”€ Delete business logic โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ”œโ”€โ”€ dto/ # ๐Ÿ“„ Data contracts โ”‚ โ”‚ โ”œโ”€โ”€ requests/ # ๐Ÿ“ค Inbound data โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ create-[entity].dto.ts # โ””โ”€ Create request โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ update-[entity].dto.ts # โ””โ”€ Update request โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ”‚ โ”œโ”€โ”€ responses/ # ๐Ÿ“ฅ Outbound data โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [entity].response.ts # โ””โ”€ Entity response โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”‚ โ””โ”€โ”€ queries/ # ๐Ÿ” CQRS queries (reads) โ”‚ โ”œโ”€โ”€ get-[entity].handler.ts # โ””โ”€ Single entity query โ”‚ โ”œโ”€โ”€ list-[entities].handler.ts # โ””โ”€ Multiple entities query โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ””โ”€โ”€ infrastructure/ # ๐Ÿ—๏ธ Infrastructure layer โ”œโ”€โ”€ mappers/ # ๐Ÿ”„ Data transformation โ”‚ โ”œโ”€โ”€ [entity].mapper.ts # โ””โ”€ Domain โ†” ORM mapping โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ”œโ”€โ”€ orm-entities/ # ๐Ÿ—„๏ธ Database schema โ”‚ โ”œโ”€โ”€ [entity].orm-entity.ts # โ””โ”€ TypeORM entity โ”‚ โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports โ””โ”€โ”€ repositories/ # ๐Ÿ’พ Data access โ”œโ”€โ”€ [entity].repository.ts # โ””โ”€ Repository implementation โ””โ”€โ”€ index.ts # โ””โ”€ Barrel exports ``` > **๐ŸŽฏ Every feature looks identical** - No surprises, no confusion, just consistency. ### ๐Ÿง  **Smart Defaults & Conventions** ```bash # Naming follows strict patterns ddd generate entity UserProfile # โ†’ user-profile.entity.ts ddd generate service OrderValidator # โ†’ order-validator.service.ts ddd generate event PaymentProcessed # โ†’ payment-processed.event.ts ``` **Built-in Intelligence:** - **๐Ÿ”„ Barrel exports** - Automatic `index.ts` files for clean imports - **๐Ÿ”’ TypeScript strict** - Zero `any` types, full type safety - **๐Ÿ’‰ DI ready** - Injectable decorators configured - **๐Ÿ“‹ Interface first** - Clear contracts between layers - **๐Ÿ“ Predictable paths** - Same location every time ### ๐Ÿ’ก **Enterprise Patterns** ```typescript // โœ… Commands (writes) - Tell, don't ask @CommandHandler(CreateUserCommand) export class CreateUserHandler { async execute(command: CreateUserCommand): Promise<void> { // Returns nothing - just does the work } } // โœ… Queries (reads) - Ask, don't tell @QueryHandler(GetUserQuery) export class GetUserHandler { async execute(query: GetUserQuery): Promise<UserResponse> { // Returns data - no side effects } } // โœ… Domain Events - Loose coupling export class UserCreatedEvent implements IEvent { constructor(public readonly userId: string) {} } ``` **Battle-tested principles:** - **Command/Query Separation** - Writes vs reads clearly separated - **Domain Events** - Decoupled communication between bounded contexts - **Repository Pattern** - Abstract data access from business logic - **Clean Architecture** - Dependencies point inward to domain ## After Generation ### ๐Ÿ”ง **Your 5-Minute Setup Checklist:** ```bash # โœ… 1. Generated files are ready - Review structure ls -la modules/your-feature/ # โœ… 2. Add business properties to entities # Edit: application/domain/entities/[entity].entity.ts # Add: name: string; email: string; etc. # โœ… 3. Update DTOs with validation rules # Edit: application/dto/requests/create-[entity].dto.ts # Add: @IsEmail() email: string; @IsNotEmpty() name: string; # โœ… 4. Configure database mappings # Edit: infrastructure/orm-entities/[entity].orm-entity.ts # Add: @Column() name: string; @Column() email: string; # โœ… 5. Wire up the module # Edit: app.module.ts # Add: YourFeatureModule to imports array ``` ### ๐ŸŽฏ **Focus on Business Value:** ```typescript // โœ… Write business rules in domain services export class OrderValidator { validateBusinessRules(order: Order): ValidationResult { // Your domain logic here - not infrastructure concerns } } // โœ… Add complex queries for reporting @QueryHandler(GetMonthlyRevenueQuery) export class GetMonthlyRevenueHandler { async execute(query: GetMonthlyRevenueQuery) { // Complex business queries - not CRUD } } // โœ… Handle domain events for integration @EventsHandler(OrderCreatedEvent) export class OrderCreatedHandler { async handle(event: OrderCreatedEvent) { // Send emails, update analytics, etc. } } ``` > **๐Ÿš€ From scaffolding to production in minutes, not days** ## Why This CLI Exists ### ๐Ÿ˜ค **The Problem** - Endless debates about folder structure - Inconsistent naming across team members - Copy-pasting boilerplate between features - Mixed patterns in the same codebase - New developers spending weeks learning "our way" ### ๐ŸŽฏ **The Solution** - **One structure** that works for all features - **Zero configuration** - works out of the box - **Battle-tested patterns** from real enterprise apps - **Instant onboarding** - same structure everywhere - **Focus on business logic** instead of architecture decisions ### ๐Ÿ† **The Result** - 10x faster feature development - Consistent codebase architecture - Easy code reviews and maintenance - New developers productive from day one - No more "where does this file go?" questions --- ## Contributing & Development ### ๐Ÿ”ง **Local Development** ```bash # Clone and setup git clone https://github.com/eshe-huli/nestjs-ddd-cli cd nestjs-ddd-cli npm install # Test changes locally npm run dev -- generate entity Test -m test # Build for production npm run build # Test globally installed version ddd generate entity Test -m test ``` ### ๐Ÿงช **Testing Your Changes** ```bash # Create a test project mkdir test-project && cd test-project # Test scaffolding ddd scaffold Product -m inventory # Verify structure matches expectations tree modules/inventory/ # Test individual generators ddd generate service ProductValidator -m inventory ddd generate event ProductCreated -m inventory ddd generate query GetProductsByCategory -m inventory ``` ### ๐Ÿ“‹ **Template Structure** ``` src/templates/ โ”œโ”€โ”€ ๐Ÿ“ entity/ # Domain entity templates โ”œโ”€โ”€ ๐Ÿ“ service/ # Domain service templates โ”œโ”€โ”€ ๐Ÿ“ event/ # Domain event templates โ”œโ”€โ”€ ๐Ÿ“ query/ # Query handler templates โ”œโ”€โ”€ ๐Ÿ“ usecase/ # Use case templates โ”œโ”€โ”€ ๐Ÿ“ controller/ # Controller templates โ”œโ”€โ”€ ๐Ÿ“ repository/ # Repository templates โ””โ”€โ”€ ๐Ÿ“ ... (more templates) ``` > **๐Ÿค Pull requests welcome!** Help make DDD development even better. ## License MIT - Build amazing things ๐Ÿš€