@bloomneo/appkit 1.5.1 โ†’ 1.5.2

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 (111) hide show
  1. package/AGENTS.md +195 -0
  2. package/CHANGELOG.md +253 -0
  3. package/README.md +147 -799
  4. package/bin/commands/generate.js +7 -7
  5. package/cookbook/README.md +26 -0
  6. package/cookbook/api-key-service.ts +106 -0
  7. package/cookbook/auth-protected-crud.ts +112 -0
  8. package/cookbook/file-upload-pipeline.ts +113 -0
  9. package/cookbook/multi-tenant-saas.ts +87 -0
  10. package/cookbook/real-time-chat.ts +121 -0
  11. package/dist/auth/auth.d.ts +21 -4
  12. package/dist/auth/auth.d.ts.map +1 -1
  13. package/dist/auth/auth.js +56 -44
  14. package/dist/auth/auth.js.map +1 -1
  15. package/dist/auth/defaults.d.ts +1 -1
  16. package/dist/auth/defaults.js +35 -35
  17. package/dist/cache/cache.d.ts +29 -6
  18. package/dist/cache/cache.d.ts.map +1 -1
  19. package/dist/cache/cache.js +72 -44
  20. package/dist/cache/cache.js.map +1 -1
  21. package/dist/cache/defaults.js +25 -25
  22. package/dist/cache/index.d.ts +19 -10
  23. package/dist/cache/index.d.ts.map +1 -1
  24. package/dist/cache/index.js +21 -18
  25. package/dist/cache/index.js.map +1 -1
  26. package/dist/config/defaults.d.ts +1 -1
  27. package/dist/config/defaults.js +8 -8
  28. package/dist/config/index.d.ts +3 -3
  29. package/dist/config/index.js +4 -4
  30. package/dist/database/adapters/mongoose.js +2 -2
  31. package/dist/database/adapters/prisma.js +2 -2
  32. package/dist/database/defaults.d.ts +1 -1
  33. package/dist/database/defaults.js +4 -4
  34. package/dist/database/index.js +2 -2
  35. package/dist/database/index.js.map +1 -1
  36. package/dist/email/defaults.js +20 -20
  37. package/dist/error/defaults.d.ts +1 -1
  38. package/dist/error/defaults.js +12 -12
  39. package/dist/error/error.d.ts +12 -0
  40. package/dist/error/error.d.ts.map +1 -1
  41. package/dist/error/error.js +19 -0
  42. package/dist/error/error.js.map +1 -1
  43. package/dist/error/index.d.ts +14 -3
  44. package/dist/error/index.d.ts.map +1 -1
  45. package/dist/error/index.js +14 -3
  46. package/dist/error/index.js.map +1 -1
  47. package/dist/event/defaults.js +30 -30
  48. package/dist/logger/defaults.d.ts +1 -1
  49. package/dist/logger/defaults.js +40 -40
  50. package/dist/logger/index.d.ts +1 -0
  51. package/dist/logger/index.d.ts.map +1 -1
  52. package/dist/logger/index.js.map +1 -1
  53. package/dist/logger/logger.d.ts +8 -0
  54. package/dist/logger/logger.d.ts.map +1 -1
  55. package/dist/logger/logger.js +13 -3
  56. package/dist/logger/logger.js.map +1 -1
  57. package/dist/logger/transports/console.js +1 -1
  58. package/dist/logger/transports/http.d.ts +1 -1
  59. package/dist/logger/transports/http.js +1 -1
  60. package/dist/logger/transports/webhook.d.ts +1 -1
  61. package/dist/logger/transports/webhook.js +1 -1
  62. package/dist/queue/defaults.d.ts +2 -2
  63. package/dist/queue/defaults.js +38 -38
  64. package/dist/security/defaults.d.ts +1 -1
  65. package/dist/security/defaults.js +29 -29
  66. package/dist/security/index.d.ts +1 -1
  67. package/dist/security/index.js +3 -3
  68. package/dist/security/security.d.ts +1 -1
  69. package/dist/security/security.js +4 -4
  70. package/dist/storage/defaults.js +19 -19
  71. package/dist/util/defaults.d.ts +1 -1
  72. package/dist/util/defaults.js +34 -34
  73. package/dist/util/env.d.ts +35 -0
  74. package/dist/util/env.d.ts.map +1 -0
  75. package/dist/util/env.js +50 -0
  76. package/dist/util/env.js.map +1 -0
  77. package/dist/util/errors.d.ts +52 -0
  78. package/dist/util/errors.d.ts.map +1 -0
  79. package/dist/util/errors.js +82 -0
  80. package/dist/util/errors.js.map +1 -0
  81. package/examples/.env.example +80 -0
  82. package/examples/README.md +16 -0
  83. package/examples/auth.ts +228 -0
  84. package/examples/cache.ts +36 -0
  85. package/examples/config.ts +45 -0
  86. package/examples/database.ts +69 -0
  87. package/examples/email.ts +53 -0
  88. package/examples/error.ts +50 -0
  89. package/examples/event.ts +42 -0
  90. package/examples/logger.ts +41 -0
  91. package/examples/queue.ts +58 -0
  92. package/examples/security.ts +46 -0
  93. package/examples/storage.ts +44 -0
  94. package/examples/util.ts +47 -0
  95. package/llms.txt +591 -0
  96. package/package.json +19 -10
  97. package/src/auth/README.md +850 -0
  98. package/src/cache/README.md +756 -0
  99. package/src/config/README.md +604 -0
  100. package/src/database/README.md +818 -0
  101. package/src/email/README.md +759 -0
  102. package/src/error/README.md +660 -0
  103. package/src/event/README.md +729 -0
  104. package/src/logger/README.md +435 -0
  105. package/src/queue/README.md +851 -0
  106. package/src/security/README.md +612 -0
  107. package/src/storage/README.md +1008 -0
  108. package/src/util/README.md +955 -0
  109. package/bin/templates/backend/docs/APPKIT_CLI.md +0 -507
  110. package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +0 -61
  111. package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +0 -2539
@@ -0,0 +1,604 @@
1
+ # @bloomneo/appkit - Config Module โš™๏ธ
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@bloomneo/appkit.svg)](https://www.npmjs.com/package/@bloomneo/appkit)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ > Ultra-simple, convention-driven configuration management that just works
7
+
8
+ **One function** returns a config object with automatic environment variable
9
+ parsing. Zero configuration files needed, production-ready validation by
10
+ default, with built-in type conversion and smart defaults.
11
+
12
+ ## ๐Ÿš€ Why Choose This?
13
+
14
+ - **โšก One Function** - Just `configClass.get()`, everything else is automatic
15
+ - **๐Ÿ”ฉ UPPER_SNAKE_CASE Convention** - `DATABASE_HOST` becomes
16
+ `config.get('database.host')`
17
+ - **๐Ÿ”ง Zero Configuration** - No config files, no setup, just environment
18
+ variables
19
+ - **๐Ÿ›ก๏ธ Type-Safe** - Automatic conversion: `"true"` โ†’ `true`, `"123"` โ†’ `123`
20
+ - **๐ŸŒ Environment-First** - Perfect compatibility with Docker, Vercel, Railway,
21
+ etc.
22
+ - **๐Ÿ” Production Validation** - Validates critical config at startup
23
+ - **๐Ÿค– AI-Ready** - Optimized for LLM code generation
24
+
25
+ ## ๐Ÿ“ฆ Installation
26
+
27
+ ```bash
28
+ npm install @bloomneo/appkit
29
+ ```
30
+
31
+ ## ๐Ÿƒโ€โ™‚๏ธ Quick Start (30 seconds)
32
+
33
+ ### 1. Set Environment Variables
34
+
35
+ ```bash
36
+ # Database settings
37
+ DATABASE_HOST=localhost
38
+ DATABASE_PORT=5432
39
+ DATABASE_CREDENTIALS_USER=admin
40
+ DATABASE_CREDENTIALS_PASSWORD=secret
41
+
42
+ # Feature flags
43
+ FEATURES_ENABLE_BETA=true
44
+ FEATURES_MAX_UPLOADS=100
45
+
46
+ # API settings
47
+ API_BASE_URL=https://api.example.com
48
+ API_TIMEOUT=30000
49
+ API_RATE_LIMIT=1000
50
+ ```
51
+
52
+ ### 2. Use in Your Code
53
+
54
+ ```typescript
55
+ import { configClass } from '@bloomneo/appkit/config';
56
+
57
+ const config = configClass.get();
58
+
59
+ // Access nested values with dot notation (all properly typed!)
60
+ const dbHost = config.get('database.host'); // 'localhost'
61
+ const dbPort = config.get('database.port'); // 5432 (number!)
62
+ const dbUser = config.get('database.credentials.user'); // 'admin'
63
+ const isBeta = config.get('features.enable_beta'); // true (boolean!)
64
+ const maxUploads = config.get('features.max_uploads'); // 100 (number!)
65
+
66
+ // Get with defaults
67
+ const timeout = config.get('redis.timeout', 5000); // 5000 if not set
68
+ const retries = config.get('api.retries', 3); // 3 if not set
69
+
70
+ // Check if config exists
71
+ if (config.has('features.enable_beta')) {
72
+ console.log('Beta features are configured');
73
+ }
74
+
75
+ console.log(`Connecting to ${dbUser}@${dbHost}:${dbPort}`);
76
+ ```
77
+
78
+ **That's it!** All your environment variables are available in a clean,
79
+ structured, and type-safe object.
80
+
81
+ ## ๐Ÿง  Mental Model
82
+
83
+ ### **The UPPER_SNAKE_CASE Convention**
84
+
85
+ Single underscores create nesting:
86
+
87
+ ```bash
88
+ # Environment Variable โ†’ Config Path
89
+ DATABASE_HOST=localhost โ†’ config.get('database.host')
90
+ DATABASE_CONNECTION_POOL_SIZE=10 โ†’ config.get('database.connection.pool_size')
91
+ STRIPE_API_KEYS_PUBLIC=pk_test_123 โ†’ config.get('stripe.api.keys.public')
92
+ FEATURES_ANALYTICS_ENABLED=true โ†’ config.get('features.analytics.enabled')
93
+ ```
94
+
95
+ ### **Framework vs Application Variables**
96
+
97
+ ```bash
98
+ # ๐Ÿ”ง Framework Configuration (BLOOM_* prefix)
99
+ BLOOM_AUTH_SECRET=jwt-secret-key # AppKit auth module
100
+ BLOOM_ERROR_STACK=false # AppKit error module
101
+ BLOOM_SERVICE_NAME=my-app # AppKit service identification
102
+
103
+ # ๐ŸŽฏ Application Configuration (everything else)
104
+ DATABASE_HOST=localhost # Your database connection
105
+ API_TIMEOUT=5000 # Your API client settings
106
+ FEATURES_BETA_ENABLED=true # Your feature flags
107
+ ```
108
+
109
+ ### **Automatic Type Conversion**
110
+
111
+ No manual parsing needed:
112
+
113
+ ```bash
114
+ # String values
115
+ API_BASE_URL=https://api.com โ†’ "https://api.com"
116
+
117
+ # Number values
118
+ DATABASE_PORT=5432 โ†’ 5432
119
+ API_TIMEOUT=30000 โ†’ 30000
120
+
121
+ # Boolean values
122
+ FEATURES_ENABLE_BETA=true โ†’ true
123
+ DEBUG_VERBOSE=false โ†’ false
124
+
125
+ # Special handling
126
+ USER_ID=0123456789 โ†’ "0123456789" (keeps leading zero)
127
+ ```
128
+
129
+ ## ๐Ÿค– LLM Quick Reference - Copy These Patterns
130
+
131
+ ### **Environment Variable Setup (Copy Exactly)**
132
+
133
+ ```bash
134
+ # โœ… CORRECT - Framework variables
135
+ BLOOM_AUTH_SECRET=your-secret-key
136
+ BLOOM_SERVICE_NAME=my-app
137
+ NODE_ENV=production
138
+
139
+ # โœ… CORRECT - Application variables
140
+ DATABASE_HOST=localhost
141
+ DATABASE_PORT=5432
142
+ REDIS_URL=redis://localhost:6379
143
+ FEATURES_ANALYTICS_ENABLED=true
144
+ API_TIMEOUT=30000
145
+ ```
146
+
147
+ ### **Configuration Access (Copy These Patterns)**
148
+
149
+ ```typescript
150
+ // โœ… CORRECT - Basic access with defaults
151
+ const config = configClass.get();
152
+ const dbHost = config.get('database.host', 'localhost');
153
+ const dbPort = config.get<number>('database.port', 5432);
154
+ const isEnabled = config.get<boolean>('features.analytics.enabled', false);
155
+
156
+ // โœ… CORRECT - Required configuration
157
+ const apiKey = config.getRequired<string>('api.key');
158
+ const dbUrl = config.getRequired<string>('database.url');
159
+
160
+ // โœ… CORRECT - Environment checks
161
+ if (configClass.isProduction()) {
162
+ // Production-specific code
163
+ }
164
+
165
+ // โœ… CORRECT - Module configuration
166
+ const dbConfig = configClass.getModuleConfig('database', {
167
+ host: 'localhost',
168
+ port: 5432,
169
+ });
170
+ ```
171
+
172
+ ### **Startup Validation (Copy This Pattern)**
173
+
174
+ ```typescript
175
+ // โœ… CORRECT - App startup validation
176
+ try {
177
+ const config = configClass.get();
178
+
179
+ // Validate required configuration
180
+ configClass.validateRequired(['database.url', 'api.key']);
181
+
182
+ console.log('โœ… Configuration validation passed');
183
+ } catch (error) {
184
+ console.error('โŒ Configuration validation failed:', error.message);
185
+ process.exit(1);
186
+ }
187
+ ```
188
+
189
+ ## โš ๏ธ Common LLM Mistakes - Avoid These
190
+
191
+ ### **Wrong Environment Variable Format**
192
+
193
+ ```bash
194
+ # โŒ WRONG - Mixed conventions
195
+ database-host=localhost # Use underscores, not dashes
196
+ DATABASE__HOST=localhost # Don't use double underscores
197
+ database_host=localhost # Must be uppercase
198
+
199
+ # โœ… CORRECT - Use UPPER_SNAKE_CASE
200
+ DATABASE_HOST=localhost
201
+ ```
202
+
203
+ ### **Wrong Configuration Access**
204
+
205
+ ```typescript
206
+ // โŒ WRONG - Direct process.env access
207
+ const dbHost = process.env.DATABASE_HOST;
208
+ const port = parseInt(process.env.DATABASE_PORT || '5432');
209
+
210
+ // โœ… CORRECT - Use config system
211
+ const config = configClass.get();
212
+ const dbHost = config.get('database.host');
213
+ const port = config.get<number>('database.port', 5432);
214
+ ```
215
+
216
+ ### **Wrong Required Configuration Handling**
217
+
218
+ ```typescript
219
+ // โŒ WRONG - Manual fallbacks for critical config
220
+ const apiKey = config.get('api.key') || 'fallback-key';
221
+ const dbUrl = config.get('database.url') || 'postgres://localhost/db';
222
+
223
+ // โœ… CORRECT - Use getRequired for critical config
224
+ const apiKey = config.getRequired<string>('api.key');
225
+ const dbUrl = config.getRequired<string>('database.url');
226
+ ```
227
+
228
+ ## ๐Ÿšจ Error Handling Patterns
229
+
230
+ ### **Startup Validation**
231
+
232
+ ```typescript
233
+ import { configClass } from '@bloomneo/appkit/config';
234
+
235
+ // App startup validation
236
+ async function validateAppConfig() {
237
+ try {
238
+ const config = configClass.get();
239
+
240
+ // Validate required configuration
241
+ configClass.validateRequired(['database.url', 'redis.url', 'api.key']);
242
+
243
+ // Production-specific validation
244
+ if (configClass.isProduction()) {
245
+ configClass.validateRequired([
246
+ 'monitoring.sentry.dsn',
247
+ 'email.smtp.host',
248
+ ]);
249
+ }
250
+
251
+ console.log('โœ… Configuration validation passed');
252
+ } catch (error) {
253
+ console.error('โŒ Configuration validation failed:', error.message);
254
+ process.exit(1);
255
+ }
256
+ }
257
+
258
+ // Call at app startup
259
+ validateAppConfig();
260
+ ```
261
+
262
+ ### **Runtime Configuration Access**
263
+
264
+ ```typescript
265
+ // Safe configuration access with error handling
266
+ function getDatabaseConfig() {
267
+ const config = configClass.get();
268
+
269
+ try {
270
+ return {
271
+ host: config.getRequired<string>('database.host'),
272
+ port: config.get<number>('database.port', 5432),
273
+ ssl: config.get<boolean>('database.ssl.enabled', false),
274
+ };
275
+ } catch (error) {
276
+ throw new Error(`Database configuration error: ${error.message}`);
277
+ }
278
+ }
279
+ ```
280
+
281
+ ## ๐ŸŒ Environment Variables
282
+
283
+ ```bash
284
+ # Framework variables (handled by Bloomneo internally)
285
+ BLOOM_AUTH_SECRET=your-super-secure-jwt-secret-key
286
+ BLOOM_SERVICE_NAME=my-awesome-app
287
+ BLOOM_ERROR_STACK=false
288
+
289
+ # Application variables (your configuration)
290
+ DATABASE_HOST=localhost
291
+ DATABASE_PORT=5432
292
+ DATABASE_NAME=myapp
293
+ DATABASE_CREDENTIALS_USER=admin
294
+ DATABASE_CREDENTIALS_PASSWORD=secret
295
+ DATABASE_POOL_MIN=2
296
+ DATABASE_POOL_MAX=10
297
+ DATABASE_SSL_ENABLED=true
298
+
299
+ REDIS_URL=redis://localhost:6379
300
+ REDIS_TTL=3600
301
+ REDIS_MAX_RETRIES=3
302
+
303
+ STRIPE_API_KEYS_SECRET=sk_live_...
304
+ STRIPE_API_KEYS_PUBLIC=pk_live_...
305
+
306
+ FEATURES_ANALYTICS_ENABLED=true
307
+ FEATURES_BETA_UI_ENABLED=false
308
+ FEATURES_AI_SEARCH_ENABLED=true
309
+
310
+ API_BASE_URL=https://api.example.com
311
+ API_TIMEOUT=30000
312
+ API_RATE_LIMIT=1000
313
+ ```
314
+
315
+ ## ๐Ÿ“– Complete API Reference
316
+
317
+ ### **Core Function**
318
+
319
+ ```typescript
320
+ const config = configClass.get(); // One function, all methods
321
+ ```
322
+
323
+ ### **Configuration Access Methods**
324
+
325
+ ```typescript
326
+ // Get value with optional default
327
+ config.get<string>('database.host', 'localhost');
328
+ config.get<number>('database.port', 5432);
329
+ config.get<boolean>('features.enable_beta', false);
330
+
331
+ // Get required value (throws if missing)
332
+ config.getRequired<string>('database.url');
333
+
334
+ // Check if config exists
335
+ config.has('features.enable_beta'); // true/false
336
+
337
+ // Get multiple related values
338
+ config.getMany({
339
+ host: 'database.host',
340
+ port: 'database.port',
341
+ user: 'database.credentials.user',
342
+ }); // { host: '...', port: 5432, user: '...' }
343
+
344
+ // Get entire config (for debugging)
345
+ config.getAll(); // Complete config object
346
+ ```
347
+
348
+ ### **Environment Helper Methods**
349
+
350
+ ```typescript
351
+ // Environment detection
352
+ configClass.isDevelopment(); // NODE_ENV === 'development'
353
+ configClass.isProduction(); // NODE_ENV === 'production'
354
+ configClass.isTest(); // NODE_ENV === 'test'
355
+ configClass.getEnvironment(); // Current NODE_ENV value
356
+
357
+ // Module-specific configuration
358
+ configClass.getModuleConfig('database', {
359
+ host: 'localhost',
360
+ port: 5432,
361
+ }); // Gets all 'database.*' config with defaults
362
+
363
+ // Startup validation
364
+ configClass.validateRequired(['database.url', 'api.key']); // Throws with helpful errors if missing
365
+ ```
366
+
367
+ ### **Utility Methods**
368
+
369
+ ```typescript
370
+ // Get all non-framework environment variables
371
+ configClass.getEnvVars(); // { DATABASE_HOST: 'localhost', ... }
372
+
373
+ // Reset for testing
374
+ configClass.reset(customConfig); // Reset with custom config
375
+ configClass.clearCache(); // Clear cached config
376
+ ```
377
+
378
+ ## ๐ŸŽฏ Usage Examples
379
+
380
+ ### **Express Server Configuration**
381
+
382
+ ```typescript
383
+ import express from 'express';
384
+ import { configClass } from '@bloomneo/appkit/config';
385
+
386
+ const config = configClass.get();
387
+
388
+ const app = express();
389
+
390
+ // Get server configuration
391
+ const port = config.get('server.port', 3000);
392
+ const host = config.get('server.host', '0.0.0.0');
393
+ const cors = config.get('server.cors.enabled', true);
394
+
395
+ // Database configuration
396
+ const dbConfig = config.getMany({
397
+ host: 'database.host',
398
+ port: 'database.port',
399
+ name: 'database.name',
400
+ user: 'database.credentials.user',
401
+ password: 'database.credentials.password',
402
+ });
403
+
404
+ console.log(`Server starting on ${host}:${port}`);
405
+ console.log(
406
+ `Database: ${dbConfig.user}@${dbConfig.host}:${dbConfig.port}/${dbConfig.name}`
407
+ );
408
+
409
+ app.listen(port, host);
410
+ ```
411
+
412
+ **Environment Variables:**
413
+
414
+ ```bash
415
+ SERVER_PORT=3000
416
+ SERVER_HOST=0.0.0.0
417
+ SERVER_CORS_ENABLED=true
418
+ DATABASE_HOST=localhost
419
+ DATABASE_PORT=5432
420
+ DATABASE_NAME=myapp
421
+ DATABASE_CREDENTIALS_USER=admin
422
+ DATABASE_CREDENTIALS_PASSWORD=secret
423
+ ```
424
+
425
+ ### **Module-Specific Configuration**
426
+
427
+ ```typescript
428
+ // Database module
429
+ class DatabaseService {
430
+ constructor() {
431
+ const config = configClass.get();
432
+
433
+ // Get all database config with defaults
434
+ this.config = config.getModuleConfig('database', {
435
+ host: 'localhost',
436
+ port: 5432,
437
+ pool: { min: 2, max: 10 },
438
+ ssl: false,
439
+ });
440
+
441
+ // Validate required values
442
+ configClass.validateRequired([
443
+ 'database.credentials.user',
444
+ 'database.credentials.password',
445
+ ]);
446
+ }
447
+
448
+ connect() {
449
+ const { host, port, credentials, ssl } = this.config;
450
+ console.log(
451
+ `Connecting to ${credentials.user}@${host}:${port} (SSL: ${ssl})`
452
+ );
453
+ }
454
+ }
455
+ ```
456
+
457
+ **Environment Variables:**
458
+
459
+ ```bash
460
+ DATABASE_HOST=db.example.com
461
+ DATABASE_PORT=5432
462
+ DATABASE_CREDENTIALS_USER=app_user
463
+ DATABASE_CREDENTIALS_PASSWORD=secure_password
464
+ DATABASE_POOL_MIN=2
465
+ DATABASE_POOL_MAX=10
466
+ DATABASE_SSL=true
467
+ ```
468
+
469
+ ## ๐Ÿš€ Production Deployment
470
+
471
+ ### **Environment Configuration**
472
+
473
+ ```bash
474
+ # โœ… Framework variables
475
+ BLOOM_SERVICE_NAME=my-production-app
476
+ NODE_ENV=production
477
+
478
+ # โœ… Application variables
479
+ DATABASE_HOST=prod-db.example.com
480
+ DATABASE_PORT=5432
481
+ DATABASE_CREDENTIALS_USER=prod_user
482
+ DATABASE_CREDENTIALS_PASSWORD=secure_prod_password
483
+ DATABASE_SSL_ENABLED=true
484
+
485
+ REDIS_URL=redis://prod-redis.example.com:6379
486
+ API_TIMEOUT=30000
487
+ FEATURES_ANALYTICS_ENABLED=true
488
+ ```
489
+
490
+ ### **Docker Setup**
491
+
492
+ ```dockerfile
493
+ # Dockerfile
494
+ FROM node:18-alpine
495
+
496
+ WORKDIR /app
497
+ COPY package*.json ./
498
+ RUN npm ci --only=production
499
+
500
+ COPY . .
501
+
502
+ CMD ["npm", "start"]
503
+ ```
504
+
505
+ ```bash
506
+ # Docker run with environment variables
507
+ docker run -d \
508
+ -e NODE_ENV=production \
509
+ -e BLOOM_SERVICE_NAME=my-app \
510
+ -e DATABASE_HOST=postgres.internal \
511
+ -e DATABASE_PORT=5432 \
512
+ -e DATABASE_CREDENTIALS_USER=app_user \
513
+ -e DATABASE_CREDENTIALS_PASSWORD=secure_pass \
514
+ -e REDIS_URL=redis://redis.internal:6379 \
515
+ -e FEATURES_ANALYTICS_ENABLED=true \
516
+ my-app:latest
517
+ ```
518
+
519
+ ## ๐Ÿงช Testing
520
+
521
+ ```typescript
522
+ import { configClass } from '@bloomneo/appkit/config';
523
+
524
+ describe('Configuration Tests', () => {
525
+ beforeEach(() => {
526
+ // Clear cache before each test
527
+ configClass.clearCache();
528
+ });
529
+
530
+ afterEach(() => {
531
+ // Clean up environment
532
+ delete process.env.TEST_CONFIG_VALUE;
533
+ });
534
+
535
+ test('should parse environment variables correctly', () => {
536
+ // Set test environment variables
537
+ process.env.TEST_CONFIG_VALUE = 'test-value';
538
+ process.env.TEST_CONFIG_NUMBER = '123';
539
+ process.env.TEST_CONFIG_BOOLEAN = 'true';
540
+
541
+ const config = configClass.get();
542
+
543
+ expect(config.get('test_config.value')).toBe('test-value');
544
+ expect(config.get('test_config.number')).toBe(123);
545
+ expect(config.get('test_config.boolean')).toBe(true);
546
+ });
547
+
548
+ test('should use defaults when environment variables are missing', () => {
549
+ const config = configClass.get();
550
+
551
+ expect(config.get('missing.value', 'default')).toBe('default');
552
+ expect(config.get('missing.number', 42)).toBe(42);
553
+ });
554
+
555
+ test('should validate required configuration', () => {
556
+ expect(() => {
557
+ configClass.validateRequired(['missing.required.value']);
558
+ }).toThrow('Missing required configuration');
559
+ });
560
+ });
561
+ ```
562
+
563
+ ## ๐Ÿ“ˆ Performance
564
+
565
+ - **Environment Parsing**: Once per application startup (~2ms)
566
+ - **Configuration Access**: ~0.01ms per `get()` call
567
+ - **Memory Usage**: <500KB overhead
568
+ - **Type Conversion**: Cached after first access
569
+ - **Validation**: Only runs during startup
570
+
571
+ ## ๐Ÿ” TypeScript Support
572
+
573
+ Full TypeScript support with comprehensive interfaces:
574
+
575
+ ```typescript
576
+ import type { ConfigValue, AppConfig } from '@bloomneo/appkit/config';
577
+
578
+ // Strongly typed configuration access
579
+ const config = configClass.get();
580
+ const dbPort: number = config.get<number>('database.port', 5432);
581
+ const features: boolean = config.get<boolean>('features.enabled', false);
582
+
583
+ // Custom configuration interfaces
584
+ interface DatabaseConfig {
585
+ host: string;
586
+ port: number;
587
+ credentials: {
588
+ user: string;
589
+ password: string;
590
+ };
591
+ }
592
+
593
+ const dbConfig: DatabaseConfig = config.getModuleConfig('database');
594
+ ```
595
+
596
+ ## ๐Ÿ“„ License
597
+
598
+ MIT ยฉ [Bloomneo](https://github.com/bloomneo)
599
+
600
+ ---
601
+
602
+ <p align="center">
603
+ Built with โค๏ธ in India by the <a href="https://github.com/orgs/bloomneo/people">Bloomneo Team</a>
604
+ </p>