nestcraftx 0.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.
@@ -0,0 +1,579 @@
1
+ const { logInfo } = require("../loggers/logInfo");
2
+ const {
3
+ createDirectory,
4
+ createFile,
5
+ updateFile,
6
+ safeUpdateAppModule,
7
+ } = require("../userInput");
8
+ const { logError } = require("../loggers/logError");
9
+ const { logSuccess } = require("../loggers/logSuccess");
10
+ const {
11
+ generateEntityFileContent,
12
+ generateMapper,
13
+ generateDto,
14
+ generateMiddlewares,
15
+ generateRepository,
16
+ } = require("../utils");
17
+
18
+ async function setupCleanArchitecture(inputs) {
19
+ logInfo("Génération de la structure Clean Architecture");
20
+ // log("inputs entitiesData: ", inputs.entitiesData.entities);
21
+
22
+ const entitiesData = inputs.entitiesData;
23
+ const dbConfig = inputs.dbConfig;
24
+
25
+ const srcPath = "src";
26
+ const baseFolders = [
27
+ "application/use-cases",
28
+ "application/dtos",
29
+ "application/interfaces",
30
+ "domain/entities",
31
+ "domain/enums",
32
+ "domain/mappers",
33
+ "infrastructure/repositories",
34
+ "infrastructure/services",
35
+ "infrastructure/adapters",
36
+ "presentation/controllers",
37
+ ];
38
+
39
+ try {
40
+ // modifier app module pour exporter configService globalement
41
+ const appModuleTsPath = "src/app.module.ts";
42
+ // let mainTs = fs.readFileSync(mainTsPath, "utf8");
43
+
44
+ /* await createDirectory("src");
45
+ await createFile({
46
+ path: appModuleTsPath,
47
+ contente: `import { Module } from '@nestjs/common';
48
+ @Module({
49
+ imports: [],
50
+ controllers: [],
51
+ providers: [],
52
+ })
53
+ export class AppModule {}`,
54
+ }); */
55
+
56
+ // ajouter l'import configModule
57
+ await updateFile({
58
+ path: "src/app.module.ts",
59
+ pattern: "import { Module } from '@nestjs/common';",
60
+ replacement: `import { Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';`,
61
+ });
62
+
63
+ // configurer configservice
64
+ await updateFile({
65
+ path: "src/app.module.ts",
66
+ pattern: "imports: [",
67
+ replacement: `imports: [
68
+ ConfigModule.forRoot({
69
+ isGlobal: true, // Rendre ConfigModule accessible globalement
70
+ envFilePath: '.env', // Charger les variables d'environnement
71
+ }),`,
72
+ });
73
+
74
+ for (const entity of entitiesData.entities) {
75
+ const entityNameCapitalized = capitalize(entity.name);
76
+ const entityNameLower = decapitalize(entity.name);
77
+
78
+ const entityPath = `${srcPath}/${entityNameLower}`;
79
+
80
+ for (const folder of baseFolders) {
81
+ await createDirectory(`${entityPath}/${folder}`);
82
+ }
83
+
84
+ // 📌 1. Entité
85
+ const entityContent = await generateEntityFileContent(entity);
86
+ await createFile({
87
+ path: `${entityPath}/domain/entities/${entityNameLower}.entity.ts`,
88
+ contente: entityContent,
89
+ });
90
+
91
+ // 📌 2. Interface Repository
92
+ await createFile({
93
+ path: `${entityPath}/application/interfaces/${entityNameLower}.repository.interface.ts`,
94
+ contente: `import { Create${entityNameCapitalized}Dto, Update${entityNameCapitalized}Dto } from 'src/${entityNameLower}/application/dtos/${entityNameLower}.dto';
95
+ import { ${entityNameCapitalized}Entity } from 'src/${entityNameLower}/domain/entities/${entityNameLower}.entity';
96
+
97
+ export interface I${entityNameCapitalized}Repository {
98
+ create(data: Create${entityNameCapitalized}Dto): Promise<${entityNameCapitalized}Entity>;
99
+ findById(id: string): Promise<${entityNameCapitalized}Entity | null>;
100
+ findAll(): Promise<${entityNameCapitalized}Entity[]>;
101
+ update(id: string, data: Update${entityNameCapitalized}Dto): Promise<${entityNameCapitalized}Entity | null>;
102
+ delete(id: string): Promise<void>;
103
+ }`,
104
+ });
105
+
106
+ // 📌 3. Repository Implémentation
107
+ await generateRepository(entity.name, dbConfig.orm);
108
+ /* await createFile({
109
+ path: `${entityPath}/infrastructure/repositories/${entityNameLower}.repository.ts`,
110
+ contente: repositoryContent,
111
+ }); */
112
+
113
+ // 📌 4. Use Cases
114
+ const useCases = ["Create", "GetById", "GetAll", "Update", "Delete"];
115
+ useCases.forEach(async (useCase) => {
116
+ let content = "";
117
+
118
+ switch (useCase) {
119
+ case "Create":
120
+ content = `/**
121
+ * Use Case pour créer un ${capitalize(entity.name)}.
122
+ */
123
+ import { Inject } from '@nestjs/common';
124
+ import { Create${capitalize(entity.name)}Dto } from 'src/${
125
+ entity.name
126
+ }/application/dtos/${entity.name}.dto';
127
+ import { I${capitalize(entity.name)}Repository } from 'src/${
128
+ entity.name
129
+ }/application/interfaces/${entity.name}.repository.interface';
130
+
131
+ export class ${useCase}${capitalize(entity.name)}UseCase {
132
+ constructor(
133
+ @Inject("I${capitalize(entity.name)}Repository")
134
+ private readonly ${decapitalize(entity.name)}Repository: I${capitalize(
135
+ entity.name
136
+ )}Repository,
137
+ ) {}
138
+
139
+ execute(data: Create${capitalize(entity.name)}Dto) {
140
+ return this.${decapitalize(entity.name)}Repository.create(data);
141
+ }
142
+ }`;
143
+ break;
144
+
145
+ case "GetById":
146
+ content = `/**
147
+ * Use Case pour récupérer un ${capitalize(entity.name)} par son ID.
148
+ */
149
+ import { Inject } from '@nestjs/common';
150
+ import { I${capitalize(entity.name)}Repository } from 'src/${
151
+ entity.name
152
+ }/application/interfaces/${entity.name}.repository.interface';
153
+
154
+ export class ${useCase}${capitalize(entity.name)}UseCase {
155
+ constructor(
156
+ @Inject("I${capitalize(entity.name)}Repository")
157
+ private readonly ${decapitalize(entity.name)}Repository: I${capitalize(
158
+ entity.name
159
+ )}Repository,
160
+ ) {}
161
+
162
+ execute(id: string) {
163
+ return this.${decapitalize(entity.name)}Repository.findById(id);
164
+ }
165
+ }`;
166
+ break;
167
+
168
+ case "GetAll":
169
+ content = `/**
170
+ * Use Case pour récupérer tous les ${capitalize(entity.name)}s.
171
+ */
172
+ import { Inject } from '@nestjs/common';
173
+ import { I${capitalize(entity.name)}Repository } from 'src/${
174
+ entity.name
175
+ }/application/interfaces/${entity.name}.repository.interface';
176
+
177
+ export class ${useCase}${capitalize(entity.name)}UseCase {
178
+ constructor(
179
+ @Inject("I${capitalize(entity.name)}Repository")
180
+ private readonly ${decapitalize(entity.name)}Repository: I${capitalize(
181
+ entity.name
182
+ )}Repository,
183
+ ) {}
184
+
185
+ execute() {
186
+ return this.${decapitalize(entity.name)}Repository.findAll();
187
+ }
188
+ }`;
189
+ break;
190
+
191
+ case "Update":
192
+ content = `/**
193
+ * Use Case pour mettre à jour un ${capitalize(entity.name)} existant.
194
+ */
195
+ import { Inject } from '@nestjs/common';
196
+ import { Update${capitalize(entity.name)}Dto } from 'src/${
197
+ entity.name
198
+ }/application/dtos/${entity.name}.dto';
199
+ import { I${capitalize(entity.name)}Repository } from 'src/${
200
+ entity.name
201
+ }/application/interfaces/${entity.name}.repository.interface';
202
+
203
+ export class ${useCase}${capitalize(entity.name)}UseCase {
204
+ constructor(
205
+ @Inject("I${capitalize(entity.name)}Repository")
206
+ private readonly ${decapitalize(entity.name)}Repository: I${capitalize(
207
+ entity.name
208
+ )}Repository,
209
+ ) {}
210
+
211
+ execute(id: string, data: Update${capitalize(entity.name)}Dto) {
212
+ return this.${decapitalize(entity.name)}Repository.update(id, data);
213
+ }
214
+ }`;
215
+ break;
216
+
217
+ case "Delete":
218
+ content = `/**
219
+ * Use Case pour supprimer un ${capitalize(entity.name)}.
220
+ */
221
+ import { Inject } from '@nestjs/common';
222
+ import { I${capitalize(entity.name)}Repository } from 'src/${
223
+ entity.name
224
+ }/application/interfaces/${entity.name}.repository.interface';
225
+
226
+ export class ${useCase}${capitalize(entity.name)}UseCase {
227
+ constructor(
228
+ @Inject("I${capitalize(entity.name)}Repository")
229
+ private readonly ${decapitalize(entity.name)}Repository: I${capitalize(
230
+ entity.name
231
+ )}Repository,
232
+ ) {}
233
+
234
+ execute(id: string) {
235
+ return this.${decapitalize(entity.name)}Repository.delete(id);
236
+ }
237
+ }`;
238
+ break;
239
+ }
240
+
241
+ await createFile({
242
+ path: `${entityPath}/application/use-cases/${decapitalize(useCase)}-${
243
+ entity.name
244
+ }.use-case.ts`,
245
+ contente: content.trim(),
246
+ });
247
+ });
248
+
249
+ // 📌 5. DTOs
250
+ const DtoFileContent = await generateDto(entity);
251
+ await createFile({
252
+ path: `${entityPath}/application/dtos/${entity.name}.dto.ts`,
253
+ contente: DtoFileContent,
254
+ });
255
+
256
+ // 📌 6. Enums
257
+ await createFile({
258
+ path: `${entityPath}/domain/enums/${entityNameLower}.enum.ts`,
259
+ contente: `// Enumération des différents états possibles pour ${entityNameCapitalized}
260
+ export enum ${entityNameCapitalized}Enum {
261
+ // Décommentez et ajustez les valeurs de l'énumération selon les besoins de votre entité.
262
+ // Exemple :
263
+ // ACTIVE = 'ACTIVE', // Représente l'état actif de l'entité
264
+ // INACTIVE = 'INACTIVE', // Représente l'état inactif de l'entité
265
+ // Vous pouvez ajouter d'autres états si nécessaire, comme 'PENDING', 'ARCHIVED', etc.
266
+ }
267
+ `,
268
+ });
269
+
270
+ if (entity.name.toLowerCase() === "user") {
271
+ await createFile({
272
+ path: `${entityPath}/domain/enums/role.enum.ts`,
273
+ contente: `// Enumération des rôles utilisateurs
274
+ export enum Role {
275
+ USER = 'USER',
276
+ ADMIN = 'ADMIN',
277
+ SUPER_ADMIN = 'SUPER_ADMIN',
278
+ }
279
+ `,
280
+ });
281
+ }
282
+
283
+ // 📌 7. Mapper
284
+ const mapperFileContent = await generateMapper(entity);
285
+ await createFile({
286
+ path: `${entityPath}/domain/mappers/${entity.name}.mapper.ts`,
287
+ contente: mapperFileContent,
288
+ });
289
+
290
+ // 📌 8. Service
291
+ await createFile({
292
+ path: `${entityPath}/infrastructure/services/${entityNameLower}.service.ts`,
293
+ contente: `
294
+ // Le service est responsable de la logique métier de l'application. Il agit comme un orchestrateur entre
295
+ // différents composants tels que les repositories, les use cases et les adaptateurs.
296
+
297
+ import { Inject } from '@nestjs/common';
298
+ import { I${entityNameCapitalized}Repository } from 'src/${entityNameLower}/application/interfaces/${entityNameLower}.repository.interface';
299
+
300
+ export class ${entityNameCapitalized}Service {
301
+ constructor(
302
+ @Inject("I${entityNameCapitalized}Repository")
303
+ private readonly repository: I${entityNameCapitalized}Repository,
304
+ ) {}
305
+
306
+ // La méthode 'process' prend en charge la logique pour traiter les données.
307
+ async process(data: any) {
308
+ if (!data || !data.id) {
309
+ throw new Error('Données invalides, ID requis');
310
+ }
311
+
312
+ const entityFromDb = await this.repository.findById(data.id);
313
+
314
+ if (!entityFromDb) {
315
+ throw new Error('Entité non trouvée avec cet ID');
316
+ }
317
+
318
+ const processedData = {
319
+ ...entityFromDb,
320
+ updatedAt: new Date(),
321
+ processedBy: 'System',
322
+ };
323
+
324
+ return processedData;
325
+ }
326
+
327
+ // Vous pouvez ajouter d'autres méthodes métier ici si nécessaire.
328
+ async create(data: any) {
329
+ // Logique pour créer une nouvelle entité
330
+ }
331
+
332
+ async update(id: string, data: any) {
333
+ // Logique pour mettre à jour une entité existante
334
+ }
335
+
336
+ async delete(id: string) {
337
+ // Logique pour supprimer une entité
338
+ }
339
+ }
340
+ `,
341
+ });
342
+
343
+ // 📌 9. Adapter
344
+ await createFile({
345
+ path: `${entityPath}/infrastructure/adapters/${entityNameLower}.adapter.ts`,
346
+ contente: `
347
+ // L'adaptateur permet de transformer ou d'adapter les données d'un format source vers un format cible.
348
+ // Cela est particulièrement utile lorsque nous devons interagir avec des API externes ou des services ayant des structures de données différentes.
349
+
350
+ export class ${entityNameCapitalized}Adapter {
351
+ // La méthode 'adapt' prend des données brutes d'un format spécifique et les transforme
352
+ // en un format qui est attendu par le système de notre domaine.
353
+ adapt(data: any) {
354
+ // Exemple d'adaptation des données - ceci est un exemple générique.
355
+ // Nous transformons les données pour que le format interne du système soit respecté.
356
+
357
+ const adaptedData = {
358
+ // Assurez-vous que vous mappez les propriétés nécessaires et les transformez.
359
+ id: data.id, // Mapping de l'ID de la donnée source à notre format interne
360
+ name: data.fullName || data.name, // Exemple de transformation de champ
361
+ description: data.details || data.description, // Gestion des données optionnelles
362
+ createdAt: new Date(data.createdAt), // Transformation de la date
363
+ updatedAt: new Date(data.updatedAt), // Idem pour la date de mise à jour
364
+ // Vous pouvez adapter d'autres champs en fonction des exigences spécifiques
365
+ };
366
+
367
+ // Retournez les données adaptées dans un format compréhensible pour le système
368
+ return adaptedData;
369
+ }
370
+ }
371
+ `,
372
+ });
373
+
374
+ // 📌 10. Controller
375
+ await createFile({
376
+ path: `${entityPath}/presentation/controllers/${entityNameLower}.controller.ts`,
377
+ contente: `
378
+ /**
379
+ * ${entityNameCapitalized}Controller gère les endpoints de l'API pour l'entité ${entityNameCapitalized}.
380
+ * Il utilise les cas d'utilisation (Use Cases) pour orchestrer les différentes actions métiers liées à l'entité.
381
+ * Ce contrôleur est responsable des actions HTTP telles que la création, la mise à jour, la récupération, et la suppression de ${entityNameCapitalized}.
382
+ */
383
+
384
+ import { Controller, Get, Post, Body, Param, Put, Delete, Injectable } from "@nestjs/common";
385
+ import { ApiTags, ApiOperation } from '@nestjs/swagger';
386
+ // Importation des cas d'utilisation (Use Cases) spécifiques à ${entityNameCapitalized}
387
+ import { Create${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/create-${entityNameLower}.use-case";
388
+ import { Update${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/update-${entityNameLower}.use-case";
389
+ import { GetById${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/getById-${entityNameLower}.use-case";
390
+ import { GetAll${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/getAll-${entityNameLower}.use-case";
391
+ import { Delete${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/delete-${entityNameLower}.use-case";
392
+ // Importation des DTOs pour la validation et la transformation des données entrantes
393
+ import { Create${entityNameCapitalized}Dto, Update${entityNameCapitalized}Dto } from 'src/${entityNameLower}/application/dtos/${entityNameLower}.dto';
394
+
395
+ /**
396
+ * Le contrôleur est annoté avec @ApiTags pour la documentation Swagger.
397
+ * Il regroupe les opérations HTTP relatives à l'entité ${entityNameCapitalized}.
398
+ */
399
+ @Injectable()
400
+ @ApiTags('${entityNameCapitalized}')
401
+ @Controller('${entityNameLower}')
402
+ export class ${entityNameCapitalized}Controller {
403
+ constructor(
404
+ private readonly createUseCase: Create${entityNameCapitalized}UseCase,
405
+ private readonly updateUseCase: Update${entityNameCapitalized}UseCase,
406
+ private readonly getByIdUseCase: GetById${entityNameCapitalized}UseCase,
407
+ private readonly getAllUseCase: GetAll${entityNameCapitalized}UseCase,
408
+ private readonly deleteUseCase: Delete${entityNameCapitalized}UseCase,
409
+ ) {}
410
+
411
+ // 📌 Créer un ${entityNameLower}
412
+ @Post()
413
+ @ApiOperation({ summary: 'Create a new ${entityNameLower}' })
414
+ async create${entityNameCapitalized}(
415
+ @Body() create${entityNameCapitalized}Dto: Create${entityNameCapitalized}Dto,
416
+ ) {
417
+ return this.createUseCase.execute(create${entityNameCapitalized}Dto);
418
+ }
419
+
420
+ // 📌 Mettre à jour un ${entityNameLower}
421
+ @Put(':id')
422
+ @ApiOperation({ summary: 'Update a ${entityNameLower}' })
423
+ async update${entityNameCapitalized}(
424
+ @Param('id') id: string,
425
+ @Body() update${entityNameCapitalized}Dto: Update${entityNameCapitalized}Dto,
426
+ ) {
427
+ return this.updateUseCase.execute(id, update${entityNameCapitalized}Dto);
428
+ }
429
+
430
+ // 📌 Récupérer un ${entityNameLower} par ID
431
+ @Get(':id')
432
+ @ApiOperation({ summary: 'Get a ${entityNameLower} by ID' })
433
+ async getById${entityNameCapitalized}(@Param('id') id: string) {
434
+ return this.getByIdUseCase.execute(id);
435
+ }
436
+
437
+ // 📌 Récupérer tous les ${entityNameLower}s
438
+ @Get()
439
+ @ApiOperation({ summary: 'Get all ${entityNameLower}s' })
440
+ async getAll${entityNameCapitalized}() {
441
+ return this.getAllUseCase.execute();
442
+ }
443
+
444
+ // 📌 Supprimer un ${entityNameLower}
445
+ @Delete(':id')
446
+ @ApiOperation({ summary: 'Delete a ${entityNameLower} by ID' })
447
+ async delete${entityNameCapitalized}(@Param('id') id: string) {
448
+ return this.deleteUseCase.execute(id);
449
+ }
450
+ }
451
+ `,
452
+ });
453
+
454
+ // 📌 11. Module
455
+ let Import = "";
456
+ let prismaProvider = "";
457
+ let importTormM = `imports: [
458
+ TypeOrmModule.forFeature([${entityNameCapitalized}]), // Injection de l'entité
459
+ ],`;
460
+
461
+ if (dbConfig.orm === "prisma") {
462
+ prismaImport = `import { PrismaService } from 'src/prisma/prisma.service';`;
463
+ prismaProvider = ` PrismaService,`;
464
+ } else if (dbConfig.orm === "typeorm") {
465
+ Import = `import { ${entityNameCapitalized} } from 'src/entities/${entityNameCapitalized}.entity';`;
466
+ }
467
+
468
+ await createFile({
469
+ path: `${entityPath}/${entityNameLower}.module.ts`,
470
+ contente: `
471
+ /**
472
+ * ${entityNameCapitalized}Module est le module principal qui gère l'entité ${entityNameCapitalized}.
473
+ * Il regroupe tous les composants nécessaires pour traiter cette entité :
474
+ * - Contrôleur
475
+ * - Répository
476
+ * - Use Cases
477
+ * - Mapper
478
+ */
479
+ import { Module } from '@nestjs/common';
480
+ import { TypeOrmModule } from '@nestjs/typeorm';
481
+ import { ${entityNameCapitalized}Controller } from '${entityPath}/presentation/controllers/${entityNameLower}.controller';
482
+ import { ${entityNameCapitalized}Repository } from '${entityPath}/infrastructure/repositories/${entityNameLower}.repository';
483
+ import { Create${entityNameCapitalized}UseCase } from '${entityPath}/application/use-cases/create-${entityNameLower}.use-case';
484
+ import { Update${entityNameCapitalized}UseCase } from '${entityPath}/application/use-cases/update-${entityNameLower}.use-case';
485
+ import { GetById${entityNameCapitalized}UseCase } from '${entityPath}/application/use-cases/getById-${entityNameLower}.use-case';
486
+ import { GetAll${entityNameCapitalized}UseCase } from '${entityPath}/application/use-cases/getAll-${entityNameLower}.use-case';
487
+ import { Delete${entityNameCapitalized}UseCase } from '${entityPath}/application/use-cases/delete-${entityNameLower}.use-case';
488
+ import { ${entityNameCapitalized}Mapper } from '${entityPath}/domain/mappers/${entityNameLower}.mapper';
489
+ ${Import}
490
+
491
+ @Module({
492
+
493
+ ${importTormM}
494
+
495
+ /**
496
+ * Déclare le contrôleur qui gère les requêtes HTTP relatives à ${entityNameCapitalized}.
497
+ * Ce contrôleur contient les actions d'API pour manipuler l'entité ${entityNameCapitalized}.
498
+ */
499
+ controllers: [${entityNameCapitalized}Controller],
500
+
501
+ /**
502
+ * Liste des providers nécessaires à la gestion de ${entityNameCapitalized}.
503
+ * Cela inclut :
504
+ * - Repository : Fournisseur pour accéder aux données de ${entityNameCapitalized}.
505
+ * - Use Cases : Logique métier pour la gestion de ${entityNameCapitalized}.
506
+ * - Mapper : Permet la transformation entre les DTOs et les entités.
507
+ */
508
+ providers: [
509
+ ${prismaProvider}
510
+
511
+ // Repository : Permet d'interagir avec la base de données
512
+ {
513
+ provide: 'I${entityNameCapitalized}Repository', // Interface du repository
514
+ useClass: ${entityNameCapitalized}Repository, // Classe qui implémente l'interface
515
+ },
516
+ ${entityNameCapitalized}Repository, // Fournisseur pour l'accès aux données
517
+
518
+ // Use Cases : Logique métier pour la gestion de ${entityNameCapitalized}
519
+ Create${entityNameCapitalized}UseCase, // Use Case pour créer un ${entityNameLower}
520
+ Update${entityNameCapitalized}UseCase, // Use Case pour mettre à jour un ${entityNameLower}
521
+ GetById${entityNameCapitalized}UseCase, // Use Case pour récupérer un ${entityNameLower} par son ID
522
+ GetAll${entityNameCapitalized}UseCase, // Use Case pour récupérer tous les ${entityNameLower}s
523
+ Delete${entityNameCapitalized}UseCase, // Use Case pour supprimer un ${entityNameLower}
524
+
525
+ // Mapper : Convertit entre les entités et les DTOs
526
+ ${entityNameCapitalized}Mapper, // Mapper pour la transformation des données
527
+ ],
528
+ })
529
+ /**
530
+ * Le module ${entityNameCapitalized} est une unité logique regroupant toutes les dépendances nécessaires
531
+ * pour le bon fonctionnement de l'entité ${entityNameCapitalized}.
532
+ * Il gère l'injection des services, les actions métier, ainsi que la transformation des données.
533
+ */
534
+ export class ${entityNameCapitalized}Module {}
535
+ `.trim(),
536
+ });
537
+
538
+ await safeUpdateAppModule(entityNameLower);
539
+ }
540
+ await generateMiddlewares();
541
+
542
+ // modification de AppModule
543
+ const appModulePath = "src/app.module.ts";
544
+
545
+ // Étape 1 : Ajouter les imports nécessaires
546
+ await updateFile({
547
+ path: appModulePath,
548
+ pattern: `import { Module } from '@nestjs/common';`,
549
+ replacement: `import { Module } from '@nestjs/common';
550
+ import { ResponseInterceptor } from './common/interceptors/response.interceptor';
551
+ import { APP_INTERCEPTOR } from '@nestjs/core';`,
552
+ });
553
+
554
+ // Étape 2 : Ajouter le provider APP_INTERCEPTOR dans providers[]
555
+ await updateFile({
556
+ path: appModulePath,
557
+ pattern: `providers: \\[`,
558
+ replacement: `providers: [
559
+ {
560
+ provide: APP_INTERCEPTOR,
561
+ useClass: ResponseInterceptor,
562
+ },`,
563
+ });
564
+
565
+ logSuccess("structure Clean Architecture générée avec succès !");
566
+ } catch (error) {
567
+ logError(`process currency have error: ${error}`);
568
+ }
569
+ }
570
+
571
+ function capitalize(str) {
572
+ return str.charAt(0).toUpperCase() + str.slice(1);
573
+ }
574
+
575
+ function decapitalize(str) {
576
+ return str.charAt(0).toLowerCase() + str.slice(1);
577
+ }
578
+
579
+ module.exports = { setupCleanArchitecture };
@@ -0,0 +1,5 @@
1
+ function logError(message) {
2
+ console.error(`\n \x1b[31m[ERROR] ${message}\x1b[0m`);
3
+ }
4
+
5
+ module.exports = { logError };
@@ -0,0 +1,4 @@
1
+ function logInfo(message) {
2
+ console.log(`\n \x1b[34m[INFO] ${message}\x1b[0m`);
3
+ }
4
+ module.exports = { logInfo };
@@ -0,0 +1,4 @@
1
+ function logSuccess(message) {
2
+ console.log(`\n \x1b[32m[SUCCESS] ${message}\x1b[0m`);
3
+ }
4
+ module.exports = { logSuccess };