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