@abuhannaa/create-apptemplate 1.0.11 → 1.1.0
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 +57 -761
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,676 +4,13 @@
|
|
|
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
|
-
|
|
670
7
|
// src/cli.ts
|
|
671
8
|
var validProjectTypes = ["fullstack", "backend", "frontend"];
|
|
672
9
|
var validBackends = ["dotnet", "spring", "nestjs"];
|
|
673
10
|
var validArchitectures = ["clean", "nlayer", "feature"];
|
|
674
11
|
var validFrontendFrameworks = ["vue", "react"];
|
|
675
12
|
var validUILibraries = ["vuetify", "primevue", "primereact", "mui"];
|
|
676
|
-
var
|
|
13
|
+
var validVariants = ["minimal", "full"];
|
|
677
14
|
function parseArgs() {
|
|
678
15
|
const args = process.argv.slice(2);
|
|
679
16
|
const result = {};
|
|
@@ -760,20 +97,12 @@ function parseArgs() {
|
|
|
760
97
|
i++;
|
|
761
98
|
continue;
|
|
762
99
|
}
|
|
763
|
-
if (arg === "
|
|
100
|
+
if (arg === "-V" || arg === "--variant") {
|
|
764
101
|
const value = args[++i];
|
|
765
|
-
if (value) {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
}
|
|
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
|
-
}
|
|
102
|
+
if (isValidVariant(value)) {
|
|
103
|
+
result.variant = value;
|
|
104
|
+
} else {
|
|
105
|
+
console.warn(`Warning: Invalid variant "${value}". Valid options: ${validVariants.join(", ")}`);
|
|
777
106
|
}
|
|
778
107
|
i++;
|
|
779
108
|
continue;
|
|
@@ -800,6 +129,9 @@ function isValidFrontendFramework(value) {
|
|
|
800
129
|
function isValidUI(value) {
|
|
801
130
|
return value !== void 0 && validUILibraries.includes(value);
|
|
802
131
|
}
|
|
132
|
+
function isValidVariant(value) {
|
|
133
|
+
return value !== void 0 && validVariants.includes(value);
|
|
134
|
+
}
|
|
803
135
|
function isValidProjectName(value) {
|
|
804
136
|
if (!value) return false;
|
|
805
137
|
const pattern = /^[A-Za-z][A-Za-z0-9]*(\.[A-Za-z][A-Za-z0-9]*)+$/;
|
|
@@ -958,25 +290,25 @@ async function runInteractivePrompts(cliArgs) {
|
|
|
958
290
|
if (p.isCancel(result)) return result;
|
|
959
291
|
ui = result;
|
|
960
292
|
}
|
|
961
|
-
let
|
|
962
|
-
if (!cliArgs.
|
|
963
|
-
const result = await p.
|
|
964
|
-
message: "Which
|
|
965
|
-
options:
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
293
|
+
let variant = cliArgs.variant || "full";
|
|
294
|
+
if (!cliArgs.variant) {
|
|
295
|
+
const result = await p.select({
|
|
296
|
+
message: "Which template variant would you like?",
|
|
297
|
+
options: [
|
|
298
|
+
{
|
|
299
|
+
value: "full",
|
|
300
|
+
label: "Full",
|
|
301
|
+
hint: "User management, departments, dashboard, all features"
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
value: "minimal",
|
|
305
|
+
label: "Minimal",
|
|
306
|
+
hint: "Auth, files, audit logs, notifications (no user/dept management)"
|
|
307
|
+
}
|
|
308
|
+
]
|
|
972
309
|
});
|
|
973
310
|
if (p.isCancel(result)) return result;
|
|
974
|
-
|
|
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
|
-
}
|
|
311
|
+
variant = result;
|
|
980
312
|
}
|
|
981
313
|
let projectName = cliArgs.projectName;
|
|
982
314
|
const needsNamespace = projectType !== "frontend" && (backend === "dotnet" || backend === "spring");
|
|
@@ -1030,7 +362,7 @@ async function runInteractivePrompts(cliArgs) {
|
|
|
1030
362
|
summaryLines.push(`${pc.cyan("Frontend:")} ${getFrontendLabel(frontendFramework)}`);
|
|
1031
363
|
summaryLines.push(`${pc.cyan("UI Library:")} ${getUILabel(ui)}`);
|
|
1032
364
|
}
|
|
1033
|
-
summaryLines.push(`${pc.cyan("
|
|
365
|
+
summaryLines.push(`${pc.cyan("Template:")} ${getVariantLabel(variant)}`);
|
|
1034
366
|
if (needsNamespace && projectName) {
|
|
1035
367
|
summaryLines.push(`${pc.cyan("Namespace:")} ${projectName}`);
|
|
1036
368
|
}
|
|
@@ -1056,7 +388,7 @@ async function runInteractivePrompts(cliArgs) {
|
|
|
1056
388
|
projectName,
|
|
1057
389
|
installDeps,
|
|
1058
390
|
placeInRoot,
|
|
1059
|
-
|
|
391
|
+
variant
|
|
1060
392
|
};
|
|
1061
393
|
}
|
|
1062
394
|
function toPascalCase(str) {
|
|
@@ -1094,6 +426,13 @@ function getUILabel(ui) {
|
|
|
1094
426
|
};
|
|
1095
427
|
return labels[ui];
|
|
1096
428
|
}
|
|
429
|
+
function getVariantLabel(variant) {
|
|
430
|
+
const labels = {
|
|
431
|
+
full: "Full (all features)",
|
|
432
|
+
minimal: "Minimal (no user/dept management)"
|
|
433
|
+
};
|
|
434
|
+
return labels[variant];
|
|
435
|
+
}
|
|
1097
436
|
|
|
1098
437
|
// src/generator.ts
|
|
1099
438
|
import * as p2 from "@clack/prompts";
|
|
@@ -1105,7 +444,18 @@ import fs5 from "fs";
|
|
|
1105
444
|
import degit from "degit";
|
|
1106
445
|
import path2 from "path";
|
|
1107
446
|
import fs2 from "fs";
|
|
1108
|
-
async function
|
|
447
|
+
async function downloadBackendTemplate(repo, backend, architecture, variant, destPath) {
|
|
448
|
+
const folder = `backend/${backend}/${architecture}-architecture/${variant}`;
|
|
449
|
+
const source = `${repo}/${folder}`;
|
|
450
|
+
const emitter = degit(source, {
|
|
451
|
+
cache: false,
|
|
452
|
+
force: true,
|
|
453
|
+
verbose: false
|
|
454
|
+
});
|
|
455
|
+
await emitter.clone(destPath);
|
|
456
|
+
}
|
|
457
|
+
async function downloadFrontendTemplate(repo, framework, ui, variant, destPath) {
|
|
458
|
+
const folder = `frontend/${framework}/${ui}/${variant}`;
|
|
1109
459
|
const source = `${repo}/${folder}`;
|
|
1110
460
|
const emitter = degit(source, {
|
|
1111
461
|
cache: false,
|
|
@@ -1433,8 +783,6 @@ async function generateProject(config) {
|
|
|
1433
783
|
spinner2.start("Downloading templates...");
|
|
1434
784
|
try {
|
|
1435
785
|
if (config.projectType !== "frontend") {
|
|
1436
|
-
const archSuffix = config.architecture === "clean" ? "" : `-${config.architecture}`;
|
|
1437
|
-
const sourceFolder = `backend-${config.backend}${archSuffix}`;
|
|
1438
786
|
let destFolder;
|
|
1439
787
|
if (config.projectType === "fullstack") {
|
|
1440
788
|
destFolder = "backend";
|
|
@@ -1442,11 +790,10 @@ async function generateProject(config) {
|
|
|
1442
790
|
destFolder = config.placeInRoot ? "" : "backend";
|
|
1443
791
|
}
|
|
1444
792
|
const destPath = destFolder ? path5.join(absolutePath, destFolder) : absolutePath;
|
|
1445
|
-
await
|
|
1446
|
-
spinner2.message(`Downloaded
|
|
793
|
+
await downloadBackendTemplate(REPO, config.backend, config.architecture, config.variant, destPath);
|
|
794
|
+
spinner2.message(`Downloaded backend-${config.backend}-${config.architecture}-${config.variant}`);
|
|
1447
795
|
}
|
|
1448
796
|
if (config.projectType !== "backend") {
|
|
1449
|
-
const sourceFolder = `frontend-${config.ui}`;
|
|
1450
797
|
let destFolder;
|
|
1451
798
|
if (config.projectType === "fullstack") {
|
|
1452
799
|
destFolder = "frontend";
|
|
@@ -1454,8 +801,8 @@ async function generateProject(config) {
|
|
|
1454
801
|
destFolder = config.placeInRoot ? "" : "frontend";
|
|
1455
802
|
}
|
|
1456
803
|
const destPath = destFolder ? path5.join(absolutePath, destFolder) : absolutePath;
|
|
1457
|
-
await
|
|
1458
|
-
spinner2.message(`Downloaded
|
|
804
|
+
await downloadFrontendTemplate(REPO, config.frontendFramework, config.ui, config.variant, destPath);
|
|
805
|
+
spinner2.message(`Downloaded frontend-${config.frontendFramework}-${config.ui}-${config.variant}`);
|
|
1459
806
|
}
|
|
1460
807
|
await copyRootFiles(REPO, absolutePath, config);
|
|
1461
808
|
spinner2.message("Downloaded configuration files");
|
|
@@ -1464,16 +811,6 @@ async function generateProject(config) {
|
|
|
1464
811
|
spinner2.stop("Download failed");
|
|
1465
812
|
throw error;
|
|
1466
813
|
}
|
|
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
|
-
}
|
|
1477
814
|
spinner2.start("Updating configuration files...");
|
|
1478
815
|
try {
|
|
1479
816
|
await updateFolderReferences(absolutePath, config);
|
|
@@ -1518,48 +855,6 @@ async function generateProject(config) {
|
|
|
1518
855
|
await createAppSettingsFromExample(absolutePath, config);
|
|
1519
856
|
}
|
|
1520
857
|
}
|
|
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
|
-
}
|
|
1563
858
|
function cleanupFullstackDockerFiles(projectPath) {
|
|
1564
859
|
const filesToDelete = [
|
|
1565
860
|
"backend/Dockerfile",
|
|
@@ -1724,7 +1019,7 @@ async function main() {
|
|
|
1724
1019
|
projectName: cliArgs.projectName,
|
|
1725
1020
|
installDeps: cliArgs.install || false,
|
|
1726
1021
|
placeInRoot: cliArgs.root || false,
|
|
1727
|
-
|
|
1022
|
+
variant: cliArgs.variant || "full"
|
|
1728
1023
|
};
|
|
1729
1024
|
} else {
|
|
1730
1025
|
const result = await runInteractivePrompts(cliArgs);
|
|
@@ -1760,8 +1055,9 @@ ${pc3.bold("Options:")}
|
|
|
1760
1055
|
${pc3.yellow("-u, --ui")} UI library: vuetify, primevue (Vue) | mui, primereact (React)
|
|
1761
1056
|
${pc3.yellow("-n, --name")} Project namespace (Company.Project format, .NET/Spring only)
|
|
1762
1057
|
${pc3.yellow("-r, --root")} Place files in project root ${pc3.gray("(backend/frontend-only)")}
|
|
1763
|
-
${pc3.yellow("--
|
|
1764
|
-
|
|
1058
|
+
${pc3.yellow("-V, --variant")} Template variant: full, minimal ${pc3.gray("(default: full)")}
|
|
1059
|
+
full: All features (user management, departments, dashboard)
|
|
1060
|
+
minimal: Auth, files, audit logs, notifications only
|
|
1765
1061
|
${pc3.yellow("-i, --install")} Install dependencies after creation
|
|
1766
1062
|
${pc3.yellow("-h, --help")} Show this help message
|
|
1767
1063
|
${pc3.yellow("-v, --version")} Show version number
|
|
@@ -1773,8 +1069,8 @@ ${pc3.bold("Examples:")}
|
|
|
1773
1069
|
${pc3.gray("# Create fullstack project with .NET backend")}
|
|
1774
1070
|
npm create apptemplate@latest my-app -b dotnet -n "MyCompany.MyApp" -i
|
|
1775
1071
|
|
|
1776
|
-
${pc3.gray("# Create backend-only project
|
|
1777
|
-
npm create apptemplate@latest my-api -t backend -b spring -n "MyCompany.MyApi"
|
|
1072
|
+
${pc3.gray("# Create minimal backend-only project (no user management)")}
|
|
1073
|
+
npm create apptemplate@latest my-api -t backend -b spring -n "MyCompany.MyApi" -V minimal
|
|
1778
1074
|
|
|
1779
1075
|
${pc3.gray("# Create frontend-only project with PrimeVue")}
|
|
1780
1076
|
npm create apptemplate@latest my-spa -t frontend -u primevue
|