nestcraftx 0.2.4 → 0.2.6

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.
Files changed (63) hide show
  1. package/.gitattributes +6 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  4. package/.github/ISSUE_TEMPLATE/pull_request_template.md +24 -0
  5. package/CHANGELOG.fr.md +97 -97
  6. package/CHANGELOG.md +98 -98
  7. package/CLI_USAGE.fr.md +331 -331
  8. package/CLI_USAGE.md +364 -364
  9. package/DEMO.fr.md +292 -292
  10. package/DEMO.md +294 -294
  11. package/LICENSE +21 -21
  12. package/MIGRATION_GUIDE.fr.md +127 -127
  13. package/MIGRATION_GUIDE.md +124 -124
  14. package/QUICK_START.fr.md +152 -152
  15. package/QUICK_START.md +169 -169
  16. package/README.fr.md +653 -659
  17. package/SECURITY.md +10 -0
  18. package/bin/nestcraft.js +84 -64
  19. package/commands/demo.js +333 -330
  20. package/commands/generate.js +93 -0
  21. package/commands/generateConf.js +91 -0
  22. package/commands/help.js +78 -78
  23. package/commands/info.js +48 -48
  24. package/commands/new.js +338 -335
  25. package/commands/start.js +19 -19
  26. package/commands/test.js +7 -7
  27. package/package.json +41 -41
  28. package/readme.md +638 -643
  29. package/utils/cliParser.js +133 -76
  30. package/utils/colors.js +62 -62
  31. package/utils/configs/configureDocker.js +120 -120
  32. package/utils/configs/setupCleanArchitecture.js +563 -557
  33. package/utils/configs/setupLightArchitecture.js +701 -660
  34. package/utils/envGenerator.js +122 -122
  35. package/utils/file-utils/packageJsonUtils.js +49 -55
  36. package/utils/file-utils/saveProjectConfig.js +36 -0
  37. package/utils/fullModeInput.js +607 -607
  38. package/utils/generators/application/dtoUpdater.js +54 -0
  39. package/utils/generators/cleanModuleGenerator.js +475 -0
  40. package/utils/generators/database/setupDatabase.js +31 -0
  41. package/utils/generators/domain/entityUpdater.js +78 -0
  42. package/utils/generators/infrastructure/mapperUpdater.js +65 -0
  43. package/utils/generators/lightModuleGenerator.js +131 -0
  44. package/utils/generators/relation/relation.engine.js +64 -0
  45. package/utils/interactive/askEntityInputs.js +165 -0
  46. package/utils/lightModeInput.js +460 -460
  47. package/utils/loggers/logError.js +7 -7
  48. package/utils/loggers/logInfo.js +7 -7
  49. package/utils/loggers/logSuccess.js +7 -7
  50. package/utils/loggers/logWarning.js +7 -7
  51. package/utils/setups/orms/typeOrmSetup.js +630 -630
  52. package/utils/setups/projectSetup.js +46 -46
  53. package/utils/setups/setupAuth.js +973 -926
  54. package/utils/setups/setupDatabase.js +75 -75
  55. package/utils/setups/setupLogger.js +69 -59
  56. package/utils/setups/setupMongoose.js +377 -432
  57. package/utils/setups/setupPrisma.js +802 -630
  58. package/utils/setups/setupSwagger.js +97 -88
  59. package/utils/shell.js +32 -32
  60. package/utils/spinner.js +57 -57
  61. package/utils/systemCheck.js +124 -124
  62. package/utils/userInput.js +421 -421
  63. package/utils/utils.js +2197 -1762
@@ -1,122 +1,122 @@
1
- const crypto = require("crypto");
2
- const fs = require("fs");
3
- const path = require("path");
4
-
5
- function generateSecret(length = 64) {
6
- return crypto.randomBytes(length).toString("base64url");
7
- }
8
-
9
- async function generateEnvFile(inputs) {
10
- const jwtSecret = generateSecret(64);
11
- const jwtRefreshSecret = generateSecret(64);
12
-
13
- // --- SECTION APPLICATION ---
14
- let content = `# ==============================================================================
15
- # APPLICATION CONFIGURATION
16
- # ==============================================================================
17
- # development | production | test
18
- NODE_ENV=development
19
- PORT=3000
20
-
21
- `;
22
-
23
- // --- SECTION AUTHENTIFICATION ---
24
- content += `# ------------------------------------------------------------------------------
25
- # AUTHENTICATION (JWT)
26
- # ------------------------------------------------------------------------------
27
- # Secrets auto-générés pour sécuriser les tokens.
28
- # Ne partagez jamais ces clés en production.
29
- JWT_SECRET=${jwtSecret}
30
- JWT_REFRESH_SECRET=${jwtRefreshSecret}
31
-
32
- # Formats acceptés : 15m (minutes), 1h (heures), 7d (jours)
33
- JWT_EXPIRES_IN=15m
34
- JWT_REFRESH_EXPIRES_IN=7d
35
-
36
- `;
37
-
38
- // --- SECTION DATABASE ---
39
- content += `# ------------------------------------------------------------------------------
40
- # DATABASE CONFIGURATION (${inputs.dbConfig.orm.toUpperCase()})
41
- # ------------------------------------------------------------------------------
42
- `;
43
-
44
- if (inputs.dbConfig.orm === "mongoose") {
45
- const mongoUri = inputs.dbConfig.MONGO_URI || "mongodb://localhost:27017";
46
- const mongoDb = inputs.dbConfig.MONGO_DB || inputs.projectName;
47
- content += `# URI de connexion MongoDB
48
- MONGO_URI=${mongoUri}
49
- MONGO_DB=${mongoDb}
50
- `;
51
- } else {
52
- const user = inputs.dbConfig.POSTGRES_USER || "postgres";
53
- const pass = inputs.dbConfig.POSTGRES_PASSWORD || "postgres";
54
- const db = inputs.dbConfig.POSTGRES_DB || inputs.projectName;
55
- const host = inputs.dbConfig.POSTGRES_HOST || "localhost";
56
- const port = inputs.dbConfig.POSTGRES_PORT || "5432";
57
-
58
- const dbUrl = buildDatabaseUrl(
59
- user,
60
- pass,
61
- host,
62
- port,
63
- db,
64
- inputs.dbConfig.orm
65
- );
66
-
67
- content += `# Variables individuelles (utiles pour Docker ou scripts tiers)
68
- POSTGRES_USER=${user}
69
- POSTGRES_PASSWORD=${pass}
70
- POSTGRES_DB=${db}
71
- POSTGRES_HOST=${host}
72
- POSTGRES_PORT=${port}
73
-
74
- # URL de connexion complète utilisée par ${inputs.dbConfig.orm.toUpperCase()}
75
- DATABASE_URL=${dbUrl}
76
- `;
77
- }
78
-
79
- return content;
80
- }
81
-
82
- function buildDatabaseUrl(user, password, host, port, database, orm) {
83
- const baseUrl = `postgresql://${user}:${password}@${host}:${port}/${database}`;
84
- return orm === "prisma" ? `${baseUrl}?schema=public` : baseUrl;
85
- }
86
-
87
- function writeEnvFile(envContent, projectPath = ".") {
88
- // Écriture du .env (avec secrets)
89
- const envPath = path.join(projectPath, ".env");
90
- fs.writeFileSync(envPath, envContent, "utf8");
91
-
92
- // Génération du .env.example (sans secrets pour le Git)
93
- const envExample = envContent
94
- .split("\n")
95
- .map((line) => {
96
- if (
97
- line.includes("JWT_SECRET=") ||
98
- line.includes("JWT_REFRESH_SECRET=")
99
- ) {
100
- return line.split("=")[0] + "=votre_cle_secrete_ici";
101
- }
102
- if (line.includes("POSTGRES_PASSWORD=")) {
103
- return "POSTGRES_PASSWORD=votre_mot_de_passe";
104
- }
105
- if (line.includes("DATABASE_URL=")) {
106
- // Masquer le mot de passe dans l'URL d'exemple
107
- return "DATABASE_URL=postgresql://user:password@localhost:5432/db_name?schema=public";
108
- }
109
- return line;
110
- })
111
- .join("\n");
112
-
113
- const envExamplePath = path.join(projectPath, ".env.example");
114
- fs.writeFileSync(envExamplePath, envExample, "utf8");
115
- }
116
-
117
- module.exports = {
118
- generateSecret,
119
- generateEnvFile,
120
- writeEnvFile,
121
- buildDatabaseUrl,
122
- };
1
+ const crypto = require("crypto");
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+
5
+ function generateSecret(length = 64) {
6
+ return crypto.randomBytes(length).toString("base64url");
7
+ }
8
+
9
+ async function generateEnvFile(inputs) {
10
+ const jwtSecret = generateSecret(64);
11
+ const jwtRefreshSecret = generateSecret(64);
12
+
13
+ // --- APPLICATION SECTION ---
14
+ let content = `# ==============================================================================
15
+ # APPLICATION CONFIGURATION
16
+ # ==============================================================================
17
+ # development | production | test
18
+ NODE_ENV=development
19
+ PORT=3000
20
+
21
+ `;
22
+
23
+ // --- AUTHENTICATION SECTION ---
24
+ content += `# ------------------------------------------------------------------------------
25
+ # AUTHENTICATION (JWT)
26
+ # ------------------------------------------------------------------------------
27
+ # Auto-generated secrets to secure tokens.
28
+ # Never share these keys in production.
29
+ JWT_SECRET=${jwtSecret}
30
+ JWT_REFRESH_SECRET=${jwtRefreshSecret}
31
+
32
+ # Accepted formats: 15m (minutes), 1h (hours), 7d (days)
33
+ JWT_EXPIRES_IN=15m
34
+ JWT_REFRESH_EXPIRES_IN=7d
35
+
36
+ `;
37
+
38
+ // --- DATABASE SECTION ---
39
+ content += `# ------------------------------------------------------------------------------
40
+ # DATABASE CONFIGURATION (${inputs.dbConfig.orm.toUpperCase()})
41
+ # ------------------------------------------------------------------------------
42
+ `;
43
+
44
+ if (inputs.dbConfig.orm === "mongoose") {
45
+ const mongoUri = inputs.dbConfig.MONGO_URI || "mongodb://localhost:27017";
46
+ const mongoDb = inputs.dbConfig.MONGO_DB || inputs.projectName;
47
+ content += `# MongoDB connection URI
48
+ MONGO_URI=${mongoUri}
49
+ MONGO_DB=${mongoDb}
50
+ `;
51
+ } else {
52
+ const user = inputs.dbConfig.POSTGRES_USER || "postgres";
53
+ const pass = inputs.dbConfig.POSTGRES_PASSWORD || "postgres";
54
+ const db = inputs.dbConfig.POSTGRES_DB || inputs.projectName;
55
+ const host = inputs.dbConfig.POSTGRES_HOST || "localhost";
56
+ const port = inputs.dbConfig.POSTGRES_PORT || "5432";
57
+
58
+ const dbUrl = buildDatabaseUrl(
59
+ user,
60
+ pass,
61
+ host,
62
+ port,
63
+ db,
64
+ inputs.dbConfig.orm
65
+ );
66
+
67
+ content += `# Individual variables (useful for Docker or third-party scripts)
68
+ POSTGRES_USER=${user}
69
+ POSTGRES_PASSWORD=${pass}
70
+ POSTGRES_DB=${db}
71
+ POSTGRES_HOST=${host}
72
+ POSTGRES_PORT=${port}
73
+
74
+ # Full connection URL used by ${inputs.dbConfig.orm.toUpperCase()}
75
+ DATABASE_URL=${dbUrl}
76
+ `;
77
+ }
78
+
79
+ return content;
80
+ }
81
+
82
+ function buildDatabaseUrl(user, password, host, port, database, orm) {
83
+ const baseUrl = `postgresql://${user}:${password}@${host}:${port}/${database}`;
84
+ return orm === "prisma" ? `${baseUrl}?schema=public` : baseUrl;
85
+ }
86
+
87
+ function writeEnvFile(envContent, projectPath = ".") {
88
+ // Écriture du .env (avec secrets)
89
+ const envPath = path.join(projectPath, ".env");
90
+ fs.writeFileSync(envPath, envContent, "utf8");
91
+
92
+ // Génération du .env.example (sans secrets pour le Git)
93
+ const envExample = envContent
94
+ .split("\n")
95
+ .map((line) => {
96
+ if (
97
+ line.includes("JWT_SECRET=") ||
98
+ line.includes("JWT_REFRESH_SECRET=")
99
+ ) {
100
+ return line.split("=")[0] + "=votre_cle_secrete_ici";
101
+ }
102
+ if (line.includes("POSTGRES_PASSWORD=")) {
103
+ return "POSTGRES_PASSWORD=votre_mot_de_passe";
104
+ }
105
+ if (line.includes("DATABASE_URL=")) {
106
+ // Masquer le mot de passe dans l'URL d'exemple
107
+ return "DATABASE_URL=postgresql://user:password@localhost:5432/db_name?schema=public";
108
+ }
109
+ return line;
110
+ })
111
+ .join("\n");
112
+
113
+ const envExamplePath = path.join(projectPath, ".env.example");
114
+ fs.writeFileSync(envExamplePath, envExample, "utf8");
115
+ }
116
+
117
+ module.exports = {
118
+ generateSecret,
119
+ generateEnvFile,
120
+ writeEnvFile,
121
+ buildDatabaseUrl,
122
+ };
@@ -1,55 +1,49 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const { logError } = require("../loggers/logError");
4
-
5
- /**
6
- * Lit le package.json, fusionne les scripts et les dépendances, et réécrit le fichier.
7
- *
8
- * @param {object} inputs Les inputs du CLI (pour le chemin du projet et le nom)
9
- * @param {object} scripts Les scripts à ajouter/mettre à jour (ex: { "seed": "npm run prisma:seed" })
10
- * @param {object} [devDependencies={}] Les dépendances de développement à ajouter/mettre à jour
11
- */
12
- async function updatePackageJson(inputs, scripts, devDependencies = {}) {
13
- const projectPath = process.cwd();
14
- const packageJsonPath = path.join(projectPath, "package.json");
15
-
16
- try {
17
- // 1. Lire le contenu actuel
18
- const fileContent = fs.readFileSync(packageJsonPath, "utf8");
19
- const packageJson = JSON.parse(fileContent);
20
-
21
- // 2. Fusionner les scripts
22
- packageJson.scripts = {
23
- ...packageJson.scripts,
24
- ...scripts,
25
- };
26
-
27
- // 3. Fusionner les dépendances de développement (si fournies)
28
- packageJson.devDependencies = {
29
- ...packageJson.devDependencies,
30
- ...devDependencies,
31
- };
32
-
33
- if (inputs.dbConfig.orm === "prisma") {
34
- packageJson.prisma = {
35
- seed: "ts-node prisma/seed.ts",
36
- };
37
- }
38
-
39
- // 4. Réécrire le fichier (avec une indentation de 2 espaces pour la lisibilité)
40
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
41
-
42
- // Note: Les dépendances installées via runCommand (npm install X) sont déjà dans package.json,
43
- // cette fonction est surtout utile pour les scripts personnalisés ou les dépendances manquantes.
44
- } catch (error) {
45
- logError(
46
- `❌ Erreur lors de la mise à jour de package.json pour ${inputs.projectName}:`,
47
- error.message
48
- );
49
- throw new Error(
50
- `Échec de la mise à jour du fichier package.json., ${error.message}`
51
- );
52
- }
53
- }
54
-
55
- module.exports = { updatePackageJson };
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { logError } = require("../loggers/logError");
4
+
5
+ /**
6
+ * Lit le package.json, fusionne les scripts et les dépendances, et réécrit le fichier.
7
+ *
8
+ * @param {object} inputs Les inputs du CLI (pour le chemin du projet et le nom)
9
+ * @param {object} scripts Les scripts à ajouter/mettre à jour (ex: { "seed": "npm run prisma:seed" })
10
+ * @param {object} [devDependencies={}] Les dépendances de développement à ajouter/mettre à jour
11
+ */
12
+ async function updatePackageJson(inputs, scripts, devDependencies = {}) {
13
+ const projectPath = process.cwd();
14
+ const packageJsonPath = path.join(projectPath, "package.json");
15
+
16
+ try {
17
+ // 1. Lire le contenu actuel
18
+ const fileContent = fs.readFileSync(packageJsonPath, "utf8");
19
+ const packageJson = JSON.parse(fileContent);
20
+
21
+ // 2. Fusionner les scripts
22
+ packageJson.scripts = {
23
+ ...packageJson.scripts,
24
+ ...scripts,
25
+ };
26
+
27
+ // 3. Fusionner les dépendances de développement (si fournies)
28
+ packageJson.devDependencies = {
29
+ ...packageJson.devDependencies,
30
+ ...devDependencies,
31
+ };
32
+
33
+ // 4. Réécrire le fichier (avec une indentation de 2 espaces pour la lisibilité)
34
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
35
+
36
+ // Note: Les dépendances installées via runCommand (npm install X) sont déjà dans package.json,
37
+ // cette fonction est surtout utile pour les scripts personnalisés ou les dépendances manquantes.
38
+ } catch (error) {
39
+ logError(
40
+ `❌ Erreur lors de la mise à jour de package.json pour ${inputs.projectName}:`,
41
+ error.message
42
+ );
43
+ throw new Error(
44
+ `Échec de la mise à jour du fichier package.json., ${error.message}`
45
+ );
46
+ }
47
+ }
48
+
49
+ module.exports = { updatePackageJson };
@@ -0,0 +1,36 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ /**
5
+ * Lit le package.json, fusionne les scripts et les dépendances, et réécrit le fichier.
6
+ *
7
+ * @param {object} inputs Les inputs du CLI (pour le chemin du projet et le nom)
8
+ *
9
+ */
10
+ async function saveProjectConfig(inputs) {
11
+ const configDir = path.join(process.cwd(), ".nestcraftx");
12
+ const configFile = path.join(configDir, ".nestcraftxrc");
13
+
14
+ const configData = {
15
+ name: inputs.projectName,
16
+ mode: inputs.mode,
17
+ orm: inputs.dbConfig.orm,
18
+ database: inputs.selectedDB,
19
+ auth: inputs.useAuth,
20
+ swagger: inputs.useSwagger,
21
+ packageManager: inputs.packageManager,
22
+ docker: inputs.useDocker,
23
+ generatedAt: new Date().toISOString(),
24
+ };
25
+
26
+ try {
27
+ if (!fs.existsSync(configDir)) {
28
+ fs.mkdirSync(configDir, { recursive: true });
29
+ }
30
+ fs.writeFileSync(configFile, JSON.stringify(configData, null, 2));
31
+ } catch (error) {
32
+ logWarning("Could not save project configuration file.");
33
+ }
34
+ }
35
+
36
+ module.exports = { saveProjectConfig };