@arc-js/config-manager 0.0.1
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 +608 -0
- package/config.d.ts +13 -0
- package/config.js +913 -0
- package/config.min.js +2 -0
- package/core/ConfigurationService.d.ts +33 -0
- package/core/ConfigurationService.js +1154 -0
- package/core/ConfigurationService.min.js +2 -0
- package/core/types.d.ts +27 -0
- package/core/types.js +1 -0
- package/core/types.min.js +2 -0
- package/hooks/useConfig.d.ts +29 -0
- package/hooks/useConfig.js +3178 -0
- package/hooks/useConfig.min.js +2 -0
- package/index.d.ts +34 -0
- package/index.js +3455 -0
- package/index.min.js +2 -0
- package/package.json +27 -0
- package/providers/ConfigProvider.jsx +57 -0
- package/providers/ConfigProvider.tsx +64 -0
- package/tsconfig.json +27 -0
- package/utils/loaders.d.ts +5 -0
- package/utils/loaders.js +985 -0
- package/utils/loaders.min.js +2 -0
- package/utils/mergeConfigs.d.ts +3 -0
- package/utils/mergeConfigs.js +23 -0
- package/utils/mergeConfigs.min.js +2 -0
- package/utils.d.ts +3 -0
- package/utils.js +901 -0
- package/utils.min.js +2 -0
- package/vite.config.ts +12 -0
package/README.md
ADDED
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
# @arc-js/config-manager
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
**@arc-js/config-manager** est un système de gestion de configuration modulaire pour les applications React avec TypeScript/JavaScript. Il fournit une gestion centralisée des configurations, un chargement dynamique des modules, et une intégration transparente avec les variables d'environnement.
|
|
9
|
+
|
|
10
|
+
## ✨ Fonctionnalités Principales
|
|
11
|
+
|
|
12
|
+
### ⚙️ Gestion Modulaire des Configurations
|
|
13
|
+
- **Configurations hiérarchiques** avec fusion intelligente
|
|
14
|
+
- **Chargement dynamique** des fichiers de configuration
|
|
15
|
+
- **Support des modules indépendants** avec isolation
|
|
16
|
+
- **Héritage automatique** de la configuration globale
|
|
17
|
+
|
|
18
|
+
### 🔌 Intégration Environnement
|
|
19
|
+
- **Variables d'environnement** automatiquement chargées (module `ENV`)
|
|
20
|
+
- **Support Vite et Node.js** (process.env)
|
|
21
|
+
- **Typage fort** pour les configurations
|
|
22
|
+
- **Validation des chemins** avec fallback sécurisé
|
|
23
|
+
|
|
24
|
+
### 🚀 Performance Optimisée
|
|
25
|
+
- **Chargement paresseux** des configurations
|
|
26
|
+
- **Cache mémoire** pour les accès répétés
|
|
27
|
+
- **Hot reload** pendant le développement
|
|
28
|
+
- **Minimal bundle size**
|
|
29
|
+
|
|
30
|
+
### 🛡️ Sécurité et Fiabilité
|
|
31
|
+
- **Gestion des erreurs** avec valeurs par défaut
|
|
32
|
+
- **Validation des chemins** avant accès
|
|
33
|
+
- **Logs en mode développement** uniquement
|
|
34
|
+
- **Types TypeScript complets**
|
|
35
|
+
|
|
36
|
+
## 📦 Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install @arc-js/config-manager
|
|
40
|
+
# ou
|
|
41
|
+
yarn add @arc-js/config-manager
|
|
42
|
+
# ou
|
|
43
|
+
pnpm add @arc-js/config-manager
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Dépendances requises
|
|
47
|
+
- React 19+
|
|
48
|
+
- TypeScript 5.0+ (recommandé)
|
|
49
|
+
- Vite (pour le chargement dynamique)
|
|
50
|
+
|
|
51
|
+
## 🚀 Démarrage Rapide
|
|
52
|
+
|
|
53
|
+
### Structure de projet recommandée
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
src/
|
|
57
|
+
├── config.json # Configuration globale
|
|
58
|
+
├── modules/
|
|
59
|
+
│ ├── admin/
|
|
60
|
+
│ │ └── config.json # Configuration du module admin
|
|
61
|
+
│ ├── dashboard/
|
|
62
|
+
│ │ └── config.json # Configuration du module dashboard
|
|
63
|
+
│ └── api/
|
|
64
|
+
│ └── config.json # Configuration du module API
|
|
65
|
+
└── main.tsx
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Configuration de base
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
// src/config.json (Configuration globale)
|
|
72
|
+
{
|
|
73
|
+
"app": {
|
|
74
|
+
"name": "Mon Application",
|
|
75
|
+
"version": "1.0.0",
|
|
76
|
+
"debug": false,
|
|
77
|
+
"features": {
|
|
78
|
+
"analytics": true,
|
|
79
|
+
"notifications": false
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"api": {
|
|
83
|
+
"baseUrl": "https://api.example.com",
|
|
84
|
+
"timeout": 30000,
|
|
85
|
+
"retryAttempts": 3
|
|
86
|
+
},
|
|
87
|
+
"ui": {
|
|
88
|
+
"theme": "light",
|
|
89
|
+
"language": "fr"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
// src/modules/admin/config.json (Module admin)
|
|
96
|
+
{
|
|
97
|
+
"app": {
|
|
98
|
+
"name": "Admin Panel", // Écrase le nom global pour ce module
|
|
99
|
+
"debug": true // Surcharge le debug global
|
|
100
|
+
},
|
|
101
|
+
"admin": {
|
|
102
|
+
"permissions": ["users:read", "users:write", "settings:manage"],
|
|
103
|
+
"dashboard": {
|
|
104
|
+
"refreshInterval": 5000,
|
|
105
|
+
"maxItems": 100
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Utilisation de base
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// main.tsx
|
|
115
|
+
import React from 'react';
|
|
116
|
+
import ReactDOM from 'react-dom/client';
|
|
117
|
+
import { ConfigProvider } from '@arc-js/config-manager';
|
|
118
|
+
|
|
119
|
+
const App = () => {
|
|
120
|
+
return (
|
|
121
|
+
<div>
|
|
122
|
+
<h1>Mon Application Configurée</h1>
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
128
|
+
<React.StrictMode>
|
|
129
|
+
<ConfigProvider preloadModules={['admin', 'dashboard']}>
|
|
130
|
+
<App />
|
|
131
|
+
</ConfigProvider>
|
|
132
|
+
</React.StrictMode>
|
|
133
|
+
);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## 📚 Documentation API
|
|
137
|
+
|
|
138
|
+
### Hook useConfig
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { useConfig } from '@arc-js/config-manager';
|
|
142
|
+
|
|
143
|
+
const MyComponent = () => {
|
|
144
|
+
const config = useConfig('admin'); // Optionnel: nom du module
|
|
145
|
+
|
|
146
|
+
// Récupérer une valeur avec chemin pointé
|
|
147
|
+
const appName = config.get('app.name');
|
|
148
|
+
const apiTimeout = config.get('api.timeout');
|
|
149
|
+
|
|
150
|
+
// Récupérer avec valeur par défaut
|
|
151
|
+
const debugMode = config.get('app.debug', { defaultValue: false });
|
|
152
|
+
|
|
153
|
+
// Récupérer ou lancer une exception si non trouvé
|
|
154
|
+
const baseUrl = config.getOrThrow('api.baseUrl');
|
|
155
|
+
|
|
156
|
+
// Vérifier l'existence d'un chemin
|
|
157
|
+
const hasAnalytics = config.has('app.features.analytics');
|
|
158
|
+
|
|
159
|
+
// Récupérer toutes les configurations
|
|
160
|
+
const allConfigs = config.getAll();
|
|
161
|
+
|
|
162
|
+
// Accès aux variables d'environnement
|
|
163
|
+
const nodeEnv = config.getEnv('NODE_ENV');
|
|
164
|
+
const apiUrl = config.getEnv('apiUrl'); // VITE_API_URL
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<div>
|
|
168
|
+
<h1>{appName}</h1>
|
|
169
|
+
<p>API Timeout: {apiTimeout}ms</p>
|
|
170
|
+
<p>Environment: {nodeEnv}</p>
|
|
171
|
+
</div>
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Hook useConfigValue (Typé)
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { useConfigValue } from '@arc-js/config-manager';
|
|
180
|
+
|
|
181
|
+
const FeatureToggle = () => {
|
|
182
|
+
const { value: isEnabled, isLoading, exists } =
|
|
183
|
+
useConfigValue<boolean>('app.features.analytics', {
|
|
184
|
+
moduleName: 'admin',
|
|
185
|
+
defaultValue: false
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
if (isLoading) return <div>Chargement...</div>;
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<div>
|
|
192
|
+
<p>Analytics: {isEnabled ? 'Activé' : 'Désactivé'}</p>
|
|
193
|
+
<p>Configuration existante: {exists ? 'Oui' : 'Non'}</p>
|
|
194
|
+
</div>
|
|
195
|
+
);
|
|
196
|
+
};
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Modifier une configuration
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
const SettingsPanel = () => {
|
|
203
|
+
const config = useConfig();
|
|
204
|
+
|
|
205
|
+
const toggleDebug = () => {
|
|
206
|
+
const currentDebug = config.get('app.debug', { defaultValue: false });
|
|
207
|
+
config.set('app.debug', !currentDebug);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const updateApiConfig = () => {
|
|
211
|
+
config.merge({
|
|
212
|
+
api: {
|
|
213
|
+
timeout: 60000,
|
|
214
|
+
retryAttempts: 5
|
|
215
|
+
}
|
|
216
|
+
}, 'admin'); // Appliquer uniquement au module admin
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
<div>
|
|
221
|
+
<button onClick={toggleDebug}>
|
|
222
|
+
Toggle Debug Mode
|
|
223
|
+
</button>
|
|
224
|
+
<button onClick={updateApiConfig}>
|
|
225
|
+
Update API Settings
|
|
226
|
+
</button>
|
|
227
|
+
</div>
|
|
228
|
+
);
|
|
229
|
+
};
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 🔧 Utilisation Avancée
|
|
233
|
+
|
|
234
|
+
### Variables d'environnement
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# .env
|
|
238
|
+
VITE_API_URL=https://api.example.com
|
|
239
|
+
VITE_APP_NAME="My App"
|
|
240
|
+
VITE_DEBUG=true
|
|
241
|
+
NODE_ENV=development
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
const EnvironmentInfo = () => {
|
|
246
|
+
const config = useConfig();
|
|
247
|
+
|
|
248
|
+
// Accès aux variables VITE_*
|
|
249
|
+
const apiUrl = config.getEnv('apiUrl'); // VITE_API_URL
|
|
250
|
+
const appName = config.getEnv('appName'); // VITE_APP_NAME
|
|
251
|
+
|
|
252
|
+
// Ou via le module ENV
|
|
253
|
+
const viteApiUrl = config.get('apiUrl', { moduleName: 'ENV' });
|
|
254
|
+
|
|
255
|
+
// Vérifier l'environnement
|
|
256
|
+
const isProd = config.isProduction();
|
|
257
|
+
const isDev = config.isDevelopment();
|
|
258
|
+
const isTest = config.isTest();
|
|
259
|
+
|
|
260
|
+
return (
|
|
261
|
+
<div>
|
|
262
|
+
<h2>Environment Configuration</h2>
|
|
263
|
+
<p>API URL: {apiUrl}</p>
|
|
264
|
+
<p>App Name: {appName}</p>
|
|
265
|
+
<p>Mode: {isProd ? 'Production' : isDev ? 'Development' : 'Test'}</p>
|
|
266
|
+
</div>
|
|
267
|
+
);
|
|
268
|
+
};
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Configuration hiérarchique complexe
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
// src/modules/complex/config.json
|
|
275
|
+
{
|
|
276
|
+
"database": {
|
|
277
|
+
"connections": {
|
|
278
|
+
"primary": {
|
|
279
|
+
"host": "localhost",
|
|
280
|
+
"port": 5432,
|
|
281
|
+
"credentials": {
|
|
282
|
+
"username": "admin",
|
|
283
|
+
"password": "secret"
|
|
284
|
+
},
|
|
285
|
+
"options": {
|
|
286
|
+
"ssl": true,
|
|
287
|
+
"pool": {
|
|
288
|
+
"max": 20,
|
|
289
|
+
"min": 5,
|
|
290
|
+
"idleTimeout": 30000
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
"replica": {
|
|
295
|
+
"host": "replica.local",
|
|
296
|
+
"port": 5432
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
const DatabaseConfig = () => {
|
|
305
|
+
const config = useConfig('complex');
|
|
306
|
+
|
|
307
|
+
// Accès aux chemins profonds
|
|
308
|
+
const primaryHost = config.get('database.connections.primary.host');
|
|
309
|
+
const poolMax = config.get('database.connections.primary.options.pool.max');
|
|
310
|
+
const sslEnabled = config.get('database.connections.primary.options.ssl');
|
|
311
|
+
|
|
312
|
+
// Utilisation avec tableau de chemin
|
|
313
|
+
const credentials = config.get(['database', 'connections', 'primary', 'credentials']);
|
|
314
|
+
|
|
315
|
+
return (
|
|
316
|
+
<div>
|
|
317
|
+
<h3>Database Configuration</h3>
|
|
318
|
+
<p>Primary Host: {primaryHost}</p>
|
|
319
|
+
<p>Max Pool Connections: {poolMax}</p>
|
|
320
|
+
<p>SSL: {sslEnabled ? 'Enabled' : 'Disabled'}</p>
|
|
321
|
+
<pre>{JSON.stringify(credentials, null, 2)}</pre>
|
|
322
|
+
</div>
|
|
323
|
+
);
|
|
324
|
+
};
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## 🎯 Exemples Complets
|
|
328
|
+
|
|
329
|
+
### Exemple 1 : Configuration d'API avec fallback
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
import { useConfig } from '@arc-js/config-manager';
|
|
333
|
+
|
|
334
|
+
const ApiClient = () => {
|
|
335
|
+
const config = useConfig();
|
|
336
|
+
|
|
337
|
+
const getApiConfig = () => {
|
|
338
|
+
// Utiliser l'URL de l'ENV si disponible, sinon la config globale
|
|
339
|
+
const baseUrl = config.getEnv('apiUrl') ||
|
|
340
|
+
config.get('api.baseUrl', {
|
|
341
|
+
defaultValue: 'http://localhost:3000'
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
const timeout = config.get('api.timeout', { defaultValue: 30000 });
|
|
345
|
+
const retryAttempts = config.get('api.retryAttempts', { defaultValue: 3 });
|
|
346
|
+
|
|
347
|
+
return { baseUrl, timeout, retryAttempts };
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
const fetchData = async () => {
|
|
351
|
+
const { baseUrl, timeout } = getApiConfig();
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
const response = await fetch(`\${baseUrl}/data`, {
|
|
355
|
+
timeout,
|
|
356
|
+
headers: {
|
|
357
|
+
'Content-Type': 'application/json'
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
return await response.json();
|
|
362
|
+
} catch (error) {
|
|
363
|
+
console.error('API Error:', error);
|
|
364
|
+
throw error;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
return (
|
|
369
|
+
<div>
|
|
370
|
+
<button onClick={fetchData}>
|
|
371
|
+
Fetch Data
|
|
372
|
+
</button>
|
|
373
|
+
</div>
|
|
374
|
+
);
|
|
375
|
+
};
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Exemple 2 : Feature flags modulaires
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
import { useConfigValue } from '@arc-js/config-manager';
|
|
382
|
+
|
|
383
|
+
const FeatureComponent = ({ featureName, moduleName }: {
|
|
384
|
+
featureName: string,
|
|
385
|
+
moduleName?: string
|
|
386
|
+
}) => {
|
|
387
|
+
const { value: isEnabled, isLoading } = useConfigValue<boolean>(
|
|
388
|
+
`features.\${featureName}`,
|
|
389
|
+
{
|
|
390
|
+
moduleName,
|
|
391
|
+
defaultValue: false
|
|
392
|
+
}
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
if (isLoading) return <div>Loading feature...</div>;
|
|
396
|
+
if (!isEnabled) return null;
|
|
397
|
+
|
|
398
|
+
return (
|
|
399
|
+
<div className={`feature \${featureName}`}>
|
|
400
|
+
<h3>Feature: {featureName}</h3>
|
|
401
|
+
{/* Contenu de la feature */}
|
|
402
|
+
</div>
|
|
403
|
+
);
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
// Utilisation
|
|
407
|
+
const AppFeatures = () => {
|
|
408
|
+
return (
|
|
409
|
+
<div>
|
|
410
|
+
<FeatureComponent featureName="analytics" moduleName="admin" />
|
|
411
|
+
<FeatureComponent featureName="darkMode" />
|
|
412
|
+
<FeatureComponent featureName="experimental" moduleName="dashboard" />
|
|
413
|
+
</div>
|
|
414
|
+
);
|
|
415
|
+
};
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Exemple 3 : Configuration dynamique avec React Query
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
import { useQuery } from '@tanstack/react-query';
|
|
422
|
+
import { useConfig } from '@arc-js/config-manager';
|
|
423
|
+
|
|
424
|
+
const ConfigBasedQuery = () => {
|
|
425
|
+
const config = useConfig('admin');
|
|
426
|
+
|
|
427
|
+
const { data, isLoading, error } = useQuery({
|
|
428
|
+
queryKey: ['users', 'list'],
|
|
429
|
+
queryFn: async () => {
|
|
430
|
+
const baseUrl = config.getOrThrow('api.baseUrl');
|
|
431
|
+
const pageSize = config.get('pagination.pageSize', { defaultValue: 20 });
|
|
432
|
+
|
|
433
|
+
const response = await fetch(
|
|
434
|
+
`\${baseUrl}/users?limit=\${pageSize}`
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
if (!response.ok) throw new Error('Failed to fetch');
|
|
438
|
+
return response.json();
|
|
439
|
+
},
|
|
440
|
+
// Utiliser la config pour les options de requête
|
|
441
|
+
retry: config.get('api.retryAttempts', { defaultValue: 3 }),
|
|
442
|
+
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
|
|
443
|
+
enabled: config.get('features.dataFetching', { defaultValue: true })
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
if (isLoading) return <div>Loading...</div>;
|
|
447
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
448
|
+
|
|
449
|
+
return (
|
|
450
|
+
<div>
|
|
451
|
+
<h2>Users</h2>
|
|
452
|
+
<ul>
|
|
453
|
+
{data?.users?.map(user => (
|
|
454
|
+
<li key={user.id}>{user.name}</li>
|
|
455
|
+
))}
|
|
456
|
+
</ul>
|
|
457
|
+
</div>
|
|
458
|
+
);
|
|
459
|
+
};
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
## 🔧 Configuration Avancée
|
|
463
|
+
|
|
464
|
+
### Configuration Vite
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
// vite.config.ts
|
|
468
|
+
import { defineConfig } from 'vite';
|
|
469
|
+
import react from '@vitejs/plugin-react';
|
|
470
|
+
|
|
471
|
+
export default defineConfig({
|
|
472
|
+
plugins: [react()],
|
|
473
|
+
define: {
|
|
474
|
+
// Exposer les variables d'environnement
|
|
475
|
+
'import.meta.env': process.env
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Configuration TypeScript
|
|
481
|
+
|
|
482
|
+
```json
|
|
483
|
+
{
|
|
484
|
+
"compilerOptions": {
|
|
485
|
+
"target": "ES2020",
|
|
486
|
+
"lib": ["DOM", "DOM.Iterable", "ES2020"],
|
|
487
|
+
"module": "ESNext",
|
|
488
|
+
"moduleResolution": "bundler",
|
|
489
|
+
"allowImportingTsExtensions": true,
|
|
490
|
+
"resolveJsonModule": true,
|
|
491
|
+
"isolatedModules": true,
|
|
492
|
+
"noEmit": true,
|
|
493
|
+
"jsx": "react-jsx",
|
|
494
|
+
"strict": true,
|
|
495
|
+
"types": ["vite/client"]
|
|
496
|
+
},
|
|
497
|
+
"include": ["src", "node_modules/@arc-js/config-manager/**/*"]
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Scripts de validation
|
|
502
|
+
|
|
503
|
+
```json
|
|
504
|
+
{
|
|
505
|
+
"scripts": {
|
|
506
|
+
"validate-config": "node scripts/validate-config.js",
|
|
507
|
+
"generate-config-schema": "node scripts/generate-schema.js",
|
|
508
|
+
"check-env": "node scripts/check-environment.js"
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
## 📋 Table des Conventions
|
|
514
|
+
|
|
515
|
+
### Chemins de configuration
|
|
516
|
+
|
|
517
|
+
| Type | Format | Exemple |
|
|
518
|
+
|------|--------|---------|
|
|
519
|
+
| Pointé | `parent.child.grandchild` | `app.features.analytics` |
|
|
520
|
+
| Tableau | `['parent', 'child', 'grandchild']` | `['api', 'baseUrl']` |
|
|
521
|
+
| Mixte | Supporté | `app.features[0].name` |
|
|
522
|
+
|
|
523
|
+
### Fichiers de configuration
|
|
524
|
+
|
|
525
|
+
| Chemin | Portée | Priorité |
|
|
526
|
+
|--------|--------|----------|
|
|
527
|
+
| `src/config.json` | Globale | Base |
|
|
528
|
+
| `src/modules/*/config.json` | Module | Écrase la globale |
|
|
529
|
+
| `.env` / Variables | Environnement | Écrase tout |
|
|
530
|
+
|
|
531
|
+
### Variables d'environnement
|
|
532
|
+
|
|
533
|
+
| Variable | Conversion | Accès |
|
|
534
|
+
|----------|------------|-------|
|
|
535
|
+
| `VITE_API_URL` | `apiUrl` | `config.getEnv('apiUrl')` |
|
|
536
|
+
| `VITE_APP_NAME` | `appName` | `config.get('appName', {moduleName: 'ENV'})` |
|
|
537
|
+
| `NODE_ENV` | `nodeEnv` | `config.getEnv('NODE_ENV')` |
|
|
538
|
+
|
|
539
|
+
## 🛡️ Gestion des Erreurs
|
|
540
|
+
|
|
541
|
+
### Fallback et validation
|
|
542
|
+
|
|
543
|
+
```typescript
|
|
544
|
+
const SafeConfigAccess = () => {
|
|
545
|
+
const config = useConfig();
|
|
546
|
+
|
|
547
|
+
try {
|
|
548
|
+
// Cette méthode lève une exception si le chemin n'existe pas
|
|
549
|
+
const requiredValue = config.getOrThrow('required.path', 'admin');
|
|
550
|
+
|
|
551
|
+
return (
|
|
552
|
+
<div>
|
|
553
|
+
<p>Value: {requiredValue}</p>
|
|
554
|
+
</div>
|
|
555
|
+
);
|
|
556
|
+
} catch (error) {
|
|
557
|
+
return (
|
|
558
|
+
<div className="error">
|
|
559
|
+
<p>Configuration error: {(error as Error).message}</p>
|
|
560
|
+
<p>Using fallback configuration...</p>
|
|
561
|
+
</div>
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### Logs en développement
|
|
568
|
+
|
|
569
|
+
```typescript
|
|
570
|
+
// Le service loggue automatiquement en mode développement
|
|
571
|
+
const DebugConfig = () => {
|
|
572
|
+
const config = useConfig();
|
|
573
|
+
const isDev = config.isDevelopment();
|
|
574
|
+
|
|
575
|
+
if (isDev) {
|
|
576
|
+
// Afficher toute la configuration en dev
|
|
577
|
+
console.log('Current Configuration:', config.getAll());
|
|
578
|
+
|
|
579
|
+
// Vérifier les chemins manquants
|
|
580
|
+
const missingPaths = ['app.name', 'api.baseUrl', 'unknown.path'];
|
|
581
|
+
missingPaths.forEach(path => {
|
|
582
|
+
if (!config.has(path)) {
|
|
583
|
+
console.warn(`Missing config path: \${path}`);
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
return null;
|
|
589
|
+
};
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## 📄 Licence
|
|
593
|
+
|
|
594
|
+
MIT License - Voir le fichier [LICENSE](LICENSE) pour plus de détails.
|
|
595
|
+
|
|
596
|
+
## 🐛 Signaler un Bug
|
|
597
|
+
|
|
598
|
+
Envoyez-nous un mail à l'adresse `contact.inicode@gmail.com` pour :
|
|
599
|
+
- Signaler un bug
|
|
600
|
+
- Proposer une amélioration
|
|
601
|
+
- Poser une question sur l'utilisation
|
|
602
|
+
- Demander une nouvelle fonctionnalité
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
**@arc-js/config-manager** - Le système de configuration modulaire pour React et TypeScript.
|
|
607
|
+
|
|
608
|
+
*Développé par l'équipe INICODE*
|
package/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare const DEFAULT_LOCALE = "en";
|
|
2
|
+
declare const SUPPORTED_LOCALES: string[];
|
|
3
|
+
declare const COOKIE_NAME = "app_locale";
|
|
4
|
+
type Locale = typeof SUPPORTED_LOCALES[number];
|
|
5
|
+
declare const getSavedLocale: (supportedLocales?: string[]) => string;
|
|
6
|
+
declare const saveLocale: (locale: string) => void;
|
|
7
|
+
declare const PATH_CONFIG: {
|
|
8
|
+
SRC_DIR: string;
|
|
9
|
+
};
|
|
10
|
+
declare const SRC_DIR: string;
|
|
11
|
+
|
|
12
|
+
export { COOKIE_NAME, DEFAULT_LOCALE, PATH_CONFIG, SRC_DIR, SUPPORTED_LOCALES, getSavedLocale, saveLocale };
|
|
13
|
+
export type { Locale };
|