@jsarc/initiator 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +440 -0
- package/config.ts +153 -0
- package/index.ts +13 -0
- package/intl.ts +353 -0
- package/js/config.js +110 -0
- package/js/index.js +10 -0
- package/js/intl.js +274 -0
- package/js/provider.js +323 -0
- package/js/routing.js +473 -0
- package/package.json +20 -0
- package/provider.ts +423 -0
- package/tsconfig.json +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
# @jsarc/initiator
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
**@jsarc/initiator** est un plugin d'initialisation intelligent pour les applications React avec TypeScript/Javascript. Il génère automatiquement les fichiers de configuration, de routage et d'internationalisation basés sur la structure de votre projet.
|
|
9
|
+
|
|
10
|
+
## ✨ Fonctionnalités Principales
|
|
11
|
+
|
|
12
|
+
### 🗺️ Génération Automatique
|
|
13
|
+
- **Génération automatique des routes** à partir de la structure du système de fichiers
|
|
14
|
+
- **Configuration modulaire** avec détection automatique des modules
|
|
15
|
+
- **Internationalisation automatisée** avec extraction des clés de traduction
|
|
16
|
+
- **Fichiers de configuration** générés dynamiquement
|
|
17
|
+
|
|
18
|
+
### ⚙️ Initialisation Intelligente
|
|
19
|
+
- **Détection automatique** des fichiers de pages et modules
|
|
20
|
+
- **Génération de fichiers TypeScript** typesafe
|
|
21
|
+
- **Support des layouts hiérarchiques** avec héritage automatique
|
|
22
|
+
- **Configuration minimale** requise
|
|
23
|
+
|
|
24
|
+
### 📁 Structure de Projet
|
|
25
|
+
- **Organisation modulaire** naturelle
|
|
26
|
+
- **Support des pages spéciales** (layout, error, 404)
|
|
27
|
+
- **Routes dynamiques** avec paramètres
|
|
28
|
+
- **Modules indépendants** avec leur propre configuration
|
|
29
|
+
|
|
30
|
+
## 📦 Installation
|
|
31
|
+
|
|
32
|
+
### Installation globale (recommandée)
|
|
33
|
+
```bash
|
|
34
|
+
npm install -g @jsarc/initiator
|
|
35
|
+
# ou
|
|
36
|
+
yarn global add @jsarc/initiator
|
|
37
|
+
# ou
|
|
38
|
+
pnpm add -g @jsarc/initiator
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Installation locale
|
|
42
|
+
```bash
|
|
43
|
+
npm install @jsarc/initiator
|
|
44
|
+
# ou
|
|
45
|
+
yarn add @jsarc/initiator
|
|
46
|
+
# ou
|
|
47
|
+
pnpm add @jsarc/initiator
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 🚀 Utilisation Rapide
|
|
51
|
+
|
|
52
|
+
### Commande de base
|
|
53
|
+
```bash
|
|
54
|
+
# Depuis la racine de votre projet
|
|
55
|
+
arc-init
|
|
56
|
+
# ou
|
|
57
|
+
npx @jsarc/initiator
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Options disponibles
|
|
61
|
+
```bash
|
|
62
|
+
# Initialiser avec un répertoire spécifique
|
|
63
|
+
arc-init --dir ./mon-projet
|
|
64
|
+
|
|
65
|
+
# Forcer la régénération des fichiers
|
|
66
|
+
arc-init --force
|
|
67
|
+
|
|
68
|
+
# Mode silencieux (moins de logs)
|
|
69
|
+
arc-init --quiet
|
|
70
|
+
|
|
71
|
+
# Afficher l'aide
|
|
72
|
+
arc-init --help
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Structure de projet générée
|
|
76
|
+
```
|
|
77
|
+
src/
|
|
78
|
+
├── auto-config.ts # Configuration générée
|
|
79
|
+
├── auto-intl.ts # Internationalisation générée
|
|
80
|
+
├── auto-routes.tsx # Routes générées
|
|
81
|
+
├── config.json # Configuration racine
|
|
82
|
+
├── locales/
|
|
83
|
+
│ ├── en.json # Traductions anglais
|
|
84
|
+
│ └── fr.json # Traductions français
|
|
85
|
+
├── pages/
|
|
86
|
+
│ ├── _layout.tsx # Layout racine
|
|
87
|
+
│ ├── _error.tsx # Page d'erreur
|
|
88
|
+
│ ├── _404.tsx # Page 404
|
|
89
|
+
│ └── index.tsx # Page d'accueil
|
|
90
|
+
└── modules/
|
|
91
|
+
└── example/
|
|
92
|
+
├── config.json # Configuration du module
|
|
93
|
+
├── locales/
|
|
94
|
+
│ ├── en.json # Traductions module
|
|
95
|
+
│ └── fr.json # Traductions module
|
|
96
|
+
└── pages/
|
|
97
|
+
└── index.tsx # Page du module
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 🔧 Fonctionnalités Détaillées
|
|
101
|
+
|
|
102
|
+
### 1. Génération de Routes
|
|
103
|
+
Le plugin scanne automatiquement vos dossiers `pages/` et `modules/*/pages/` pour :
|
|
104
|
+
- **Créer des routes React Router** automatiquement
|
|
105
|
+
- **Gérer les layouts hiérarchiques**
|
|
106
|
+
- **Supporter les pages d'erreur spécifiques**
|
|
107
|
+
- **Générer des composants lazy-loaded**
|
|
108
|
+
|
|
109
|
+
### 2. Internationalisation
|
|
110
|
+
Extraction automatique des clés de traduction :
|
|
111
|
+
- **Scan des fichiers source** pour les appels `t()`
|
|
112
|
+
- **Détection des modules** avec fichiers de traduction
|
|
113
|
+
- **Génération des imports dynamiques**
|
|
114
|
+
- **Support multi-langue**
|
|
115
|
+
|
|
116
|
+
### 3. Configuration
|
|
117
|
+
Génération centralisée de configuration :
|
|
118
|
+
- **Configuration racine** depuis `config.json`
|
|
119
|
+
- **Configuration des modules** depuis `modules/*/config.json`
|
|
120
|
+
- **Fichier TypeScript** avec imports dynamiques
|
|
121
|
+
|
|
122
|
+
## 📚 API du Plugin
|
|
123
|
+
|
|
124
|
+
### Fonction principale
|
|
125
|
+
```typescript
|
|
126
|
+
import init from '@jsarc/initiator';
|
|
127
|
+
|
|
128
|
+
// Initialisation par défaut (utilise __dirname)
|
|
129
|
+
init();
|
|
130
|
+
|
|
131
|
+
// Avec répertoire personnalisé
|
|
132
|
+
init('/chemin/vers/mon/projet');
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Classes exportées
|
|
136
|
+
```typescript
|
|
137
|
+
import {
|
|
138
|
+
TranslationGenerator,
|
|
139
|
+
RouteGenerator,
|
|
140
|
+
ConfigGenerator
|
|
141
|
+
} from '@jsarc/initiator';
|
|
142
|
+
|
|
143
|
+
// Utilisation avancée
|
|
144
|
+
const translationGen = new TranslationGenerator(config);
|
|
145
|
+
const routeGen = new RouteGenerator(config);
|
|
146
|
+
const configGen = new ConfigGenerator(config);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Interfaces TypeScript
|
|
150
|
+
```typescript
|
|
151
|
+
import type {
|
|
152
|
+
TranslationConfig,
|
|
153
|
+
RouteConfig,
|
|
154
|
+
ConfigGeneratorOptions,
|
|
155
|
+
TranslationKey,
|
|
156
|
+
RouteFile
|
|
157
|
+
} from '@jsarc/initiator';
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 🎯 Exemples d'Utilisation
|
|
161
|
+
|
|
162
|
+
### Exemple 1 : Script d'initialisation
|
|
163
|
+
```javascript
|
|
164
|
+
// scripts/init.js
|
|
165
|
+
import init from '@jsarc/initiator';
|
|
166
|
+
|
|
167
|
+
// Initialiser avec le répertoire du projet
|
|
168
|
+
init(process.cwd());
|
|
169
|
+
|
|
170
|
+
console.log('✅ Initialisation terminée !');
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Exemple 2 : Personnalisation avancée
|
|
174
|
+
```typescript
|
|
175
|
+
// scripts/custom-init.ts
|
|
176
|
+
import { RouteGenerator } from '@jsarc/initiator';
|
|
177
|
+
|
|
178
|
+
const customConfig = {
|
|
179
|
+
srcDir: './src',
|
|
180
|
+
modulesDir: './src/modules',
|
|
181
|
+
pagesDir: './src/views', // Dossier personnalisé
|
|
182
|
+
outputFile: './src/generated/routes.tsx',
|
|
183
|
+
layoutFileName: 'layout',
|
|
184
|
+
errorFileName: 'error-page',
|
|
185
|
+
notFoundFileName: 'not-found-page'
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const generator = new RouteGenerator(customConfig);
|
|
189
|
+
await generator.generate();
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Exemple 3 : Intégration avec un build personnalisé
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"scripts": {
|
|
196
|
+
"dev": "vite",
|
|
197
|
+
"build": "npm run generate && vite build",
|
|
198
|
+
"generate": "node scripts/generate-all.js",
|
|
199
|
+
"generate:routes": "node scripts/generate-routes.js",
|
|
200
|
+
"generate:intl": "node scripts/generate-intl.js",
|
|
201
|
+
"generate:config": "node scripts/generate-config.js"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## 🔧 Configuration Avancée
|
|
207
|
+
|
|
208
|
+
### Configuration de la traduction
|
|
209
|
+
```typescript
|
|
210
|
+
const translationConfig = {
|
|
211
|
+
srcDir: './src',
|
|
212
|
+
supportedLocales: ['en', 'fr', 'es'], // Langues supportées
|
|
213
|
+
outputFile: './src/auto-intl.ts',
|
|
214
|
+
modulesDir: './src/modules',
|
|
215
|
+
localesDir: './src/locales'
|
|
216
|
+
};
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Configuration du routage
|
|
220
|
+
```typescript
|
|
221
|
+
const routeConfig = {
|
|
222
|
+
srcDir: './src',
|
|
223
|
+
modulesDir: './src/modules',
|
|
224
|
+
pagesDir: './src/pages', // Ou 'views', 'screens', etc.
|
|
225
|
+
outputFile: './src/auto-routes.tsx',
|
|
226
|
+
layoutFileName: '_layout', // Fichier de layout
|
|
227
|
+
errorFileName: '_error', // Fichier d'erreur
|
|
228
|
+
notFoundFileName: '_404' // Fichier 404
|
|
229
|
+
};
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Fichier config.json racine
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"name": "Mon Application",
|
|
236
|
+
"version": "1.0.0",
|
|
237
|
+
"description": "Description de l'application",
|
|
238
|
+
"author": "Votre Nom",
|
|
239
|
+
"defaultLocale": "fr",
|
|
240
|
+
"supportedLocales": ["fr", "en"],
|
|
241
|
+
"apiUrl": "https://api.example.com",
|
|
242
|
+
"features": {
|
|
243
|
+
"auth": true,
|
|
244
|
+
"analytics": false,
|
|
245
|
+
"pwa": true
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Fichier config.json de module
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"name": "Module Admin",
|
|
254
|
+
"description": "Module d'administration",
|
|
255
|
+
"author": "Équipe Admin",
|
|
256
|
+
"version": "1.0.0",
|
|
257
|
+
"routePrefix": "/admin",
|
|
258
|
+
"isEnabled": true,
|
|
259
|
+
"dependencies": ["auth"],
|
|
260
|
+
"permissions": ["admin", "superuser"]
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## 📁 Conventions de Fichiers
|
|
265
|
+
|
|
266
|
+
### Pages spéciales
|
|
267
|
+
| Fichier | Description | Route générée |
|
|
268
|
+
|---------|-------------|---------------|
|
|
269
|
+
| `_layout.tsx` | Layout du dossier | Non accessible directement |
|
|
270
|
+
| `_error.tsx` | Page d'erreur | Utilisée comme errorElement |
|
|
271
|
+
| `_404.tsx` | Page non trouvée | Route catch-all |
|
|
272
|
+
| `[param].tsx` | Route paramétrée | `/:param` |
|
|
273
|
+
| `[...slug].tsx` | Route catch-all | `/*` |
|
|
274
|
+
| `index.tsx` | Page d'index | `/` ou `/dossier/` |
|
|
275
|
+
|
|
276
|
+
### Structure de module
|
|
277
|
+
```
|
|
278
|
+
modules/
|
|
279
|
+
└── nom-du-module/
|
|
280
|
+
├── config.json # Configuration du module
|
|
281
|
+
├── locales/ # Traductions du module
|
|
282
|
+
│ ├── en.json
|
|
283
|
+
│ └── fr.json
|
|
284
|
+
├── pages/ # Pages du module
|
|
285
|
+
│ ├── _layout.tsx # Layout du module
|
|
286
|
+
│ ├── _error.tsx # Erreur du module
|
|
287
|
+
│ ├── _404.tsx # 404 du module
|
|
288
|
+
│ └── index.tsx # Page d'accueil du module
|
|
289
|
+
└── components/ # Composants du module (optionnel)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## 🔄 Workflow de Développement
|
|
293
|
+
|
|
294
|
+
### 1. Initialisation du projet
|
|
295
|
+
```bash
|
|
296
|
+
# Créer un nouveau projet
|
|
297
|
+
npm create vite@latest mon-app -- --template react-ts
|
|
298
|
+
cd mon-app
|
|
299
|
+
|
|
300
|
+
# Installer l'initiator
|
|
301
|
+
npm install @jsarc/initiator
|
|
302
|
+
|
|
303
|
+
# Générer la structure initiale
|
|
304
|
+
npx @jsarc/initiator
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### 2. Ajout d'un nouveau module
|
|
308
|
+
```bash
|
|
309
|
+
# Créer la structure du module
|
|
310
|
+
mkdir -p src/modules/admin/{locales,pages,components}
|
|
311
|
+
|
|
312
|
+
# Ajouter les fichiers de base
|
|
313
|
+
touch src/modules/admin/config.json
|
|
314
|
+
touch src/modules/admin/pages/index.tsx
|
|
315
|
+
touch src/modules/admin/locales/fr.json
|
|
316
|
+
|
|
317
|
+
# Régénérer les fichiers
|
|
318
|
+
npx @jsarc/initiator
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### 3. Développement avec hot-reload
|
|
322
|
+
```bash
|
|
323
|
+
# Démarrer le serveur de développement
|
|
324
|
+
npm run dev
|
|
325
|
+
|
|
326
|
+
# Dans un autre terminal, surveiller les changements
|
|
327
|
+
npx @jsarc/initiator --watch
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## 🛠️ Intégration avec d'autres outils
|
|
331
|
+
|
|
332
|
+
### Avec Vite
|
|
333
|
+
```javascript
|
|
334
|
+
// vite.config.js
|
|
335
|
+
import { defineConfig } from 'vite';
|
|
336
|
+
import react from '@vitejs/plugin-react';
|
|
337
|
+
|
|
338
|
+
export default defineConfig({
|
|
339
|
+
plugins: [react()],
|
|
340
|
+
build: {
|
|
341
|
+
rollupOptions: {
|
|
342
|
+
external: ['@jsarc/initiator']
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Avec Next.js (Adaptation)
|
|
349
|
+
```javascript
|
|
350
|
+
// next.config.js
|
|
351
|
+
const { generateRoutes } = require('@jsarc/initiator/adapters/next');
|
|
352
|
+
|
|
353
|
+
module.exports = {
|
|
354
|
+
async rewrites() {
|
|
355
|
+
const routes = await generateRoutes();
|
|
356
|
+
return routes.map(route => ({
|
|
357
|
+
source: route.path,
|
|
358
|
+
destination: route.filePath
|
|
359
|
+
}));
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Avec Webpack
|
|
365
|
+
```javascript
|
|
366
|
+
// webpack.config.js
|
|
367
|
+
const { GenerateRoutesPlugin } = require('@jsarc/initiator/webpack');
|
|
368
|
+
|
|
369
|
+
module.exports = {
|
|
370
|
+
plugins: [
|
|
371
|
+
new GenerateRoutesPlugin({
|
|
372
|
+
watch: process.env.NODE_ENV === 'development'
|
|
373
|
+
})
|
|
374
|
+
]
|
|
375
|
+
};
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## 🐛 Dépannage
|
|
379
|
+
|
|
380
|
+
### Problèmes courants
|
|
381
|
+
|
|
382
|
+
1. **"Cannot find module"**
|
|
383
|
+
```bash
|
|
384
|
+
# Réinstaller le plugin
|
|
385
|
+
npm install @jsarc/initiator
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
2. **Fichiers non générés**
|
|
389
|
+
```bash
|
|
390
|
+
# Forcer la régénération
|
|
391
|
+
npx @jsarc/initiator --force
|
|
392
|
+
|
|
393
|
+
# Vérifier les permissions
|
|
394
|
+
chmod +x node_modules/.bin/arc-init
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
3. **Erreurs TypeScript**
|
|
398
|
+
```bash
|
|
399
|
+
# Vérifier les types
|
|
400
|
+
npm run type-check
|
|
401
|
+
|
|
402
|
+
# Régénérer les fichiers
|
|
403
|
+
npx @jsarc/initiator
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Logs de débogage
|
|
407
|
+
```bash
|
|
408
|
+
# Activer les logs détaillés
|
|
409
|
+
DEBUG=jsarc:* npx @jsarc/initiator
|
|
410
|
+
|
|
411
|
+
# Sauvegarder les logs dans un fichier
|
|
412
|
+
npx @jsarc/initiator 2>&1 | tee init.log
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## 📄 Licence
|
|
416
|
+
|
|
417
|
+
MIT License - Voir le fichier [LICENSE](LICENSE) pour plus de détails.
|
|
418
|
+
|
|
419
|
+
## 🤝 Contribution
|
|
420
|
+
|
|
421
|
+
Les contributions sont les bienvenues ! Pour contribuer :
|
|
422
|
+
|
|
423
|
+
1. Fork le projet
|
|
424
|
+
2. Créer une branche (`git checkout -b feature/amazing-feature`)
|
|
425
|
+
3. Commit vos changements (`git commit -m 'Add amazing feature'`)
|
|
426
|
+
4. Push vers la branche (`git push origin feature/amazing-feature`)
|
|
427
|
+
5. Ouvrir une Pull Request
|
|
428
|
+
|
|
429
|
+
## 🐛 Signaler un Bug
|
|
430
|
+
|
|
431
|
+
Envoyez nous un mail à l'adresse `contact.inicode@gmail.com` pour :
|
|
432
|
+
- Signaler un bug
|
|
433
|
+
- Proposer une amélioration
|
|
434
|
+
- Poser une question
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
**@jsarc/initiator** - Le plugin d'initialisation intelligent pour React et TypeScript.
|
|
439
|
+
|
|
440
|
+
*Développé par l'équipe INICODE*
|
package/config.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { Pajo } from '@jsarc/pajo';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
export interface ConfigGeneratorOptions {
|
|
10
|
+
srcDir: string;
|
|
11
|
+
outputFile: string;
|
|
12
|
+
modulesDir: string;
|
|
13
|
+
rootConfigPath: string;
|
|
14
|
+
projectRoot: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class ConfigGenerator {
|
|
18
|
+
private config: ConfigGeneratorOptions;
|
|
19
|
+
private modules: Set<string> = new Set();
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
config: Partial<ConfigGeneratorOptions> = {},
|
|
23
|
+
dirname: string | undefined = __dirname,
|
|
24
|
+
) {
|
|
25
|
+
this.config = {
|
|
26
|
+
srcDir: config.srcDir || Pajo.join(dirname, 'src') || '',
|
|
27
|
+
outputFile: config.outputFile || Pajo.join(dirname, 'src\\auto-config.ts') || '',
|
|
28
|
+
modulesDir: config.modulesDir || Pajo.join(dirname, 'src\\modules') || '',
|
|
29
|
+
rootConfigPath: config.rootConfigPath || Pajo.join(dirname, 'src\\config.json') || '',
|
|
30
|
+
projectRoot: config.projectRoot || dirname || ''
|
|
31
|
+
};
|
|
32
|
+
console.log(`--> ConfigGenerator config:: `, this.config);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public async generate(): Promise<void> {
|
|
36
|
+
console.log('🔍 Scanning for configuration files...');
|
|
37
|
+
|
|
38
|
+
await this.discoverModules();
|
|
39
|
+
|
|
40
|
+
await this.generateAutoConfigFile();
|
|
41
|
+
|
|
42
|
+
console.log(`✅ Generated ${this.config.outputFile}`);
|
|
43
|
+
console.log(`📦 Found modules with config: ${Array.from(this.modules).join(', ')}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private async discoverModules(): Promise<void> {
|
|
47
|
+
try {
|
|
48
|
+
|
|
49
|
+
if (!fs.existsSync(this.config.modulesDir)) {
|
|
50
|
+
console.log(`⚠️ Modules directory not found: ${this.config.modulesDir}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const moduleDirs = fs.readdirSync(this.config.modulesDir, { withFileTypes: true })
|
|
55
|
+
.filter(dirent => dirent.isDirectory())
|
|
56
|
+
.map(dirent => dirent.name);
|
|
57
|
+
|
|
58
|
+
for (const moduleName of moduleDirs) {
|
|
59
|
+
const configPath = path.join(this.config.modulesDir, moduleName, 'config.json');
|
|
60
|
+
|
|
61
|
+
if (fs.existsSync(configPath)) {
|
|
62
|
+
this.modules.add(moduleName);
|
|
63
|
+
console.log(`📁 Found config for module: ${moduleName}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error('Error discovering modules:', error);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private async generateAutoConfigFile(): Promise<void> {
|
|
72
|
+
const outputDir = path.dirname(this.config.outputFile);
|
|
73
|
+
|
|
74
|
+
if (!fs.existsSync(outputDir)) {
|
|
75
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const content = this.generateFileContent();
|
|
79
|
+
fs.writeFileSync(this.config.outputFile, content, 'utf-8');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private getRelativeImportPath(targetPath: string): string {
|
|
83
|
+
|
|
84
|
+
const outputDir = path.dirname(this.config.outputFile);
|
|
85
|
+
const relative = path.relative(outputDir, targetPath);
|
|
86
|
+
|
|
87
|
+
let importPath = relative.replace(/\\/g, '/');
|
|
88
|
+
|
|
89
|
+
if (!importPath.startsWith('.') && !importPath.startsWith('/')) {
|
|
90
|
+
importPath = './' + importPath;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return importPath;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private generateFileContent(): string {
|
|
97
|
+
const { rootConfigPath, modulesDir } = this.config;
|
|
98
|
+
|
|
99
|
+
const sortedModules = Array.from(this.modules).sort();
|
|
100
|
+
|
|
101
|
+
const rootConfigExists = fs.existsSync(rootConfigPath);
|
|
102
|
+
console.log(`📄 Root config exists: ${rootConfigExists} at ${rootConfigPath}`);
|
|
103
|
+
|
|
104
|
+
const baseImportPath = rootConfigExists
|
|
105
|
+
? this.getRelativeImportPath(rootConfigPath)
|
|
106
|
+
: null;
|
|
107
|
+
|
|
108
|
+
const baseConfig = rootConfigExists && baseImportPath
|
|
109
|
+
? ` 'app': (() => import('${baseImportPath}').then(module => module.default || module))`
|
|
110
|
+
: ` 'app': (() => Promise.resolve({}))`;
|
|
111
|
+
|
|
112
|
+
const modulesImports = sortedModules.map(moduleName => {
|
|
113
|
+
const configPath = path.join(modulesDir, moduleName, 'config.json');
|
|
114
|
+
const configExists = fs.existsSync(configPath);
|
|
115
|
+
|
|
116
|
+
if (configExists) {
|
|
117
|
+
const importPath = this.getRelativeImportPath(configPath);
|
|
118
|
+
console.log(`📄 Module ${moduleName} config: ${configPath} -> ${importPath}`);
|
|
119
|
+
return ` '${moduleName}': (() => import('${importPath}').then(module => module.default || module))`;
|
|
120
|
+
} else {
|
|
121
|
+
console.log(`⚠️ Module ${moduleName} config not found: ${configPath}`);
|
|
122
|
+
return ` '${moduleName}': (() => Promise.resolve({}))`;
|
|
123
|
+
}
|
|
124
|
+
}).join(',\n');
|
|
125
|
+
|
|
126
|
+
return `export const configs = {
|
|
127
|
+
'base': {
|
|
128
|
+
${baseConfig}
|
|
129
|
+
},
|
|
130
|
+
'modules': {
|
|
131
|
+
${modulesImports.length > 0 ? modulesImports : ' // No modules with config.json found'}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export default configs;`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function ConfigInitiator(
|
|
140
|
+
dirname: string | undefined = __dirname
|
|
141
|
+
) {
|
|
142
|
+
const config: Partial<ConfigGeneratorOptions> = {};
|
|
143
|
+
|
|
144
|
+
const generator = new ConfigGenerator(config, dirname);
|
|
145
|
+
|
|
146
|
+
generator.generate().then(() => {
|
|
147
|
+
console.log('🎉 Config generation completed successfully!');
|
|
148
|
+
}).catch((err) => {
|
|
149
|
+
console.error('❌ Failed to generate config: ', err);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export default ConfigInitiator;
|
package/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import TranslationInitiator from './intl';
|
|
2
|
+
import ConfigInitiator from './config';
|
|
3
|
+
import RouteInitiator from './routing';
|
|
4
|
+
import ProviderInitiator from './provider';
|
|
5
|
+
|
|
6
|
+
export default function(
|
|
7
|
+
dirname: string = __dirname
|
|
8
|
+
) {
|
|
9
|
+
TranslationInitiator(dirname);
|
|
10
|
+
ConfigInitiator(dirname);
|
|
11
|
+
RouteInitiator(dirname);
|
|
12
|
+
ProviderInitiator(dirname);
|
|
13
|
+
}
|