@abdokouta/react-config 1.0.0 → 1.0.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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -1
  3. package/config/config.config.ts +9 -9
  4. package/dist/{index.d.mts → index.d.cts} +34 -2
  5. package/dist/index.d.ts +34 -2
  6. package/dist/index.js +28 -11
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +28 -11
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +55 -25
  11. package/.examples/01-basic-usage.ts +0 -289
  12. package/.examples/02-env-helper.ts +0 -282
  13. package/.examples/README.md +0 -285
  14. package/.prettierrc.js +0 -1
  15. package/__tests__/config.module.test.ts +0 -244
  16. package/__tests__/drivers/env.driver.test.ts +0 -259
  17. package/__tests__/services/config.service.test.ts +0 -328
  18. package/__tests__/setup.d.ts +0 -11
  19. package/__tests__/vitest.setup.ts +0 -30
  20. package/eslint.config.js +0 -13
  21. package/src/config.module.ts +0 -154
  22. package/src/constants/index.ts +0 -5
  23. package/src/constants/tokens.constant.ts +0 -38
  24. package/src/drivers/env.driver.ts +0 -194
  25. package/src/drivers/file.driver.ts +0 -81
  26. package/src/drivers/index.ts +0 -6
  27. package/src/index.ts +0 -92
  28. package/src/interfaces/config-driver.interface.ts +0 -30
  29. package/src/interfaces/config-module-options.interface.ts +0 -84
  30. package/src/interfaces/config-service.interface.ts +0 -71
  31. package/src/interfaces/index.ts +0 -8
  32. package/src/interfaces/vite-config-plugin-options.interface.ts +0 -56
  33. package/src/plugins/index.ts +0 -5
  34. package/src/plugins/vite.plugin.ts +0 -115
  35. package/src/services/config.service.ts +0 -172
  36. package/src/services/index.ts +0 -5
  37. package/src/utils/get-nested-value.util.ts +0 -56
  38. package/src/utils/index.ts +0 -6
  39. package/src/utils/load-config-file.util.ts +0 -37
  40. package/src/utils/scan-config-files.util.ts +0 -40
  41. package/tsconfig.json +0 -28
  42. package/tsup.config.ts +0 -105
  43. package/vitest.config.ts +0 -66
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Refine
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # @abdokouta/config
2
2
 
3
- NestJS-inspired configuration management with multiple drivers (Env, File, Firebase) for Refine applications.
3
+ NestJS-inspired configuration management with multiple drivers (Env, File,
4
+ Firebase) for Refine applications.
4
5
 
5
6
  ## Features
6
7
 
@@ -1,39 +1,39 @@
1
1
  /**
2
2
  * Config Package Configuration
3
- *
3
+ *
4
4
  * Configuration for the @abdokouta/config package.
5
5
  * Defines how environment variables are loaded and accessed.
6
- *
6
+ *
7
7
  * @module config/config
8
8
  */
9
9
 
10
- import type { ConfigModuleOptions } from '@abdokouta/config';
10
+ import { defineConfig } from '@abdokouta/config';
11
11
 
12
12
  /**
13
13
  * Config Configuration
14
- *
14
+ *
15
15
  * Settings:
16
16
  * - driver: 'env' (reads from process.env)
17
17
  * - ignoreEnvFile: true (don't load .env file in browser)
18
18
  * - isGlobal: true (available to all modules)
19
19
  * - envPrefix: 'auto' (auto-detect and strip VITE_ or NEXT_PUBLIC_ prefix)
20
- *
20
+ *
21
21
  * With envPrefix: 'auto', you can access:
22
22
  * - VITE_APP_NAME as APP_NAME
23
23
  * - NEXT_PUBLIC_API_URL as API_URL
24
- *
24
+ *
25
25
  * @example
26
26
  * ```typescript
27
27
  * // In app.module.ts
28
28
  * import { configConfig } from '@/config/config.config';
29
- *
29
+ *
30
30
  * @Module({
31
31
  * imports: [ConfigModule.forRoot(configConfig)],
32
32
  * })
33
33
  * export class AppModule {}
34
34
  * ```
35
35
  */
36
- export const configConfig: ConfigModuleOptions = {
36
+ export const configConfig = defineConfig({
37
37
  /**
38
38
  * Driver to use for loading configuration
39
39
  * 'env' reads from process.env
@@ -59,4 +59,4 @@ export const configConfig: ConfigModuleOptions = {
59
59
  * So VITE_APP_NAME becomes accessible as APP_NAME
60
60
  */
61
61
  envPrefix: 'auto',
62
- };
62
+ });
@@ -357,7 +357,7 @@ declare class EnvDriver implements ConfigDriver {
357
357
  * Loads configuration from TypeScript/JavaScript files.
358
358
  * This is a server-side only driver. For client-side, use the Vite plugin.
359
359
  *
360
- * @see packages/pixielity/config/src/plugins/vite-config.plugin.ts
360
+ * @see packages/abdokouta/config/src/plugins/vite-config.plugin.ts
361
361
  */
362
362
  declare class FileDriver implements ConfigDriver {
363
363
  private config;
@@ -433,6 +433,38 @@ interface ViteConfigPluginOptions {
433
433
  globalName?: string;
434
434
  }
435
435
 
436
+ /**
437
+ * Define Config Utility
438
+ *
439
+ * Helper function to define config module options with type safety.
440
+ *
441
+ * @module @abdokouta/config
442
+ */
443
+
444
+ /**
445
+ * Helper function to define config module options with type safety
446
+ *
447
+ * Provides IDE autocomplete and type checking for configuration objects.
448
+ * This pattern is consistent with modern tooling (Vite, Vitest, etc.).
449
+ *
450
+ * @param config - The config module options object
451
+ * @returns The same configuration object with proper typing
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * // config.config.ts
456
+ * import { defineConfig } from '@abdokouta/config';
457
+ *
458
+ * export default defineConfig({
459
+ * driver: 'env',
460
+ * ignoreEnvFile: true,
461
+ * isGlobal: true,
462
+ * envPrefix: 'auto',
463
+ * });
464
+ * ```
465
+ */
466
+ declare function defineConfig(config: ConfigModuleOptions): ConfigModuleOptions;
467
+
436
468
  /**
437
469
  * Get nested value from object using dot notation
438
470
  *
@@ -471,4 +503,4 @@ declare function hasNestedValue(obj: Record<string, any>, path: string): boolean
471
503
  */
472
504
  declare function loadConfigFile(filePath: string): Promise<Record<string, any>>;
473
505
 
474
- export { type ConfigDriver, ConfigModule, type ConfigModuleOptions, ConfigService, type ConfigServiceInterface, EnvDriver, FileDriver, type ViteConfigPluginOptions, getNestedValue, hasNestedValue, loadConfigFile };
506
+ export { type ConfigDriver, ConfigModule, type ConfigModuleOptions, ConfigService, type ConfigServiceInterface, EnvDriver, FileDriver, type ViteConfigPluginOptions, defineConfig, getNestedValue, hasNestedValue, loadConfigFile };
package/dist/index.d.ts CHANGED
@@ -357,7 +357,7 @@ declare class EnvDriver implements ConfigDriver {
357
357
  * Loads configuration from TypeScript/JavaScript files.
358
358
  * This is a server-side only driver. For client-side, use the Vite plugin.
359
359
  *
360
- * @see packages/pixielity/config/src/plugins/vite-config.plugin.ts
360
+ * @see packages/abdokouta/config/src/plugins/vite-config.plugin.ts
361
361
  */
362
362
  declare class FileDriver implements ConfigDriver {
363
363
  private config;
@@ -433,6 +433,38 @@ interface ViteConfigPluginOptions {
433
433
  globalName?: string;
434
434
  }
435
435
 
436
+ /**
437
+ * Define Config Utility
438
+ *
439
+ * Helper function to define config module options with type safety.
440
+ *
441
+ * @module @abdokouta/config
442
+ */
443
+
444
+ /**
445
+ * Helper function to define config module options with type safety
446
+ *
447
+ * Provides IDE autocomplete and type checking for configuration objects.
448
+ * This pattern is consistent with modern tooling (Vite, Vitest, etc.).
449
+ *
450
+ * @param config - The config module options object
451
+ * @returns The same configuration object with proper typing
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * // config.config.ts
456
+ * import { defineConfig } from '@abdokouta/config';
457
+ *
458
+ * export default defineConfig({
459
+ * driver: 'env',
460
+ * ignoreEnvFile: true,
461
+ * isGlobal: true,
462
+ * envPrefix: 'auto',
463
+ * });
464
+ * ```
465
+ */
466
+ declare function defineConfig(config: ConfigModuleOptions): ConfigModuleOptions;
467
+
436
468
  /**
437
469
  * Get nested value from object using dot notation
438
470
  *
@@ -471,4 +503,4 @@ declare function hasNestedValue(obj: Record<string, any>, path: string): boolean
471
503
  */
472
504
  declare function loadConfigFile(filePath: string): Promise<Record<string, any>>;
473
505
 
474
- export { type ConfigDriver, ConfigModule, type ConfigModuleOptions, ConfigService, type ConfigServiceInterface, EnvDriver, FileDriver, type ViteConfigPluginOptions, getNestedValue, hasNestedValue, loadConfigFile };
506
+ export { type ConfigDriver, ConfigModule, type ConfigModuleOptions, ConfigService, type ConfigServiceInterface, EnvDriver, FileDriver, type ViteConfigPluginOptions, defineConfig, getNestedValue, hasNestedValue, loadConfigFile };
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ __export(index_exports, {
35
35
  ConfigService: () => ConfigService,
36
36
  EnvDriver: () => EnvDriver,
37
37
  FileDriver: () => FileDriver,
38
+ defineConfig: () => defineConfig,
38
39
  getNestedValue: () => getNestedValue,
39
40
  hasNestedValue: () => hasNestedValue,
40
41
  loadConfigFile: () => loadConfigFile
@@ -92,19 +93,33 @@ var EnvDriver = class {
92
93
  const globalName = this.options.globalName || "__APP_CONFIG__";
93
94
  if (typeof window !== "undefined" && window[globalName]) {
94
95
  this.config = { ...window[globalName] };
95
- console.log(`[EnvDriver] Loaded config from window.${globalName}:`, Object.keys(this.config).length, "keys");
96
+ console.log(
97
+ `[EnvDriver] Loaded config from window.${globalName}:`,
98
+ Object.keys(this.config).length,
99
+ "keys"
100
+ );
96
101
  } else if (typeof process !== "undefined" && process.env) {
97
102
  this.config = { ...process.env };
98
- console.log("[EnvDriver] Loaded config from process.env:", Object.keys(this.config).length, "keys");
103
+ console.log(
104
+ "[EnvDriver] Loaded config from process.env:",
105
+ Object.keys(this.config).length,
106
+ "keys"
107
+ );
99
108
  } else {
100
- console.warn("[EnvDriver] No config source available (neither window." + globalName + " nor process.env)");
109
+ console.warn(
110
+ "[EnvDriver] No config source available (neither window." + globalName + " nor process.env)"
111
+ );
101
112
  this.config = {};
102
113
  }
103
- console.log("[EnvDriver] Initial config keys:", [...Object.keys(this.config).filter((k) => k.includes("APP") || k.includes("VITE"))]);
114
+ console.log("[EnvDriver] Initial config keys:", [
115
+ ...Object.keys(this.config).filter((k) => k.includes("APP") || k.includes("VITE"))
116
+ ]);
104
117
  if (this.options.envPrefix !== false) {
105
118
  console.log("[EnvDriver] Stripping prefix...");
106
119
  this.stripPrefix();
107
- console.log("[EnvDriver] After stripPrefix, config keys:", [...Object.keys(this.config).filter((k) => k.includes("APP") || k.includes("VITE"))]);
120
+ console.log("[EnvDriver] After stripPrefix, config keys:", [
121
+ ...Object.keys(this.config).filter((k) => k.includes("APP") || k.includes("VITE"))
122
+ ]);
108
123
  }
109
124
  if (this.options.expandVariables) {
110
125
  this.expandEnvVariables();
@@ -406,7 +421,7 @@ ConfigService = __decorateClass([
406
421
  var ConfigModule = class {
407
422
  /**
408
423
  * Register configuration module with options
409
- *
424
+ *
410
425
  * @param options - Configuration options
411
426
  * @returns Dynamic module
412
427
  */
@@ -439,7 +454,7 @@ var ConfigModule = class {
439
454
  }
440
455
  /**
441
456
  * Register configuration module asynchronously
442
- *
457
+ *
443
458
  * @param options - Async configuration options
444
459
  * @returns Dynamic module
445
460
  */
@@ -493,6 +508,11 @@ ConfigModule = __decorateClass([
493
508
  (0, import_react_di2.Module)({})
494
509
  ], ConfigModule);
495
510
 
511
+ // src/utils/define-config.util.ts
512
+ function defineConfig(config) {
513
+ return config;
514
+ }
515
+
496
516
  // src/utils/load-config-file.util.ts
497
517
  async function loadConfigFile(filePath) {
498
518
  try {
@@ -506,10 +526,7 @@ async function loadConfigFile(filePath) {
506
526
  }
507
527
  return config;
508
528
  } catch (error) {
509
- console.warn(
510
- `[vite-plugin-config] Failed to load config file: ${filePath}`,
511
- error
512
- );
529
+ console.warn(`[vite-plugin-config] Failed to load config file: ${filePath}`, error);
513
530
  return {};
514
531
  }
515
532
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.module.ts","../src/utils/get-nested-value.util.ts","../src/drivers/env.driver.ts","../src/drivers/file.driver.ts","../src/services/config.service.ts","../src/constants/tokens.constant.ts","../src/utils/load-config-file.util.ts"],"sourcesContent":["/**\n * @abdokouta/config\n *\n * NestJS-inspired configuration management with multiple drivers for loading\n * configuration from various sources (environment variables, files, etc.).\n * Provides type-safe access to configuration values with support for nested\n * properties and default values.\n *\n * @example\n * Basic usage with environment variables:\n * ```typescript\n * import { ConfigModule, ConfigService, EnvDriver } from '@abdokouta/config';\n * import { Module, Injectable, Inject } from '@abdokouta/react-di';\n *\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * driver: new EnvDriver(),\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * @Injectable()\n * class DatabaseService {\n * constructor(@Inject(ConfigService) private config: ConfigService) {}\n *\n * connect() {\n * const host = this.config.get('DATABASE_HOST', 'localhost');\n * const port = this.config.get('DATABASE_PORT', 5432);\n * // Connect to database...\n * }\n * }\n * ```\n *\n * @example\n * Using file-based configuration:\n * ```typescript\n * import { ConfigModule, FileDriver } from '@abdokouta/config';\n *\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * driver: new FileDriver({\n * path: './config/app.json',\n * }),\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n *\n * @example\n * Accessing nested configuration:\n * ```typescript\n * // config.json: { \"database\": { \"host\": \"localhost\", \"port\": 5432 } }\n * const host = config.get('database.host');\n * const port = config.get('database.port', 3306);\n * ```\n *\n * @module @abdokouta/config\n */\n\n// ============================================================================\n// Module (DI Configuration)\n// ============================================================================\nexport { ConfigModule } from './config.module';\n\n// ============================================================================\n// Core Service\n// ============================================================================\nexport { ConfigService } from './services/config.service';\n\n// ============================================================================\n// Drivers\n// ============================================================================\nexport { EnvDriver } from './drivers/env.driver';\nexport { FileDriver } from './drivers/file.driver';\n\n// ============================================================================\n// Interfaces\n// ============================================================================\nexport type { ConfigDriver } from './interfaces/config-driver.interface';\nexport type { ConfigModuleOptions } from './interfaces/config-module-options.interface';\nexport type { ConfigServiceInterface } from './interfaces/config-service.interface';\nexport type { ViteConfigPluginOptions } from './interfaces/vite-config-plugin-options.interface';\n\n// ============================================================================\n// Utilities\n// ============================================================================\nexport { getNestedValue, hasNestedValue } from './utils/get-nested-value.util';\nexport { loadConfigFile } from './utils/load-config-file.util';\n","import { Module, DynamicModule } from '@abdokouta/react-di';\n\nimport { EnvDriver } from './drivers/env.driver';\nimport { FileDriver } from './drivers/file.driver';\nimport { ConfigService } from './services/config.service';\nimport type { ConfigDriver } from './interfaces/config-driver.interface';\nimport type { ConfigModuleOptions } from './interfaces/config-module-options.interface';\nimport { CONFIG_DRIVER, CONFIG_OPTIONS, CONFIG_SERVICE } from './constants/tokens.constant';\n\n/**\n * Configuration Module\n * \n * Provides configuration management with multiple drivers.\n * Similar to NestJS ConfigModule.\n * \n * @example\n * ```typescript\n * // Using environment variables (default)\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * envFilePath: '.env',\n * isGlobal: true,\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n * \n * @example\n * ```typescript\n * // Using file-based configuration\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * driver: 'file',\n * filePattern: 'config/**\\/*.config.ts',\n * isGlobal: true,\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class ConfigModule {\n /**\n * Register configuration module with options\n * \n * @param options - Configuration options\n * @returns Dynamic module\n */\n static forRoot(options: ConfigModuleOptions = {}): DynamicModule {\n const driver = this.createDriver(options);\n \n const isGlobal = options.isGlobal ?? false;\n \n const providers = [\n {\n provide: CONFIG_OPTIONS,\n useValue: options,\n isGlobal,\n },\n {\n provide: CONFIG_DRIVER,\n useValue: driver,\n isGlobal,\n },\n ConfigService,\n {\n provide: CONFIG_SERVICE,\n useExisting: ConfigService,\n isGlobal,\n },\n ];\n\n return {\n module: ConfigModule,\n providers: providers as any,\n exports: [ConfigService],\n };\n }\n\n /**\n * Register configuration module asynchronously\n * \n * @param options - Async configuration options\n * @returns Dynamic module\n */\n static async forRootAsync(\n options: ConfigModuleOptions & {\n useFactory?: () => Promise<ConfigModuleOptions> | ConfigModuleOptions;\n }\n ): Promise<DynamicModule> {\n const resolvedOptions = options.useFactory\n ? await options.useFactory()\n : options;\n\n return this.forRoot(resolvedOptions);\n }\n\n /**\n * Create configuration driver based on options\n */\n private static createDriver(options: ConfigModuleOptions): ConfigDriver {\n const driverType = options.driver || 'env';\n\n switch (driverType) {\n case 'env':\n const envDriver = new EnvDriver({\n envFilePath: options.envFilePath,\n ignoreEnvFile: options.ignoreEnvFile,\n expandVariables: options.expandVariables,\n envPrefix: options.envPrefix,\n globalName: options.globalName,\n });\n envDriver.load();\n \n // Merge custom load function if provided\n if (options.load) {\n this.mergeCustomConfig(envDriver, options.load);\n }\n \n return envDriver;\n\n case 'file':\n const fileDriver = new FileDriver({\n config: typeof options.load === 'object' ? options.load : undefined,\n });\n return fileDriver;\n\n default:\n throw new Error(`Unknown configuration driver: ${driverType}`);\n }\n }\n\n /**\n * Merge custom configuration into driver\n */\n private static mergeCustomConfig(\n driver: ConfigDriver,\n load: Record<string, any> | (() => Record<string, any> | Promise<Record<string, any>>)\n ): void {\n const customConfig = typeof load === 'function' ? load() : load;\n \n if (customConfig instanceof Promise) {\n customConfig.then(config => {\n Object.assign(driver.all(), config);\n });\n } else {\n Object.assign(driver.all(), customConfig);\n }\n }\n}\n","/**\n * Get nested value from object using dot notation\n * \n * @param obj - Source object\n * @param path - Dot-notated path (e.g., 'database.host')\n * @param defaultValue - Default value if path not found\n * @returns Value at path or default value\n * \n * @example\n * ```typescript\n * const config = { database: { host: 'localhost' } };\n * getNestedValue(config, 'database.host'); // 'localhost'\n * getNestedValue(config, 'database.port', 5432); // 5432\n * ```\n */\nexport function getNestedValue<T = any>(\n obj: Record<string, any>,\n path: string,\n defaultValue?: T\n): T | undefined {\n const keys = path.split('.');\n let current: any = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return defaultValue;\n }\n current = current[key];\n }\n\n return current !== undefined ? current : defaultValue;\n}\n\n/**\n * Check if nested path exists in object\n * \n * @param obj - Source object\n * @param path - Dot-notated path\n * @returns True if path exists\n */\nexport function hasNestedValue(\n obj: Record<string, any>,\n path: string\n): boolean {\n const keys = path.split('.');\n let current: any = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined || !(key in current)) {\n return false;\n }\n current = current[key];\n }\n\n return true;\n}\n","import type { ConfigDriver } from '../interfaces/config-driver.interface';\nimport { getNestedValue, hasNestedValue } from '../utils/get-nested-value.util';\n\n/**\n * Environment Variable Configuration Driver\n * \n * Loads configuration from environment variables (process.env).\n * Supports .env files via dotenv.\n */\nexport class EnvDriver implements ConfigDriver {\n private config: Record<string, any> = {};\n private loaded = false;\n\n constructor(\n private options: {\n envFilePath?: string | string[];\n ignoreEnvFile?: boolean;\n expandVariables?: boolean;\n envPrefix?: string | false;\n globalName?: string; // Custom global variable name\n } = {}\n ) {}\n\n /**\n * Load environment variables\n */\n load(): Record<string, any> {\n if (this.loaded) {\n console.log('[EnvDriver] Already loaded, returning cached config');\n return this.config;\n }\n\n console.log('[EnvDriver] Loading environment variables...');\n console.log('[EnvDriver] Options:', { ...this.options });\n\n // Load .env file if not ignored\n if (!this.options.ignoreEnvFile) {\n this.loadDotEnv();\n }\n\n // Get global config name (default: __APP_CONFIG__)\n const globalName = this.options.globalName || '__APP_CONFIG__';\n\n // Try to load from custom global variable first (browser environment)\n if (typeof window !== 'undefined' && (window as any)[globalName]) {\n this.config = { ...(window as any)[globalName] };\n console.log(`[EnvDriver] Loaded config from window.${globalName}:`, Object.keys(this.config).length, 'keys');\n }\n // Fallback to process.env (Node.js environment or backward compatibility)\n else if (typeof process !== 'undefined' && process.env) {\n this.config = { ...process.env };\n console.log('[EnvDriver] Loaded config from process.env:', Object.keys(this.config).length, 'keys');\n }\n // No config source available\n else {\n console.warn('[EnvDriver] No config source available (neither window.' + globalName + ' nor process.env)');\n this.config = {};\n }\n\n console.log('[EnvDriver] Initial config keys:', [...Object.keys(this.config).filter(k => k.includes('APP') || k.includes('VITE'))]);\n\n // Strip prefix if configured\n if (this.options.envPrefix !== false) {\n console.log('[EnvDriver] Stripping prefix...');\n this.stripPrefix();\n console.log('[EnvDriver] After stripPrefix, config keys:', [...Object.keys(this.config).filter(k => k.includes('APP') || k.includes('VITE'))]);\n }\n\n // Expand variables if enabled\n if (this.options.expandVariables) {\n this.expandEnvVariables();\n }\n\n this.loaded = true;\n console.log('[EnvDriver] Load complete. Sample values:', {\n APP_NAME: this.config.APP_NAME,\n VITE_APP_NAME: this.config.VITE_APP_NAME,\n });\n return this.config;\n }\n\n /**\n * Get configuration value\n */\n get<T = any>(key: string, defaultValue?: T): T | undefined {\n if (!this.loaded) {\n this.load();\n }\n const value = getNestedValue(this.config, key, defaultValue);\n console.log(`[EnvDriver] get(\"${key}\", \"${defaultValue}\") = \"${value}\"`);\n return value;\n }\n\n /**\n * Check if key exists\n */\n has(key: string): boolean {\n if (!this.loaded) {\n this.load();\n }\n return hasNestedValue(this.config, key);\n }\n\n /**\n * Get all configuration\n */\n all(): Record<string, any> {\n if (!this.loaded) {\n this.load();\n }\n return { ...this.config };\n }\n\n /**\n * Load .env file using dotenv\n */\n private loadDotEnv(): void {\n try {\n // Try to load dotenv\n const dotenv = require('dotenv');\n const paths = Array.isArray(this.options.envFilePath)\n ? this.options.envFilePath\n : [this.options.envFilePath || '.env'];\n\n for (const path of paths) {\n dotenv.config({ path });\n }\n } catch (error) {\n // dotenv not installed, skip\n }\n }\n\n /**\n * Expand environment variables (e.g., ${VAR_NAME})\n */\n private expandEnvVariables(): void {\n const regex = /\\$\\{([^}]+)\\}/g;\n\n const expand = (value: string): string => {\n return value.replace(regex, (_, key) => {\n return this.config[key] || '';\n });\n };\n\n for (const [key, value] of Object.entries(this.config)) {\n if (typeof value === 'string' && value.includes('${')) {\n this.config[key] = expand(value);\n }\n }\n }\n\n /**\n * Strip environment variable prefix\n * Auto-detects framework (Vite, Next.js) or uses custom prefix\n */\n private stripPrefix(): void {\n let prefix = this.options.envPrefix;\n\n // Auto-detect framework prefix\n if (prefix === 'auto' || prefix === undefined) {\n // Check for Vite (import.meta.env exists or VITE_ variables present)\n const hasViteVars = Object.keys(this.config).some(key => key.startsWith('VITE_'));\n if (hasViteVars || typeof import.meta !== 'undefined') {\n prefix = 'VITE_';\n }\n // Check for Next.js (NEXT_PUBLIC_ variables present)\n else if (Object.keys(this.config).some(key => key.startsWith('NEXT_PUBLIC_'))) {\n prefix = 'NEXT_PUBLIC_';\n }\n // No framework detected, don't strip\n else {\n return;\n }\n }\n\n // Strip the prefix from all matching keys\n if (typeof prefix === 'string' && prefix.length > 0) {\n const newConfig: Record<string, any> = {};\n \n for (const [key, value] of Object.entries(this.config)) {\n if (key.startsWith(prefix)) {\n // Add both prefixed and unprefixed versions\n const unprefixedKey = key.substring(prefix.length);\n newConfig[unprefixedKey] = value;\n newConfig[key] = value; // Keep original too\n } else {\n newConfig[key] = value;\n }\n }\n \n this.config = newConfig;\n }\n }\n}\n","import type { ConfigDriver } from '@/interfaces/config-driver.interface';\nimport { getNestedValue, hasNestedValue } from '@/utils/get-nested-value.util';\n\n/**\n * File-based Configuration Driver\n * \n * Loads configuration from TypeScript/JavaScript files.\n * This is a server-side only driver. For client-side, use the Vite plugin.\n * \n * @see packages/pixielity/config/src/plugins/vite-config.plugin.ts\n */\nexport class FileDriver implements ConfigDriver {\n private config: Record<string, any> = {};\n private loaded = false;\n\n constructor(\n options: {\n config?: Record<string, any>;\n } = {}\n ) {\n // Pre-loaded config from Vite plugin or server\n if (options.config) {\n this.config = options.config;\n this.loaded = true;\n }\n }\n\n /**\n * Load configuration\n * Config should be pre-loaded via Vite plugin or passed in constructor\n */\n async load(): Promise<Record<string, any>> {\n if (this.loaded) {\n return this.config;\n }\n\n // If running on server (Node.js), throw error\n const isServer = typeof globalThis !== 'undefined' && \n typeof (globalThis as typeof globalThis & { window?: any }).window === 'undefined';\n \n if (isServer) {\n throw new Error(\n 'FileDriver requires pre-loaded configuration. ' +\n 'Use Vite plugin for client-side or pass config in constructor for server-side.'\n );\n }\n\n this.loaded = true;\n return this.config;\n }\n\n /**\n * Get configuration value\n */\n get<T = any>(key: string, defaultValue?: T): T | undefined {\n if (!this.loaded) {\n throw new Error('Configuration not loaded. Call load() first or use async initialization.');\n }\n return getNestedValue(this.config, key, defaultValue);\n }\n\n /**\n * Check if key exists\n */\n has(key: string): boolean {\n if (!this.loaded) {\n throw new Error('Configuration not loaded. Call load() first or use async initialization.');\n }\n return hasNestedValue(this.config, key);\n }\n\n /**\n * Get all configuration\n */\n all(): Record<string, any> {\n if (!this.loaded) {\n throw new Error('Configuration not loaded. Call load() first or use async initialization.');\n }\n return { ...this.config };\n }\n}\n","import { Inject, Injectable } from \"@abdokouta/react-di\";\n\nimport { CONFIG_DRIVER } from \"@/constants/tokens.constant\";\nimport type { ConfigDriver } from \"@/interfaces/config-driver.interface\";\nimport type { ConfigServiceInterface } from \"@/interfaces/config-service.interface\";\n\n/**\n * Configuration Service\n *\n * Provides type-safe access to configuration values with various getter methods.\n * Similar to NestJS ConfigService.\n *\n * @example\n * ```typescript\n * class MyService {\n * constructor(private config: ConfigService) {}\n *\n * getDbConfig() {\n * return {\n * host: this.config.getString('DB_HOST', 'localhost'),\n * port: this.config.getNumber('DB_PORT', 5432),\n * ssl: this.config.getBool('DB_SSL', false),\n * };\n * }\n * }\n * ```\n */\n@Injectable()\nexport class ConfigService implements ConfigServiceInterface {\n constructor(\n @Inject(CONFIG_DRIVER)\n private driver: ConfigDriver,\n ) {}\n\n /**\n * Get configuration value\n */\n get<T = any>(key: string, defaultValue?: T): T | undefined {\n return this.driver.get<T>(key, defaultValue);\n }\n\n /**\n * Get configuration value or throw if not found\n */\n getOrThrow<T = any>(key: string): T {\n const value = this.get<T>(key);\n if (value === undefined) {\n throw new Error(`Configuration key \"${key}\" is required but not set`);\n }\n return value;\n }\n\n /**\n * Get string value\n */\n getString(key: string, defaultValue?: string): string | undefined {\n const value = this.get(key, defaultValue);\n return value !== undefined ? String(value) : undefined;\n }\n\n /**\n * Get string value or throw\n */\n getStringOrThrow(key: string): string {\n return String(this.getOrThrow(key));\n }\n\n /**\n * Get number value\n */\n getNumber(key: string, defaultValue?: number): number | undefined {\n const value = this.get(key, defaultValue);\n if (value === undefined) {\n return undefined;\n }\n const parsed = Number(value);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n\n /**\n * Get number value or throw\n */\n getNumberOrThrow(key: string): number {\n const value = this.getNumber(key);\n if (value === undefined) {\n throw new Error(`Configuration key \"${key}\" is required but not set`);\n }\n return value;\n }\n\n /**\n * Get boolean value\n * Treats 'true', '1', 'yes', 'on' as true\n */\n getBool(key: string, defaultValue?: boolean): boolean | undefined {\n const value = this.get(key, defaultValue);\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n return [\"true\", \"1\", \"yes\", \"on\"].includes(String(value).toLowerCase());\n }\n\n /**\n * Get boolean value or throw\n */\n getBoolOrThrow(key: string): boolean {\n const value = this.getBool(key);\n if (value === undefined) {\n throw new Error(`Configuration key \"${key}\" is required but not set`);\n }\n return value;\n }\n\n /**\n * Get array value (comma-separated string or actual array)\n */\n getArray(key: string, defaultValue?: string[]): string[] | undefined {\n const value = this.get(key, defaultValue);\n if (value === undefined) {\n return undefined;\n }\n if (Array.isArray(value)) {\n return value.map(String);\n }\n return String(value)\n .split(\",\")\n .map((v) => v.trim())\n .filter(Boolean);\n }\n\n /**\n * Get JSON value\n */\n getJson<T = any>(key: string, defaultValue?: T): T | undefined {\n const value = this.get(key, defaultValue);\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"object\") {\n return value as T;\n }\n try {\n return JSON.parse(String(value)) as T;\n } catch {\n return defaultValue;\n }\n }\n\n /**\n * Check if configuration key exists\n */\n has(key: string): boolean {\n return this.driver.has(key);\n }\n\n /**\n * Get all configuration values\n */\n all(): Record<string, any> {\n return this.driver.all();\n }\n\n /**\n * Clear cache (no-op since we don't cache in ConfigService)\n */\n clearCache(): void {\n // No-op - caching should be done at a higher level if needed\n }\n}\n","/**\n * Dependency Injection Tokens\n * \n * Used for injecting configuration dependencies.\n */\n\n/**\n * Configuration driver token\n * \n * @example\n * ```typescript\n * @Inject(CONFIG_DRIVER)\n * private driver: ConfigDriver\n * ```\n */\nexport const CONFIG_DRIVER = Symbol('CONFIG_DRIVER');\n\n/**\n * Configuration options token\n * \n * @example\n * ```typescript\n * @Inject(CONFIG_OPTIONS)\n * private options: ConfigModuleOptions\n * ```\n */\nexport const CONFIG_OPTIONS = Symbol('CONFIG_OPTIONS');\n\n/**\n * Configuration service token\n * \n * @example\n * ```typescript\n * @Inject(CONFIG_SERVICE)\n * private config: ConfigService\n * ```\n */\nexport const CONFIG_SERVICE = Symbol('CONFIG_SERVICE');\n","/**\n * Load Config File Utility\n *\n * Dynamically loads and parses a config file.\n */\n\n/**\n * Load and parse config file\n *\n * @param filePath - Absolute path to the config file\n * @returns Parsed config object\n */\nexport async function loadConfigFile(\n filePath: string\n): Promise<Record<string, any>> {\n try {\n // Dynamic import of the config file\n // @ts-ignore - Dynamic import path\n const module = await import(/* @vite-ignore */ filePath);\n\n // Extract config object (could be default export or named export)\n const config = module.default || module;\n\n // If it's a function, call it\n if (typeof config === 'function') {\n return await config();\n }\n\n return config;\n } catch (error) {\n console.warn(\n `[vite-plugin-config] Failed to load config file: ${filePath}`,\n error\n );\n return {};\n }\n}\n"],"mappings":"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","names":["import_react_di","module"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.module.ts","../src/utils/get-nested-value.util.ts","../src/drivers/env.driver.ts","../src/drivers/file.driver.ts","../src/services/config.service.ts","../src/constants/tokens.constant.ts","../src/utils/define-config.util.ts","../src/utils/load-config-file.util.ts"],"sourcesContent":["/**\n * @abdokouta/config\n *\n * NestJS-inspired configuration management with multiple drivers for loading\n * configuration from various sources (environment variables, files, etc.).\n * Provides type-safe access to configuration values with support for nested\n * properties and default values.\n *\n * @example\n * Basic usage with environment variables:\n * ```typescript\n * import { ConfigModule, ConfigService, EnvDriver } from '@abdokouta/config';\n * import { Module, Injectable, Inject } from '@abdokouta/react-di';\n *\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * driver: new EnvDriver(),\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * @Injectable()\n * class DatabaseService {\n * constructor(@Inject(ConfigService) private config: ConfigService) {}\n *\n * connect() {\n * const host = this.config.get('DATABASE_HOST', 'localhost');\n * const port = this.config.get('DATABASE_PORT', 5432);\n * // Connect to database...\n * }\n * }\n * ```\n *\n * @example\n * Using file-based configuration:\n * ```typescript\n * import { ConfigModule, FileDriver } from '@abdokouta/config';\n *\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * driver: new FileDriver({\n * path: './config/app.json',\n * }),\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n *\n * @example\n * Accessing nested configuration:\n * ```typescript\n * // config.json: { \"database\": { \"host\": \"localhost\", \"port\": 5432 } }\n * const host = config.get('database.host');\n * const port = config.get('database.port', 3306);\n * ```\n *\n * @module @abdokouta/config\n */\n\n// ============================================================================\n// Module (DI Configuration)\n// ============================================================================\nexport { ConfigModule } from './config.module';\n\n// ============================================================================\n// Core Service\n// ============================================================================\nexport { ConfigService } from './services/config.service';\n\n// ============================================================================\n// Drivers\n// ============================================================================\nexport { EnvDriver } from './drivers/env.driver';\nexport { FileDriver } from './drivers/file.driver';\n\n// ============================================================================\n// Interfaces\n// ============================================================================\nexport type { ConfigDriver } from './interfaces/config-driver.interface';\nexport type { ConfigModuleOptions } from './interfaces/config-module-options.interface';\nexport type { ConfigServiceInterface } from './interfaces/config-service.interface';\nexport type { ViteConfigPluginOptions } from './interfaces/vite-config-plugin-options.interface';\n\n// ============================================================================\n// Utilities\n// ============================================================================\nexport { defineConfig } from './utils/define-config.util';\nexport { getNestedValue, hasNestedValue } from './utils/get-nested-value.util';\nexport { loadConfigFile } from './utils/load-config-file.util';\n","import { Module, DynamicModule } from '@abdokouta/react-di';\n\nimport { EnvDriver } from './drivers/env.driver';\nimport { FileDriver } from './drivers/file.driver';\nimport { ConfigService } from './services/config.service';\nimport type { ConfigDriver } from './interfaces/config-driver.interface';\nimport type { ConfigModuleOptions } from './interfaces/config-module-options.interface';\nimport { CONFIG_DRIVER, CONFIG_OPTIONS, CONFIG_SERVICE } from './constants/tokens.constant';\n\n/**\n * Configuration Module\n *\n * Provides configuration management with multiple drivers.\n * Similar to NestJS ConfigModule.\n *\n * @example\n * ```typescript\n * // Using environment variables (default)\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * envFilePath: '.env',\n * isGlobal: true,\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n *\n * @example\n * ```typescript\n * // Using file-based configuration\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * driver: 'file',\n * filePattern: 'config/**\\/*.config.ts',\n * isGlobal: true,\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class ConfigModule {\n /**\n * Register configuration module with options\n *\n * @param options - Configuration options\n * @returns Dynamic module\n */\n static forRoot(options: ConfigModuleOptions = {}): DynamicModule {\n const driver = this.createDriver(options);\n\n const isGlobal = options.isGlobal ?? false;\n\n const providers = [\n {\n provide: CONFIG_OPTIONS,\n useValue: options,\n isGlobal,\n },\n {\n provide: CONFIG_DRIVER,\n useValue: driver,\n isGlobal,\n },\n ConfigService,\n {\n provide: CONFIG_SERVICE,\n useExisting: ConfigService,\n isGlobal,\n },\n ];\n\n return {\n module: ConfigModule,\n providers: providers as any,\n exports: [ConfigService],\n };\n }\n\n /**\n * Register configuration module asynchronously\n *\n * @param options - Async configuration options\n * @returns Dynamic module\n */\n static async forRootAsync(\n options: ConfigModuleOptions & {\n useFactory?: () => Promise<ConfigModuleOptions> | ConfigModuleOptions;\n }\n ): Promise<DynamicModule> {\n const resolvedOptions = options.useFactory ? await options.useFactory() : options;\n\n return this.forRoot(resolvedOptions);\n }\n\n /**\n * Create configuration driver based on options\n */\n private static createDriver(options: ConfigModuleOptions): ConfigDriver {\n const driverType = options.driver || 'env';\n\n switch (driverType) {\n case 'env':\n const envDriver = new EnvDriver({\n envFilePath: options.envFilePath,\n ignoreEnvFile: options.ignoreEnvFile,\n expandVariables: options.expandVariables,\n envPrefix: options.envPrefix,\n globalName: options.globalName,\n });\n envDriver.load();\n\n // Merge custom load function if provided\n if (options.load) {\n this.mergeCustomConfig(envDriver, options.load);\n }\n\n return envDriver;\n\n case 'file':\n const fileDriver = new FileDriver({\n config: typeof options.load === 'object' ? options.load : undefined,\n });\n return fileDriver;\n\n default:\n throw new Error(`Unknown configuration driver: ${driverType}`);\n }\n }\n\n /**\n * Merge custom configuration into driver\n */\n private static mergeCustomConfig(\n driver: ConfigDriver,\n load: Record<string, any> | (() => Record<string, any> | Promise<Record<string, any>>)\n ): void {\n const customConfig = typeof load === 'function' ? load() : load;\n\n if (customConfig instanceof Promise) {\n customConfig.then((config) => {\n Object.assign(driver.all(), config);\n });\n } else {\n Object.assign(driver.all(), customConfig);\n }\n }\n}\n","/**\n * Get nested value from object using dot notation\n *\n * @param obj - Source object\n * @param path - Dot-notated path (e.g., 'database.host')\n * @param defaultValue - Default value if path not found\n * @returns Value at path or default value\n *\n * @example\n * ```typescript\n * const config = { database: { host: 'localhost' } };\n * getNestedValue(config, 'database.host'); // 'localhost'\n * getNestedValue(config, 'database.port', 5432); // 5432\n * ```\n */\nexport function getNestedValue<T = any>(\n obj: Record<string, any>,\n path: string,\n defaultValue?: T\n): T | undefined {\n const keys = path.split('.');\n let current: any = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return defaultValue;\n }\n current = current[key];\n }\n\n return current !== undefined ? current : defaultValue;\n}\n\n/**\n * Check if nested path exists in object\n *\n * @param obj - Source object\n * @param path - Dot-notated path\n * @returns True if path exists\n */\nexport function hasNestedValue(obj: Record<string, any>, path: string): boolean {\n const keys = path.split('.');\n let current: any = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined || !(key in current)) {\n return false;\n }\n current = current[key];\n }\n\n return true;\n}\n","import type { ConfigDriver } from '../interfaces/config-driver.interface';\nimport { getNestedValue, hasNestedValue } from '../utils/get-nested-value.util';\n\n/**\n * Environment Variable Configuration Driver\n *\n * Loads configuration from environment variables (process.env).\n * Supports .env files via dotenv.\n */\nexport class EnvDriver implements ConfigDriver {\n private config: Record<string, any> = {};\n private loaded = false;\n\n constructor(\n private options: {\n envFilePath?: string | string[];\n ignoreEnvFile?: boolean;\n expandVariables?: boolean;\n envPrefix?: string | false;\n globalName?: string; // Custom global variable name\n } = {}\n ) {}\n\n /**\n * Load environment variables\n */\n load(): Record<string, any> {\n if (this.loaded) {\n console.log('[EnvDriver] Already loaded, returning cached config');\n return this.config;\n }\n\n console.log('[EnvDriver] Loading environment variables...');\n console.log('[EnvDriver] Options:', { ...this.options });\n\n // Load .env file if not ignored\n if (!this.options.ignoreEnvFile) {\n this.loadDotEnv();\n }\n\n // Get global config name (default: __APP_CONFIG__)\n const globalName = this.options.globalName || '__APP_CONFIG__';\n\n // Try to load from custom global variable first (browser environment)\n if (typeof window !== 'undefined' && (window as any)[globalName]) {\n this.config = { ...(window as any)[globalName] };\n console.log(\n `[EnvDriver] Loaded config from window.${globalName}:`,\n Object.keys(this.config).length,\n 'keys'\n );\n }\n // Fallback to process.env (Node.js environment or backward compatibility)\n else if (typeof process !== 'undefined' && process.env) {\n this.config = { ...process.env };\n console.log(\n '[EnvDriver] Loaded config from process.env:',\n Object.keys(this.config).length,\n 'keys'\n );\n }\n // No config source available\n else {\n console.warn(\n '[EnvDriver] No config source available (neither window.' + globalName + ' nor process.env)'\n );\n this.config = {};\n }\n\n console.log('[EnvDriver] Initial config keys:', [\n ...Object.keys(this.config).filter((k) => k.includes('APP') || k.includes('VITE')),\n ]);\n\n // Strip prefix if configured\n if (this.options.envPrefix !== false) {\n console.log('[EnvDriver] Stripping prefix...');\n this.stripPrefix();\n console.log('[EnvDriver] After stripPrefix, config keys:', [\n ...Object.keys(this.config).filter((k) => k.includes('APP') || k.includes('VITE')),\n ]);\n }\n\n // Expand variables if enabled\n if (this.options.expandVariables) {\n this.expandEnvVariables();\n }\n\n this.loaded = true;\n console.log('[EnvDriver] Load complete. Sample values:', {\n APP_NAME: this.config.APP_NAME,\n VITE_APP_NAME: this.config.VITE_APP_NAME,\n });\n return this.config;\n }\n\n /**\n * Get configuration value\n */\n get<T = any>(key: string, defaultValue?: T): T | undefined {\n if (!this.loaded) {\n this.load();\n }\n const value = getNestedValue(this.config, key, defaultValue);\n console.log(`[EnvDriver] get(\"${key}\", \"${defaultValue}\") = \"${value}\"`);\n return value;\n }\n\n /**\n * Check if key exists\n */\n has(key: string): boolean {\n if (!this.loaded) {\n this.load();\n }\n return hasNestedValue(this.config, key);\n }\n\n /**\n * Get all configuration\n */\n all(): Record<string, any> {\n if (!this.loaded) {\n this.load();\n }\n return { ...this.config };\n }\n\n /**\n * Load .env file using dotenv\n */\n private loadDotEnv(): void {\n try {\n // Try to load dotenv\n const dotenv = require('dotenv');\n const paths = Array.isArray(this.options.envFilePath)\n ? this.options.envFilePath\n : [this.options.envFilePath || '.env'];\n\n for (const path of paths) {\n dotenv.config({ path });\n }\n } catch (error) {\n // dotenv not installed, skip\n }\n }\n\n /**\n * Expand environment variables (e.g., ${VAR_NAME})\n */\n private expandEnvVariables(): void {\n const regex = /\\$\\{([^}]+)\\}/g;\n\n const expand = (value: string): string => {\n return value.replace(regex, (_, key) => {\n return this.config[key] || '';\n });\n };\n\n for (const [key, value] of Object.entries(this.config)) {\n if (typeof value === 'string' && value.includes('${')) {\n this.config[key] = expand(value);\n }\n }\n }\n\n /**\n * Strip environment variable prefix\n * Auto-detects framework (Vite, Next.js) or uses custom prefix\n */\n private stripPrefix(): void {\n let prefix = this.options.envPrefix;\n\n // Auto-detect framework prefix\n if (prefix === 'auto' || prefix === undefined) {\n // Check for Vite (import.meta.env exists or VITE_ variables present)\n const hasViteVars = Object.keys(this.config).some((key) => key.startsWith('VITE_'));\n if (hasViteVars || typeof import.meta !== 'undefined') {\n prefix = 'VITE_';\n }\n // Check for Next.js (NEXT_PUBLIC_ variables present)\n else if (Object.keys(this.config).some((key) => key.startsWith('NEXT_PUBLIC_'))) {\n prefix = 'NEXT_PUBLIC_';\n }\n // No framework detected, don't strip\n else {\n return;\n }\n }\n\n // Strip the prefix from all matching keys\n if (typeof prefix === 'string' && prefix.length > 0) {\n const newConfig: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(this.config)) {\n if (key.startsWith(prefix)) {\n // Add both prefixed and unprefixed versions\n const unprefixedKey = key.substring(prefix.length);\n newConfig[unprefixedKey] = value;\n newConfig[key] = value; // Keep original too\n } else {\n newConfig[key] = value;\n }\n }\n\n this.config = newConfig;\n }\n }\n}\n","import type { ConfigDriver } from '@/interfaces/config-driver.interface';\nimport { getNestedValue, hasNestedValue } from '@/utils/get-nested-value.util';\n\n/**\n * File-based Configuration Driver\n *\n * Loads configuration from TypeScript/JavaScript files.\n * This is a server-side only driver. For client-side, use the Vite plugin.\n *\n * @see packages/abdokouta/config/src/plugins/vite-config.plugin.ts\n */\nexport class FileDriver implements ConfigDriver {\n private config: Record<string, any> = {};\n private loaded = false;\n\n constructor(\n options: {\n config?: Record<string, any>;\n } = {}\n ) {\n // Pre-loaded config from Vite plugin or server\n if (options.config) {\n this.config = options.config;\n this.loaded = true;\n }\n }\n\n /**\n * Load configuration\n * Config should be pre-loaded via Vite plugin or passed in constructor\n */\n async load(): Promise<Record<string, any>> {\n if (this.loaded) {\n return this.config;\n }\n\n // If running on server (Node.js), throw error\n const isServer =\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as typeof globalThis & { window?: any }).window === 'undefined';\n\n if (isServer) {\n throw new Error(\n 'FileDriver requires pre-loaded configuration. ' +\n 'Use Vite plugin for client-side or pass config in constructor for server-side.'\n );\n }\n\n this.loaded = true;\n return this.config;\n }\n\n /**\n * Get configuration value\n */\n get<T = any>(key: string, defaultValue?: T): T | undefined {\n if (!this.loaded) {\n throw new Error('Configuration not loaded. Call load() first or use async initialization.');\n }\n return getNestedValue(this.config, key, defaultValue);\n }\n\n /**\n * Check if key exists\n */\n has(key: string): boolean {\n if (!this.loaded) {\n throw new Error('Configuration not loaded. Call load() first or use async initialization.');\n }\n return hasNestedValue(this.config, key);\n }\n\n /**\n * Get all configuration\n */\n all(): Record<string, any> {\n if (!this.loaded) {\n throw new Error('Configuration not loaded. Call load() first or use async initialization.');\n }\n return { ...this.config };\n }\n}\n","import { Inject, Injectable } from '@abdokouta/react-di';\n\nimport { CONFIG_DRIVER } from '@/constants/tokens.constant';\nimport type { ConfigDriver } from '@/interfaces/config-driver.interface';\nimport type { ConfigServiceInterface } from '@/interfaces/config-service.interface';\n\n/**\n * Configuration Service\n *\n * Provides type-safe access to configuration values with various getter methods.\n * Similar to NestJS ConfigService.\n *\n * @example\n * ```typescript\n * class MyService {\n * constructor(private config: ConfigService) {}\n *\n * getDbConfig() {\n * return {\n * host: this.config.getString('DB_HOST', 'localhost'),\n * port: this.config.getNumber('DB_PORT', 5432),\n * ssl: this.config.getBool('DB_SSL', false),\n * };\n * }\n * }\n * ```\n */\n@Injectable()\nexport class ConfigService implements ConfigServiceInterface {\n constructor(\n @Inject(CONFIG_DRIVER)\n private driver: ConfigDriver\n ) {}\n\n /**\n * Get configuration value\n */\n get<T = any>(key: string, defaultValue?: T): T | undefined {\n return this.driver.get<T>(key, defaultValue);\n }\n\n /**\n * Get configuration value or throw if not found\n */\n getOrThrow<T = any>(key: string): T {\n const value = this.get<T>(key);\n if (value === undefined) {\n throw new Error(`Configuration key \"${key}\" is required but not set`);\n }\n return value;\n }\n\n /**\n * Get string value\n */\n getString(key: string, defaultValue?: string): string | undefined {\n const value = this.get(key, defaultValue);\n return value !== undefined ? String(value) : undefined;\n }\n\n /**\n * Get string value or throw\n */\n getStringOrThrow(key: string): string {\n return String(this.getOrThrow(key));\n }\n\n /**\n * Get number value\n */\n getNumber(key: string, defaultValue?: number): number | undefined {\n const value = this.get(key, defaultValue);\n if (value === undefined) {\n return undefined;\n }\n const parsed = Number(value);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n\n /**\n * Get number value or throw\n */\n getNumberOrThrow(key: string): number {\n const value = this.getNumber(key);\n if (value === undefined) {\n throw new Error(`Configuration key \"${key}\" is required but not set`);\n }\n return value;\n }\n\n /**\n * Get boolean value\n * Treats 'true', '1', 'yes', 'on' as true\n */\n getBool(key: string, defaultValue?: boolean): boolean | undefined {\n const value = this.get(key, defaultValue);\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === 'boolean') {\n return value;\n }\n return ['true', '1', 'yes', 'on'].includes(String(value).toLowerCase());\n }\n\n /**\n * Get boolean value or throw\n */\n getBoolOrThrow(key: string): boolean {\n const value = this.getBool(key);\n if (value === undefined) {\n throw new Error(`Configuration key \"${key}\" is required but not set`);\n }\n return value;\n }\n\n /**\n * Get array value (comma-separated string or actual array)\n */\n getArray(key: string, defaultValue?: string[]): string[] | undefined {\n const value = this.get(key, defaultValue);\n if (value === undefined) {\n return undefined;\n }\n if (Array.isArray(value)) {\n return value.map(String);\n }\n return String(value)\n .split(',')\n .map((v) => v.trim())\n .filter(Boolean);\n }\n\n /**\n * Get JSON value\n */\n getJson<T = any>(key: string, defaultValue?: T): T | undefined {\n const value = this.get(key, defaultValue);\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === 'object') {\n return value as T;\n }\n try {\n return JSON.parse(String(value)) as T;\n } catch {\n return defaultValue;\n }\n }\n\n /**\n * Check if configuration key exists\n */\n has(key: string): boolean {\n return this.driver.has(key);\n }\n\n /**\n * Get all configuration values\n */\n all(): Record<string, any> {\n return this.driver.all();\n }\n\n /**\n * Clear cache (no-op since we don't cache in ConfigService)\n */\n clearCache(): void {\n // No-op - caching should be done at a higher level if needed\n }\n}\n","/**\n * Dependency Injection Tokens\n *\n * Used for injecting configuration dependencies.\n */\n\n/**\n * Configuration driver token\n *\n * @example\n * ```typescript\n * @Inject(CONFIG_DRIVER)\n * private driver: ConfigDriver\n * ```\n */\nexport const CONFIG_DRIVER = Symbol('CONFIG_DRIVER');\n\n/**\n * Configuration options token\n *\n * @example\n * ```typescript\n * @Inject(CONFIG_OPTIONS)\n * private options: ConfigModuleOptions\n * ```\n */\nexport const CONFIG_OPTIONS = Symbol('CONFIG_OPTIONS');\n\n/**\n * Configuration service token\n *\n * @example\n * ```typescript\n * @Inject(CONFIG_SERVICE)\n * private config: ConfigService\n * ```\n */\nexport const CONFIG_SERVICE = Symbol('CONFIG_SERVICE');\n","/**\n * Define Config Utility\n *\n * Helper function to define config module options with type safety.\n *\n * @module @abdokouta/config\n */\n\nimport type { ConfigModuleOptions } from '../interfaces/config-module-options.interface';\n\n/**\n * Helper function to define config module options with type safety\n *\n * Provides IDE autocomplete and type checking for configuration objects.\n * This pattern is consistent with modern tooling (Vite, Vitest, etc.).\n *\n * @param config - The config module options object\n * @returns The same configuration object with proper typing\n *\n * @example\n * ```typescript\n * // config.config.ts\n * import { defineConfig } from '@abdokouta/config';\n *\n * export default defineConfig({\n * driver: 'env',\n * ignoreEnvFile: true,\n * isGlobal: true,\n * envPrefix: 'auto',\n * });\n * ```\n */\nexport function defineConfig(config: ConfigModuleOptions): ConfigModuleOptions {\n return config;\n}\n","/**\n * Load Config File Utility\n *\n * Dynamically loads and parses a config file.\n */\n\n/**\n * Load and parse config file\n *\n * @param filePath - Absolute path to the config file\n * @returns Parsed config object\n */\nexport async function loadConfigFile(filePath: string): Promise<Record<string, any>> {\n try {\n // Dynamic import of the config file\n // @ts-ignore - Dynamic import path\n const module = await import(/* @vite-ignore */ filePath);\n\n // Extract config object (could be default export or named export)\n const config = module.default || module;\n\n // If it's a function, call it\n if (typeof config === 'function') {\n return await config();\n }\n\n return config;\n } catch (error) {\n console.warn(`[vite-plugin-config] Failed to load config file: ${filePath}`, error);\n return {};\n }\n}\n"],"mappings":"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","names":["import_react_di","module"]}
package/dist/index.mjs CHANGED
@@ -68,19 +68,33 @@ var EnvDriver = class {
68
68
  const globalName = this.options.globalName || "__APP_CONFIG__";
69
69
  if (typeof window !== "undefined" && window[globalName]) {
70
70
  this.config = { ...window[globalName] };
71
- console.log(`[EnvDriver] Loaded config from window.${globalName}:`, Object.keys(this.config).length, "keys");
71
+ console.log(
72
+ `[EnvDriver] Loaded config from window.${globalName}:`,
73
+ Object.keys(this.config).length,
74
+ "keys"
75
+ );
72
76
  } else if (typeof process !== "undefined" && process.env) {
73
77
  this.config = { ...process.env };
74
- console.log("[EnvDriver] Loaded config from process.env:", Object.keys(this.config).length, "keys");
78
+ console.log(
79
+ "[EnvDriver] Loaded config from process.env:",
80
+ Object.keys(this.config).length,
81
+ "keys"
82
+ );
75
83
  } else {
76
- console.warn("[EnvDriver] No config source available (neither window." + globalName + " nor process.env)");
84
+ console.warn(
85
+ "[EnvDriver] No config source available (neither window." + globalName + " nor process.env)"
86
+ );
77
87
  this.config = {};
78
88
  }
79
- console.log("[EnvDriver] Initial config keys:", [...Object.keys(this.config).filter((k) => k.includes("APP") || k.includes("VITE"))]);
89
+ console.log("[EnvDriver] Initial config keys:", [
90
+ ...Object.keys(this.config).filter((k) => k.includes("APP") || k.includes("VITE"))
91
+ ]);
80
92
  if (this.options.envPrefix !== false) {
81
93
  console.log("[EnvDriver] Stripping prefix...");
82
94
  this.stripPrefix();
83
- console.log("[EnvDriver] After stripPrefix, config keys:", [...Object.keys(this.config).filter((k) => k.includes("APP") || k.includes("VITE"))]);
95
+ console.log("[EnvDriver] After stripPrefix, config keys:", [
96
+ ...Object.keys(this.config).filter((k) => k.includes("APP") || k.includes("VITE"))
97
+ ]);
84
98
  }
85
99
  if (this.options.expandVariables) {
86
100
  this.expandEnvVariables();
@@ -382,7 +396,7 @@ ConfigService = __decorateClass([
382
396
  var ConfigModule = class {
383
397
  /**
384
398
  * Register configuration module with options
385
- *
399
+ *
386
400
  * @param options - Configuration options
387
401
  * @returns Dynamic module
388
402
  */
@@ -415,7 +429,7 @@ var ConfigModule = class {
415
429
  }
416
430
  /**
417
431
  * Register configuration module asynchronously
418
- *
432
+ *
419
433
  * @param options - Async configuration options
420
434
  * @returns Dynamic module
421
435
  */
@@ -469,6 +483,11 @@ ConfigModule = __decorateClass([
469
483
  Module({})
470
484
  ], ConfigModule);
471
485
 
486
+ // src/utils/define-config.util.ts
487
+ function defineConfig(config) {
488
+ return config;
489
+ }
490
+
472
491
  // src/utils/load-config-file.util.ts
473
492
  async function loadConfigFile(filePath) {
474
493
  try {
@@ -482,10 +501,7 @@ async function loadConfigFile(filePath) {
482
501
  }
483
502
  return config;
484
503
  } catch (error) {
485
- console.warn(
486
- `[vite-plugin-config] Failed to load config file: ${filePath}`,
487
- error
488
- );
504
+ console.warn(`[vite-plugin-config] Failed to load config file: ${filePath}`, error);
489
505
  return {};
490
506
  }
491
507
  }
@@ -494,6 +510,7 @@ export {
494
510
  ConfigService,
495
511
  EnvDriver,
496
512
  FileDriver,
513
+ defineConfig,
497
514
  getNestedValue,
498
515
  hasNestedValue,
499
516
  loadConfigFile