@abdokouta/react-config 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.examples/01-basic-usage.ts +289 -0
  2. package/.examples/02-env-helper.ts +282 -0
  3. package/.examples/README.md +285 -0
  4. package/.prettierrc.js +1 -0
  5. package/README.md +261 -0
  6. package/__tests__/config.module.test.ts +244 -0
  7. package/__tests__/drivers/env.driver.test.ts +259 -0
  8. package/__tests__/services/config.service.test.ts +328 -0
  9. package/__tests__/setup.d.ts +11 -0
  10. package/__tests__/vitest.setup.ts +30 -0
  11. package/config/config.config.ts +62 -0
  12. package/dist/index.d.mts +474 -0
  13. package/dist/index.d.ts +474 -0
  14. package/dist/index.js +516 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/index.mjs +501 -0
  17. package/dist/index.mjs.map +1 -0
  18. package/eslint.config.js +13 -0
  19. package/package.json +77 -0
  20. package/src/config.module.ts +154 -0
  21. package/src/constants/index.ts +5 -0
  22. package/src/constants/tokens.constant.ts +38 -0
  23. package/src/drivers/env.driver.ts +194 -0
  24. package/src/drivers/file.driver.ts +81 -0
  25. package/src/drivers/index.ts +6 -0
  26. package/src/index.ts +92 -0
  27. package/src/interfaces/config-driver.interface.ts +30 -0
  28. package/src/interfaces/config-module-options.interface.ts +84 -0
  29. package/src/interfaces/config-service.interface.ts +71 -0
  30. package/src/interfaces/index.ts +8 -0
  31. package/src/interfaces/vite-config-plugin-options.interface.ts +56 -0
  32. package/src/plugins/index.ts +5 -0
  33. package/src/plugins/vite.plugin.ts +115 -0
  34. package/src/services/config.service.ts +172 -0
  35. package/src/services/index.ts +5 -0
  36. package/src/utils/get-nested-value.util.ts +56 -0
  37. package/src/utils/index.ts +6 -0
  38. package/src/utils/load-config-file.util.ts +37 -0
  39. package/src/utils/scan-config-files.util.ts +40 -0
  40. package/tsconfig.json +28 -0
  41. package/tsup.config.ts +105 -0
  42. package/vitest.config.ts +66 -0
@@ -0,0 +1,285 @@
1
+ # Config Examples
2
+
3
+ This folder contains examples demonstrating how to use `@abdokouta/config` in various scenarios.
4
+
5
+ ## Examples Overview
6
+
7
+ ### 1. Basic Usage (`01-basic-usage.ts`)
8
+
9
+ Learn the fundamental configuration operations:
10
+ - ✅ Environment variable access
11
+ - ✅ Type-safe getters (getString, getNumber, getBool)
12
+ - ✅ Default values
13
+ - ✅ Nested configuration
14
+ - ✅ JSON configuration
15
+ - ✅ Array values
16
+
17
+ **Run:**
18
+ ```bash
19
+ ts-node examples/01-basic-usage.ts
20
+ ```
21
+
22
+ ### 2. Multiple Drivers (`02-multiple-drivers.ts`)
23
+
24
+ Work with different configuration drivers:
25
+ - ✅ Environment driver (dotenv)
26
+ - ✅ File driver (TypeScript/JSON)
27
+ - ✅ Switching between drivers
28
+ - ✅ Driver-specific features
29
+ - ✅ Configuration merging
30
+
31
+ **Run:**
32
+ ```bash
33
+ ts-node examples/02-multiple-drivers.ts
34
+ ```
35
+
36
+ ### 3. Env Helper (`03-env-helper.ts`)
37
+
38
+ Use the standalone Env utility:
39
+ - ✅ Direct environment access
40
+ - ✅ Type conversions
41
+ - ✅ No service injection needed
42
+ - ✅ Static helper methods
43
+ - ✅ Quick access patterns
44
+
45
+ **Run:**
46
+ ```bash
47
+ ts-node examples/03-env-helper.ts
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ ### Installation
53
+
54
+ ```bash
55
+ npm install @abdokouta/config @abdokouta/container
56
+ ```
57
+
58
+ ### Basic Setup
59
+
60
+ ```typescript
61
+ import { ConfigModule, ConfigService } from '@abdokouta/config';
62
+ import { Inversiland } from '@abdokouta/container';
63
+
64
+ // Initialize config
65
+ const app = await Inversiland.run({
66
+ module: class AppModule {},
67
+ imports: [
68
+ ConfigModule.forRoot({
69
+ driver: 'env',
70
+ envFilePath: '.env',
71
+ isGlobal: true,
72
+ }),
73
+ ],
74
+ });
75
+
76
+ // Get config service
77
+ const config = app.get(ConfigService);
78
+
79
+ // Use config
80
+ const dbHost = config.getString('DB_HOST', 'localhost');
81
+ const dbPort = config.getNumber('DB_PORT', 5432);
82
+ ```
83
+
84
+ ## Common Patterns
85
+
86
+ ### 1. Database Configuration
87
+
88
+ ```typescript
89
+ const dbConfig = {
90
+ host: config.getString('DB_HOST', 'localhost'),
91
+ port: config.getNumber('DB_PORT', 5432),
92
+ database: config.getString('DB_NAME', 'myapp'),
93
+ username: config.getStringOrThrow('DB_USER'),
94
+ password: config.getStringOrThrow('DB_PASSWORD'),
95
+ ssl: config.getBool('DB_SSL', false),
96
+ };
97
+ ```
98
+
99
+ ### 2. API Configuration
100
+
101
+ ```typescript
102
+ const apiConfig = {
103
+ url: config.getString('API_URL', 'http://localhost:3000'),
104
+ timeout: config.getNumber('API_TIMEOUT', 5000),
105
+ retries: config.getNumber('API_RETRIES', 3),
106
+ apiKey: config.getStringOrThrow('API_KEY'),
107
+ };
108
+ ```
109
+
110
+ ### 3. Feature Flags
111
+
112
+ ```typescript
113
+ const features = {
114
+ enableCache: config.getBool('FEATURE_CACHE', true),
115
+ enableLogging: config.getBool('FEATURE_LOGGING', true),
116
+ enableMetrics: config.getBool('FEATURE_METRICS', false),
117
+ };
118
+ ```
119
+
120
+ ### 4. Array Configuration
121
+
122
+ ```typescript
123
+ const allowedOrigins = config.getArray('CORS_ORIGINS', ['http://localhost:3000']);
124
+ const trustedProxies = config.getArray('TRUSTED_PROXIES', []);
125
+ ```
126
+
127
+ ### 5. JSON Configuration
128
+
129
+ ```typescript
130
+ const complexConfig = config.getJson('APP_CONFIG', {
131
+ theme: 'light',
132
+ locale: 'en',
133
+ features: [],
134
+ });
135
+ ```
136
+
137
+ ## Best Practices
138
+
139
+ ### 1. Use Type-Safe Getters
140
+
141
+ ```typescript
142
+ // Good: Type-safe with defaults
143
+ const port = config.getNumber('PORT', 3000);
144
+ const debug = config.getBool('DEBUG', false);
145
+
146
+ // Bad: Generic get without type safety
147
+ const port = config.get('PORT') || 3000;
148
+ ```
149
+
150
+ ### 2. Require Critical Values
151
+
152
+ ```typescript
153
+ // Use OrThrow for required configuration
154
+ const apiKey = config.getStringOrThrow('API_KEY');
155
+ const dbPassword = config.getStringOrThrow('DB_PASSWORD');
156
+ ```
157
+
158
+ ### 3. Group Related Configuration
159
+
160
+ ```typescript
161
+ class DatabaseConfig {
162
+ constructor(private config: ConfigService) {}
163
+
164
+ get host() {
165
+ return this.config.getString('DB_HOST', 'localhost');
166
+ }
167
+
168
+ get port() {
169
+ return this.config.getNumber('DB_PORT', 5432);
170
+ }
171
+
172
+ get credentials() {
173
+ return {
174
+ username: this.config.getStringOrThrow('DB_USER'),
175
+ password: this.config.getStringOrThrow('DB_PASSWORD'),
176
+ };
177
+ }
178
+ }
179
+ ```
180
+
181
+ ### 4. Use Environment-Specific Defaults
182
+
183
+ ```typescript
184
+ const env = config.getString('NODE_ENV', 'development');
185
+
186
+ const logLevel = config.getString(
187
+ 'LOG_LEVEL',
188
+ env === 'production' ? 'error' : 'debug'
189
+ );
190
+ ```
191
+
192
+ ### 5. Validate Configuration on Startup
193
+
194
+ ```typescript
195
+ function validateConfig(config: ConfigService) {
196
+ const required = ['DB_HOST', 'DB_USER', 'DB_PASSWORD', 'API_KEY'];
197
+
198
+ for (const key of required) {
199
+ if (!config.has(key)) {
200
+ throw new Error(`Missing required configuration: ${key}`);
201
+ }
202
+ }
203
+ }
204
+ ```
205
+
206
+ ## Configuration Examples
207
+
208
+ ### Environment Driver
209
+
210
+ ```typescript
211
+ ConfigModule.forRoot({
212
+ driver: 'env',
213
+ envFilePath: '.env',
214
+ ignoreEnvFile: false,
215
+ expandVariables: true,
216
+ isGlobal: true,
217
+ })
218
+ ```
219
+
220
+ ### File Driver
221
+
222
+ ```typescript
223
+ ConfigModule.forRoot({
224
+ driver: 'file',
225
+ load: {
226
+ database: {
227
+ host: 'localhost',
228
+ port: 5432,
229
+ },
230
+ api: {
231
+ url: 'http://localhost:3000',
232
+ },
233
+ },
234
+ isGlobal: true,
235
+ })
236
+ ```
237
+
238
+ ### Custom Configuration
239
+
240
+ ```typescript
241
+ ConfigModule.forRoot({
242
+ driver: 'env',
243
+ load: {
244
+ // Merge custom config with env vars
245
+ app: {
246
+ name: 'My App',
247
+ version: '1.0.0',
248
+ },
249
+ },
250
+ isGlobal: true,
251
+ })
252
+ ```
253
+
254
+ ## Troubleshooting
255
+
256
+ ### Configuration Not Loading
257
+
258
+ 1. Check if ConfigModule is imported
259
+ 2. Verify .env file exists and is readable
260
+ 3. Check environment variable names
261
+ 4. Verify driver configuration
262
+
263
+ ### Type Conversion Issues
264
+
265
+ 1. Use appropriate getter methods
266
+ 2. Check default values
267
+ 3. Validate input format
268
+ 4. Use getOrThrow for debugging
269
+
270
+ ### Missing Values
271
+
272
+ 1. Use has() to check existence
273
+ 2. Provide sensible defaults
274
+ 3. Use getOrThrow for required values
275
+ 4. Check environment variable names
276
+
277
+ ## Additional Resources
278
+
279
+ - [Main README](../README.md) - Package documentation
280
+ - [NestJS Config Documentation](https://docs.nestjs.com/techniques/configuration) - Inspiration
281
+ - [dotenv Documentation](https://github.com/motdotla/dotenv) - Environment variables
282
+
283
+ ## Contributing
284
+
285
+ Found an issue or have a suggestion? Please open an issue or submit a pull request!
package/.prettierrc.js ADDED
@@ -0,0 +1 @@
1
+ export default '@nesvel/prettier-config';
package/README.md ADDED
@@ -0,0 +1,261 @@
1
+ # @abdokouta/config
2
+
3
+ NestJS-inspired configuration management with multiple drivers (Env, File, Firebase) for Refine applications.
4
+
5
+ ## Features
6
+
7
+ - 🔧 Multiple drivers: Environment variables, File-based, Firebase
8
+ - 🎯 Type-safe getters: `getString()`, `getNumber()`, `getBool()`, etc.
9
+ - 🌍 Environment helper: `Env.get()`, `Env.getBool()`, etc.
10
+ - 📁 File pattern scanning for config files
11
+ - 🔄 Variable expansion support
12
+ - 💾 Built-in caching
13
+ - 🎨 Laravel and NestJS inspired API
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @abdokouta/config
19
+ # or
20
+ pnpm add @abdokouta/config
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ### 1. Using Environment Variables (Default)
26
+
27
+ ```typescript
28
+ import { Module } from '@abdokouta/container';
29
+ import { ConfigModule, ConfigService } from '@abdokouta/config';
30
+
31
+ @Module({
32
+ imports: [
33
+ ConfigModule.forRoot({
34
+ envFilePath: '.env',
35
+ isGlobal: true,
36
+ }),
37
+ ],
38
+ })
39
+ export class AppModule {}
40
+
41
+ // Use in your services
42
+ @Injectable()
43
+ export class DatabaseService {
44
+ constructor(private config: ConfigService) {}
45
+
46
+ getConnection() {
47
+ return {
48
+ host: this.config.getString('DB_HOST', 'localhost'),
49
+ port: this.config.getNumber('DB_PORT', 5432),
50
+ ssl: this.config.getBool('DB_SSL', false),
51
+ };
52
+ }
53
+ }
54
+ ```
55
+
56
+ ### 2. Using File-Based Configuration
57
+
58
+ ```typescript
59
+ @Module({
60
+ imports: [
61
+ ConfigModule.forRoot({
62
+ driver: 'file',
63
+ filePattern: 'config/**/*.config.ts',
64
+ isGlobal: true,
65
+ }),
66
+ ],
67
+ })
68
+ export class AppModule {}
69
+ ```
70
+
71
+ Create config files:
72
+
73
+ ```typescript
74
+ // config/database.config.ts
75
+ export default {
76
+ host: process.env.DB_HOST || 'localhost',
77
+ port: parseInt(process.env.DB_PORT || '5432'),
78
+ database: process.env.DB_NAME || 'myapp',
79
+ };
80
+
81
+ // config/cache.config.ts
82
+ export default {
83
+ driver: process.env.CACHE_DRIVER || 'memory',
84
+ ttl: 300,
85
+ };
86
+ ```
87
+
88
+ Access in your code:
89
+
90
+ ```typescript
91
+ const dbHost = this.config.get('database.host');
92
+ const cacheDriver = this.config.get('cache.driver');
93
+ ```
94
+
95
+ ## ConfigService API
96
+
97
+ ### Type-Safe Getters
98
+
99
+ ```typescript
100
+ // Get string
101
+ config.getString('APP_NAME', 'MyApp');
102
+ config.getStringOrThrow('APP_NAME');
103
+
104
+ // Get number
105
+ config.getNumber('PORT', 3000);
106
+ config.getNumberOrThrow('PORT');
107
+
108
+ // Get boolean
109
+ config.getBool('DEBUG', false);
110
+ config.getBoolOrThrow('DEBUG');
111
+
112
+ // Get array (comma-separated)
113
+ config.getArray('ALLOWED_HOSTS', ['localhost']);
114
+
115
+ // Get JSON
116
+ config.getJson<MyType>('COMPLEX_CONFIG', defaultValue);
117
+
118
+ // Generic get
119
+ config.get<string>('KEY', 'default');
120
+ config.getOrThrow<string>('KEY');
121
+
122
+ // Check existence
123
+ config.has('KEY');
124
+
125
+ // Get all
126
+ config.all();
127
+ ```
128
+
129
+ ## Env Helper
130
+
131
+ Use the `Env` helper for direct environment variable access:
132
+
133
+ ```typescript
134
+ import { Env } from '@abdokouta/config';
135
+
136
+ // Get string
137
+ const appName = Env.get('APP_NAME', 'MyApp');
138
+ const apiKey = Env.getOrThrow('API_KEY');
139
+
140
+ // Get number
141
+ const port = Env.getNumber('PORT', 3000);
142
+
143
+ // Get boolean
144
+ const debug = Env.getBool('DEBUG', false);
145
+
146
+ // Get array
147
+ const hosts = Env.getArray('ALLOWED_HOSTS', ['localhost']);
148
+
149
+ // Get JSON
150
+ const config = Env.getJson<MyConfig>('APP_CONFIG');
151
+
152
+ // Check existence
153
+ if (Env.has('FEATURE_FLAG')) {
154
+ // ...
155
+ }
156
+
157
+ // Get all
158
+ const allEnv = Env.all();
159
+ ```
160
+
161
+ ## Configuration Options
162
+
163
+ ```typescript
164
+ interface ConfigModuleOptions {
165
+ // Driver type
166
+ driver?: 'env' | 'file' | 'firebase';
167
+
168
+ // Env driver options
169
+ envFilePath?: string | string[];
170
+ ignoreEnvFile?: boolean;
171
+ expandVariables?: boolean;
172
+
173
+ // File driver options
174
+ filePattern?: string | string[];
175
+
176
+ // Custom configuration
177
+ load?: Record<string, any> | (() => Record<string, any>);
178
+
179
+ // Module options
180
+ isGlobal?: boolean;
181
+ cache?: boolean;
182
+ validate?: (config: Record<string, any>) => void;
183
+ }
184
+ ```
185
+
186
+ ## Examples
187
+
188
+ ### Environment Variables with Expansion
189
+
190
+ ```typescript
191
+ ConfigModule.forRoot({
192
+ envFilePath: '.env',
193
+ expandVariables: true, // Enables ${VAR} expansion
194
+ });
195
+ ```
196
+
197
+ ```.env
198
+ BASE_URL=https://api.example.com
199
+ API_ENDPOINT=${BASE_URL}/v1
200
+ ```
201
+
202
+ ### Multiple Environment Files
203
+
204
+ ```typescript
205
+ ConfigModule.forRoot({
206
+ envFilePath: ['.env', `.env.${process.env.NODE_ENV}`],
207
+ });
208
+ ```
209
+
210
+ ### Custom Configuration
211
+
212
+ ```typescript
213
+ ConfigModule.forRoot({
214
+ load: {
215
+ app: {
216
+ name: 'MyApp',
217
+ version: '1.0.0',
218
+ },
219
+ },
220
+ });
221
+ ```
222
+
223
+ ### Validation
224
+
225
+ ```typescript
226
+ ConfigModule.forRoot({
227
+ validate: (config) => {
228
+ if (!config.DATABASE_URL) {
229
+ throw new Error('DATABASE_URL is required');
230
+ }
231
+ },
232
+ });
233
+ ```
234
+
235
+ ## Comparison with Other Packages
236
+
237
+ ### vs @abdokouta/cache and @abdokouta/logger
238
+
239
+ All three packages follow the same pattern:
240
+
241
+ ```typescript
242
+ // Cache
243
+ import cacheConfig from '@abdokouta/cache/config/cache.config';
244
+ CacheModule.forRoot(cacheConfig);
245
+
246
+ // Logger
247
+ import loggerConfig from '@abdokouta/logger/config/logger.config';
248
+ LoggerModule.forRoot(loggerConfig);
249
+
250
+ // Config (manages both!)
251
+ import { ConfigModule, ConfigService } from '@abdokouta/config';
252
+ ConfigModule.forRoot({ isGlobal: true });
253
+
254
+ // Now use ConfigService to get cache/logger settings
255
+ const cacheDriver = config.getString('CACHE_DRIVER', 'memory');
256
+ const logLevel = config.getString('LOG_LEVEL', 'debug');
257
+ ```
258
+
259
+ ## License
260
+
261
+ MIT