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