@morojs/moro 1.5.17 → 1.6.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.
Files changed (138) hide show
  1. package/README.md +48 -65
  2. package/dist/core/auth/morojs-adapter.js +12 -16
  3. package/dist/core/auth/morojs-adapter.js.map +1 -1
  4. package/dist/core/config/file-loader.d.ts +5 -0
  5. package/dist/core/config/file-loader.js +171 -0
  6. package/dist/core/config/file-loader.js.map +1 -1
  7. package/dist/core/config/index.d.ts +10 -39
  8. package/dist/core/config/index.js +29 -66
  9. package/dist/core/config/index.js.map +1 -1
  10. package/dist/core/config/loader.d.ts +7 -0
  11. package/dist/core/config/loader.js +269 -0
  12. package/dist/core/config/loader.js.map +1 -0
  13. package/dist/core/config/schema.js +31 -41
  14. package/dist/core/config/schema.js.map +1 -1
  15. package/dist/core/config/utils.d.ts +2 -9
  16. package/dist/core/config/utils.js +32 -19
  17. package/dist/core/config/utils.js.map +1 -1
  18. package/dist/core/config/validation.d.ts +17 -0
  19. package/dist/core/config/validation.js +131 -0
  20. package/dist/core/config/validation.js.map +1 -0
  21. package/dist/core/database/adapters/mongodb.d.ts +0 -10
  22. package/dist/core/database/adapters/mongodb.js +2 -23
  23. package/dist/core/database/adapters/mongodb.js.map +1 -1
  24. package/dist/core/database/adapters/mysql.d.ts +0 -11
  25. package/dist/core/database/adapters/mysql.js +0 -1
  26. package/dist/core/database/adapters/mysql.js.map +1 -1
  27. package/dist/core/database/adapters/postgresql.d.ts +1 -9
  28. package/dist/core/database/adapters/postgresql.js +1 -1
  29. package/dist/core/database/adapters/postgresql.js.map +1 -1
  30. package/dist/core/database/adapters/redis.d.ts +0 -9
  31. package/dist/core/database/adapters/redis.js +4 -14
  32. package/dist/core/database/adapters/redis.js.map +1 -1
  33. package/dist/core/framework.d.ts +7 -6
  34. package/dist/core/framework.js +16 -131
  35. package/dist/core/framework.js.map +1 -1
  36. package/dist/core/http/http-server.d.ts +0 -12
  37. package/dist/core/http/http-server.js +23 -151
  38. package/dist/core/http/http-server.js.map +1 -1
  39. package/dist/core/http/router.d.ts +0 -12
  40. package/dist/core/http/router.js +36 -114
  41. package/dist/core/http/router.js.map +1 -1
  42. package/dist/core/logger/filters.js +4 -12
  43. package/dist/core/logger/filters.js.map +1 -1
  44. package/dist/core/logger/index.d.ts +1 -1
  45. package/dist/core/logger/index.js +1 -2
  46. package/dist/core/logger/index.js.map +1 -1
  47. package/dist/core/logger/logger.d.ts +13 -29
  48. package/dist/core/logger/logger.js +203 -380
  49. package/dist/core/logger/logger.js.map +1 -1
  50. package/dist/core/logger/outputs.js +2 -0
  51. package/dist/core/logger/outputs.js.map +1 -1
  52. package/dist/core/middleware/built-in/auth.js +17 -88
  53. package/dist/core/middleware/built-in/auth.js.map +1 -1
  54. package/dist/core/middleware/built-in/cache.js +1 -3
  55. package/dist/core/middleware/built-in/cache.js.map +1 -1
  56. package/dist/core/middleware/built-in/index.d.ts +0 -1
  57. package/dist/core/middleware/built-in/index.js +1 -6
  58. package/dist/core/middleware/built-in/index.js.map +1 -1
  59. package/dist/core/middleware/built-in/request-logger.js +2 -3
  60. package/dist/core/middleware/built-in/request-logger.js.map +1 -1
  61. package/dist/core/middleware/built-in/sse.js +7 -9
  62. package/dist/core/middleware/built-in/sse.js.map +1 -1
  63. package/dist/core/modules/auto-discovery.d.ts +0 -17
  64. package/dist/core/modules/auto-discovery.js +12 -367
  65. package/dist/core/modules/auto-discovery.js.map +1 -1
  66. package/dist/core/modules/modules.js +2 -12
  67. package/dist/core/modules/modules.js.map +1 -1
  68. package/dist/core/networking/adapters/ws-adapter.d.ts +1 -1
  69. package/dist/core/networking/adapters/ws-adapter.js +2 -2
  70. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  71. package/dist/core/networking/service-discovery.js +7 -7
  72. package/dist/core/networking/service-discovery.js.map +1 -1
  73. package/dist/core/routing/index.d.ts +0 -20
  74. package/dist/core/routing/index.js +13 -178
  75. package/dist/core/routing/index.js.map +1 -1
  76. package/dist/core/runtime/node-adapter.js +6 -12
  77. package/dist/core/runtime/node-adapter.js.map +1 -1
  78. package/dist/moro.d.ts +0 -48
  79. package/dist/moro.js +148 -456
  80. package/dist/moro.js.map +1 -1
  81. package/dist/types/config.d.ts +2 -58
  82. package/dist/types/core.d.ts +40 -34
  83. package/dist/types/http.d.ts +1 -16
  84. package/dist/types/logger.d.ts +0 -7
  85. package/dist/types/module.d.ts +0 -11
  86. package/package.json +2 -2
  87. package/src/core/auth/morojs-adapter.ts +13 -18
  88. package/src/core/config/file-loader.ts +233 -0
  89. package/src/core/config/index.ts +32 -77
  90. package/src/core/config/loader.ts +633 -0
  91. package/src/core/config/schema.ts +31 -41
  92. package/src/core/config/utils.ts +29 -22
  93. package/src/core/config/validation.ts +140 -0
  94. package/src/core/database/README.md +16 -26
  95. package/src/core/database/adapters/mongodb.ts +2 -30
  96. package/src/core/database/adapters/mysql.ts +0 -14
  97. package/src/core/database/adapters/postgresql.ts +2 -12
  98. package/src/core/database/adapters/redis.ts +4 -27
  99. package/src/core/framework.ts +23 -163
  100. package/src/core/http/http-server.ts +36 -176
  101. package/src/core/http/router.ts +38 -127
  102. package/src/core/logger/filters.ts +4 -12
  103. package/src/core/logger/index.ts +0 -1
  104. package/src/core/logger/logger.ts +216 -427
  105. package/src/core/logger/outputs.ts +2 -0
  106. package/src/core/middleware/built-in/auth.ts +17 -98
  107. package/src/core/middleware/built-in/cache.ts +1 -3
  108. package/src/core/middleware/built-in/index.ts +0 -8
  109. package/src/core/middleware/built-in/request-logger.ts +1 -3
  110. package/src/core/middleware/built-in/sse.ts +7 -9
  111. package/src/core/modules/auto-discovery.ts +13 -476
  112. package/src/core/modules/modules.ts +9 -20
  113. package/src/core/networking/adapters/ws-adapter.ts +5 -2
  114. package/src/core/networking/service-discovery.ts +7 -6
  115. package/src/core/routing/index.ts +14 -198
  116. package/src/core/runtime/node-adapter.ts +6 -12
  117. package/src/moro.ts +166 -554
  118. package/src/types/config.ts +2 -59
  119. package/src/types/core.ts +45 -47
  120. package/src/types/http.ts +1 -23
  121. package/src/types/logger.ts +0 -9
  122. package/src/types/module.ts +0 -12
  123. package/dist/core/config/config-manager.d.ts +0 -44
  124. package/dist/core/config/config-manager.js +0 -114
  125. package/dist/core/config/config-manager.js.map +0 -1
  126. package/dist/core/config/config-sources.d.ts +0 -21
  127. package/dist/core/config/config-sources.js +0 -502
  128. package/dist/core/config/config-sources.js.map +0 -1
  129. package/dist/core/config/config-validator.d.ts +0 -21
  130. package/dist/core/config/config-validator.js +0 -765
  131. package/dist/core/config/config-validator.js.map +0 -1
  132. package/dist/core/middleware/built-in/jwt-helpers.d.ts +0 -118
  133. package/dist/core/middleware/built-in/jwt-helpers.js +0 -221
  134. package/dist/core/middleware/built-in/jwt-helpers.js.map +0 -1
  135. package/src/core/config/config-manager.ts +0 -133
  136. package/src/core/config/config-sources.ts +0 -596
  137. package/src/core/config/config-validator.ts +0 -1078
  138. package/src/core/middleware/built-in/jwt-helpers.ts +0 -240
@@ -172,3 +172,236 @@ async function setupTypeScriptLoader(): Promise<void> {
172
172
  // the TypeScript transpilation is already handled by those tools.
173
173
  logger.debug('TypeScript config loading delegated to runtime environment');
174
174
  }
175
+
176
+ /**
177
+ * Convert a configuration object to environment variable mappings
178
+ * This function flattens the config object and sets corresponding environment variables
179
+ */
180
+ export function applyConfigAsEnvironmentVariables(config: Partial<AppConfig>): void {
181
+ if (!config || typeof config !== 'object') {
182
+ return;
183
+ }
184
+
185
+ // Apply server configuration
186
+ if (config.server) {
187
+ setEnvIfNotSet('PORT', config.server.port?.toString());
188
+ setEnvIfNotSet('HOST', config.server.host);
189
+ setEnvIfNotSet('NODE_ENV', config.server.environment);
190
+ setEnvIfNotSet('MAX_CONNECTIONS', config.server.maxConnections?.toString());
191
+ setEnvIfNotSet('REQUEST_TIMEOUT', config.server.timeout?.toString());
192
+ }
193
+
194
+ // Apply database configuration
195
+ if (config.database) {
196
+ setEnvIfNotSet('DATABASE_URL', config.database.url);
197
+
198
+ if (config.database.redis) {
199
+ setEnvIfNotSet('REDIS_URL', config.database.redis.url);
200
+ setEnvIfNotSet('REDIS_MAX_RETRIES', config.database.redis.maxRetries?.toString());
201
+ setEnvIfNotSet('REDIS_RETRY_DELAY', config.database.redis.retryDelay?.toString());
202
+ setEnvIfNotSet('REDIS_KEY_PREFIX', config.database.redis.keyPrefix);
203
+ }
204
+
205
+ if (config.database.mysql) {
206
+ setEnvIfNotSet('MYSQL_HOST', config.database.mysql.host);
207
+ setEnvIfNotSet('MYSQL_PORT', config.database.mysql.port?.toString());
208
+ setEnvIfNotSet('MYSQL_DATABASE', config.database.mysql.database);
209
+ setEnvIfNotSet('MYSQL_USERNAME', config.database.mysql.username);
210
+ setEnvIfNotSet('MYSQL_PASSWORD', config.database.mysql.password);
211
+ setEnvIfNotSet('MYSQL_CONNECTION_LIMIT', config.database.mysql.connectionLimit?.toString());
212
+ setEnvIfNotSet('MYSQL_ACQUIRE_TIMEOUT', config.database.mysql.acquireTimeout?.toString());
213
+ setEnvIfNotSet('MYSQL_TIMEOUT', config.database.mysql.timeout?.toString());
214
+ }
215
+ }
216
+
217
+ // Apply service discovery configuration
218
+ if (config.serviceDiscovery) {
219
+ setEnvIfNotSet('SERVICE_DISCOVERY_ENABLED', config.serviceDiscovery.enabled?.toString());
220
+ setEnvIfNotSet('DISCOVERY_TYPE', config.serviceDiscovery.type);
221
+ setEnvIfNotSet('CONSUL_URL', config.serviceDiscovery.consulUrl);
222
+ setEnvIfNotSet('K8S_NAMESPACE', config.serviceDiscovery.kubernetesNamespace);
223
+ setEnvIfNotSet(
224
+ 'HEALTH_CHECK_INTERVAL',
225
+ config.serviceDiscovery.healthCheckInterval?.toString()
226
+ );
227
+ setEnvIfNotSet('DISCOVERY_RETRY_ATTEMPTS', config.serviceDiscovery.retryAttempts?.toString());
228
+ }
229
+
230
+ // Apply logging configuration
231
+ if (config.logging) {
232
+ setEnvIfNotSet('LOG_LEVEL', config.logging.level);
233
+ setEnvIfNotSet('LOG_FORMAT', config.logging.format);
234
+ setEnvIfNotSet('LOG_COLORS', config.logging.enableColors?.toString());
235
+ setEnvIfNotSet('LOG_TIMESTAMP', config.logging.enableTimestamp?.toString());
236
+ setEnvIfNotSet('LOG_CONTEXT', config.logging.enableContext?.toString());
237
+
238
+ if (config.logging.outputs) {
239
+ setEnvIfNotSet('LOG_CONSOLE', config.logging.outputs.console?.toString());
240
+
241
+ if (config.logging.outputs.file) {
242
+ setEnvIfNotSet('LOG_FILE_ENABLED', config.logging.outputs.file.enabled?.toString());
243
+ setEnvIfNotSet('LOG_FILE_PATH', config.logging.outputs.file.path);
244
+ setEnvIfNotSet('LOG_FILE_MAX_SIZE', config.logging.outputs.file.maxSize);
245
+ setEnvIfNotSet('LOG_FILE_MAX_FILES', config.logging.outputs.file.maxFiles?.toString());
246
+ }
247
+
248
+ if (config.logging.outputs.webhook) {
249
+ setEnvIfNotSet('LOG_WEBHOOK_ENABLED', config.logging.outputs.webhook.enabled?.toString());
250
+ setEnvIfNotSet('LOG_WEBHOOK_URL', config.logging.outputs.webhook.url);
251
+ if (config.logging.outputs.webhook.headers) {
252
+ setEnvIfNotSet(
253
+ 'LOG_WEBHOOK_HEADERS',
254
+ JSON.stringify(config.logging.outputs.webhook.headers)
255
+ );
256
+ }
257
+ }
258
+ }
259
+ }
260
+
261
+ // Apply module defaults
262
+ if (config.modules) {
263
+ if (config.modules.cache) {
264
+ setEnvIfNotSet('CACHE_ENABLED', config.modules.cache.enabled?.toString());
265
+ setEnvIfNotSet('DEFAULT_CACHE_TTL', config.modules.cache.defaultTtl?.toString());
266
+ setEnvIfNotSet('CACHE_MAX_SIZE', config.modules.cache.maxSize?.toString());
267
+ setEnvIfNotSet('CACHE_STRATEGY', config.modules.cache.strategy);
268
+ }
269
+
270
+ if (config.modules.rateLimit) {
271
+ setEnvIfNotSet('RATE_LIMIT_ENABLED', config.modules.rateLimit.enabled?.toString());
272
+ setEnvIfNotSet(
273
+ 'DEFAULT_RATE_LIMIT_REQUESTS',
274
+ config.modules.rateLimit.defaultRequests?.toString()
275
+ );
276
+ setEnvIfNotSet(
277
+ 'DEFAULT_RATE_LIMIT_WINDOW',
278
+ config.modules.rateLimit.defaultWindow?.toString()
279
+ );
280
+ setEnvIfNotSet(
281
+ 'RATE_LIMIT_SKIP_SUCCESS',
282
+ config.modules.rateLimit.skipSuccessfulRequests?.toString()
283
+ );
284
+ setEnvIfNotSet(
285
+ 'RATE_LIMIT_SKIP_FAILED',
286
+ config.modules.rateLimit.skipFailedRequests?.toString()
287
+ );
288
+ }
289
+
290
+ if (config.modules.validation) {
291
+ setEnvIfNotSet('VALIDATION_ENABLED', config.modules.validation.enabled?.toString());
292
+ setEnvIfNotSet(
293
+ 'VALIDATION_STRIP_UNKNOWN',
294
+ config.modules.validation.stripUnknown?.toString()
295
+ );
296
+ setEnvIfNotSet('VALIDATION_ABORT_EARLY', config.modules.validation.abortEarly?.toString());
297
+ }
298
+ }
299
+
300
+ // Apply security configuration
301
+ if (config.security) {
302
+ if (config.security.cors) {
303
+ setEnvIfNotSet('CORS_ENABLED', config.security.cors.enabled?.toString());
304
+ if (typeof config.security.cors.origin === 'string') {
305
+ setEnvIfNotSet('CORS_ORIGIN', config.security.cors.origin);
306
+ } else if (Array.isArray(config.security.cors.origin)) {
307
+ setEnvIfNotSet('CORS_ORIGIN', config.security.cors.origin.join(','));
308
+ } else if (typeof config.security.cors.origin === 'boolean') {
309
+ setEnvIfNotSet('CORS_ORIGIN', config.security.cors.origin.toString());
310
+ }
311
+ setEnvIfNotSet('CORS_METHODS', config.security.cors.methods?.join(','));
312
+ setEnvIfNotSet('CORS_HEADERS', config.security.cors.allowedHeaders?.join(','));
313
+ setEnvIfNotSet('CORS_CREDENTIALS', config.security.cors.credentials?.toString());
314
+ }
315
+
316
+ if (config.security.helmet) {
317
+ setEnvIfNotSet('HELMET_ENABLED', config.security.helmet.enabled?.toString());
318
+ setEnvIfNotSet('HELMET_CSP', config.security.helmet.contentSecurityPolicy?.toString());
319
+ setEnvIfNotSet('HELMET_HSTS', config.security.helmet.hsts?.toString());
320
+ setEnvIfNotSet('HELMET_NO_SNIFF', config.security.helmet.noSniff?.toString());
321
+ setEnvIfNotSet('HELMET_FRAMEGUARD', config.security.helmet.frameguard?.toString());
322
+ }
323
+
324
+ if (config.security.rateLimit?.global) {
325
+ setEnvIfNotSet(
326
+ 'GLOBAL_RATE_LIMIT_ENABLED',
327
+ config.security.rateLimit.global.enabled?.toString()
328
+ );
329
+ setEnvIfNotSet(
330
+ 'GLOBAL_RATE_LIMIT_REQUESTS',
331
+ config.security.rateLimit.global.requests?.toString()
332
+ );
333
+ setEnvIfNotSet(
334
+ 'GLOBAL_RATE_LIMIT_WINDOW',
335
+ config.security.rateLimit.global.window?.toString()
336
+ );
337
+ }
338
+ }
339
+
340
+ // Apply external services configuration
341
+ if (config.external) {
342
+ if (config.external.stripe) {
343
+ setEnvIfNotSet('STRIPE_SECRET_KEY', config.external.stripe.secretKey);
344
+ setEnvIfNotSet('STRIPE_PUBLISHABLE_KEY', config.external.stripe.publishableKey);
345
+ setEnvIfNotSet('STRIPE_WEBHOOK_SECRET', config.external.stripe.webhookSecret);
346
+ setEnvIfNotSet('STRIPE_API_VERSION', config.external.stripe.apiVersion);
347
+ }
348
+
349
+ if (config.external.paypal) {
350
+ setEnvIfNotSet('PAYPAL_CLIENT_ID', config.external.paypal.clientId);
351
+ setEnvIfNotSet('PAYPAL_CLIENT_SECRET', config.external.paypal.clientSecret);
352
+ setEnvIfNotSet('PAYPAL_WEBHOOK_ID', config.external.paypal.webhookId);
353
+ setEnvIfNotSet('PAYPAL_ENVIRONMENT', config.external.paypal.environment);
354
+ }
355
+
356
+ if (config.external.smtp) {
357
+ setEnvIfNotSet('SMTP_HOST', config.external.smtp.host);
358
+ setEnvIfNotSet('SMTP_PORT', config.external.smtp.port?.toString());
359
+ setEnvIfNotSet('SMTP_SECURE', config.external.smtp.secure?.toString());
360
+ setEnvIfNotSet('SMTP_USERNAME', config.external.smtp.username);
361
+ setEnvIfNotSet('SMTP_PASSWORD', config.external.smtp.password);
362
+ }
363
+ }
364
+
365
+ // Apply performance configuration
366
+ if (config.performance) {
367
+ if (config.performance.compression) {
368
+ setEnvIfNotSet('COMPRESSION_ENABLED', config.performance.compression.enabled?.toString());
369
+ setEnvIfNotSet('COMPRESSION_LEVEL', config.performance.compression.level?.toString());
370
+ setEnvIfNotSet('COMPRESSION_THRESHOLD', config.performance.compression.threshold?.toString());
371
+ }
372
+
373
+ if (config.performance.circuitBreaker) {
374
+ setEnvIfNotSet(
375
+ 'CIRCUIT_BREAKER_ENABLED',
376
+ config.performance.circuitBreaker.enabled?.toString()
377
+ );
378
+ setEnvIfNotSet(
379
+ 'CIRCUIT_BREAKER_THRESHOLD',
380
+ config.performance.circuitBreaker.failureThreshold?.toString()
381
+ );
382
+ setEnvIfNotSet(
383
+ 'CIRCUIT_BREAKER_RESET',
384
+ config.performance.circuitBreaker.resetTimeout?.toString()
385
+ );
386
+ setEnvIfNotSet(
387
+ 'CIRCUIT_BREAKER_MONITOR',
388
+ config.performance.circuitBreaker.monitoringPeriod?.toString()
389
+ );
390
+ }
391
+
392
+ if (config.performance.clustering) {
393
+ setEnvIfNotSet('CLUSTERING_ENABLED', config.performance.clustering.enabled?.toString());
394
+ setEnvIfNotSet('CLUSTER_WORKERS', config.performance.clustering.workers?.toString());
395
+ }
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Set environment variable only if it's not already set
401
+ * This ensures environment variables take precedence over config file values
402
+ */
403
+ function setEnvIfNotSet(key: string, value: string | undefined): void {
404
+ if (value !== undefined && process.env[key] === undefined) {
405
+ process.env[key] = value;
406
+ }
407
+ }
@@ -1,105 +1,60 @@
1
- /**
2
- * Configuration System - Immutable Config with createApp Override Support
3
- *
4
- * This is the main entry point for the MoroJS configuration system.
5
- * It provides a clean, immutable configuration that is locked at createApp() time.
6
- *
7
- * Key Features:
8
- * - Immutable configuration after initialization
9
- * - Clear precedence: Env Vars > createApp Options > Config File > Defaults
10
- * - Type-safe validation
11
- * - Single source of truth
12
- */
13
-
14
- // Export types and core components
1
+ // Configuration System - Main Exports and Utilities
15
2
  export * from './schema';
16
- export * from './config-sources';
17
- export * from './config-validator';
18
- export * from './file-loader';
19
-
20
- // Export specific functions from config-manager to avoid conflicts
21
- export { initializeAndLockConfig, isConfigLocked, resetConfigForTesting } from './config-manager';
22
-
23
- // Export utilities for backward compatibility
3
+ export * from './loader';
24
4
  export * from './utils';
5
+ export * from './file-loader';
25
6
 
26
- import { MoroOptions } from '../../types/core';
27
- import { AppConfig } from '../../types/config';
28
- import { loadConfigFromAllSources } from './config-sources';
29
- import {
30
- initializeAndLockConfig,
31
- getGlobalConfig as getConfig,
32
- isConfigLocked,
33
- resetConfigForTesting,
34
- } from './config-manager';
35
- import { createFrameworkLogger } from '../logger';
7
+ // Main configuration loading function
8
+ import { loadConfig } from './loader';
9
+ import type { AppConfig } from './schema';
10
+ import { setConfig } from './utils';
36
11
 
37
- const logger = createFrameworkLogger('ConfigSystem');
12
+ // Global configuration instance
13
+ let globalConfig: AppConfig | null = null;
38
14
 
39
15
  /**
40
- * Initialize configuration system with createApp options
41
- * This is the main entry point called by createApp()
42
- *
43
- * @param options - createApp options that can override config file and defaults
44
- * @returns Immutable, validated configuration object
16
+ * Initialize and load the global application configuration
17
+ * This should be called once at application startup
45
18
  */
46
- export function initializeConfig(options?: MoroOptions): Readonly<AppConfig> {
47
- if (isConfigLocked()) {
48
- logger.debug('Configuration already locked, returning existing config');
49
- return getConfig();
19
+ export function initializeConfig(): AppConfig {
20
+ if (globalConfig) {
21
+ return globalConfig;
50
22
  }
51
23
 
52
- logger.debug('Initializing configuration system');
53
-
54
- // Load configuration from all sources with proper precedence
55
- const config = loadConfigFromAllSources(options);
24
+ globalConfig = loadConfig();
56
25
 
57
- // Lock the configuration to prevent further changes
58
- initializeAndLockConfig(config);
26
+ // Also set the config for utils functions
27
+ setConfig(globalConfig);
59
28
 
60
- logger.info(
61
- `Configuration system initialized and locked: ${process.env.NODE_ENV || 'development'}:${config.server.port} (sources: env + file + options + defaults)`
62
- );
63
-
64
- return config;
65
- }
66
-
67
- /**
68
- * Load configuration without locking (for testing and utilities)
69
- * This maintains backward compatibility with existing code
70
- */
71
- export function loadConfig(): AppConfig {
72
- return loadConfigFromAllSources();
73
- }
74
-
75
- /**
76
- * Load configuration with createApp options (for testing and utilities)
77
- * This maintains backward compatibility with existing code
78
- */
79
- export function loadConfigWithOptions(options: MoroOptions): AppConfig {
80
- return loadConfigFromAllSources(options);
29
+ return globalConfig;
81
30
  }
82
31
 
83
32
  /**
84
33
  * Get the current global configuration
85
- * Alias for getGlobalConfig() for backward compatibility
34
+ * Throws if configuration hasn't been initialized
86
35
  */
87
- export function getGlobalConfig(): Readonly<AppConfig> {
88
- return getConfig();
36
+ export function getGlobalConfig(): AppConfig {
37
+ if (!globalConfig) {
38
+ throw new Error('Configuration not initialized. Call initializeConfig() first.');
39
+ }
40
+ return globalConfig;
89
41
  }
90
42
 
91
43
  /**
92
- * Check if configuration has been initialized and locked
93
- * Alias for isConfigLocked() for backward compatibility
44
+ * Check if configuration has been initialized
94
45
  */
95
46
  export function isConfigInitialized(): boolean {
96
- return isConfigLocked();
47
+ return globalConfig !== null;
97
48
  }
98
49
 
99
50
  /**
100
- * Reset configuration state (for testing only)
51
+ * Reset the global configuration state (for testing purposes)
101
52
  * @internal
102
53
  */
103
54
  export function resetConfig(): void {
104
- resetConfigForTesting();
55
+ globalConfig = null;
56
+
57
+ // Also reset the utils config (by setting it to null via direct access)
58
+ const { setConfig } = require('./utils');
59
+ setConfig(null as any);
105
60
  }