nestcraftx 0.1.7 → 0.1.9
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/package.json +1 -1
- package/unutils.txt +397 -216
- package/utils/configs/configureDocker.js +1 -1
- package/utils/configs/setupCleanArchitecture.js +181 -119
- package/utils/setups/orms/typeOrmSetup.js +1 -1
- package/utils/setups/projectSetup.js +1 -1
- package/utils/setups/setupAuth.js +43 -31
- package/utils/setups/setupDatabase.js +2 -2
- package/utils/setups/setupMongoose.js +45 -0
- package/utils/setups/setupPrisma.js +113 -21
- package/utils/userInput.js +128 -225
- package/utils/utils.js +571 -165
package/package.json
CHANGED
package/unutils.txt
CHANGED
|
@@ -1,250 +1,431 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
/*ancien input*/
|
|
2
|
+
import * as readline from "readline-sync";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
|
|
5
|
+
export async function getUserInputs2() {
|
|
6
|
+
console.log("\n🔹🔹🔹 Configuration du projet 🔹🔹🔹\n");
|
|
7
|
+
|
|
8
|
+
const dataBases = [
|
|
9
|
+
{
|
|
10
|
+
name: "postgresql",
|
|
11
|
+
label: "PostgreSQL",
|
|
12
|
+
ormOptions: ["prisma", "typeorm"], // Choix des ORM supportés
|
|
13
|
+
required: [
|
|
14
|
+
{
|
|
15
|
+
title: "Nom d’utilisateur PostgreSQL",
|
|
16
|
+
envVar: "POSTGRES_USER",
|
|
17
|
+
defaultValue: "postgres",
|
|
18
|
+
hideEchoBack: false,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
title: "Mot de passe PostgreSQL",
|
|
22
|
+
envVar: "POSTGRES_PASSWORD",
|
|
23
|
+
defaultValue: null,
|
|
24
|
+
hideEchoBack: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: "Nom de la base de données",
|
|
28
|
+
envVar: "POSTGRES_DB",
|
|
29
|
+
defaultValue: "mydb",
|
|
30
|
+
hideEchoBack: false,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
title: "Hôte PostgreSQL",
|
|
34
|
+
envVar: "POSTGRES_HOST",
|
|
35
|
+
defaultValue: "localhost",
|
|
36
|
+
hideEchoBack: false,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
title: "Port PostgreSQL",
|
|
40
|
+
envVar: "POSTGRES_PORT",
|
|
41
|
+
defaultValue: "5432",
|
|
42
|
+
hideEchoBack: false,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
/* {
|
|
47
|
+
name: "mysql",
|
|
48
|
+
label: "MySQL / MariaDB",
|
|
49
|
+
ormOptions: ["prisma", "typeorm"], // Choix des ORM supportés
|
|
50
|
+
required: [
|
|
51
|
+
{
|
|
52
|
+
title: "Nom d’utilisateur MySQL",
|
|
53
|
+
envVar: "MYSQL_USER",
|
|
54
|
+
defaultValue: "root",
|
|
55
|
+
hideEchoBack: false,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
title: "Mot de passe MySQL",
|
|
59
|
+
envVar: "MYSQL_PASSWORD",
|
|
60
|
+
defaultValue: null,
|
|
61
|
+
hideEchoBack: true,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
title: "Nom de la base de données",
|
|
65
|
+
envVar: "MYSQL_DB",
|
|
66
|
+
defaultValue: "mydb",
|
|
67
|
+
hideEchoBack: false,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
title: "Hôte MySQL",
|
|
71
|
+
envVar: "MYSQL_HOST",
|
|
72
|
+
defaultValue: "localhost",
|
|
73
|
+
hideEchoBack: false,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
title: "Port MySQL",
|
|
77
|
+
envVar: "MYSQL_PORT",
|
|
78
|
+
defaultValue: "3306",
|
|
79
|
+
hideEchoBack: false,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "mongodb",
|
|
85
|
+
label: "MongoDB",
|
|
86
|
+
ormOptions: ["mongoose"], // Choix d'ORM pour MongoDB
|
|
87
|
+
required: [
|
|
88
|
+
{
|
|
89
|
+
title: "URL de connexion MongoDB",
|
|
90
|
+
envVar: "MONGO_URI",
|
|
91
|
+
defaultValue: "mongodb://localhost:27017",
|
|
92
|
+
hideEchoBack: false,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
title: "Nom de la base de données",
|
|
96
|
+
envVar: "MONGO_DB",
|
|
97
|
+
defaultValue: "mydb",
|
|
98
|
+
hideEchoBack: false,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "sqlite",
|
|
104
|
+
label: "SQLite",
|
|
105
|
+
ormOptions: ["prisma", "sequelize"], // Choix des ORM supportés
|
|
106
|
+
required: [
|
|
107
|
+
{
|
|
108
|
+
title: "Chemin du fichier SQLite",
|
|
109
|
+
envVar: "SQLITE_PATH",
|
|
110
|
+
defaultValue: "./data/sqlite.db",
|
|
111
|
+
hideEchoBack: false,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "firebase",
|
|
117
|
+
label: "Firebase Firestore",
|
|
118
|
+
ormOptions: ["firebase"], // Firebase n'a pas d'ORM traditionnel
|
|
119
|
+
required: [
|
|
120
|
+
{
|
|
121
|
+
title: "Chemin vers le fichier de configuration Firebase (JSON)",
|
|
122
|
+
envVar: "FIREBASE_CONFIG_PATH",
|
|
123
|
+
defaultValue: "./firebase-config.json",
|
|
124
|
+
hideEchoBack: false,
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "redis",
|
|
130
|
+
label: "Redis",
|
|
131
|
+
ormOptions: ["redis"], // Redis n'a pas d'ORM traditionnel
|
|
132
|
+
required: [
|
|
133
|
+
{
|
|
134
|
+
title: "URL de connexion Redis",
|
|
135
|
+
envVar: "REDIS_URL",
|
|
136
|
+
defaultValue: "redis://localhost:6379",
|
|
137
|
+
hideEchoBack: false,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
}, */
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
const projectName = readline.question("Nom du projet: ");
|
|
144
|
+
// const databaseName = readline.question("Nom de la base de données: ");
|
|
145
|
+
|
|
146
|
+
let usedDB = readline.question(
|
|
147
|
+
`Quelle base de donnée voulez-vous utiliser ? (${dataBases
|
|
148
|
+
.map((db) => db.name)
|
|
149
|
+
.join(", ")}) : `,
|
|
150
|
+
{ defaultInput: "postgresql" }
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
let selectedDB = dataBases.find(
|
|
154
|
+
(db) => db.name.toLowerCase() === usedDB.toLowerCase()
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
while (!selectedDB) {
|
|
158
|
+
console.log("❌ Base de données non reconnue.");
|
|
159
|
+
|
|
160
|
+
usedDB = readline.question(
|
|
161
|
+
`Quelle base de donnée voulez-vous utiliser ? (${dataBases
|
|
162
|
+
.map((db) => db.name)
|
|
163
|
+
.join(", ")}) : `
|
|
27
164
|
);
|
|
28
|
-
}
|
|
29
165
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// exemple:
|
|
34
|
-
// name: dto.name,
|
|
35
|
-
// description: dto.description,
|
|
36
|
-
// ...
|
|
37
|
-
};
|
|
166
|
+
selectedDB = dataBases.find(
|
|
167
|
+
(db) => db.name.toLowerCase() === usedDB.toLowerCase()
|
|
168
|
+
);
|
|
38
169
|
}
|
|
39
170
|
|
|
40
|
-
|
|
41
|
-
const data: any = {};
|
|
42
|
-
// Logique conditionnelle pour ne mettre que les champs fournis
|
|
43
|
-
// exemple:
|
|
44
|
-
// if (dto.name) data.name = dto.name;
|
|
45
|
-
// if (dto.description) data.description = dto.description;
|
|
46
|
-
return data;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
`
|
|
50
|
-
|
|
51
|
-
// 📌 5. DTOs
|
|
52
|
-
const DtoFileContent = generateDto(entity);
|
|
53
|
-
await createFile({
|
|
54
|
-
path: `${entityPath}/application/dtos/${entity}.dto.ts`,
|
|
55
|
-
contente: `
|
|
56
|
-
// Importer les décorateurs nécessaires pour la validation et la documentation (Swagger)
|
|
57
|
-
// import { ApiProperty } from '@nestjs/swagger';
|
|
58
|
-
// import { IsString, IsOptional, IsInt, IsDate } from 'class-validator'; // Dépendances pour la validation
|
|
59
|
-
|
|
60
|
-
// Classe DTO pour la création de l'entité ${capitalize(entity)}
|
|
61
|
-
export class Create${capitalize(entity)}Dto {
|
|
62
|
-
// Exemple de propriété pour une chaîne de caractères
|
|
63
|
-
/* @ApiProperty({
|
|
64
|
-
description: 'Le nom complet de l\'utilisateur',
|
|
65
|
-
example: 'John Doe', // Exemple d'un nom complet
|
|
66
|
-
})
|
|
67
|
-
@IsString()
|
|
68
|
-
name: string; // Le nom de l'utilisateur, représenté par une chaîne de caractères */
|
|
69
|
-
|
|
70
|
-
// Exemple de propriété pour un nombre entier
|
|
71
|
-
/* @ApiProperty({
|
|
72
|
-
description: 'L\'âge de l\'utilisateur',
|
|
73
|
-
example: 25, // Exemple d'âge
|
|
74
|
-
})
|
|
75
|
-
@IsInt()
|
|
76
|
-
@IsOptional() // L'âge est optionnel lors de la création
|
|
77
|
-
age?: number; // Âge de l'utilisateur, un nombre entier */
|
|
78
|
-
|
|
79
|
-
// Exemple de propriété pour une date
|
|
80
|
-
/* @ApiProperty({
|
|
81
|
-
description: 'Date de naissance de l\'utilisateur',
|
|
82
|
-
example: '1996-05-20', // Exemple de date au format ISO
|
|
83
|
-
})
|
|
84
|
-
@IsDate()
|
|
85
|
-
birthdate: Date; // Date de naissance de l'utilisateur */
|
|
86
|
-
}
|
|
171
|
+
const dbConfig = {};
|
|
87
172
|
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
@IsOptional()
|
|
106
|
-
age?: number; // Âge mis à jour, nombre entier optionnel */
|
|
173
|
+
// Configuration de la base de données (champ utilisateur)
|
|
174
|
+
selectedDB.required.forEach((field) => {
|
|
175
|
+
const answer = readline.question(
|
|
176
|
+
`${field.title} (par défaut: ${field.defaultValue}) : `,
|
|
177
|
+
{ hideEchoBack: field.hideEchoBack }
|
|
178
|
+
);
|
|
179
|
+
dbConfig[field.envVar] = answer || field.defaultValue;
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Ajout du choix de l'ORM dans la configuration
|
|
183
|
+
if (selectedDB.ormOptions && selectedDB.ormOptions.length > 0) {
|
|
184
|
+
const ormChoice = readline.question(
|
|
185
|
+
`Choisissez un ORM pour ${selectedDB.label} (${selectedDB.ormOptions.join(
|
|
186
|
+
", "
|
|
187
|
+
)}): `
|
|
188
|
+
);
|
|
189
|
+
dbConfig.orm = ormChoice || selectedDB.ormOptions[0]; // Par défaut, choisir le premier ORM
|
|
107
190
|
}
|
|
108
|
-
`,
|
|
109
|
-
});
|
|
110
191
|
|
|
192
|
+
const useYarn = readline.keyInYNStrict("Utiliser Yarn ?");
|
|
193
|
+
const useDocker = readline.keyInYNStrict(
|
|
194
|
+
"Voulez-vous générer un fichier Docker?"
|
|
195
|
+
);
|
|
196
|
+
const useAuth = readline.keyInYNStrict(
|
|
197
|
+
"Voulez-vous ajouter une authentification JWT?"
|
|
198
|
+
);
|
|
199
|
+
const useSwagger = readline.keyInYNStrict("Voulez-vous installer Swagger?");
|
|
200
|
+
const packageManager = useYarn ? "yarn" : "npm";
|
|
201
|
+
|
|
202
|
+
// 🧱 Saisie des entités et champs
|
|
203
|
+
const entitiesData = {
|
|
204
|
+
entities: [],
|
|
205
|
+
relations: [],
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
if (useAuth) {
|
|
209
|
+
console.log("🔐 Auth activé : ajout automatique de l'entité 'User'");
|
|
210
|
+
|
|
211
|
+
entitiesData.entities.push({
|
|
212
|
+
name: "user",
|
|
213
|
+
fields: [
|
|
214
|
+
{ name: "email", type: "string" },
|
|
215
|
+
{ name: "password", type: "string" },
|
|
216
|
+
{ name: "isActive", type: "boolean" },
|
|
217
|
+
],
|
|
218
|
+
});
|
|
219
|
+
}
|
|
111
220
|
|
|
221
|
+
let addEntity = readline.keyInYNStrict(
|
|
222
|
+
"Voulez-vous ajouter une autre entité ?"
|
|
223
|
+
);
|
|
112
224
|
|
|
225
|
+
while (addEntity) {
|
|
226
|
+
const name = readline.question(`Nom de l'entité : `);
|
|
227
|
+
const fields = [];
|
|
113
228
|
|
|
229
|
+
while (true) {
|
|
230
|
+
const fname = readline.question(
|
|
231
|
+
` ➤ Nom du champ (vide pour terminer) : `
|
|
232
|
+
);
|
|
233
|
+
if (!fname) break;
|
|
114
234
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
import { ${entityNameCapitalized}Mapper } from 'src/${entityNameLower}/domain/mappers/${entityNameLower}.mapper';
|
|
235
|
+
const ftype = readline.question(
|
|
236
|
+
` Type du champ "${fname}" (ex: string, number, boolean, Date, enum, etc.) : `
|
|
237
|
+
);
|
|
238
|
+
fields.push({ name: fname, type: ftype });
|
|
239
|
+
}
|
|
121
240
|
|
|
122
|
-
|
|
123
|
-
export class ${entityNameCapitalized}Repository implements I${entityNameCapitalized}Repository {
|
|
124
|
-
constructor(
|
|
125
|
-
private readonly prisma: PrismaService,
|
|
126
|
-
private readonly mapper: ${entityNameCapitalized}Mapper,
|
|
127
|
-
) {}
|
|
241
|
+
entitiesData.entities.push({ name, fields });
|
|
128
242
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const created = await this.prisma.${entityNameLower}.create({ data: toPersist });
|
|
133
|
-
return this.mapper.toDomain(created);
|
|
243
|
+
addEntity = readline.keyInYNStrict(
|
|
244
|
+
"Voulez-vous ajouter une autre entité ?"
|
|
245
|
+
);
|
|
134
246
|
}
|
|
135
247
|
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
248
|
+
// 🔗 Gestion des relations
|
|
249
|
+
const wantsRelation = readline.keyInYNStrict(
|
|
250
|
+
"Souhaites-tu ajouter des relations entre les entités ?"
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
if (wantsRelation) {
|
|
254
|
+
while (true) {
|
|
255
|
+
console.log("\n🧩 Entités disponibles :");
|
|
256
|
+
entitiesData.entities.forEach((ent, index) =>
|
|
257
|
+
console.log(` [${index}] ${ent.name}`)
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
const fromIndex = parseInt(
|
|
261
|
+
readline.question("Depuis quelle entité ? (index) : "),
|
|
262
|
+
10
|
|
263
|
+
);
|
|
264
|
+
const toIndex = parseInt(
|
|
265
|
+
readline.question("Vers quelle entité ? (index) : "),
|
|
266
|
+
10
|
|
267
|
+
);
|
|
268
|
+
const relType = readline.question(
|
|
269
|
+
"Type de relation ? (1-1 / 1-n / n-n) : "
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
const from = entitiesData.entities[fromIndex];
|
|
273
|
+
const to = entitiesData.entities[toIndex];
|
|
274
|
+
|
|
275
|
+
if (!from || !to) {
|
|
276
|
+
console.log("❌ Indice invalide, réessaye !");
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
entitiesData.relations.push({
|
|
281
|
+
from: from.name,
|
|
282
|
+
to: to.name,
|
|
283
|
+
type: relType,
|
|
284
|
+
});
|
|
141
285
|
|
|
142
|
-
|
|
143
|
-
|
|
286
|
+
const again = readline.keyInYNStrict("Ajouter une autre relation ?");
|
|
287
|
+
if (!again) break;
|
|
144
288
|
}
|
|
289
|
+
}
|
|
145
290
|
|
|
146
|
-
|
|
291
|
+
// Swagger (facultatif)
|
|
292
|
+
let swaggerInputs;
|
|
293
|
+
if (useSwagger) {
|
|
294
|
+
swaggerInputs = getUserInputsSwagger();
|
|
147
295
|
}
|
|
148
296
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
297
|
+
return {
|
|
298
|
+
projectName: projectName,
|
|
299
|
+
useYarn: useYarn,
|
|
300
|
+
useDocker: useDocker,
|
|
301
|
+
useAuth: useAuth,
|
|
302
|
+
useSwagger: useSwagger,
|
|
303
|
+
swaggerInputs: swaggerInputs,
|
|
304
|
+
packageManager: packageManager,
|
|
305
|
+
entitiesData: entitiesData,
|
|
306
|
+
selectedDB: selectedDB.name,
|
|
307
|
+
dbConfig: dbConfig,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
156
310
|
|
|
157
|
-
|
|
158
|
-
|
|
311
|
+
export function getUserInputsSwagger() {
|
|
312
|
+
console.log("\n🔹 Configuration de Swagger 🔹");
|
|
159
313
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return records.map(record => this.mapper.toDomain(record));
|
|
164
|
-
}
|
|
314
|
+
const title = readline.question("Titre de l'API ? (ex: Mon API) ", {
|
|
315
|
+
defaultInput: "Mon API",
|
|
316
|
+
});
|
|
165
317
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
|
|
318
|
+
const description = readline.question(
|
|
319
|
+
"Description de l'API ? (ex: API de gestion) ",
|
|
320
|
+
{
|
|
321
|
+
defaultInput: "API de gestion",
|
|
322
|
+
}
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
const version = readline.question("Version de l'API ? (ex: 1.0.0) ", {
|
|
326
|
+
defaultInput: "1.0.0",
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
const endpoint = readline.question("Endpoint Swagger (ex: api/docs) ", {
|
|
330
|
+
defaultInput: "api/docs",
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
return { title, description, version, endpoint };
|
|
172
334
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
import { Create${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/create-${entityNameLower}.use-case";
|
|
187
|
-
import { Update${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/update-${entityNameLower}.use-case";
|
|
188
|
-
import { GetById${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/getById-${entityNameLower}.use-case";
|
|
189
|
-
import { GetAll${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/getAll-${entityNameLower}.use-case";
|
|
190
|
-
import { Delete${entityNameCapitalized}UseCase } from "${entityPath}/application/use-cases/delete-${entityNameLower}.use-case";
|
|
191
|
-
// Importation des DTOs pour la validation et la transformation des données entrantes
|
|
192
|
-
import { Create${entityNameCapitalized}Dto, Update${entityNameCapitalized}Dto } from 'src/${entityNameLower}/application/dtos/${entityNameLower}.dto';
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Le contrôleur est annoté avec @ApiTags pour la documentation Swagger.
|
|
196
|
-
* Il regroupe les opérations HTTP relatives à l'entité ${entityNameCapitalized}.
|
|
197
|
-
*/
|
|
198
|
-
@Injectable()
|
|
199
|
-
@ApiTags('${entityNameCapitalized}')
|
|
200
|
-
@Controller('${entityNameLower}')
|
|
201
|
-
export class ${entityNameCapitalized}Controller {
|
|
202
|
-
constructor(
|
|
203
|
-
private readonly createUseCase: Create${entityNameCapitalized}UseCase,
|
|
204
|
-
private readonly updateUseCase: Update${entityNameCapitalized}UseCase,
|
|
205
|
-
private readonly getByIdUseCase: GetById${entityNameCapitalized}UseCase,
|
|
206
|
-
private readonly getAllUseCase: GetAll${entityNameCapitalized}UseCase,
|
|
207
|
-
private readonly deleteUseCase: Delete${entityNameCapitalized}UseCase,
|
|
208
|
-
) {}
|
|
209
|
-
|
|
210
|
-
// 📌 Créer un ${entityNameLower}
|
|
211
|
-
@Post()
|
|
212
|
-
@ApiOperation({ summary: 'Create a new ${entityNameLower}' })
|
|
213
|
-
async create${entityNameCapitalized}(
|
|
214
|
-
@Body() create${entityNameCapitalized}Dto: Create${entityNameCapitalized}Dto,
|
|
215
|
-
) {
|
|
216
|
-
return this.createUseCase.execute(create${entityNameCapitalized}Dto);
|
|
335
|
+
export async function createDirectory(directoryPath) {
|
|
336
|
+
try {
|
|
337
|
+
if (!fs.existsSync(directoryPath)) {
|
|
338
|
+
fs.mkdirSync(directoryPath, { recursive: true });
|
|
339
|
+
// console.log(`Dossier créé : ${directoryPath}`);
|
|
340
|
+
} else {
|
|
341
|
+
console.log(`Le dossier existe déjà : ${directoryPath}`);
|
|
342
|
+
}
|
|
343
|
+
} catch (error) {
|
|
344
|
+
console.error(
|
|
345
|
+
`Erreur lors de la création du dossier ${directoryPath}:`,
|
|
346
|
+
error
|
|
347
|
+
);
|
|
217
348
|
}
|
|
349
|
+
}
|
|
218
350
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
351
|
+
export async function createFile(fileData) {
|
|
352
|
+
// console.log("creating file....");
|
|
353
|
+
try {
|
|
354
|
+
if (!fs.existsSync(fileData.path)) {
|
|
355
|
+
fs.writeFileSync(`${fileData.path}`, `${fileData.contente}`);
|
|
356
|
+
} else {
|
|
357
|
+
console.log(`Le fichier existe déjà : ${fileData.path}`);
|
|
358
|
+
fs.writeFileSync(`${fileData.path}`, `${fileData.contente}`);
|
|
359
|
+
}
|
|
360
|
+
} catch (error) {
|
|
361
|
+
console.error(
|
|
362
|
+
`Erreur lors de la création du fichier ${fileData.path}:`,
|
|
363
|
+
error
|
|
364
|
+
);
|
|
227
365
|
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export async function updateFile({ path, pattern, replacement }) {
|
|
369
|
+
try {
|
|
370
|
+
let mainTs = fs.readFileSync(path, "utf8");
|
|
371
|
+
|
|
372
|
+
// Si pattern est une string, on le convertit en RegExp
|
|
373
|
+
/* const regexPattern =
|
|
374
|
+
typeof pattern === "string" ? new RegExp(pattern, "g") : pattern;
|
|
375
|
+
|
|
376
|
+
if (!regexPattern.test(mainTs)) {
|
|
377
|
+
console.warn(`Pattern not found in ${path}. No changes made.`);
|
|
378
|
+
return;
|
|
379
|
+
} */
|
|
228
380
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
381
|
+
const updatedContent = mainTs.replace(pattern, replacement);
|
|
382
|
+
await fs.writeFileSync(path, updatedContent, "utf-8");
|
|
383
|
+
// console.log(`✅ Updated file: ${path}`);
|
|
384
|
+
} catch (error) {
|
|
385
|
+
console.error(`❌ Error updating file ${path}:`, error);
|
|
234
386
|
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export async function safeUpdateAppModule(entity) {
|
|
390
|
+
const filePath = "src/app.module.ts";
|
|
391
|
+
const moduleName = `${capitalize(entity)}Module`;
|
|
392
|
+
|
|
393
|
+
const content = await fs.readFileSync(filePath, "utf-8");
|
|
235
394
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
395
|
+
const importLine = `import {${moduleName}} from 'src/${entity}/${entity}.module';`;
|
|
396
|
+
|
|
397
|
+
const importPatern = `import { ConfigModule } from '@nestjs/config';`;
|
|
398
|
+
|
|
399
|
+
// Ajout de l'import s'il n'existe pas
|
|
400
|
+
if (!content.includes(importLine)) {
|
|
401
|
+
await updateFile({
|
|
402
|
+
path: filePath,
|
|
403
|
+
pattern: importPatern,
|
|
404
|
+
replacement: `${importPatern}\n${importLine}`,
|
|
405
|
+
});
|
|
241
406
|
}
|
|
242
407
|
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
408
|
+
// Regex qui capte le contenu de imports: [ ... ]
|
|
409
|
+
const importRegexPatern = `imports: [
|
|
410
|
+
ConfigModule.forRoot({
|
|
411
|
+
isGlobal: true, // Rendre ConfigModule accessible globalement
|
|
412
|
+
envFilePath: '.env', // Charger les variables d'environnement
|
|
413
|
+
}),`;
|
|
414
|
+
// const contentRegex = await fs.readFileSync(filePath, "utf-8");
|
|
415
|
+
|
|
416
|
+
if (!content.includes(moduleName)) {
|
|
417
|
+
await updateFile({
|
|
418
|
+
path: filePath,
|
|
419
|
+
pattern: importRegexPatern,
|
|
420
|
+
replacement: `${importRegexPatern}\n${moduleName},\n`,
|
|
421
|
+
});
|
|
248
422
|
}
|
|
249
423
|
}
|
|
250
|
-
|
|
424
|
+
|
|
425
|
+
export function capitalize(str) {
|
|
426
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
export function decapitalize(str) {
|
|
430
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
431
|
+
}
|
|
@@ -8,7 +8,7 @@ async function configureDocker(inputs) {
|
|
|
8
8
|
const dockerfileContent = `FROM node:18\nWORKDIR /app\nCOPY . .\nRUN ${inputs.packageManager} install\nCMD ["${inputs.packageManager}", "run", "start"]`;
|
|
9
9
|
fs.writeFileSync("Dockerfile", dockerfileContent);
|
|
10
10
|
|
|
11
|
-
const dockerComposeContent = `version: '3'\nservices:\n db:\n image: postgres\n restart: always\n environment:\n POSTGRES_USER: ${inputs.
|
|
11
|
+
const dockerComposeContent = `version: '3'\nservices:\n db:\n image: postgres\n restart: always\n environment:\n POSTGRES_USER: ${inputs.dbConfig.POSTGRES_USER}\n POSTGRES_PASSWORD: ${inputs.dbConfig.POSTGRES_PASSWORD}\n POSTGRES_DB: ${inputs.dbConfig.POSTGRES_DB}\n ports:\n - "5432:5432"`;
|
|
12
12
|
fs.writeFileSync("docker-compose.yml", dockerComposeContent);
|
|
13
13
|
|
|
14
14
|
logSuccess("Docker Configuré avec succès");
|