nestjs-ddd-cli 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +381 -60
- package/dist/commands/generate-event.d.ts +1 -0
- package/dist/commands/generate-event.js +58 -0
- package/dist/commands/generate-event.js.map +1 -0
- package/dist/commands/generate-module.js +1 -1
- package/dist/commands/generate-module.js.map +1 -1
- package/dist/commands/generate-query.d.ts +1 -0
- package/dist/commands/generate-query.js +58 -0
- package/dist/commands/generate-query.js.map +1 -0
- package/dist/commands/generate-service.d.ts +1 -0
- package/dist/commands/generate-service.js +58 -0
- package/dist/commands/generate-service.js.map +1 -0
- package/dist/index.js +14 -2
- package/dist/index.js.map +1 -1
- package/dist/templates/event/domain-event.hbs +9 -0
- package/dist/templates/query/query-handler.hbs +18 -0
- package/dist/templates/service/domain-service.hbs +13 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
# NestJS DDD CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
🏗️ **An opinionated CLI for pragmatic Domain-Driven Design with NestJS**
|
|
4
|
+
|
|
5
|
+
Stop writing boilerplate. Start building business logic.
|
|
6
|
+
|
|
7
|
+
Generate production-ready NestJS code following proven DDD/CQRS patterns with consistent structure and immutable architecture principles.
|
|
4
8
|
|
|
5
9
|
## Installation
|
|
6
10
|
|
|
11
|
+
**From NPM (Recommended):**
|
|
7
12
|
```bash
|
|
8
|
-
|
|
9
|
-
chmod +x install.sh
|
|
10
|
-
./install.sh
|
|
13
|
+
npm install -g nestjs-ddd-cli
|
|
11
14
|
```
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
**From Source:**
|
|
15
17
|
```bash
|
|
18
|
+
git clone https://github.com/eshe-huli/nestjs-ddd-cli
|
|
19
|
+
cd nestjs-ddd-cli
|
|
16
20
|
npm install
|
|
17
21
|
npm run build
|
|
18
22
|
npm link
|
|
@@ -40,6 +44,15 @@ ddd generate entity User -m user-management
|
|
|
40
44
|
# Generate a use case
|
|
41
45
|
ddd generate usecase CreateUser -m user-management
|
|
42
46
|
|
|
47
|
+
# Generate a domain service
|
|
48
|
+
ddd generate service UserValidation -m user-management
|
|
49
|
+
|
|
50
|
+
# Generate a domain event
|
|
51
|
+
ddd generate event UserCreated -m user-management
|
|
52
|
+
|
|
53
|
+
# Generate a query handler
|
|
54
|
+
ddd generate query GetUser -m user-management
|
|
55
|
+
|
|
43
56
|
# Generate everything for an entity within existing module
|
|
44
57
|
ddd generate all User -m user-management
|
|
45
58
|
```
|
|
@@ -54,85 +67,393 @@ ddd generate all User -m user-management
|
|
|
54
67
|
- `--with-events`: Include domain events
|
|
55
68
|
- `--with-queries`: Include query handlers
|
|
56
69
|
|
|
57
|
-
##
|
|
70
|
+
## Available Generators
|
|
71
|
+
|
|
72
|
+
| Generator | Command | Description |
|
|
73
|
+
|-----------|---------|-------------|
|
|
74
|
+
| **Module** | `ddd generate module <name>` | Creates complete DDD module structure |
|
|
75
|
+
| **Entity** | `ddd generate entity <name> -m <module>` | Domain entity with ORM mapping |
|
|
76
|
+
| **Use Case** | `ddd generate usecase <name> -m <module>` | CQRS command handler |
|
|
77
|
+
| **Domain Service** | `ddd generate service <name> -m <module>` | Domain service for business logic |
|
|
78
|
+
| **Domain Event** | `ddd generate event <name> -m <module>` | Domain event for CQRS |
|
|
79
|
+
| **Query Handler** | `ddd generate query <name> -m <module>` | CQRS query handler |
|
|
80
|
+
| **Complete CRUD** | `ddd scaffold <name> -m <module>` | All files for an entity |
|
|
81
|
+
| **All Entity Files** | `ddd generate all <name> -m <module>` | Entity + related files |
|
|
82
|
+
|
|
83
|
+
## Quick Start
|
|
58
84
|
|
|
85
|
+
### 🚀 **Generate Your First Feature**
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# 1. Create complete scaffolding for a User management feature
|
|
89
|
+
ddd scaffold User -m user-management
|
|
90
|
+
|
|
91
|
+
# 2. Add business logic to the generated files
|
|
92
|
+
# 3. Update index.ts exports
|
|
93
|
+
# 4. Run migrations
|
|
94
|
+
# 5. Import module in app.module.ts
|
|
59
95
|
```
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
96
|
+
|
|
97
|
+
**What you get in seconds:**
|
|
98
|
+
```
|
|
99
|
+
📁 modules/user-management/
|
|
100
|
+
├── 📄 user-management.module.ts ✅ NestJS module configured
|
|
101
|
+
├── 📁 application/
|
|
102
|
+
│ ├── 📁 controllers/
|
|
103
|
+
│ │ └── 📄 user.controller.ts ✅ REST endpoints (GET, POST, PUT, DELETE)
|
|
104
|
+
│ ├── 📁 domain/
|
|
105
|
+
│ │ ├── 📁 entities/
|
|
106
|
+
│ │ │ └── 📄 user.entity.ts ✅ Domain entity with interfaces
|
|
107
|
+
│ │ └── 📁 usecases/
|
|
108
|
+
│ │ ├── 📄 create-user.usecase.ts ✅ Business logic for creation
|
|
109
|
+
│ │ ├── 📄 update-user.usecase.ts ✅ Business logic for updates
|
|
110
|
+
│ │ └── 📄 delete-user.usecase.ts ✅ Business logic for deletion
|
|
111
|
+
│ └── 📁 dto/
|
|
112
|
+
│ ├── 📁 requests/
|
|
113
|
+
│ │ ├── 📄 create-user.dto.ts ✅ Request validation schemas
|
|
114
|
+
│ │ └── 📄 update-user.dto.ts ✅ Update validation schemas
|
|
115
|
+
│ └── 📁 responses/
|
|
116
|
+
│ └── 📄 user.response.ts ✅ Response data contracts
|
|
117
|
+
└── 📁 infrastructure/
|
|
118
|
+
├── 📁 repositories/
|
|
119
|
+
│ └── 📄 user.repository.ts ✅ CRUD operations + custom queries
|
|
120
|
+
├── 📁 orm-entities/
|
|
121
|
+
│ └── 📄 user.orm-entity.ts ✅ Database schema (TypeORM)
|
|
122
|
+
└── 📁 mappers/
|
|
123
|
+
└── 📄 user.mapper.ts ✅ Domain ↔ Database mapping
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
> **🚀 From zero to production-ready in under 30 seconds**
|
|
127
|
+
|
|
128
|
+
## Real-World Examples
|
|
129
|
+
|
|
130
|
+
### 🏢 **E-commerce Platform**
|
|
84
131
|
|
|
85
132
|
```bash
|
|
86
|
-
#
|
|
87
|
-
ddd scaffold
|
|
133
|
+
# Generate order management
|
|
134
|
+
ddd scaffold Order -m orders
|
|
88
135
|
|
|
89
|
-
#
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
136
|
+
# Add payment processing
|
|
137
|
+
ddd generate service PaymentProcessor -m orders
|
|
138
|
+
ddd generate event OrderPaid -m orders
|
|
139
|
+
|
|
140
|
+
# Add inventory checking
|
|
141
|
+
ddd generate query CheckStock -m inventory
|
|
142
|
+
ddd generate service StockValidator -m inventory
|
|
93
143
|
```
|
|
94
144
|
|
|
95
|
-
|
|
145
|
+
**Result:** Complete order system with payment processing and inventory management
|
|
146
|
+
```
|
|
147
|
+
📁 modules/orders/
|
|
148
|
+
├── 📄 orders.module.ts
|
|
149
|
+
├── 📁 application/domain/services/
|
|
150
|
+
│ └── 📄 payment-processor.service.ts 🆕 Payment business logic
|
|
151
|
+
├── 📁 application/domain/events/
|
|
152
|
+
│ └── 📄 order-paid.event.ts 🆕 Order payment event
|
|
153
|
+
└── ... (all CRUD operations)
|
|
154
|
+
|
|
155
|
+
📁 modules/inventory/
|
|
156
|
+
├── 📁 application/queries/
|
|
157
|
+
│ └── 📄 check-stock.handler.ts 🆕 Stock checking query
|
|
158
|
+
├── 📁 application/domain/services/
|
|
159
|
+
│ └── 📄 stock-validator.service.ts 🆕 Stock validation logic
|
|
160
|
+
└── ... (all CRUD operations)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 🏥 **Healthcare System**
|
|
96
164
|
|
|
97
165
|
```bash
|
|
98
|
-
#
|
|
99
|
-
ddd
|
|
166
|
+
# Patient management
|
|
167
|
+
ddd scaffold Patient -m patients
|
|
168
|
+
|
|
169
|
+
# Medical records with events
|
|
170
|
+
ddd scaffold MedicalRecord -m medical-records
|
|
171
|
+
ddd generate event RecordCreated -m medical-records
|
|
172
|
+
ddd generate event RecordUpdated -m medical-records
|
|
173
|
+
|
|
174
|
+
# Appointment scheduling
|
|
175
|
+
ddd generate query FindAvailableSlots -m appointments
|
|
176
|
+
ddd generate service AppointmentScheduler -m appointments
|
|
100
177
|
```
|
|
101
178
|
|
|
102
|
-
###
|
|
179
|
+
### 🎓 **Learning Management System**
|
|
103
180
|
|
|
104
181
|
```bash
|
|
105
|
-
#
|
|
106
|
-
ddd
|
|
182
|
+
# Course management
|
|
183
|
+
ddd scaffold Course -m courses
|
|
184
|
+
ddd generate service CourseEnrollment -m courses
|
|
185
|
+
ddd generate event StudentEnrolled -m courses
|
|
186
|
+
|
|
187
|
+
# Progress tracking
|
|
188
|
+
ddd generate query GetStudentProgress -m progress
|
|
189
|
+
ddd generate service ProgressCalculator -m progress
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
> **🎯 Each example follows identical patterns** - Learn once, apply everywhere.
|
|
193
|
+
|
|
194
|
+
## Philosophy & Principles
|
|
195
|
+
|
|
196
|
+
This CLI embodies **pragmatic Domain-Driven Design** with unwavering consistency:
|
|
197
|
+
|
|
198
|
+
### 🔒 **Immutable Architecture**
|
|
199
|
+
- **"Code once, never touch"** - Each generated component remains unchanged after creation
|
|
200
|
+
- **Evolution over modification** - New requirements create new use cases, never modify existing ones
|
|
201
|
+
- **Predictable structure** - Every project follows identical patterns, enabling instant developer onboarding
|
|
202
|
+
|
|
203
|
+
### 🎯 **Opinionated by Design**
|
|
204
|
+
- **Zero configuration fatigue** - One way to do things, the right way
|
|
205
|
+
- **Consistent naming** - PascalCase entities, kebab-case modules, predictable file names
|
|
206
|
+
- **Proven patterns** - Battle-tested DDD/CQRS structure from real-world enterprise applications
|
|
207
|
+
|
|
208
|
+
### 🚀 **Developer Experience First**
|
|
209
|
+
- **No bikeshedding** - Spend time on business logic, not folder structure debates
|
|
210
|
+
- **IDE-friendly** - Barrel exports, clear interfaces, TypeScript-first approach
|
|
211
|
+
- **Team consistency** - Every developer generates identical code structure
|
|
212
|
+
|
|
213
|
+
### 🏗️ **Enterprise Ready**
|
|
214
|
+
- **Separation of concerns** - Domain logic isolated from infrastructure
|
|
215
|
+
- **CQRS compliance** - Commands for writes, queries for reads
|
|
216
|
+
- **Testable by default** - Clean interfaces enable easy unit testing
|
|
217
|
+
|
|
218
|
+
## What Makes This Different?
|
|
219
|
+
|
|
220
|
+
### 🎨 **Structure That Scales**
|
|
221
|
+
|
|
222
|
+
Every module follows this **identical, battle-tested structure**:
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
modules/
|
|
226
|
+
└── [feature-name]/ # 🏠 Feature boundary
|
|
227
|
+
├── [feature-name].module.ts # 🔧 NestJS module wiring
|
|
228
|
+
├── application/ # 📋 Application layer
|
|
229
|
+
│ ├── commands/ # ✍️ CQRS commands (writes)
|
|
230
|
+
│ │ ├── create-[entity].command.ts # └─ Create operations
|
|
231
|
+
│ │ ├── update-[entity].command.ts # └─ Update operations
|
|
232
|
+
│ │ ├── delete-[entity].command.ts # └─ Delete operations
|
|
233
|
+
│ │ └── index.ts # └─ Barrel exports
|
|
234
|
+
│ ├── controllers/ # 🌐 HTTP/GraphQL endpoints
|
|
235
|
+
│ │ ├── [entity].controller.ts # └─ REST API endpoints
|
|
236
|
+
│ │ └── index.ts # └─ Barrel exports
|
|
237
|
+
│ ├── domain/ # 🧠 Pure business logic
|
|
238
|
+
│ │ ├── entities/ # 📦 Business objects
|
|
239
|
+
│ │ │ ├── [entity].entity.ts # └─ Domain entity
|
|
240
|
+
│ │ │ └── index.ts # └─ Barrel exports
|
|
241
|
+
│ │ ├── events/ # 🎯 Domain events
|
|
242
|
+
│ │ │ ├── [entity]-created.event.ts # └─ Event definitions
|
|
243
|
+
│ │ │ └── index.ts # └─ Barrel exports
|
|
244
|
+
│ │ ├── services/ # ⚙️ Domain services
|
|
245
|
+
│ │ │ ├── [entity].service.ts # └─ Business rules
|
|
246
|
+
│ │ │ └── index.ts # └─ Barrel exports
|
|
247
|
+
│ │ └── usecases/ # 🎬 Use case operations
|
|
248
|
+
│ │ ├── create-[entity].usecase.ts# └─ Create business logic
|
|
249
|
+
│ │ ├── update-[entity].usecase.ts# └─ Update business logic
|
|
250
|
+
│ │ ├── delete-[entity].usecase.ts# └─ Delete business logic
|
|
251
|
+
│ │ └── index.ts # └─ Barrel exports
|
|
252
|
+
│ ├── dto/ # 📄 Data contracts
|
|
253
|
+
│ │ ├── requests/ # 📤 Inbound data
|
|
254
|
+
│ │ │ ├── create-[entity].dto.ts # └─ Create request
|
|
255
|
+
│ │ │ ├── update-[entity].dto.ts # └─ Update request
|
|
256
|
+
│ │ │ └── index.ts # └─ Barrel exports
|
|
257
|
+
│ │ ├── responses/ # 📥 Outbound data
|
|
258
|
+
│ │ │ ├── [entity].response.ts # └─ Entity response
|
|
259
|
+
│ │ │ └── index.ts # └─ Barrel exports
|
|
260
|
+
│ │ └── index.ts # └─ Barrel exports
|
|
261
|
+
│ └── queries/ # 🔍 CQRS queries (reads)
|
|
262
|
+
│ ├── get-[entity].handler.ts # └─ Single entity query
|
|
263
|
+
│ ├── list-[entities].handler.ts # └─ Multiple entities query
|
|
264
|
+
│ └── index.ts # └─ Barrel exports
|
|
265
|
+
└── infrastructure/ # 🏗️ Infrastructure layer
|
|
266
|
+
├── mappers/ # 🔄 Data transformation
|
|
267
|
+
│ ├── [entity].mapper.ts # └─ Domain ↔ ORM mapping
|
|
268
|
+
│ └── index.ts # └─ Barrel exports
|
|
269
|
+
├── orm-entities/ # 🗄️ Database schema
|
|
270
|
+
│ ├── [entity].orm-entity.ts # └─ TypeORM entity
|
|
271
|
+
│ └── index.ts # └─ Barrel exports
|
|
272
|
+
└── repositories/ # 💾 Data access
|
|
273
|
+
├── [entity].repository.ts # └─ Repository implementation
|
|
274
|
+
└── index.ts # └─ Barrel exports
|
|
107
275
|
```
|
|
108
276
|
|
|
109
|
-
|
|
277
|
+
> **🎯 Every feature looks identical** - No surprises, no confusion, just consistency.
|
|
110
278
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
279
|
+
### 🧠 **Smart Defaults & Conventions**
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Naming follows strict patterns
|
|
283
|
+
ddd generate entity UserProfile # → user-profile.entity.ts
|
|
284
|
+
ddd generate service OrderValidator # → order-validator.service.ts
|
|
285
|
+
ddd generate event PaymentProcessed # → payment-processed.event.ts
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Built-in Intelligence:**
|
|
289
|
+
- **🔄 Barrel exports** - Automatic `index.ts` files for clean imports
|
|
290
|
+
- **🔒 TypeScript strict** - Zero `any` types, full type safety
|
|
291
|
+
- **💉 DI ready** - Injectable decorators configured
|
|
292
|
+
- **📋 Interface first** - Clear contracts between layers
|
|
293
|
+
- **📁 Predictable paths** - Same location every time
|
|
294
|
+
|
|
295
|
+
### 💡 **Enterprise Patterns**
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// ✅ Commands (writes) - Tell, don't ask
|
|
299
|
+
@CommandHandler(CreateUserCommand)
|
|
300
|
+
export class CreateUserHandler {
|
|
301
|
+
async execute(command: CreateUserCommand): Promise<void> {
|
|
302
|
+
// Returns nothing - just does the work
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// ✅ Queries (reads) - Ask, don't tell
|
|
307
|
+
@QueryHandler(GetUserQuery)
|
|
308
|
+
export class GetUserHandler {
|
|
309
|
+
async execute(query: GetUserQuery): Promise<UserResponse> {
|
|
310
|
+
// Returns data - no side effects
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ✅ Domain Events - Loose coupling
|
|
315
|
+
export class UserCreatedEvent implements IEvent {
|
|
316
|
+
constructor(public readonly userId: string) {}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Battle-tested principles:**
|
|
321
|
+
- **Command/Query Separation** - Writes vs reads clearly separated
|
|
322
|
+
- **Domain Events** - Decoupled communication between bounded contexts
|
|
323
|
+
- **Repository Pattern** - Abstract data access from business logic
|
|
324
|
+
- **Clean Architecture** - Dependencies point inward to domain
|
|
116
325
|
|
|
117
326
|
## After Generation
|
|
118
327
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
328
|
+
### 🔧 **Your 5-Minute Setup Checklist:**
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# ✅ 1. Generated files are ready - Review structure
|
|
332
|
+
ls -la modules/your-feature/
|
|
333
|
+
|
|
334
|
+
# ✅ 2. Add business properties to entities
|
|
335
|
+
# Edit: application/domain/entities/[entity].entity.ts
|
|
336
|
+
# Add: name: string; email: string; etc.
|
|
337
|
+
|
|
338
|
+
# ✅ 3. Update DTOs with validation rules
|
|
339
|
+
# Edit: application/dto/requests/create-[entity].dto.ts
|
|
340
|
+
# Add: @IsEmail() email: string; @IsNotEmpty() name: string;
|
|
341
|
+
|
|
342
|
+
# ✅ 4. Configure database mappings
|
|
343
|
+
# Edit: infrastructure/orm-entities/[entity].orm-entity.ts
|
|
344
|
+
# Add: @Column() name: string; @Column() email: string;
|
|
345
|
+
|
|
346
|
+
# ✅ 5. Wire up the module
|
|
347
|
+
# Edit: app.module.ts
|
|
348
|
+
# Add: YourFeatureModule to imports array
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### 🎯 **Focus on Business Value:**
|
|
352
|
+
```typescript
|
|
353
|
+
// ✅ Write business rules in domain services
|
|
354
|
+
export class OrderValidator {
|
|
355
|
+
validateBusinessRules(order: Order): ValidationResult {
|
|
356
|
+
// Your domain logic here - not infrastructure concerns
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// ✅ Add complex queries for reporting
|
|
361
|
+
@QueryHandler(GetMonthlyRevenueQuery)
|
|
362
|
+
export class GetMonthlyRevenueHandler {
|
|
363
|
+
async execute(query: GetMonthlyRevenueQuery) {
|
|
364
|
+
// Complex business queries - not CRUD
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// ✅ Handle domain events for integration
|
|
369
|
+
@EventsHandler(OrderCreatedEvent)
|
|
370
|
+
export class OrderCreatedHandler {
|
|
371
|
+
async handle(event: OrderCreatedEvent) {
|
|
372
|
+
// Send emails, update analytics, etc.
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
> **🚀 From scaffolding to production in minutes, not days**
|
|
378
|
+
|
|
379
|
+
## Why This CLI Exists
|
|
380
|
+
|
|
381
|
+
### 😤 **The Problem**
|
|
382
|
+
- Endless debates about folder structure
|
|
383
|
+
- Inconsistent naming across team members
|
|
384
|
+
- Copy-pasting boilerplate between features
|
|
385
|
+
- Mixed patterns in the same codebase
|
|
386
|
+
- New developers spending weeks learning "our way"
|
|
387
|
+
|
|
388
|
+
### 🎯 **The Solution**
|
|
389
|
+
- **One structure** that works for all features
|
|
390
|
+
- **Zero configuration** - works out of the box
|
|
391
|
+
- **Battle-tested patterns** from real enterprise apps
|
|
392
|
+
- **Instant onboarding** - same structure everywhere
|
|
393
|
+
- **Focus on business logic** instead of architecture decisions
|
|
394
|
+
|
|
395
|
+
### 🏆 **The Result**
|
|
396
|
+
- 10x faster feature development
|
|
397
|
+
- Consistent codebase architecture
|
|
398
|
+
- Easy code reviews and maintenance
|
|
399
|
+
- New developers productive from day one
|
|
400
|
+
- No more "where does this file go?" questions
|
|
124
401
|
|
|
125
|
-
|
|
402
|
+
---
|
|
126
403
|
|
|
127
|
-
|
|
404
|
+
## Contributing & Development
|
|
405
|
+
|
|
406
|
+
### 🔧 **Local Development**
|
|
128
407
|
|
|
129
408
|
```bash
|
|
130
|
-
#
|
|
409
|
+
# Clone and setup
|
|
410
|
+
git clone https://github.com/eshe-huli/nestjs-ddd-cli
|
|
411
|
+
cd nestjs-ddd-cli
|
|
412
|
+
npm install
|
|
413
|
+
|
|
414
|
+
# Test changes locally
|
|
131
415
|
npm run dev -- generate entity Test -m test
|
|
132
416
|
|
|
133
|
-
#
|
|
417
|
+
# Build for production
|
|
134
418
|
npm run build
|
|
135
419
|
|
|
136
|
-
# Test globally
|
|
420
|
+
# Test globally installed version
|
|
137
421
|
ddd generate entity Test -m test
|
|
138
|
-
```
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### 🧪 **Testing Your Changes**
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
# Create a test project
|
|
428
|
+
mkdir test-project && cd test-project
|
|
429
|
+
|
|
430
|
+
# Test scaffolding
|
|
431
|
+
ddd scaffold Product -m inventory
|
|
432
|
+
|
|
433
|
+
# Verify structure matches expectations
|
|
434
|
+
tree modules/inventory/
|
|
435
|
+
|
|
436
|
+
# Test individual generators
|
|
437
|
+
ddd generate service ProductValidator -m inventory
|
|
438
|
+
ddd generate event ProductCreated -m inventory
|
|
439
|
+
ddd generate query GetProductsByCategory -m inventory
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### 📋 **Template Structure**
|
|
443
|
+
```
|
|
444
|
+
src/templates/
|
|
445
|
+
├── 📁 entity/ # Domain entity templates
|
|
446
|
+
├── 📁 service/ # Domain service templates
|
|
447
|
+
├── 📁 event/ # Domain event templates
|
|
448
|
+
├── 📁 query/ # Query handler templates
|
|
449
|
+
├── 📁 usecase/ # Use case templates
|
|
450
|
+
├── 📁 controller/ # Controller templates
|
|
451
|
+
├── 📁 repository/ # Repository templates
|
|
452
|
+
└── 📁 ... (more templates)
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
> **🤝 Pull requests welcome!** Help make DDD development even better.
|
|
456
|
+
|
|
457
|
+
## License
|
|
458
|
+
|
|
459
|
+
MIT - Build amazing things 🚀
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateEvent(eventName: string, options: any): Promise<void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.generateEvent = generateEvent;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const file_utils_1 = require("../utils/file.utils");
|
|
43
|
+
const naming_utils_1 = require("../utils/naming.utils");
|
|
44
|
+
async function generateEvent(eventName, options) {
|
|
45
|
+
if (!options.module) {
|
|
46
|
+
throw new Error('Module name is required. Use -m option to specify the module.');
|
|
47
|
+
}
|
|
48
|
+
console.log(chalk_1.default.blue(`Generating domain event: ${eventName}`));
|
|
49
|
+
const basePath = options.path || process.cwd();
|
|
50
|
+
const modulePath = (0, file_utils_1.getModulePath)(basePath, options.module);
|
|
51
|
+
// Generate domain event
|
|
52
|
+
const templateData = (0, file_utils_1.prepareTemplateData)(eventName, options.module);
|
|
53
|
+
const templatePath = path.join(__dirname, '../templates/event/domain-event.hbs');
|
|
54
|
+
const outputPath = path.join(modulePath, 'application/domain/events', `${(0, naming_utils_1.toKebabCase)(eventName)}.event.ts`);
|
|
55
|
+
await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData);
|
|
56
|
+
console.log(chalk_1.default.green(`✅ Domain event ${eventName} generated successfully!`));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=generate-event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-event.js","sourceRoot":"","sources":["../../src/commands/generate-event.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,sCAsBC;AA3BD,2CAA6B;AAC7B,kDAA0B;AAC1B,oDAA+F;AAC/F,wDAAoD;AAE7C,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,OAAY;IACjE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,4BAA4B,SAAS,EAAE,CAAC,CAAC,CAAC;IAEjE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAA,0BAAa,EAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3D,wBAAwB;IACxB,MAAM,YAAY,GAAG,IAAA,gCAAmB,EAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qCAAqC,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAC1B,UAAU,EACV,2BAA2B,EAC3B,GAAG,IAAA,0BAAW,EAAC,SAAS,CAAC,WAAW,CACrC,CAAC;IAEF,MAAM,IAAA,iCAAoB,EAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAEnE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,kBAAkB,SAAS,0BAA0B,CAAC,CAAC,CAAC;AAClF,CAAC"}
|
|
@@ -101,7 +101,7 @@ function getArrayNameFromPath(indexPath) {
|
|
|
101
101
|
'orm-entities': 'OrmEntities',
|
|
102
102
|
'repositories': 'Repositories',
|
|
103
103
|
};
|
|
104
|
-
return mapping[lastPart] || 'Exports';
|
|
104
|
+
return (lastPart && mapping[lastPart]) || 'Exports';
|
|
105
105
|
}
|
|
106
106
|
async function generateIndexFile(filePath, arrayName) {
|
|
107
107
|
const content = `export const ${arrayName} = [];\n`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-module.js","sourceRoot":"","sources":["../../src/commands/generate-module.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"generate-module.js","sourceRoot":"","sources":["../../src/commands/generate-module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateQuery(queryName: string, options: any): Promise<void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.generateQuery = generateQuery;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const file_utils_1 = require("../utils/file.utils");
|
|
43
|
+
const naming_utils_1 = require("../utils/naming.utils");
|
|
44
|
+
async function generateQuery(queryName, options) {
|
|
45
|
+
if (!options.module) {
|
|
46
|
+
throw new Error('Module name is required. Use -m option to specify the module.');
|
|
47
|
+
}
|
|
48
|
+
console.log(chalk_1.default.blue(`Generating query handler: ${queryName}`));
|
|
49
|
+
const basePath = options.path || process.cwd();
|
|
50
|
+
const modulePath = (0, file_utils_1.getModulePath)(basePath, options.module);
|
|
51
|
+
// Generate query handler
|
|
52
|
+
const templateData = (0, file_utils_1.prepareTemplateData)(queryName, options.module);
|
|
53
|
+
const templatePath = path.join(__dirname, '../templates/query/query-handler.hbs');
|
|
54
|
+
const outputPath = path.join(modulePath, 'application/queries', `${(0, naming_utils_1.toKebabCase)(queryName)}.handler.ts`);
|
|
55
|
+
await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData);
|
|
56
|
+
console.log(chalk_1.default.green(`✅ Query handler ${queryName} generated successfully!`));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=generate-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-query.js","sourceRoot":"","sources":["../../src/commands/generate-query.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,sCAsBC;AA3BD,2CAA6B;AAC7B,kDAA0B;AAC1B,oDAA+F;AAC/F,wDAAoD;AAE7C,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,OAAY;IACjE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,6BAA6B,SAAS,EAAE,CAAC,CAAC,CAAC;IAElE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAA,0BAAa,EAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3D,yBAAyB;IACzB,MAAM,YAAY,GAAG,IAAA,gCAAmB,EAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,sCAAsC,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAC1B,UAAU,EACV,qBAAqB,EACrB,GAAG,IAAA,0BAAW,EAAC,SAAS,CAAC,aAAa,CACvC,CAAC;IAEF,MAAM,IAAA,iCAAoB,EAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAEnE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,mBAAmB,SAAS,0BAA0B,CAAC,CAAC,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateService(serviceName: string, options: any): Promise<void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.generateService = generateService;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const file_utils_1 = require("../utils/file.utils");
|
|
43
|
+
const naming_utils_1 = require("../utils/naming.utils");
|
|
44
|
+
async function generateService(serviceName, options) {
|
|
45
|
+
if (!options.module) {
|
|
46
|
+
throw new Error('Module name is required. Use -m option to specify the module.');
|
|
47
|
+
}
|
|
48
|
+
console.log(chalk_1.default.blue(`Generating domain service: ${serviceName}`));
|
|
49
|
+
const basePath = options.path || process.cwd();
|
|
50
|
+
const modulePath = (0, file_utils_1.getModulePath)(basePath, options.module);
|
|
51
|
+
// Generate domain service
|
|
52
|
+
const templateData = (0, file_utils_1.prepareTemplateData)(serviceName, options.module);
|
|
53
|
+
const templatePath = path.join(__dirname, '../templates/service/domain-service.hbs');
|
|
54
|
+
const outputPath = path.join(modulePath, 'application/domain/services', `${(0, naming_utils_1.toKebabCase)(serviceName)}.service.ts`);
|
|
55
|
+
await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData);
|
|
56
|
+
console.log(chalk_1.default.green(`✅ Domain service ${serviceName} generated successfully!`));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=generate-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-service.js","sourceRoot":"","sources":["../../src/commands/generate-service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,0CAsBC;AA3BD,2CAA6B;AAC7B,kDAA0B;AAC1B,oDAA+F;AAC/F,wDAAoD;AAE7C,KAAK,UAAU,eAAe,CAAC,WAAmB,EAAE,OAAY;IACrE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,8BAA8B,WAAW,EAAE,CAAC,CAAC,CAAC;IAErE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAA,0BAAa,EAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3D,0BAA0B;IAC1B,MAAM,YAAY,GAAG,IAAA,gCAAmB,EAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,yCAAyC,CAAC,CAAC;IACrF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAC1B,UAAU,EACV,6BAA6B,EAC7B,GAAG,IAAA,0BAAW,EAAC,WAAW,CAAC,aAAa,CACzC,CAAC;IAEF,MAAM,IAAA,iCAAoB,EAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAEnE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,oBAAoB,WAAW,0BAA0B,CAAC,CAAC,CAAC;AACtF,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,9 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
9
9
|
const generate_module_1 = require("./commands/generate-module");
|
|
10
10
|
const generate_entity_1 = require("./commands/generate-entity");
|
|
11
11
|
const generate_usecase_1 = require("./commands/generate-usecase");
|
|
12
|
+
const generate_service_1 = require("./commands/generate-service");
|
|
13
|
+
const generate_event_1 = require("./commands/generate-event");
|
|
14
|
+
const generate_query_1 = require("./commands/generate-query");
|
|
12
15
|
const generate_all_1 = require("./commands/generate-all");
|
|
13
16
|
const program = new commander_1.Command();
|
|
14
17
|
program
|
|
@@ -18,7 +21,7 @@ program
|
|
|
18
21
|
program
|
|
19
22
|
.command('generate <type> <name>')
|
|
20
23
|
.alias('g')
|
|
21
|
-
.description('Generate boilerplate code')
|
|
24
|
+
.description('Generate boilerplate code (types: module, entity, usecase, service, event, query, all)')
|
|
22
25
|
.option('-m, --module <module>', 'Module name')
|
|
23
26
|
.option('-p, --path <path>', 'Base path for generation', process.cwd())
|
|
24
27
|
.option('--skip-orm', 'Skip ORM entity generation')
|
|
@@ -39,12 +42,21 @@ program
|
|
|
39
42
|
case 'use-case':
|
|
40
43
|
await (0, generate_usecase_1.generateUseCase)(name, options);
|
|
41
44
|
break;
|
|
45
|
+
case 'service':
|
|
46
|
+
await (0, generate_service_1.generateService)(name, options);
|
|
47
|
+
break;
|
|
48
|
+
case 'event':
|
|
49
|
+
await (0, generate_event_1.generateEvent)(name, options);
|
|
50
|
+
break;
|
|
51
|
+
case 'query':
|
|
52
|
+
await (0, generate_query_1.generateQuery)(name, options);
|
|
53
|
+
break;
|
|
42
54
|
case 'all':
|
|
43
55
|
await (0, generate_all_1.generateAll)(name, options);
|
|
44
56
|
break;
|
|
45
57
|
default:
|
|
46
58
|
console.error(chalk_1.default.red(`Unknown type: ${type}`));
|
|
47
|
-
console.log(chalk_1.default.yellow('Available types: module, entity, usecase, all'));
|
|
59
|
+
console.log(chalk_1.default.yellow('Available types: module, entity, usecase, service, event, query, all'));
|
|
48
60
|
process.exit(1);
|
|
49
61
|
}
|
|
50
62
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAEA,yCAAoC;AACpC,kDAA0B;AAC1B,gEAA4D;AAC5D,gEAA4D;AAC5D,kEAA8D;AAC9D,0DAAsD;AAEtD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,wBAAwB,CAAC;KACjC,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
|
|
2
|
+
|
|
3
|
+
export class {{entityName}}Query {
|
|
4
|
+
constructor(
|
|
5
|
+
public readonly id: string,
|
|
6
|
+
) {}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@QueryHandler({{entityName}}Query)
|
|
10
|
+
export class {{entityName}}Handler implements IQueryHandler<{{entityName}}Query> {
|
|
11
|
+
constructor() {}
|
|
12
|
+
|
|
13
|
+
async execute(query: {{entityName}}Query): Promise<any> {
|
|
14
|
+
const { id } = query;
|
|
15
|
+
// Add your query logic here
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
@Injectable()
|
|
4
|
+
export class {{entityName}}Service {
|
|
5
|
+
constructor() {}
|
|
6
|
+
|
|
7
|
+
// Add your domain service methods here
|
|
8
|
+
// Example:
|
|
9
|
+
// async validateBusinessRule(data: any): Promise<boolean> {
|
|
10
|
+
// // Domain validation logic
|
|
11
|
+
// return true;
|
|
12
|
+
// }
|
|
13
|
+
}
|