nestcraftx 0.2.6 → 0.4.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.
Files changed (42) hide show
  1. package/AUDIT_ROADMAP.md +798 -0
  2. package/CHANGELOG.fr.md +22 -0
  3. package/CHANGELOG.md +22 -0
  4. package/PROGRESS.md +259 -0
  5. package/commands/demo.js +2 -42
  6. package/commands/generate.js +5 -4
  7. package/commands/help.js +29 -2
  8. package/commands/new.js +6 -49
  9. package/package.json +1 -1
  10. package/utils/app-module.updater.js +102 -0
  11. package/utils/cliParser.js +0 -45
  12. package/utils/configs/setupCleanArchitecture.js +2 -2
  13. package/utils/envGenerator.js +6 -0
  14. package/utils/file-system.js +90 -0
  15. package/utils/file-utils/packageJsonUtils.js +6 -0
  16. package/utils/file-utils/saveProjectConfig.js +6 -0
  17. package/utils/fullModeInput.js +8 -229
  18. package/utils/generators/application/dtoGenerator.js +252 -0
  19. package/utils/generators/application/dtoUpdater.js +5 -0
  20. package/utils/generators/database/setupDatabase.js +32 -14
  21. package/utils/generators/domain/entityGenerator.js +126 -0
  22. package/utils/generators/domain/entityUpdater.js +5 -0
  23. package/utils/generators/infrastructure/mapperGenerator.js +114 -0
  24. package/utils/generators/infrastructure/mapperUpdater.js +5 -0
  25. package/utils/generators/infrastructure/middlewareGenerator.js +645 -0
  26. package/utils/generators/infrastructure/mongooseSchemaGenerator.js +229 -0
  27. package/utils/generators/infrastructure/repositoryGenerator.js +334 -0
  28. package/utils/generators/presentation/controllerGenerator.js +142 -0
  29. package/utils/helpers.js +115 -0
  30. package/utils/interactive/askEntityInputs.js +5 -68
  31. package/utils/interactive/entityBuilder.js +400 -0
  32. package/utils/lightModeInput.js +13 -246
  33. package/utils/setups/orms/typeOrmSetup.js +31 -4
  34. package/utils/setups/projectSetup.js +78 -8
  35. package/utils/setups/setupAuth.js +6 -7
  36. package/utils/setups/setupDatabase.js +2 -1
  37. package/utils/setups/setupMongoose.js +96 -30
  38. package/utils/setups/setupPrisma.js +118 -134
  39. package/utils/setups/setupSwagger.js +12 -8
  40. package/utils/shell.js +125 -10
  41. package/utils/userInput.js +37 -101
  42. package/utils/utils.js +29 -2164
package/CHANGELOG.fr.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  Toutes les modifications notables apportées à NestCraftX seront documentées dans ce fichier.
4
4
 
5
+ ## [0.3.0] - 07-06-2026
6
+
7
+ ### Ajouté
8
+
9
+ - **Version dynamique de l'aide** : Lecture dynamique de la version depuis le `package.json` dans la commande d'aide pour éviter les incohérences.
10
+ - **Validation interactive des flags** : Correction de la logique de vérification pour supporter correctement le mode non-interactif.
11
+ - **Package Manager dynamique** : Prise en compte dynamique du gestionnaire de paquets choisi au lieu de forcer `npm` dans le setup auth.
12
+
13
+ ### Changé
14
+
15
+ - **Système de modules unifié** : Standardisation de tous les fichiers du projet en CommonJS afin d'éviter les crashs hybrides ESM/CJS au runtime.
16
+ - **Gestion gracieuse des erreurs** : Les échecs de commandes non critiques (comme `prisma format`) ne tuent plus l'ensemble du processus de génération.
17
+
18
+ ### Corrigé
19
+
20
+ - **Capitalisation dans le générateur Prisma** : Capitalisation forcée des noms de modèles dans les relations du schéma pour respecter les contraintes Prisma.
21
+ - **Déduplication des clés étrangères (FK)** : Résolution de la duplication des clés étrangères lors de la génération des relations Prisma.
22
+ - **Boucles asynchrones Clean Architecture** : Remplacement des boucles `forEach` asynchrones par des boucles `for...of` séquentielles pour garantir l'ordre de création des fichiers.
23
+ - **Sauvegarde de l'environnement** : Modification de `setupMongoose` pour mettre à jour le fichier `.env` au lieu de l'écraser complètement.
24
+ - **Analyse robuste de AppModule** : Amélioration de la regex dans `safeUpdateAppModule` pour gérer en toute sécurité les crochets de tableaux imbriqués.
25
+ - **Nettoyages de code** : Suppression du code mort ou commenté et retrait des `console.log` de débogage dans les guards de sécurité générés.
26
+
5
27
  ## [0.2.5] - 10-01-2026
6
28
 
7
29
  ### Ajouté
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  All notable changes to NestCraftX will be documented in this file.
4
4
 
5
+ ## [0.3.0] - 2026-06-07
6
+
7
+ ### Added
8
+
9
+ - **Dynamic Help Version**: Read version dynamically from `package.json` in the help command to prevent version mismatches.
10
+ - **Interactive Flags Check**: Fixed flag check validations to support non-interactive execution modes properly.
11
+ - **Dynamic Package Manager**: Support package manager selection dynamically based on inputs rather than hardcoding `npm`.
12
+
13
+ ### Changed
14
+
15
+ - **Unified Module System**: Standardized all project files under CommonJS format to avoid hybrid ESM/CommonJS runtime crashes.
16
+ - **Graceful Error Handling**: Non-critical shell command failures (like `prisma format`) now log warnings rather than forcing process exit.
17
+
18
+ ### Fixed
19
+
20
+ - **Prisma Generator Capitalization**: Forced capitalization of model names in database relations to match Prisma schema constraints.
21
+ - **Foreign Key Duplication**: Fixed relation mappings to prevent duplicate foreign key definitions in generated Prisma schemas.
22
+ - **Clean Architecture Loops**: Replaced asynchronous `forEach` loops with sequential `for...of` to prevent files being written out-of-order.
23
+ - **Safe Environment Generation**: `setupMongoose` now updates the `.env` file instead of overwriting it completely.
24
+ - **Robust AppModule Parsing**: Upgraded regex pattern matching in `safeUpdateAppModule` to handle nested array brackets safely.
25
+ - **Cleanups**: Removed dead/commented-out code and removed active debug `console.log` statements in generated security guards.
26
+
5
27
  ## [0.2.5] - 2026-01-10
6
28
 
7
29
  ### Added
package/PROGRESS.md ADDED
@@ -0,0 +1,259 @@
1
+ # ✅ NestCraftX — Suivi de Progression vers v1.0
2
+ > Fichier de check indépendant — le roadmap complet est dans `AUDIT_ROADMAP.md`
3
+ > **Ne jamais modifier `AUDIT_ROADMAP.md`** — il est la référence figée de l'audit.
4
+
5
+ ---
6
+
7
+ ## 📊 Tableau de bord
8
+
9
+ | Phase | Statut | Tickets | Complétés | Progression |
10
+ |---|---|---|---|---|
11
+ | Phase 0 — Stabilisation (v0.3.0) | ✅ Terminé | 17 | 17 | 100% |
12
+ | Phase 1 — Refactorisation (v0.4.0) | ✅ Terminé | 18 | 18 | 100% |
13
+ | Phase 2 — Qualité & Sécurité (v0.5.0) | ⏸️ En attente | 10 | 0 | 0% |
14
+ | Phase 3 — Tests & CI/CD (v0.6.0) | ⏸️ En attente | 15 | 0 | 0% |
15
+ | Phase 4 — Features (v0.7–0.9) | ⏸️ En attente | 14 | 0 | 0% |
16
+ | Phase 5 — Documentation (v0.9.x) | ⏸️ En attente | 8 | 0 | 0% |
17
+ | Phase 6 — Release v1.0 | ⏸️ En attente | 7 | 0 | 0% |
18
+ | **TOTAL** | | **89** | **35** | **39%** |
19
+
20
+ > Mis à jour : 2026-06-16
21
+
22
+ ---
23
+
24
+ ## 🔴 PHASE 0 — Stabilisation d'urgence (v0.3.0)
25
+ > Objectif : Zéro crash, zéro bug bloquant
26
+
27
+ ### 0A — Crash & Stabilité _(priorité maximale)_
28
+
29
+ | Ticket | Description | Fichier(s) | Statut | Date |
30
+ |---|---|---|---|---|
31
+ | PROD-03 | Refactoriser `runCommand` : ajouter `{ critical: boolean }` | `utils/shell.js` | ✅ Terminé | 2026-06-05 |
32
+ | PROD-01a | Dégradation gracieuse si `prisma format` échoue | `utils/setups/setupPrisma.js` | ✅ Terminé | 2026-06-05 |
33
+ | PROD-01b | Capitalisation modèles Prisma (`capitalize(from/to)`) | `utils/setups/setupPrisma.js` | ✅ Terminé | 2026-06-05 |
34
+ | PROD-01c | Déduplication FK dans le 2e pass des relations | `utils/setups/setupPrisma.js` | ✅ Terminé | 2026-06-05 |
35
+ | BUG-09 | `forEach async` → `for...of` dans setupCleanArchitecture | `utils/configs/setupCleanArchitecture.js` | ✅ Terminé | 2026-06-05 |
36
+ | BUG-01 | Unifier module system ESM/CJS (`utils.js` + `userInput.js`) | `utils/utils.js`, `utils/userInput.js` | ✅ Terminé | 2026-06-06 |
37
+
38
+ ### 0B — Comportement incorrect
39
+
40
+ | Ticket | Description | Fichier(s) | Statut | Date |
41
+ |---|---|---|---|---|
42
+ | BUG-03 | Fixer logique `hasAllLightModeFlags` / `hasAllFullModeFlags` | `commands/new.js` | ✅ Terminé | 2026-06-06 |
43
+ | BUG-06 | `setupAuth` : utiliser `inputs.packageManager` (pas `npm` hardcodé) | `utils/setups/setupAuth.js` | ✅ Terminé | 2026-06-06 |
44
+ | BUG-07 | `setupMongoose` : ne plus écraser le `.env` complet | `utils/setups/setupMongoose.js` | ✅ Terminé | 2026-06-07 |
45
+ | BUG-04 | `createFile` : vraiment ne pas écraser quand `overwrite: false` | `utils/userInput.js` | ✅ Terminé | 2026-06-07 |
46
+ | BUG-08 | Corriger regex AppModule dans `safeUpdateAppModule` | `utils/userInput.js` | ✅ Terminé | 2026-06-07 |
47
+
48
+ ### 0C — Nettoyage immédiat
49
+
50
+ | Ticket | Description | Fichier(s) | Statut | Date |
51
+ |---|---|---|---|---|
52
+ | BUG-12 | `help.js` : version dynamique depuis `package.json` | `commands/help.js` | ✅ Terminé | 2026-06-07 |
53
+ | MP-07a | Supprimer code mort dans `cliParser.js` (45 lignes) | `utils/cliParser.js` | ✅ Terminé | 2026-06-07 |
54
+ | MP-07b | Supprimer code mort dans `setupPrisma.js` (44 lignes) | `utils/setups/setupPrisma.js` | ✅ Terminé | 2026-06-07 |
55
+ | BUG-02 | `handleAuthGeneration` : implémenter ou message clair | `commands/generate.js` | ✅ Terminé | 2026-06-07 |
56
+ | BUG-11 | Retirer `console.log` debug du `RolesGuard` généré | `utils/setups/setupAuth.js` | ✅ Terminé | 2026-06-07 |
57
+ | BUG-12b | Corriger commentaire `PostMapper` hardcodé dans mapper généré | `utils/utils.js` | ✅ Terminé | 2026-06-07 |
58
+
59
+ ---
60
+
61
+ ## 🟠 PHASE 1 — Refactorisation Architecture (v0.4.0)
62
+ > Objectif : Code maintenable, testable, sans duplication
63
+
64
+ ### 1A — Découpage des gros fichiers
65
+
66
+ | Ticket | Description | Fichier(s) | Statut | Date |
67
+ |---|---|---|---|---|
68
+ | MP-01a | Extraire `generators/entity.generator.js` depuis `utils.js` | `utils/utils.js` | ✅ Terminé | 2026-06-07 |
69
+ | MP-01b | Extraire `generators/dto.generator.js` depuis `utils.js` | `utils/utils.js` | ✅ Terminé | 2026-06-07 |
70
+ | MP-01c | Extraire `generators/controller.generator.js` depuis `utils.js` | `utils/utils.js` | ✅ Terminé | 2026-06-07 |
71
+ | MP-01d | Extraire `generators/mapper.generator.js` depuis `utils.js` | `utils/utils.js` | ✅ Terminé | 2026-06-07 |
72
+ | MP-01e | Extraire `generators/service.generator.js` depuis `utils.js` | `utils/utils.js` | ✅ Terminé | 2026-06-07 |
73
+ | MP-01f | Extraire `utils/helpers.js` (capitalize, decapitalize, pluralize) | `utils/utils.js` | ✅ Terminé | 2026-06-07 |
74
+ | MP-07c | Éclater `userInput.js` → `utils/file-system.js` | `utils/userInput.js` | ✅ Terminé | 2026-06-07 |
75
+ | MP-07d | Éclater `userInput.js` → `utils/app-module.updater.js` | `utils/userInput.js` | ✅ Terminé | 2026-06-07 |
76
+ | MP-03 | Supprimer `generateDtox` (doublon de `generateDto`) | `utils/utils.js` | ✅ Terminé | 2026-06-07 |
77
+
78
+ ### 1B — Refonte du flow d'input entités (PROD-04 + PROD-05)
79
+
80
+ | Ticket | Description | Fichier(s) | Statut | Date |
81
+ |---|---|---|---|---|
82
+ | PROD-04a | Étendre modèle de champ : `unique`, `nullable`, `default` | `utils/fullModeInput.js`, `utils/lightModeInput.js` | ✅ Terminé | 2026-06-14 |
83
+ | PROD-05 | Écran de révision d'entité (modifier, supprimer, renommer) | `utils/fullModeInput.js`, `utils/lightModeInput.js` | ✅ Terminé | 2026-06-14 |
84
+ | PROD-04b | Refonte state-based : `EntityBuilder` navigable | `utils/fullModeInput.js` | ✅ Terminé | 2026-06-14 |
85
+ | MP-02 | Dédupliquer `addCustomEntities` et `addRelations` | `utils/fullModeInput.js`, `utils/lightModeInput.js` | ✅ Terminé | 2026-06-14 |
86
+
87
+ ### 1C — Architecture générale
88
+
89
+ | Ticket | Description | Fichier(s) | Statut | Date |
90
+ |---|---|---|---|---|
91
+ | MA-05 | Extraire flow commun `demo.js` → partager avec `new.js` | `commands/demo.js`, `commands/new.js` | ✅ Terminé | 2026-06-16 |
92
+ | MP-04 | Remplacer `execSync` par `execa` avec timeout | `utils/shell.js` | ✅ Terminé | 2026-06-16 |
93
+ | MA-01 | Mécanisme de rapport final (accumuler warnings, afficher en bloc) | `utils/shell.js`, `commands/new.js` | ✅ Terminé | 2026-06-16 |
94
+ | MA-02 | Isoler `process.chdir` — vérifier CWD avant chaque I/O | `utils/setups/projectSetup.js` | ✅ Terminé | 2026-06-16 |
95
+ | DRY-01 | Ajouter `--dry-run` flag (simuler sans écrire) | `bin/nestcraft.js`, `commands/new.js` | ✅ Terminé | 2026-06-16 |
96
+
97
+ ---
98
+
99
+ ## 🟠 PHASE 2 — Qualité & Sécurité (v0.5.0)
100
+ > Objectif : Code généré sécurisé et professionnel
101
+
102
+ ### 2A — Sécurité du code généré
103
+
104
+ | Ticket | Description | Fichier(s) | Statut | Date |
105
+ |---|---|---|---|---|
106
+ | MP-17 | `resetPassword` : stocker et valider le token (table DB / Redis) | `utils/setups/setupAuth.js` | ⬜ À faire | — |
107
+ | MP-16 | OTPs : utiliser DB ou Redis au lieu de `Map` en mémoire | `utils/setups/setupAuth.js` | ⬜ À faire | — |
108
+ | MA-06 | Pinning versions dépendances générées (ranges semver stricts) | `utils/setups/*.js` | ⬜ À faire | — |
109
+
110
+ ### 2B — Descriptions Swagger (PROD-02)
111
+
112
+ | Ticket | Description | Fichier(s) | Statut | Date |
113
+ |---|---|---|---|---|
114
+ | PROD-02a | Système de descriptions sémantiques par catégorie de champ | `utils/utils.js` (getFieldDescription) | ⬜ À faire | — |
115
+ | PROD-02b | Description manuelle optionnelle dans `getFullModeInputs` | `utils/fullModeInput.js` | ⬜ À faire | — |
116
+ | PROD-02c | Description contextuelle Create vs Update DTO | `utils/utils.js` (generateDto) | ⬜ À faire | — |
117
+
118
+ ### 2C — Corrections qualité
119
+
120
+ | Ticket | Description | Fichier(s) | Statut | Date |
121
+ |---|---|---|---|---|
122
+ | BUG-18 | Corriger condition De Morgan dans `cleanModuleGenerator` | `utils/generators/cleanModuleGenerator.js` | ⬜ À faire | — |
123
+ | MP-09 | Corriger détection ORM dans `generateConf` (ordre priorité) | `commands/generateConf.js` | ⬜ À faire | — |
124
+ | MP-13 | JWT vars conditionnelles à `useAuth` dans `envGenerator` | `utils/envGenerator.js` | ⬜ À faire | — |
125
+ | MP-10 | Supporter mode LIGHT sans nom en argument dans `new.js` | `commands/new.js` | ⬜ À faire | — |
126
+ | MA-09 | Timeout 5 min sur `npm install` dans `runCommand` | `utils/shell.js` | ⬜ À faire | — |
127
+
128
+ ---
129
+
130
+ ## 🟡 PHASE 3 — Tests & CI/CD (v0.6.0)
131
+ > Objectif : Zéro régression possible sur chaque PR
132
+
133
+ ### 3A — Tests unitaires (Jest)
134
+
135
+ | Ticket | Description | Statut | Date |
136
+ |---|---|---|---|
137
+ | TEST-01 | `generateDto()` — output TypeScript valide pour chaque ORM | ⬜ À faire | — |
138
+ | TEST-02 | `generateEntityFileContent()` — structure domaine correcte | ⬜ À faire | — |
139
+ | TEST-03 | `generateController()` — routes, guards, decorators | ⬜ À faire | — |
140
+ | TEST-04 | `mapTypeToPrisma()` — tous les types | ⬜ À faire | — |
141
+ | TEST-05 | `mapTypeToMongoose()` — tous les types | ⬜ À faire | — |
142
+ | TEST-06 | Schema Prisma relations 1-n (FK, inverse, capitalisation) | ⬜ À faire | — |
143
+ | TEST-07 | Schema Prisma relations n-n et 1-1 | ⬜ À faire | — |
144
+ | TEST-08 | CLI Parser — tous les cas de flags | ⬜ À faire | — |
145
+ | TEST-09 | `safeUpdateAppModule` — différents états `app.module.ts` | ⬜ À faire | — |
146
+
147
+ ### 3B — Tests d'intégration E2E
148
+
149
+ | Ticket | Description | Statut | Date |
150
+ |---|---|---|---|
151
+ | E2E-01 | Générer `test-full-prisma` → `tsc --noEmit` passe | ⬜ À faire | — |
152
+ | E2E-02 | Générer `test-full-typeorm` → `tsc --noEmit` passe | ⬜ À faire | — |
153
+ | E2E-03 | Générer `test-full-mongoose` → `tsc --noEmit` passe | ⬜ À faire | — |
154
+ | E2E-04 | Générer `test-light-prisma` → `tsc --noEmit` passe | ⬜ À faire | — |
155
+ | E2E-05 | Générer avec auth → `auth.module.ts` correctement câblé | ⬜ À faire | — |
156
+ | E2E-06 | Générer avec relations 1-n → schema Prisma valide | ⬜ À faire | — |
157
+ | E2E-07 | Test résilience PROD-03 : erreur migration → reste généré | ⬜ À faire | — |
158
+
159
+ ### 3C — CI/CD
160
+
161
+ | Ticket | Description | Statut | Date |
162
+ |---|---|---|---|
163
+ | CI-01 | ESLint sur chaque PR | ⬜ À faire | — |
164
+ | CI-02 | Tests Node 18, 20, 22 LTS (matrix) | ⬜ À faire | — |
165
+ | CI-03 | Génération sur Ubuntu + Windows (matrix) | ⬜ À faire | — |
166
+ | CI-04 | Semantic Release automatique | ⬜ À faire | — |
167
+ | CI-05 | Publish automatique sur npm | ⬜ À faire | — |
168
+
169
+ ---
170
+
171
+ ## 🟡 PHASE 4 — Features Manquantes (v0.7.0–v0.9.0)
172
+ > Objectif : Être feature-complete avant la v1.0
173
+
174
+ ### 4A — Features CLI
175
+
176
+ | Ticket | Description | Statut | Date |
177
+ |---|---|---|---|
178
+ | FEAT-01 | `nestcraftx g auth` — implémenter complètement | ⬜ À faire | — |
179
+ | FEAT-02 | Mode non-interactif complet (tous les flags) | ⬜ À faire | — |
180
+ | FEAT-03 | `nestcraftx update` — auto-update de la CLI | ⬜ À faire | — |
181
+ | FEAT-04 | `nestcraftx list` — lister entités depuis `.nestcraftxrc` | ⬜ À faire | — |
182
+ | FEAT-05 | Support `pnpm` | ⬜ À faire | — |
183
+
184
+ ### 4B — Qualité du code généré
185
+
186
+ | Ticket | Description | Statut | Date |
187
+ |---|---|---|---|
188
+ | FEAT-06 | Pagination GET all (`?page=1&limit=10`) | ⬜ À faire | — |
189
+ | FEAT-07 | Filtering & Sorting query params | ⬜ À faire | — |
190
+ | FEAT-08 | Rate limiting global (`@nestjs/throttler`) | ⬜ À faire | — |
191
+ | FEAT-09 | Health check endpoint (`/health`) | ⬜ À faire | — |
192
+ | FEAT-10 | Exception filter global typé | ⬜ À faire | — |
193
+ | FEAT-11 | Guards RBAC conditionnels sur endpoints | ⬜ À faire | — |
194
+ | FEAT-12 | Support MySQL/SQLite (Prisma/TypeORM) | ⬜ À faire | — |
195
+
196
+ ### 4C — Expérience développeur
197
+
198
+ | Ticket | Description | Statut | Date |
199
+ |---|---|---|---|
200
+ | FEAT-13 | Templates personnalisés depuis GitHub | ⬜ À faire | — |
201
+ | FEAT-14 | `nestcraftx g relation` — relation entre modules existants | ⬜ À faire | — |
202
+ | FEAT-15 | Rapport de génération en fin de commande | ⬜ À faire | — |
203
+
204
+ ---
205
+
206
+ ## 🟢 PHASE 5 — Documentation & Site Web (v0.9.x)
207
+ > Objectif : Site officiel avant la v1.0
208
+
209
+ | Ticket | Description | Statut | Date |
210
+ |---|---|---|---|
211
+ | DOC-01 | Créer site Docusaurus/VitePress (`nestcraftx.dev`) | ⬜ À faire | — |
212
+ | DOC-02 | Page Getting Started (5 minutes) | ⬜ À faire | — |
213
+ | DOC-03 | CLI Reference (toutes les commandes et flags) | ⬜ À faire | — |
214
+ | DOC-04 | Architecture Guide (Clean Arch générée) | ⬜ À faire | — |
215
+ | DOC-05 | ORM Guide (Prisma vs TypeORM vs Mongoose) | ⬜ À faire | — |
216
+ | DOC-06 | Auth Deep Dive (JWT, guards, roles) | ⬜ À faire | — |
217
+ | DOC-07 | Troubleshooting & Migration Guide (0.2.x → 1.0) | ⬜ À faire | — |
218
+ | DOC-08 | Playground interactif dans le navigateur | ⬜ À faire | — |
219
+
220
+ ---
221
+
222
+ ## 🟢 PHASE 6 — Release v1.0 stable
223
+
224
+ | Ticket | Description | Statut | Date |
225
+ |---|---|---|---|
226
+ | REL-01 | Audit de sécurité final | ⬜ À faire | — |
227
+ | REL-02 | Test complet Windows + macOS + Linux | ⬜ À faire | — |
228
+ | REL-03 | Revue de toutes les sorties CLI | ⬜ À faire | — |
229
+ | REL-04 | README mis à jour avec badges CI | ⬜ À faire | — |
230
+ | REL-05 | CHANGELOG complet depuis v0.2.6 | ⬜ À faire | — |
231
+ | REL-06 | Publication npm avec tag `@stable` | ⬜ À faire | — |
232
+ | REL-07 | Annonce GitHub Release avec notes détaillées | ⬜ À faire | — |
233
+
234
+ ---
235
+
236
+ ## 📝 Journal des changements
237
+
238
+ | 2026-06-05 | 0.2.6 | — | Audit initial + retours prod intégrés |
239
+ | 2026-06-05 | 0.3.0-wip | PROD-03, PROD-01a, PROD-01b, PROD-01c, BUG-09 | `runCommand` refactorisé (PROD-03). Prisma relations : capitalisation forcée des modèles et types, déduplication complète des clés étrangères (PROD-01a, b, c). Correction de la boucle asynchrone des use cases clean architecture (BUG-09). |
240
+ | 2026-06-06 | 0.3.0-wip | BUG-01, BUG-03, BUG-06 | Unification du module system en CommonJS (BUG-01). Validation non-interactive des flags (BUG-03). Utilisation de inputs.packageManager dynamique dans `setupAuth.js` au lieu de npm en dur (BUG-06). |
241
+ | 2026-06-07 | 0.3.0 | BUG-07, BUG-04, BUG-08, BUG-12, MP-07a, MP-07b, BUG-02, BUG-11, BUG-12b | Clôture de la Phase 0. Mongoose .env préservé. createFile supporte overwrite. safeUpdateAppModule robuste aux crochets imbriqués. help.js dynamic. Nettoyage de code mort et debug logs. |
242
+ | 2026-06-14 | 0.3.0-wip | PROD-04a, PROD-04b, PROD-05, MP-02 | Refonte state-based interactive de la saisie d'entités avec EntityBuilder. Support des contraintes unique, nullable et valeurs par défaut. Alignement et déduplication des générateurs (Prisma, TypeORM, Mongoose, DTOs, et Domain Entities). |
243
+
244
+ ---
245
+
246
+ ## 🔑 Légende des statuts
247
+
248
+ | Icône | Signification |
249
+ |---|---|
250
+ | ⬜ À faire | Ticket non démarré |
251
+ | 🔵 En cours | Travail en cours |
252
+ | ✅ Terminé | Ticket complété et validé |
253
+ | ❌ Annulé | Ticket annulé (avec raison dans Notes) |
254
+ | ⏸️ Bloqué | En attente d'un autre ticket |
255
+
256
+ ---
257
+
258
+ *Ce fichier est mis à jour manuellement à chaque session de travail.*
259
+ *Pour le détail technique de chaque ticket, voir [AUDIT_ROADMAP.md](./AUDIT_ROADMAP.md)*
package/commands/demo.js CHANGED
@@ -1,20 +1,7 @@
1
1
  const inquirer = require("inquirer");
2
2
  const { logInfo } = require("../utils/loggers/logInfo");
3
3
  const { logSuccess } = require("../utils/loggers/logSuccess");
4
- const { createProject } = require("../utils/setups/projectSetup");
5
- const {
6
- setupCleanArchitecture,
7
- } = require("../utils/configs/setupCleanArchitecture");
8
- const {
9
- setupLightArchitecture,
10
- } = require("../utils/configs/setupLightArchitecture");
11
- const { setupAuth } = require("../utils/setups/setupAuth");
12
- const { setupSwagger } = require("../utils/setups/setupSwagger");
13
- const { setupDatabase } = require("../utils/setups/setupDatabase");
14
- const { configureDocker } = require("../utils/configs/configureDocker");
15
- const { generateEnvFile, writeEnvFile } = require("../utils/envGenerator");
16
- const { setupBootstrapLogger } = require("../utils/setups/setupLogger");
17
- const { saveProjectConfig } = require("../utils/file-utils/saveProjectConfig");
4
+ const { runProjectSetupPipeline } = require("../utils/setups/projectSetup");
18
5
  const actualInquirer = inquirer.default || inquirer;
19
6
 
20
7
  async function demoCommand(flags = {}) {
@@ -209,34 +196,7 @@ async function demoCommand(flags = {}) {
209
196
  dbConfig,
210
197
  };
211
198
 
212
- await createProject(demoInputs);
213
-
214
- if (isLight) {
215
- await setupLightArchitecture(demoInputs);
216
- } else {
217
- await setupCleanArchitecture(demoInputs);
218
- }
219
-
220
- if (useAuth) {
221
- await setupAuth(demoInputs);
222
- }
223
-
224
- if (useSwagger) {
225
- await setupSwagger(demoInputs.swaggerInputs);
226
- } else {
227
- await setupBootstrapLogger();
228
- }
229
-
230
- if (useDocker) {
231
- await configureDocker(demoInputs);
232
- }
233
-
234
- await setupDatabase(demoInputs);
235
-
236
- const envContent = await generateEnvFile(demoInputs);
237
- writeEnvFile(envContent);
238
-
239
- await saveProjectConfig(demoInputs);
199
+ await runProjectSetupPipeline(demoInputs);
240
200
 
241
201
  console.log("\n" + "=".repeat(60));
242
202
  logSuccess("Demonstration project created successfully!");
@@ -6,8 +6,10 @@ const { logWarning } = require("../utils/loggers/logWarning");
6
6
  const generateCleanModule = require("../utils/generators/cleanModuleGenerator");
7
7
  const { askEntityInputs } = require("../utils/interactive/askEntityInputs");
8
8
  const lightModuleGenerator = require("../utils/generators/lightModuleGenerator");
9
+ const { printSetupWarnings, clearSetupWarnings } = require("../utils/shell");
9
10
 
10
11
  async function generate(subCommand, targetName, flags) {
12
+ clearSetupWarnings();
11
13
  // 1. Localisation of config file
12
14
  const configPath = path.join(process.cwd(), ".nestcraftx", ".nestcraftxrc");
13
15
 
@@ -81,13 +83,12 @@ async function handleModuleGeneration(name, config) {
81
83
  } else {
82
84
  await lightModuleGenerator(entityData, config);
83
85
  }
86
+
87
+ printSetupWarnings();
84
88
  }
85
89
 
86
90
  async function handleAuthGeneration(config) {
87
- // On réutilisera ton script setupAuth corrigé
88
- // await require('../utils/setups/setupAuth')(config);
89
-
90
- logInfo("🚀 Generating module auth...");
91
+ logWarning("nestcraftx g auth n'est pas encore disponible en v0.3 — prévu en v0.7");
91
92
  }
92
93
 
93
94
  module.exports = generate;
package/commands/help.js CHANGED
@@ -1,9 +1,36 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ function getVersion() {
5
+ try {
6
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.json"), "utf8"));
7
+ return pkg.version;
8
+ } catch (err) {
9
+ return "0.2.6";
10
+ }
11
+ }
12
+
13
+ function centerText(text, width) {
14
+ const totalSpaces = width - text.length;
15
+ const leftSpaces = Math.max(0, Math.floor(totalSpaces / 2));
16
+ const rightSpaces = Math.max(0, totalSpaces - leftSpaces);
17
+ return " ".repeat(leftSpaces) + text + " ".repeat(rightSpaces);
18
+ }
19
+
1
20
  async function helpCommand() {
21
+ const version = getVersion();
22
+ const versionLineText = `🌟 NestCraftX CLI v${version} 🌟`;
23
+ const descLineText = "Clean Architecture Generator for NestJS";
24
+
25
+ const innerWidth = 59; // 59 characters inside the border
26
+ const paddedVersionLine = centerText(versionLineText, innerWidth);
27
+ const paddedDescLine = centerText(descLineText, innerWidth);
28
+
2
29
  console.log(`
3
30
  ╔═══════════════════════════════════════════════════════════╗
4
31
  ║ ║
5
- 🌟 NestCraftX CLI v0.2.5 🌟 ║
6
- Clean Architecture Generator for NestJS ║
32
+ ║${paddedVersionLine}
33
+ ║${paddedDescLine}
7
34
  ║ ║
8
35
  ╚═══════════════════════════════════════════════════════════╝
9
36
 
package/commands/new.js CHANGED
@@ -1,25 +1,12 @@
1
1
  const { getFullModeInputs } = require("../utils/fullModeInput");
2
2
  const { getLightModeInputs } = require("../utils/lightModeInput");
3
- const { createProject } = require("../utils/setups/projectSetup");
4
- const {
5
- setupCleanArchitecture,
6
- } = require("../utils/configs/setupCleanArchitecture");
7
- const {
8
- setupLightArchitecture,
9
- } = require("../utils/configs/setupLightArchitecture");
10
- const { setupAuth } = require("../utils/setups/setupAuth");
11
- const { setupSwagger } = require("../utils/setups/setupSwagger");
12
- const { setupDatabase } = require("../utils/setups/setupDatabase");
13
- const { configureDocker } = require("../utils/configs/configureDocker");
14
- const { setupBootstrapLogger } = require("../utils/setups/setupLogger");
3
+ const { runProjectSetupPipeline } = require("../utils/setups/projectSetup");
15
4
  const { logSuccess } = require("../utils/loggers/logSuccess");
16
5
  const { logInfo } = require("../utils/loggers/logInfo");
17
6
  const { logError } = require("../utils/loggers/logError");
18
- const { generateEnvFile, writeEnvFile } = require("../utils/envGenerator");
19
7
  const readline = require("readline-sync");
20
8
  const { info, warning } = require("../utils/colors");
21
9
  const { logWarning } = require("../utils/loggers/logWarning");
22
- const { saveProjectConfig } = require("../utils/file-utils/saveProjectConfig");
23
10
 
24
11
  async function newCommand(projectName, flags = {}) {
25
12
  if (!projectName) {
@@ -96,11 +83,10 @@ async function buildFullModeInputs(projectName, flags) {
96
83
  }
97
84
 
98
85
  function hasAllLightModeFlags(flags) {
99
- // Logique interne, pas de traduction nécessaire
100
- if (!flags.interactive || flags.interactive === false) {
86
+ if (flags.interactive === true) {
101
87
  return false;
102
88
  }
103
- return true;
89
+ return flags.orm !== undefined;
104
90
  }
105
91
 
106
92
  function buildLightModeFromFlags(projectName, flags) {
@@ -166,11 +152,10 @@ function buildLightModeFromFlags(projectName, flags) {
166
152
  }
167
153
 
168
154
  function hasAllFullModeFlags(flags) {
169
- // Logique interne, pas de traduction nécessaire
170
- if (!flags.interactive || flags.interactive === false) {
155
+ if (flags.interactive === true) {
171
156
  return false;
172
157
  }
173
- return true;
158
+ return flags.orm !== undefined;
174
159
  }
175
160
 
176
161
  function buildFullModeFromFlags(projectName, flags) {
@@ -241,37 +226,9 @@ function buildFullModeFromFlags(projectName, flags) {
241
226
 
242
227
  async function executeProjectSetup(inputs) {
243
228
  try {
244
- logInfo("Starting project generation...");
245
-
246
- await createProject(inputs);
247
-
248
- if (inputs.mode === "light") {
249
- await setupLightArchitecture(inputs);
250
- } else {
251
- await setupCleanArchitecture(inputs);
252
- }
253
-
254
- if (inputs.useAuth) await setupAuth(inputs);
255
-
256
- if (inputs.useSwagger) {
257
- await setupSwagger(inputs.swaggerInputs);
258
- } else {
259
- setupBootstrapLogger();
260
- }
261
-
262
- if (inputs.useDocker) await configureDocker(inputs);
263
-
264
- await setupDatabase(inputs);
265
-
266
- const envContent = await generateEnvFile(inputs);
267
- writeEnvFile(envContent);
268
-
269
- await saveProjectConfig(inputs);
270
-
229
+ await runProjectSetupPipeline(inputs);
271
230
  printSuccessSummary(inputs);
272
231
  } catch (error) {
273
- // Erreur lors de la creation du projet: ${error.message}
274
- logError(`Error during project creation: ${error.message}`);
275
232
  throw error;
276
233
  }
277
234
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestcraftx",
3
- "version": "0.2.6",
3
+ "version": "0.4.0",
4
4
  "description": "Modern CLI to generate scalable NestJS projects with Clean Architecture (FULL) and MVP mode (LIGHT) - Enhanced with auto-generated .env secrets, complete ORM support, and entity relations",
5
5
  "main": "bin/nestcraft.js",
6
6
  "bin": {
@@ -0,0 +1,102 @@
1
+ /**
2
+ * utils/app-module.updater.js
3
+ *
4
+ * Gestion de la mise à jour sécurisée du fichier app.module.ts.
5
+ * Extrait de userInput.js pour isoler cette responsabilité spécifique.
6
+ *
7
+ * Les fichiers qui importent `safeUpdateAppModule` depuis userInput.js
8
+ * continuent de fonctionner sans modification grâce aux ré-exports.
9
+ */
10
+
11
+ const fs = require("fs");
12
+ const { updateFile } = require("./file-system");
13
+ const { logInfo } = require("./loggers/logInfo");
14
+ const { capitalize } = require("./helpers");
15
+
16
+ /**
17
+ * Ajoute un module NestJS dans le fichier `src/app.module.ts` de manière idempotente.
18
+ *
19
+ * - Ajoute la ligne `import { XModule } from 'src/x/x.module'` si absente
20
+ * - Ajoute `XModule` dans le tableau `imports: []` du décorateur @Module si absent
21
+ * - Utilise un parsing par comptage de crochets pour gérer les imports imbriqués
22
+ * (ex: ConfigModule.forRoot({ ... }))
23
+ *
24
+ * @param {string} entity - Le nom de l'entité en minuscule (ex: "user", "post")
25
+ */
26
+ async function safeUpdateAppModule(entity) {
27
+ const isDryRun = process.argv.includes("--dry-run");
28
+ if (isDryRun) {
29
+ console.log(`[DRY-RUN] Simulated: safe update app.module.ts with ${capitalize(entity)}Module`);
30
+ return;
31
+ }
32
+
33
+ const filePath = "src/app.module.ts";
34
+ const moduleName = `${capitalize(entity)}Module`;
35
+ const importLine = `import { ${moduleName} } from 'src/${entity}/${entity}.module';`;
36
+
37
+ let content = fs.readFileSync(filePath, "utf-8");
38
+
39
+ // Étape 1 : Ajout de l'import en haut du fichier si nécessaire
40
+ if (!content.includes(importLine)) {
41
+ const importMarker = `import { ConfigModule } from '@nestjs/config';`;
42
+
43
+ if (content.includes(importMarker)) {
44
+ await updateFile({
45
+ path: filePath,
46
+ pattern: importMarker,
47
+ replacement: `${importMarker}\n${importLine}`,
48
+ });
49
+ content = fs.readFileSync(filePath, "utf-8");
50
+ } else {
51
+ logInfo(
52
+ " Impossible de trouver le point d'insertion de l'import (ConfigModule manquant)",
53
+ );
54
+ }
55
+ }
56
+
57
+ // Étape 2 : Vérifier le bloc des imports du @Module avec gestion des crochets imbriqués
58
+ const importsHeaderMatch = content.match(/imports:\s*\[/);
59
+ if (!importsHeaderMatch) {
60
+ logInfo(" Impossible de trouver le bloc 'imports' dans AppModule.");
61
+ return;
62
+ }
63
+
64
+ const startIndex =
65
+ importsHeaderMatch.index + importsHeaderMatch[0].length - 1; // index du '['
66
+ let depth = 1;
67
+ let endIndex = -1;
68
+ for (let i = startIndex + 1; i < content.length; i++) {
69
+ if (content[i] === "[") {
70
+ depth++;
71
+ } else if (content[i] === "]") {
72
+ depth--;
73
+ if (depth === 0) {
74
+ endIndex = i;
75
+ break;
76
+ }
77
+ }
78
+ }
79
+
80
+ if (endIndex === -1) {
81
+ logInfo(
82
+ " Impossible de trouver le crochet de fermeture du bloc 'imports' dans AppModule.",
83
+ );
84
+ return;
85
+ }
86
+
87
+ const currentImportsBlock = content.substring(startIndex + 1, endIndex);
88
+ const isAlreadyImportedInModule = currentImportsBlock.includes(moduleName);
89
+
90
+ if (!isAlreadyImportedInModule) {
91
+ const updatedBlock = currentImportsBlock.trim().endsWith(",")
92
+ ? `${currentImportsBlock.trim()} ${moduleName},`
93
+ : `${currentImportsBlock.trim()}, ${moduleName},`;
94
+
95
+ const beforeBlock = content.substring(0, startIndex + 1);
96
+ const afterBlock = content.substring(endIndex);
97
+ const newContent = beforeBlock + updatedBlock + afterBlock;
98
+ fs.writeFileSync(filePath, newContent, "utf-8");
99
+ }
100
+ }
101
+
102
+ module.exports = { safeUpdateAppModule };