@abuhannaa/create-apptemplate 1.0.9 → 1.0.10
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/dist/index.js +754 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,12 +4,669 @@
|
|
|
4
4
|
import { intro, outro, isCancel as isCancel2 } from "@clack/prompts";
|
|
5
5
|
import pc3 from "picocolors";
|
|
6
6
|
|
|
7
|
+
// src/types.ts
|
|
8
|
+
var ALL_FEATURES = [
|
|
9
|
+
"auth",
|
|
10
|
+
"userManagement",
|
|
11
|
+
"departments",
|
|
12
|
+
"fileUpload",
|
|
13
|
+
"auditLogs",
|
|
14
|
+
"notifications",
|
|
15
|
+
"dataExport",
|
|
16
|
+
"dashboard"
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
// src/features.ts
|
|
20
|
+
var FEATURE_OPTIONS = [
|
|
21
|
+
{
|
|
22
|
+
value: "auth",
|
|
23
|
+
label: "Authentication (Login, JWT, Guards)",
|
|
24
|
+
hint: "Login/logout pages, JWT middleware, auth guards, profile"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
value: "userManagement",
|
|
28
|
+
label: "User Management",
|
|
29
|
+
hint: "User CRUD, roles, permissions"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
value: "departments",
|
|
33
|
+
label: "Departments",
|
|
34
|
+
hint: "Department CRUD module"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
value: "fileUpload",
|
|
38
|
+
label: "File Management",
|
|
39
|
+
hint: "File upload, download, preview"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
value: "auditLogs",
|
|
43
|
+
label: "Audit Logging",
|
|
44
|
+
hint: "Track all data changes with audit trail"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
value: "notifications",
|
|
48
|
+
label: "Notifications",
|
|
49
|
+
hint: "Real-time notification system (WebSocket)"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
value: "dataExport",
|
|
53
|
+
label: "Data Export",
|
|
54
|
+
hint: "CSV, Excel, PDF export"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
value: "dashboard",
|
|
58
|
+
label: "Dashboard",
|
|
59
|
+
hint: "Dashboard page with statistics (Requires Users, Depts, Notifications)"
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
function applyFeatureDependencies(selected) {
|
|
63
|
+
let result = [...selected];
|
|
64
|
+
if (!result.includes("auth")) {
|
|
65
|
+
result = result.filter((f) => f !== "userManagement" && f !== "departments");
|
|
66
|
+
}
|
|
67
|
+
if (!result.includes("userManagement")) {
|
|
68
|
+
result = result.filter((f) => f !== "departments");
|
|
69
|
+
}
|
|
70
|
+
if (!result.includes("userManagement") || !result.includes("departments") || !result.includes("notifications")) {
|
|
71
|
+
result = result.filter((f) => f !== "dashboard");
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
var DOTNET_CLEAN_MAP = {
|
|
76
|
+
auth: {
|
|
77
|
+
backend: [
|
|
78
|
+
// Application layer
|
|
79
|
+
"src/Core/App.Template.Application/Features/Authentication",
|
|
80
|
+
"src/Core/App.Template.Application/DTOs/Auth",
|
|
81
|
+
"src/Core/App.Template.Application/Interfaces/IJwtTokenService.cs",
|
|
82
|
+
"src/Core/App.Template.Application/Interfaces/IPasswordHashService.cs",
|
|
83
|
+
"src/Core/App.Template.Application/Interfaces/ISsoAuthService.cs",
|
|
84
|
+
"src/Core/App.Template.Application/Interfaces/IEmailService.cs",
|
|
85
|
+
// Infrastructure layer
|
|
86
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/JwtTokenService.cs",
|
|
87
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/PasswordHashService.cs",
|
|
88
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/SsoAuthService.cs",
|
|
89
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/SsoApiModels.cs",
|
|
90
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/EmailService.cs",
|
|
91
|
+
// Presentation layer
|
|
92
|
+
"src/Presentation/App.Template.WebAPI/Controllers/AuthController.cs"
|
|
93
|
+
],
|
|
94
|
+
frontend: []
|
|
95
|
+
// Frontend auth files handled by pattern below
|
|
96
|
+
},
|
|
97
|
+
userManagement: {
|
|
98
|
+
backend: [
|
|
99
|
+
"src/Core/App.Template.Application/Features/UserManagement",
|
|
100
|
+
"src/Core/App.Template.Application/DTOs/UserDto.cs",
|
|
101
|
+
"src/Presentation/App.Template.WebAPI/Controllers/UsersController.cs"
|
|
102
|
+
],
|
|
103
|
+
frontend: []
|
|
104
|
+
},
|
|
105
|
+
departments: {
|
|
106
|
+
backend: [
|
|
107
|
+
"src/Core/App.Template.Application/Features/DepartmentManagement",
|
|
108
|
+
"src/Core/App.Template.Application/DTOs/DepartmentDto.cs",
|
|
109
|
+
"src/Core/App.Template.Application/Interfaces/IOrganizationService.cs",
|
|
110
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/OrganizationService.cs",
|
|
111
|
+
"src/Presentation/App.Template.WebAPI/Controllers/DepartmentsController.cs"
|
|
112
|
+
],
|
|
113
|
+
frontend: []
|
|
114
|
+
},
|
|
115
|
+
fileUpload: {
|
|
116
|
+
backend: [
|
|
117
|
+
"src/Core/App.Template.Application/Features/FileManagement",
|
|
118
|
+
"src/Core/App.Template.Application/DTOs/UploadedFileDto.cs",
|
|
119
|
+
"src/Core/App.Template.Application/Interfaces/IFileStorageService.cs",
|
|
120
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/FileStorageService.cs",
|
|
121
|
+
"src/Presentation/App.Template.WebAPI/Controllers/FilesController.cs"
|
|
122
|
+
],
|
|
123
|
+
frontend: []
|
|
124
|
+
},
|
|
125
|
+
auditLogs: {
|
|
126
|
+
backend: [
|
|
127
|
+
"src/Core/App.Template.Application/Features/AuditLogManagement",
|
|
128
|
+
"src/Core/App.Template.Application/DTOs/AuditLogDto.cs",
|
|
129
|
+
"src/Infrastructure/App.Template.Infrastructure/Persistence/AuditEntry.cs",
|
|
130
|
+
"src/Presentation/App.Template.WebAPI/Controllers/AuditLogsController.cs"
|
|
131
|
+
],
|
|
132
|
+
frontend: []
|
|
133
|
+
},
|
|
134
|
+
notifications: {
|
|
135
|
+
backend: [
|
|
136
|
+
"src/Core/App.Template.Application/Features/NotificationManagement",
|
|
137
|
+
"src/Core/App.Template.Application/DTOs/NotificationDto.cs",
|
|
138
|
+
"src/Core/App.Template.Application/Interfaces/INotificationService.cs",
|
|
139
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/NotificationService.cs",
|
|
140
|
+
"src/Infrastructure/App.Template.Infrastructure/Hubs",
|
|
141
|
+
"src/Infrastructure/App.Template.Infrastructure/SignalR",
|
|
142
|
+
"src/Presentation/App.Template.WebAPI/Controllers/NotificationsController.cs"
|
|
143
|
+
],
|
|
144
|
+
frontend: []
|
|
145
|
+
},
|
|
146
|
+
dataExport: {
|
|
147
|
+
backend: [
|
|
148
|
+
"src/Core/App.Template.Application/Interfaces/IExportService.cs",
|
|
149
|
+
"src/Infrastructure/App.Template.Infrastructure/Services/ExportService.cs",
|
|
150
|
+
"src/Presentation/App.Template.WebAPI/Controllers/ExportController.cs"
|
|
151
|
+
],
|
|
152
|
+
frontend: []
|
|
153
|
+
},
|
|
154
|
+
dashboard: {
|
|
155
|
+
backend: [],
|
|
156
|
+
frontend: []
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
var DOTNET_NLAYER_MAP = {
|
|
160
|
+
auth: {
|
|
161
|
+
backend: [
|
|
162
|
+
"src/App.Template.Api/Controllers/AuthController.cs",
|
|
163
|
+
"src/App.Template.Api/Services/AuthService.cs",
|
|
164
|
+
"src/App.Template.Api/Services/JwtTokenGenerator.cs",
|
|
165
|
+
"src/App.Template.Api/Models/Dtos/AuthDtos.cs"
|
|
166
|
+
],
|
|
167
|
+
frontend: []
|
|
168
|
+
},
|
|
169
|
+
userManagement: {
|
|
170
|
+
backend: [
|
|
171
|
+
"src/App.Template.Api/Controllers/UsersController.cs",
|
|
172
|
+
"src/App.Template.Api/Services/UserService.cs",
|
|
173
|
+
"src/App.Template.Api/Services/IUserService.cs",
|
|
174
|
+
"src/App.Template.Api/Repositories/UserRepository.cs",
|
|
175
|
+
"src/App.Template.Api/Repositories/IUserRepository.cs",
|
|
176
|
+
"src/App.Template.Api/Models/Dtos/UserDtos.cs"
|
|
177
|
+
],
|
|
178
|
+
frontend: []
|
|
179
|
+
},
|
|
180
|
+
departments: {
|
|
181
|
+
backend: [
|
|
182
|
+
"src/App.Template.Api/Controllers/DepartmentsController.cs",
|
|
183
|
+
"src/App.Template.Api/Models/Dtos/DepartmentDtos.cs"
|
|
184
|
+
],
|
|
185
|
+
frontend: []
|
|
186
|
+
},
|
|
187
|
+
fileUpload: {
|
|
188
|
+
backend: [
|
|
189
|
+
"src/App.Template.Api/Controllers/FilesController.cs"
|
|
190
|
+
],
|
|
191
|
+
frontend: []
|
|
192
|
+
},
|
|
193
|
+
auditLogs: {
|
|
194
|
+
backend: [],
|
|
195
|
+
frontend: []
|
|
196
|
+
},
|
|
197
|
+
notifications: {
|
|
198
|
+
backend: [
|
|
199
|
+
"src/App.Template.Api/Controllers/NotificationsController.cs",
|
|
200
|
+
"src/App.Template.Api/Infrastructure/Hubs"
|
|
201
|
+
],
|
|
202
|
+
frontend: []
|
|
203
|
+
},
|
|
204
|
+
dataExport: {
|
|
205
|
+
backend: [
|
|
206
|
+
"src/App.Template.Api/Controllers/ExportController.cs"
|
|
207
|
+
],
|
|
208
|
+
frontend: []
|
|
209
|
+
},
|
|
210
|
+
dashboard: {
|
|
211
|
+
backend: [],
|
|
212
|
+
frontend: []
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
var DOTNET_FEATURE_MAP = {
|
|
216
|
+
auth: {
|
|
217
|
+
backend: [
|
|
218
|
+
"src/App.Template.Api/Features/Auth"
|
|
219
|
+
],
|
|
220
|
+
frontend: []
|
|
221
|
+
},
|
|
222
|
+
userManagement: {
|
|
223
|
+
backend: [
|
|
224
|
+
"src/App.Template.Api/Features/Users"
|
|
225
|
+
],
|
|
226
|
+
frontend: []
|
|
227
|
+
},
|
|
228
|
+
departments: {
|
|
229
|
+
backend: [
|
|
230
|
+
"src/App.Template.Api/Features/Departments"
|
|
231
|
+
],
|
|
232
|
+
frontend: []
|
|
233
|
+
},
|
|
234
|
+
fileUpload: {
|
|
235
|
+
backend: [
|
|
236
|
+
"src/App.Template.Api/Features/Files"
|
|
237
|
+
],
|
|
238
|
+
frontend: []
|
|
239
|
+
},
|
|
240
|
+
auditLogs: {
|
|
241
|
+
backend: [],
|
|
242
|
+
frontend: []
|
|
243
|
+
},
|
|
244
|
+
notifications: {
|
|
245
|
+
backend: [
|
|
246
|
+
"src/App.Template.Api/Features/Notifications"
|
|
247
|
+
],
|
|
248
|
+
frontend: []
|
|
249
|
+
},
|
|
250
|
+
dataExport: {
|
|
251
|
+
backend: [
|
|
252
|
+
"src/App.Template.Api/Features/Export"
|
|
253
|
+
],
|
|
254
|
+
frontend: []
|
|
255
|
+
},
|
|
256
|
+
dashboard: {
|
|
257
|
+
backend: [],
|
|
258
|
+
frontend: []
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
var SPRING_CLEAN_MAP = {
|
|
262
|
+
auth: {
|
|
263
|
+
backend: [
|
|
264
|
+
"api/src/main/java/apptemplate/api/controllers/AuthController.java"
|
|
265
|
+
],
|
|
266
|
+
frontend: []
|
|
267
|
+
},
|
|
268
|
+
userManagement: {
|
|
269
|
+
backend: [
|
|
270
|
+
"api/src/main/java/apptemplate/api/controllers/UsersController.java"
|
|
271
|
+
],
|
|
272
|
+
frontend: []
|
|
273
|
+
},
|
|
274
|
+
departments: {
|
|
275
|
+
backend: [
|
|
276
|
+
"api/src/main/java/apptemplate/api/controllers/DepartmentsController.java"
|
|
277
|
+
],
|
|
278
|
+
frontend: []
|
|
279
|
+
},
|
|
280
|
+
fileUpload: {
|
|
281
|
+
backend: [
|
|
282
|
+
"api/src/main/java/apptemplate/api/controllers/FilesController.java"
|
|
283
|
+
],
|
|
284
|
+
frontend: []
|
|
285
|
+
},
|
|
286
|
+
auditLogs: {
|
|
287
|
+
backend: [
|
|
288
|
+
"api/src/main/java/apptemplate/api/controllers/AuditLogsController.java"
|
|
289
|
+
],
|
|
290
|
+
frontend: []
|
|
291
|
+
},
|
|
292
|
+
notifications: {
|
|
293
|
+
backend: [
|
|
294
|
+
"api/src/main/java/apptemplate/api/controllers/NotificationsController.java"
|
|
295
|
+
],
|
|
296
|
+
frontend: []
|
|
297
|
+
},
|
|
298
|
+
dataExport: {
|
|
299
|
+
backend: [
|
|
300
|
+
"api/src/main/java/apptemplate/api/controllers/ExportController.java"
|
|
301
|
+
],
|
|
302
|
+
frontend: []
|
|
303
|
+
},
|
|
304
|
+
dashboard: {
|
|
305
|
+
backend: [],
|
|
306
|
+
frontend: []
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
var SPRING_NLAYER_MAP = {
|
|
310
|
+
auth: {
|
|
311
|
+
backend: [
|
|
312
|
+
"src/main/java/com/apptemplate/api/controller/AuthController.java"
|
|
313
|
+
],
|
|
314
|
+
frontend: []
|
|
315
|
+
},
|
|
316
|
+
userManagement: {
|
|
317
|
+
backend: [
|
|
318
|
+
"src/main/java/com/apptemplate/api/controller/UserController.java"
|
|
319
|
+
],
|
|
320
|
+
frontend: []
|
|
321
|
+
},
|
|
322
|
+
departments: {
|
|
323
|
+
backend: [
|
|
324
|
+
"src/main/java/com/apptemplate/api/controller/DepartmentController.java"
|
|
325
|
+
],
|
|
326
|
+
frontend: []
|
|
327
|
+
},
|
|
328
|
+
fileUpload: {
|
|
329
|
+
backend: [
|
|
330
|
+
"src/main/java/com/apptemplate/api/controller/FileController.java"
|
|
331
|
+
],
|
|
332
|
+
frontend: []
|
|
333
|
+
},
|
|
334
|
+
auditLogs: {
|
|
335
|
+
backend: [
|
|
336
|
+
"src/main/java/com/apptemplate/api/audit"
|
|
337
|
+
],
|
|
338
|
+
frontend: []
|
|
339
|
+
},
|
|
340
|
+
notifications: {
|
|
341
|
+
backend: [
|
|
342
|
+
"src/main/java/com/apptemplate/api/controller/NotificationController.java"
|
|
343
|
+
],
|
|
344
|
+
frontend: []
|
|
345
|
+
},
|
|
346
|
+
dataExport: {
|
|
347
|
+
backend: [
|
|
348
|
+
"src/main/java/com/apptemplate/api/controller/ExportController.java"
|
|
349
|
+
],
|
|
350
|
+
frontend: []
|
|
351
|
+
},
|
|
352
|
+
dashboard: {
|
|
353
|
+
backend: [],
|
|
354
|
+
frontend: []
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
var SPRING_FEATURE_MAP = {
|
|
358
|
+
auth: {
|
|
359
|
+
backend: [
|
|
360
|
+
"src/main/java/com/apptemplate/api/features/auth"
|
|
361
|
+
],
|
|
362
|
+
frontend: []
|
|
363
|
+
},
|
|
364
|
+
userManagement: {
|
|
365
|
+
backend: [
|
|
366
|
+
"src/main/java/com/apptemplate/api/features/users"
|
|
367
|
+
],
|
|
368
|
+
frontend: []
|
|
369
|
+
},
|
|
370
|
+
departments: {
|
|
371
|
+
backend: [
|
|
372
|
+
"src/main/java/com/apptemplate/api/features/departments"
|
|
373
|
+
],
|
|
374
|
+
frontend: []
|
|
375
|
+
},
|
|
376
|
+
fileUpload: {
|
|
377
|
+
backend: [
|
|
378
|
+
"src/main/java/com/apptemplate/api/features/files"
|
|
379
|
+
],
|
|
380
|
+
frontend: []
|
|
381
|
+
},
|
|
382
|
+
auditLogs: {
|
|
383
|
+
backend: [
|
|
384
|
+
"src/main/java/com/apptemplate/api/common/audit"
|
|
385
|
+
],
|
|
386
|
+
frontend: []
|
|
387
|
+
},
|
|
388
|
+
notifications: {
|
|
389
|
+
backend: [
|
|
390
|
+
"src/main/java/com/apptemplate/api/features/notifications"
|
|
391
|
+
],
|
|
392
|
+
frontend: []
|
|
393
|
+
},
|
|
394
|
+
dataExport: {
|
|
395
|
+
backend: [
|
|
396
|
+
"src/main/java/com/apptemplate/api/features/export"
|
|
397
|
+
],
|
|
398
|
+
frontend: []
|
|
399
|
+
},
|
|
400
|
+
dashboard: {
|
|
401
|
+
backend: [],
|
|
402
|
+
frontend: []
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
var NESTJS_CLEAN_MAP = {
|
|
406
|
+
auth: {
|
|
407
|
+
backend: [
|
|
408
|
+
"src/modules/auth"
|
|
409
|
+
],
|
|
410
|
+
frontend: []
|
|
411
|
+
},
|
|
412
|
+
userManagement: {
|
|
413
|
+
backend: [
|
|
414
|
+
"src/modules/user-management"
|
|
415
|
+
],
|
|
416
|
+
frontend: []
|
|
417
|
+
},
|
|
418
|
+
departments: {
|
|
419
|
+
backend: [
|
|
420
|
+
"src/modules/department-management"
|
|
421
|
+
],
|
|
422
|
+
frontend: []
|
|
423
|
+
},
|
|
424
|
+
fileUpload: {
|
|
425
|
+
backend: [
|
|
426
|
+
"src/modules/file-management"
|
|
427
|
+
],
|
|
428
|
+
frontend: []
|
|
429
|
+
},
|
|
430
|
+
auditLogs: {
|
|
431
|
+
backend: [
|
|
432
|
+
"src/modules/audit-log"
|
|
433
|
+
],
|
|
434
|
+
frontend: []
|
|
435
|
+
},
|
|
436
|
+
notifications: {
|
|
437
|
+
backend: [
|
|
438
|
+
"src/modules/notification"
|
|
439
|
+
],
|
|
440
|
+
frontend: []
|
|
441
|
+
},
|
|
442
|
+
dataExport: {
|
|
443
|
+
backend: [
|
|
444
|
+
"src/modules/export"
|
|
445
|
+
],
|
|
446
|
+
frontend: []
|
|
447
|
+
},
|
|
448
|
+
dashboard: {
|
|
449
|
+
backend: [],
|
|
450
|
+
frontend: []
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
var NESTJS_NLAYER_MAP = {
|
|
454
|
+
auth: {
|
|
455
|
+
backend: [
|
|
456
|
+
"src/auth"
|
|
457
|
+
],
|
|
458
|
+
frontend: []
|
|
459
|
+
},
|
|
460
|
+
userManagement: {
|
|
461
|
+
backend: [],
|
|
462
|
+
frontend: []
|
|
463
|
+
},
|
|
464
|
+
departments: {
|
|
465
|
+
backend: [
|
|
466
|
+
"src/modules/departments"
|
|
467
|
+
],
|
|
468
|
+
frontend: []
|
|
469
|
+
},
|
|
470
|
+
fileUpload: {
|
|
471
|
+
backend: [
|
|
472
|
+
"src/modules/files"
|
|
473
|
+
],
|
|
474
|
+
frontend: []
|
|
475
|
+
},
|
|
476
|
+
auditLogs: {
|
|
477
|
+
backend: [],
|
|
478
|
+
frontend: []
|
|
479
|
+
},
|
|
480
|
+
notifications: {
|
|
481
|
+
backend: [
|
|
482
|
+
"src/modules/notifications"
|
|
483
|
+
],
|
|
484
|
+
frontend: []
|
|
485
|
+
},
|
|
486
|
+
dataExport: {
|
|
487
|
+
backend: [
|
|
488
|
+
"src/modules/export"
|
|
489
|
+
],
|
|
490
|
+
frontend: []
|
|
491
|
+
},
|
|
492
|
+
dashboard: {
|
|
493
|
+
backend: [],
|
|
494
|
+
frontend: []
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
var NESTJS_FEATURE_MAP = {
|
|
498
|
+
auth: {
|
|
499
|
+
backend: [
|
|
500
|
+
"src/features/auth"
|
|
501
|
+
],
|
|
502
|
+
frontend: []
|
|
503
|
+
},
|
|
504
|
+
userManagement: {
|
|
505
|
+
backend: [
|
|
506
|
+
"src/features/users"
|
|
507
|
+
],
|
|
508
|
+
frontend: []
|
|
509
|
+
},
|
|
510
|
+
departments: {
|
|
511
|
+
backend: [
|
|
512
|
+
"src/features/departments"
|
|
513
|
+
],
|
|
514
|
+
frontend: []
|
|
515
|
+
},
|
|
516
|
+
fileUpload: {
|
|
517
|
+
backend: [
|
|
518
|
+
"src/features/files"
|
|
519
|
+
],
|
|
520
|
+
frontend: []
|
|
521
|
+
},
|
|
522
|
+
auditLogs: {
|
|
523
|
+
backend: [],
|
|
524
|
+
frontend: []
|
|
525
|
+
},
|
|
526
|
+
notifications: {
|
|
527
|
+
backend: [
|
|
528
|
+
"src/features/notifications"
|
|
529
|
+
],
|
|
530
|
+
frontend: []
|
|
531
|
+
},
|
|
532
|
+
dataExport: {
|
|
533
|
+
backend: [
|
|
534
|
+
"src/features/export"
|
|
535
|
+
],
|
|
536
|
+
frontend: []
|
|
537
|
+
},
|
|
538
|
+
dashboard: {
|
|
539
|
+
backend: [],
|
|
540
|
+
frontend: []
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
var VUE_FRONTEND_MAP = {
|
|
544
|
+
auth: [
|
|
545
|
+
"src/pages/login.vue",
|
|
546
|
+
"src/pages/forgot-password.vue",
|
|
547
|
+
"src/pages/reset-password.vue",
|
|
548
|
+
"src/pages/profile.vue",
|
|
549
|
+
"src/stores/auth.js",
|
|
550
|
+
"src/services/authApi.js"
|
|
551
|
+
],
|
|
552
|
+
userManagement: [
|
|
553
|
+
"src/pages/users",
|
|
554
|
+
"src/stores/user.js",
|
|
555
|
+
"src/services/userApi.js"
|
|
556
|
+
],
|
|
557
|
+
departments: [
|
|
558
|
+
"src/pages/departments",
|
|
559
|
+
"src/stores/department.js",
|
|
560
|
+
"src/services/departmentApi.js"
|
|
561
|
+
],
|
|
562
|
+
fileUpload: [
|
|
563
|
+
"src/pages/files",
|
|
564
|
+
"src/services/fileService.js"
|
|
565
|
+
],
|
|
566
|
+
auditLogs: [
|
|
567
|
+
"src/pages/audit-logs",
|
|
568
|
+
"src/services/auditLogService.js"
|
|
569
|
+
],
|
|
570
|
+
notifications: [
|
|
571
|
+
"src/pages/notifications",
|
|
572
|
+
"src/stores/notification.js",
|
|
573
|
+
"src/stores/persistentNotification.js",
|
|
574
|
+
"src/services/notificationApi.js"
|
|
575
|
+
],
|
|
576
|
+
dataExport: [
|
|
577
|
+
"src/services/exportService.js"
|
|
578
|
+
],
|
|
579
|
+
dashboard: [
|
|
580
|
+
"src/pages/dashboard.vue"
|
|
581
|
+
]
|
|
582
|
+
};
|
|
583
|
+
var REACT_FRONTEND_MAP = {
|
|
584
|
+
auth: [
|
|
585
|
+
"src/pages/Login.tsx",
|
|
586
|
+
"src/pages/ForgotPassword.tsx",
|
|
587
|
+
"src/pages/ResetPassword.tsx",
|
|
588
|
+
"src/pages/Profile.tsx",
|
|
589
|
+
"src/stores/authStore.ts",
|
|
590
|
+
"src/services/authApi.ts"
|
|
591
|
+
],
|
|
592
|
+
userManagement: [
|
|
593
|
+
"src/pages/Users.tsx",
|
|
594
|
+
"src/stores/userStore.ts",
|
|
595
|
+
"src/services/userApi.ts"
|
|
596
|
+
],
|
|
597
|
+
departments: [
|
|
598
|
+
"src/pages/Departments.tsx",
|
|
599
|
+
"src/stores/departmentStore.ts",
|
|
600
|
+
"src/services/departmentApi.ts"
|
|
601
|
+
],
|
|
602
|
+
fileUpload: [
|
|
603
|
+
"src/pages/FilesPage.tsx",
|
|
604
|
+
"src/services/fileService.ts"
|
|
605
|
+
],
|
|
606
|
+
auditLogs: [
|
|
607
|
+
"src/pages/AuditLogsPage.tsx",
|
|
608
|
+
"src/pages/AuditLogs.tsx",
|
|
609
|
+
"src/services/auditLogService.ts"
|
|
610
|
+
],
|
|
611
|
+
notifications: [
|
|
612
|
+
"src/pages/Notifications.tsx",
|
|
613
|
+
"src/stores/notificationStore.ts",
|
|
614
|
+
"src/stores/persistentNotificationStore.ts",
|
|
615
|
+
"src/services/notificationApi.ts"
|
|
616
|
+
],
|
|
617
|
+
dataExport: [
|
|
618
|
+
"src/services/exportService.ts"
|
|
619
|
+
],
|
|
620
|
+
dashboard: [
|
|
621
|
+
"src/pages/Dashboard.tsx",
|
|
622
|
+
"src/pages/Dashboard.scss"
|
|
623
|
+
]
|
|
624
|
+
};
|
|
625
|
+
function getBackendFileMap(backend, architecture) {
|
|
626
|
+
const key = `${backend}-${architecture}`;
|
|
627
|
+
switch (key) {
|
|
628
|
+
case "dotnet-clean":
|
|
629
|
+
return DOTNET_CLEAN_MAP;
|
|
630
|
+
case "dotnet-nlayer":
|
|
631
|
+
return DOTNET_NLAYER_MAP;
|
|
632
|
+
case "dotnet-feature":
|
|
633
|
+
return DOTNET_FEATURE_MAP;
|
|
634
|
+
case "spring-clean":
|
|
635
|
+
return SPRING_CLEAN_MAP;
|
|
636
|
+
case "spring-nlayer":
|
|
637
|
+
return SPRING_NLAYER_MAP;
|
|
638
|
+
case "spring-feature":
|
|
639
|
+
return SPRING_FEATURE_MAP;
|
|
640
|
+
case "nestjs-clean":
|
|
641
|
+
return NESTJS_CLEAN_MAP;
|
|
642
|
+
case "nestjs-nlayer":
|
|
643
|
+
return NESTJS_NLAYER_MAP;
|
|
644
|
+
case "nestjs-feature":
|
|
645
|
+
return NESTJS_FEATURE_MAP;
|
|
646
|
+
default:
|
|
647
|
+
return {};
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
function getFrontendFileMap(frontendFramework) {
|
|
651
|
+
return frontendFramework === "vue" ? VUE_FRONTEND_MAP : REACT_FRONTEND_MAP;
|
|
652
|
+
}
|
|
653
|
+
function getFeaturesLabel(features, allFeatures) {
|
|
654
|
+
if (features.length === allFeatures.length) {
|
|
655
|
+
return "All features";
|
|
656
|
+
}
|
|
657
|
+
if (features.length === 0) {
|
|
658
|
+
return "None (bare template)";
|
|
659
|
+
}
|
|
660
|
+
return features.map((f) => FEATURE_OPTIONS.find((o) => o.value === f)?.label || f).join(", ");
|
|
661
|
+
}
|
|
662
|
+
|
|
7
663
|
// src/cli.ts
|
|
8
664
|
var validProjectTypes = ["fullstack", "backend", "frontend"];
|
|
9
665
|
var validBackends = ["dotnet", "spring", "nestjs"];
|
|
10
666
|
var validArchitectures = ["clean", "nlayer", "feature"];
|
|
11
667
|
var validFrontendFrameworks = ["vue", "react"];
|
|
12
668
|
var validUILibraries = ["vuetify", "primevue", "primereact", "mui"];
|
|
669
|
+
var validFeatures = [...ALL_FEATURES];
|
|
13
670
|
function parseArgs() {
|
|
14
671
|
const args = process.argv.slice(2);
|
|
15
672
|
const result = {};
|
|
@@ -96,6 +753,24 @@ function parseArgs() {
|
|
|
96
753
|
i++;
|
|
97
754
|
continue;
|
|
98
755
|
}
|
|
756
|
+
if (arg === "--features" || arg === "--feat") {
|
|
757
|
+
const value = args[++i];
|
|
758
|
+
if (value) {
|
|
759
|
+
if (value === "all") {
|
|
760
|
+
result.features = [...ALL_FEATURES];
|
|
761
|
+
} else {
|
|
762
|
+
const requested = value.split(",").map((s) => s.trim());
|
|
763
|
+
const valid = requested.filter((f) => validFeatures.includes(f));
|
|
764
|
+
const invalid = requested.filter((f) => !validFeatures.includes(f));
|
|
765
|
+
if (invalid.length > 0) {
|
|
766
|
+
console.warn(`Warning: Invalid features "${invalid.join(", ")}". Valid options: ${validFeatures.join(", ")}`);
|
|
767
|
+
}
|
|
768
|
+
result.features = applyFeatureDependencies(valid);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
i++;
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
99
774
|
if (!arg.startsWith("-") && !result.projectPath) {
|
|
100
775
|
result.projectPath = arg;
|
|
101
776
|
}
|
|
@@ -276,6 +951,26 @@ async function runInteractivePrompts(cliArgs) {
|
|
|
276
951
|
if (p.isCancel(result)) return result;
|
|
277
952
|
ui = result;
|
|
278
953
|
}
|
|
954
|
+
let features = cliArgs.features || [...ALL_FEATURES];
|
|
955
|
+
if (!cliArgs.features) {
|
|
956
|
+
const result = await p.multiselect({
|
|
957
|
+
message: "Which features would you like to include?",
|
|
958
|
+
options: FEATURE_OPTIONS.map((opt) => ({
|
|
959
|
+
value: opt.value,
|
|
960
|
+
label: opt.label,
|
|
961
|
+
hint: opt.hint
|
|
962
|
+
})),
|
|
963
|
+
initialValues: [...ALL_FEATURES],
|
|
964
|
+
required: false
|
|
965
|
+
});
|
|
966
|
+
if (p.isCancel(result)) return result;
|
|
967
|
+
features = applyFeatureDependencies(result);
|
|
968
|
+
if (features.length < result.length) {
|
|
969
|
+
const removed = result.filter((f) => !features.includes(f));
|
|
970
|
+
const removedLabels = removed.map((f) => FEATURE_OPTIONS.find((o) => o.value === f)?.label || f);
|
|
971
|
+
console.log(pc.yellow(` \u26A0 Auto-removed due to dependencies: ${removedLabels.join(", ")}`));
|
|
972
|
+
}
|
|
973
|
+
}
|
|
279
974
|
let projectName = cliArgs.projectName;
|
|
280
975
|
const needsNamespace = projectType !== "frontend" && (backend === "dotnet" || backend === "spring");
|
|
281
976
|
if (needsNamespace && !projectName) {
|
|
@@ -328,6 +1023,7 @@ async function runInteractivePrompts(cliArgs) {
|
|
|
328
1023
|
summaryLines.push(`${pc.cyan("Frontend:")} ${getFrontendLabel(frontendFramework)}`);
|
|
329
1024
|
summaryLines.push(`${pc.cyan("UI Library:")} ${getUILabel(ui)}`);
|
|
330
1025
|
}
|
|
1026
|
+
summaryLines.push(`${pc.cyan("Features:")} ${getFeaturesLabel(features, ALL_FEATURES)}`);
|
|
331
1027
|
if (needsNamespace && projectName) {
|
|
332
1028
|
summaryLines.push(`${pc.cyan("Namespace:")} ${projectName}`);
|
|
333
1029
|
}
|
|
@@ -352,7 +1048,8 @@ async function runInteractivePrompts(cliArgs) {
|
|
|
352
1048
|
ui,
|
|
353
1049
|
projectName,
|
|
354
1050
|
installDeps,
|
|
355
|
-
placeInRoot
|
|
1051
|
+
placeInRoot,
|
|
1052
|
+
features
|
|
356
1053
|
};
|
|
357
1054
|
}
|
|
358
1055
|
function toPascalCase(str) {
|
|
@@ -760,6 +1457,16 @@ async function generateProject(config) {
|
|
|
760
1457
|
spinner2.stop("Download failed");
|
|
761
1458
|
throw error;
|
|
762
1459
|
}
|
|
1460
|
+
const deselectedFeatures = ALL_FEATURES.filter((f) => !config.features.includes(f));
|
|
1461
|
+
if (deselectedFeatures.length > 0) {
|
|
1462
|
+
spinner2.start("Removing deselected feature files...");
|
|
1463
|
+
try {
|
|
1464
|
+
await removeDeselectedFeatures(absolutePath, config, deselectedFeatures);
|
|
1465
|
+
spinner2.stop(`Removed ${deselectedFeatures.length} deselected feature(s)`);
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
spinner2.stop("Feature removal had warnings");
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
763
1470
|
spinner2.start("Updating configuration files...");
|
|
764
1471
|
try {
|
|
765
1472
|
await updateFolderReferences(absolutePath, config);
|
|
@@ -804,6 +1511,48 @@ async function generateProject(config) {
|
|
|
804
1511
|
await createAppSettingsFromExample(absolutePath, config);
|
|
805
1512
|
}
|
|
806
1513
|
}
|
|
1514
|
+
async function removeDeselectedFeatures(projectPath, config, deselectedFeatures) {
|
|
1515
|
+
if (config.projectType !== "frontend") {
|
|
1516
|
+
const backendMap = getBackendFileMap(config.backend, config.architecture);
|
|
1517
|
+
let backendDir;
|
|
1518
|
+
if (config.projectType === "fullstack") {
|
|
1519
|
+
backendDir = path5.join(projectPath, "backend");
|
|
1520
|
+
} else {
|
|
1521
|
+
backendDir = config.placeInRoot ? projectPath : path5.join(projectPath, "backend");
|
|
1522
|
+
}
|
|
1523
|
+
for (const feature of deselectedFeatures) {
|
|
1524
|
+
const featureMap = backendMap[feature];
|
|
1525
|
+
if (featureMap) {
|
|
1526
|
+
for (const filePath of featureMap.backend) {
|
|
1527
|
+
const fullPath = path5.join(backendDir, filePath);
|
|
1528
|
+
if (fs5.existsSync(fullPath)) {
|
|
1529
|
+
fs5.rmSync(fullPath, { recursive: true, force: true });
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
if (config.projectType !== "backend") {
|
|
1536
|
+
const frontendMap = getFrontendFileMap(config.frontendFramework);
|
|
1537
|
+
let frontendDir;
|
|
1538
|
+
if (config.projectType === "fullstack") {
|
|
1539
|
+
frontendDir = path5.join(projectPath, "frontend");
|
|
1540
|
+
} else {
|
|
1541
|
+
frontendDir = config.placeInRoot ? projectPath : path5.join(projectPath, "frontend");
|
|
1542
|
+
}
|
|
1543
|
+
for (const feature of deselectedFeatures) {
|
|
1544
|
+
const featurePaths = frontendMap[feature];
|
|
1545
|
+
if (featurePaths) {
|
|
1546
|
+
for (const filePath of featurePaths) {
|
|
1547
|
+
const fullPath = path5.join(frontendDir, filePath);
|
|
1548
|
+
if (fs5.existsSync(fullPath)) {
|
|
1549
|
+
fs5.rmSync(fullPath, { recursive: true, force: true });
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
807
1556
|
function cleanupFullstackDockerFiles(projectPath) {
|
|
808
1557
|
const filesToDelete = [
|
|
809
1558
|
"backend/Dockerfile",
|
|
@@ -967,7 +1716,8 @@ async function main() {
|
|
|
967
1716
|
ui: cliArgs.ui || (frontendFramework === "vue" ? "vuetify" : "mui"),
|
|
968
1717
|
projectName: cliArgs.projectName,
|
|
969
1718
|
installDeps: cliArgs.install || false,
|
|
970
|
-
placeInRoot: cliArgs.root || false
|
|
1719
|
+
placeInRoot: cliArgs.root || false,
|
|
1720
|
+
features: cliArgs.features || [...ALL_FEATURES]
|
|
971
1721
|
};
|
|
972
1722
|
} else {
|
|
973
1723
|
const result = await runInteractivePrompts(cliArgs);
|
|
@@ -1003,6 +1753,8 @@ ${pc3.bold("Options:")}
|
|
|
1003
1753
|
${pc3.yellow("-u, --ui")} UI library: vuetify, primevue (Vue) | mui, primereact (React)
|
|
1004
1754
|
${pc3.yellow("-n, --name")} Project namespace (Company.Project format, .NET/Spring only)
|
|
1005
1755
|
${pc3.yellow("-r, --root")} Place files in project root ${pc3.gray("(backend/frontend-only)")}
|
|
1756
|
+
${pc3.yellow("--features")} Features to include (comma-separated or "all")
|
|
1757
|
+
Options: auth,userManagement,departments,fileUpload,auditLogs,notifications,dataExport,dashboard
|
|
1006
1758
|
${pc3.yellow("-i, --install")} Install dependencies after creation
|
|
1007
1759
|
${pc3.yellow("-h, --help")} Show this help message
|
|
1008
1760
|
${pc3.yellow("-v, --version")} Show version number
|