@abdokouta/react-config 1.0.1 → 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 (39) hide show
  1. package/dist/{index.d.mts → index.d.cts} +1 -1
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +46 -17
  6. package/.examples/01-basic-usage.ts +0 -291
  7. package/.examples/02-env-helper.ts +0 -282
  8. package/.examples/README.md +0 -297
  9. package/.prettierrc.js +0 -1
  10. package/__tests__/config.module.test.ts +0 -244
  11. package/__tests__/drivers/env.driver.test.ts +0 -259
  12. package/__tests__/services/config.service.test.ts +0 -335
  13. package/__tests__/setup.d.ts +0 -11
  14. package/__tests__/vitest.setup.ts +0 -30
  15. package/eslint.config.js +0 -13
  16. package/src/config.module.ts +0 -152
  17. package/src/constants/index.ts +0 -5
  18. package/src/constants/tokens.constant.ts +0 -38
  19. package/src/drivers/env.driver.ts +0 -208
  20. package/src/drivers/file.driver.ts +0 -82
  21. package/src/drivers/index.ts +0 -6
  22. package/src/index.ts +0 -93
  23. package/src/interfaces/config-driver.interface.ts +0 -30
  24. package/src/interfaces/config-module-options.interface.ts +0 -84
  25. package/src/interfaces/config-service.interface.ts +0 -71
  26. package/src/interfaces/index.ts +0 -8
  27. package/src/interfaces/vite-config-plugin-options.interface.ts +0 -56
  28. package/src/plugins/index.ts +0 -5
  29. package/src/plugins/vite.plugin.ts +0 -118
  30. package/src/services/config.service.ts +0 -172
  31. package/src/services/index.ts +0 -5
  32. package/src/utils/define-config.util.ts +0 -35
  33. package/src/utils/get-nested-value.util.ts +0 -53
  34. package/src/utils/index.ts +0 -9
  35. package/src/utils/load-config-file.util.ts +0 -32
  36. package/src/utils/scan-config-files.util.ts +0 -36
  37. package/tsconfig.json +0 -28
  38. package/tsup.config.ts +0 -105
  39. package/vitest.config.ts +0 -66
@@ -1,259 +0,0 @@
1
- /**
2
- * @fileoverview Tests for EnvDriver
3
- *
4
- * This test suite verifies the EnvDriver functionality including:
5
- * - Loading environment variables
6
- * - Getting values with dot notation
7
- * - Variable expansion
8
- * - Default values
9
- * - Type conversions
10
- *
11
- * @module @abdokouta/config
12
- * @category Tests
13
- */
14
-
15
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
16
- import { EnvDriver } from '@/drivers/env.driver';
17
-
18
- describe('EnvDriver', () => {
19
- const originalEnv = process.env;
20
-
21
- beforeEach(() => {
22
- // Arrange: Reset environment
23
- process.env = { ...originalEnv };
24
- });
25
-
26
- afterEach(() => {
27
- // Cleanup: Restore environment
28
- process.env = originalEnv;
29
- });
30
-
31
- describe('load', () => {
32
- it('should load environment variables', () => {
33
- // Arrange: Set env vars
34
- process.env.APP_NAME = 'Test App';
35
- process.env.APP_PORT = '3000';
36
- process.env.APP_DEBUG = 'true';
37
-
38
- const driver = new EnvDriver();
39
-
40
- // Act: Load config
41
- const config = driver.load();
42
-
43
- // Assert: Config is loaded
44
- expect(config).toBeDefined();
45
- expect(typeof config).toBe('object');
46
- });
47
-
48
- it('should handle empty environment', () => {
49
- // Arrange: Clear env
50
- process.env = {};
51
-
52
- const driver = new EnvDriver();
53
-
54
- // Act: Load config
55
- const config = driver.load();
56
-
57
- // Assert: Empty config is returned
58
- expect(config).toBeDefined();
59
- expect(typeof config).toBe('object');
60
- });
61
- });
62
-
63
- describe('get', () => {
64
- beforeEach(() => {
65
- // Arrange: Set test env vars
66
- process.env.APP_NAME = 'Test App';
67
- process.env.APP_PORT = '3000';
68
- process.env.DATABASE_HOST = 'localhost';
69
- process.env.DATABASE_PORT = '5432';
70
- });
71
-
72
- it('should get environment variable', () => {
73
- // Arrange: Create driver
74
- const driver = new EnvDriver();
75
- driver.load();
76
-
77
- // Act: Get value
78
- const appName = driver.get('APP_NAME');
79
-
80
- // Assert: Value is returned
81
- expect(appName).toBe('Test App');
82
- });
83
-
84
- it("should return default value when key doesn't exist", () => {
85
- // Arrange: Create driver
86
- const driver = new EnvDriver();
87
- driver.load();
88
-
89
- // Act: Get with default
90
- const value = driver.get('MISSING_KEY', 'default');
91
-
92
- // Assert: Default is returned
93
- expect(value).toBe('default');
94
- });
95
-
96
- it("should return undefined when key doesn't exist and no default", () => {
97
- // Arrange: Create driver
98
- const driver = new EnvDriver();
99
- driver.load();
100
-
101
- // Act: Get without default
102
- const value = driver.get('MISSING_KEY');
103
-
104
- // Assert: Undefined is returned
105
- expect(value).toBeUndefined();
106
- });
107
-
108
- it('should handle numeric string values', () => {
109
- // Arrange: Create driver
110
- const driver = new EnvDriver();
111
- driver.load();
112
-
113
- // Act: Get numeric value
114
- const port = driver.get('APP_PORT');
115
-
116
- // Assert: String is returned (no auto-conversion)
117
- expect(port).toBe('3000');
118
- });
119
- });
120
-
121
- describe('has', () => {
122
- beforeEach(() => {
123
- // Arrange: Set test env vars
124
- process.env.APP_NAME = 'Test App';
125
- process.env.EMPTY_VAR = '';
126
- });
127
-
128
- it('should return true for existing key', () => {
129
- // Arrange: Create driver
130
- const driver = new EnvDriver();
131
- driver.load();
132
-
133
- // Act: Check existence
134
- const exists = driver.has('APP_NAME');
135
-
136
- // Assert: Key exists
137
- expect(exists).toBe(true);
138
- });
139
-
140
- it('should return false for missing key', () => {
141
- // Arrange: Create driver
142
- const driver = new EnvDriver();
143
- driver.load();
144
-
145
- // Act: Check existence
146
- const exists = driver.has('MISSING_KEY');
147
-
148
- // Assert: Key doesn't exist
149
- expect(exists).toBe(false);
150
- });
151
-
152
- it('should return true for empty string value', () => {
153
- // Arrange: Create driver
154
- const driver = new EnvDriver();
155
- driver.load();
156
-
157
- // Act: Check existence
158
- const exists = driver.has('EMPTY_VAR');
159
-
160
- // Assert: Key exists even with empty value
161
- expect(exists).toBe(true);
162
- });
163
- });
164
-
165
- describe('all', () => {
166
- beforeEach(() => {
167
- // Arrange: Set test env vars
168
- process.env.APP_NAME = 'Test App';
169
- process.env.APP_PORT = '3000';
170
- process.env.DATABASE_HOST = 'localhost';
171
- });
172
-
173
- it('should return all configuration', () => {
174
- // Arrange: Create driver
175
- const driver = new EnvDriver();
176
- driver.load();
177
-
178
- // Act: Get all config
179
- const config = driver.all();
180
-
181
- // Assert: All config is returned
182
- expect(config).toBeDefined();
183
- expect(typeof config).toBe('object');
184
- });
185
-
186
- it('should include all loaded variables', () => {
187
- // Arrange: Create driver
188
- const driver = new EnvDriver();
189
- driver.load();
190
-
191
- // Act: Get all config
192
- const config = driver.all();
193
-
194
- // Assert: Contains loaded vars
195
- expect(config).toBeDefined();
196
- });
197
- });
198
-
199
- describe('Variable Expansion', () => {
200
- it('should expand variables when enabled', () => {
201
- // Arrange: Set vars with references
202
- process.env.BASE_URL = 'http://localhost';
203
- process.env.API_URL = '${BASE_URL}/api';
204
-
205
- const driver = new EnvDriver({ expandVariables: true });
206
- driver.load();
207
-
208
- // Act: Get expanded value
209
- const apiUrl = driver.get('API_URL');
210
-
211
- // Assert: Variable is expanded (if implemented)
212
- expect(apiUrl).toBeDefined();
213
- });
214
- });
215
-
216
- describe('Edge Cases', () => {
217
- it('should handle special characters in values', () => {
218
- // Arrange: Set var with special chars
219
- process.env.SPECIAL = 'value with spaces & symbols!@#';
220
-
221
- const driver = new EnvDriver();
222
- driver.load();
223
-
224
- // Act: Get value
225
- const value = driver.get('SPECIAL');
226
-
227
- // Assert: Special chars are preserved
228
- expect(value).toBe('value with spaces & symbols!@#');
229
- });
230
-
231
- it('should handle multiline values', () => {
232
- // Arrange: Set multiline var
233
- process.env.MULTILINE = 'line1\\nline2\\nline3';
234
-
235
- const driver = new EnvDriver();
236
- driver.load();
237
-
238
- // Act: Get value
239
- const value = driver.get('MULTILINE');
240
-
241
- // Assert: Multiline is preserved
242
- expect(value).toBeDefined();
243
- });
244
-
245
- it('should handle empty environment', () => {
246
- // Arrange: Clear all env vars
247
- process.env = {};
248
-
249
- const driver = new EnvDriver();
250
-
251
- // Act: Load and get
252
- driver.load();
253
- const value = driver.get('ANY_KEY', 'default');
254
-
255
- // Assert: Default is returned
256
- expect(value).toBe('default');
257
- });
258
- });
259
- });
@@ -1,335 +0,0 @@
1
- /**
2
- * @fileoverview Tests for ConfigService
3
- *
4
- * This test suite verifies the ConfigService functionality including:
5
- * - Getting configuration values
6
- * - Type-safe getters (getString, getNumber, getBoolean)
7
- * - Throwing methods (getOrThrow, getStringOrThrow)
8
- * - Default value handling
9
- * - Nested key access
10
- *
11
- * @module @abdokouta/config
12
- * @category Tests
13
- */
14
-
15
- import { describe, it, expect, beforeEach, vi } from 'vitest';
16
- import { ConfigService } from '@/services/config.service';
17
- import type { ConfigDriver } from '@/interfaces/config-driver.interface';
18
-
19
- describe('ConfigService', () => {
20
- let mockDriver: ConfigDriver;
21
- let configService: ConfigService;
22
-
23
- beforeEach(() => {
24
- // Arrange: Create mock driver
25
- mockDriver = {
26
- load: vi.fn().mockReturnValue({
27
- app: {
28
- name: 'Test App',
29
- port: 3000,
30
- debug: true,
31
- },
32
- database: {
33
- host: 'localhost',
34
- port: 5432,
35
- name: 'testdb',
36
- },
37
- api: {
38
- key: 'test-key-123',
39
- timeout: 5000,
40
- },
41
- }),
42
- get: vi.fn((key: string, defaultValue?: any) => {
43
- const data: any = {
44
- 'app.name': 'Test App',
45
- 'app.port': 3000,
46
- 'app.debug': true,
47
- 'database.host': 'localhost',
48
- 'database.port': 5432,
49
- 'api.key': 'test-key-123',
50
- };
51
- return data[key] ?? defaultValue;
52
- }),
53
- has: vi.fn((key: string) => {
54
- const keys = [
55
- 'app.name',
56
- 'app.port',
57
- 'app.debug',
58
- 'database.host',
59
- 'database.port',
60
- 'api.key',
61
- ];
62
- return keys.includes(key);
63
- }),
64
- all: vi.fn().mockReturnValue({
65
- app: { name: 'Test App', port: 3000, debug: true },
66
- database: { host: 'localhost', port: 5432, name: 'testdb' },
67
- }),
68
- };
69
-
70
- configService = new ConfigService(mockDriver);
71
- });
72
-
73
- describe('get', () => {
74
- it('should get existing configuration value', () => {
75
- // Act: Get config value
76
- const appName = configService.get('app.name');
77
-
78
- // Assert: Value is returned
79
- expect(appName).toBe('Test App');
80
- expect(mockDriver.get).toHaveBeenCalledWith('app.name', undefined);
81
- });
82
-
83
- it("should return default value when key doesn't exist", () => {
84
- // Arrange: Mock missing key
85
- mockDriver.get = vi.fn((key, defaultValue) => defaultValue);
86
-
87
- // Act: Get with default
88
- const value = configService.get('missing.key', 'default');
89
-
90
- // Assert: Default is returned
91
- expect(value).toBe('default');
92
- });
93
-
94
- it("should return undefined when key doesn't exist and no default", () => {
95
- // Arrange: Mock missing key
96
- mockDriver.get = vi.fn(() => undefined);
97
-
98
- // Act: Get without default
99
- const value = configService.get('missing.key');
100
-
101
- // Assert: Undefined is returned
102
- expect(value).toBeUndefined();
103
- });
104
-
105
- it('should handle nested keys', () => {
106
- // Act: Get nested value
107
- const dbHost = configService.get('database.host');
108
-
109
- // Assert: Nested value is returned
110
- expect(dbHost).toBe('localhost');
111
- });
112
-
113
- it('should handle numeric values', () => {
114
- // Act: Get numeric value
115
- const port = configService.get<number>('app.port');
116
-
117
- // Assert: Number is returned
118
- expect(port).toBe(3000);
119
- expect(typeof port).toBe('number');
120
- });
121
-
122
- it('should handle boolean values', () => {
123
- // Act: Get boolean value
124
- const debug = configService.get<boolean>('app.debug');
125
-
126
- // Assert: Boolean is returned
127
- expect(debug).toBe(true);
128
- expect(typeof debug).toBe('boolean');
129
- });
130
- });
131
-
132
- describe('getOrThrow', () => {
133
- it('should return value when key exists', () => {
134
- // Act: Get existing key
135
- const appName = configService.getOrThrow('app.name');
136
-
137
- // Assert: Value is returned
138
- expect(appName).toBe('Test App');
139
- });
140
-
141
- it("should throw error when key doesn't exist", () => {
142
- // Arrange: Mock missing key
143
- mockDriver.get = vi.fn(() => undefined);
144
-
145
- // Act & Assert: Should throw
146
- expect(() => {
147
- configService.getOrThrow('missing.key');
148
- }).toThrow();
149
- });
150
-
151
- it('should throw with descriptive error message', () => {
152
- // Arrange: Mock missing key
153
- mockDriver.get = vi.fn(() => undefined);
154
-
155
- // Act & Assert: Should throw with message
156
- expect(() => {
157
- configService.getOrThrow('missing.key');
158
- }).toThrow(/missing\.key/);
159
- });
160
- });
161
-
162
- describe('getString', () => {
163
- it('should return string value', () => {
164
- // Act: Get string
165
- const appName = configService.getString('app.name');
166
-
167
- // Assert: String is returned
168
- expect(appName).toBe('Test App');
169
- expect(typeof appName).toBe('string');
170
- });
171
-
172
- it("should return default string when key doesn't exist", () => {
173
- // Arrange: Mock missing key
174
- mockDriver.get = vi.fn((key, defaultValue) => defaultValue);
175
-
176
- // Act: Get with default
177
- const value = configService.getString('missing.key', 'default');
178
-
179
- // Assert: Default is returned
180
- expect(value).toBe('default');
181
- });
182
-
183
- it('should return undefined when no default provided', () => {
184
- // Arrange: Mock missing key
185
- mockDriver.get = vi.fn(() => undefined);
186
-
187
- // Act: Get without default
188
- const value = configService.getString('missing.key');
189
-
190
- // Assert: Undefined is returned
191
- expect(value).toBeUndefined();
192
- });
193
- });
194
-
195
- describe('getStringOrThrow', () => {
196
- it('should return string value when key exists', () => {
197
- // Act: Get existing string
198
- const apiKey = configService.getStringOrThrow('api.key');
199
-
200
- // Assert: String is returned
201
- expect(apiKey).toBe('test-key-123');
202
- expect(typeof apiKey).toBe('string');
203
- });
204
-
205
- it("should throw when key doesn't exist", () => {
206
- // Arrange: Mock missing key
207
- mockDriver.get = vi.fn(() => undefined);
208
-
209
- // Act & Assert: Should throw
210
- expect(() => {
211
- configService.getStringOrThrow('missing.key');
212
- }).toThrow();
213
- });
214
- });
215
-
216
- describe('getNumber', () => {
217
- it('should return number value', () => {
218
- // Act: Get number
219
- const port = configService.getNumber('app.port');
220
-
221
- // Assert: Number is returned
222
- expect(port).toBe(3000);
223
- expect(typeof port).toBe('number');
224
- });
225
-
226
- it("should return default number when key doesn't exist", () => {
227
- // Arrange: Mock missing key
228
- mockDriver.get = vi.fn((key, defaultValue) => defaultValue);
229
-
230
- // Act: Get with default
231
- const value = configService.getNumber('missing.key', 8080);
232
-
233
- // Assert: Default is returned
234
- expect(value).toBe(8080);
235
- });
236
-
237
- it('should parse string numbers', () => {
238
- // Arrange: Mock string number
239
- mockDriver.get = vi.fn(() => '5432');
240
-
241
- // Act: Get as number
242
- const port = configService.getNumber('database.port');
243
-
244
- // Assert: Parsed number is returned
245
- expect(port).toBe(5432);
246
- expect(typeof port).toBe('number');
247
- });
248
- });
249
-
250
- describe('getBoolean', () => {
251
- it('should return boolean value', () => {
252
- // Act: Get boolean
253
- const debug = configService.getBoolean('app.debug');
254
-
255
- // Assert: Boolean is returned
256
- expect(debug).toBe(true);
257
- expect(typeof debug).toBe('boolean');
258
- });
259
-
260
- it('should parse string booleans', () => {
261
- // Arrange: Mock string boolean
262
- mockDriver.get = vi.fn((key) => {
263
- if (key === 'feature.enabled') return 'true';
264
- if (key === 'feature.disabled') return 'false';
265
- return undefined;
266
- });
267
-
268
- // Act: Get as boolean
269
- const enabled = configService.getBoolean('feature.enabled');
270
- const disabled = configService.getBoolean('feature.disabled');
271
-
272
- // Assert: Parsed booleans are returned
273
- expect(enabled).toBe(true);
274
- expect(disabled).toBe(false);
275
- });
276
-
277
- it('should handle truthy/falsy values', () => {
278
- // Arrange: Mock various values
279
- mockDriver.get = vi.fn((key) => {
280
- if (key === 'one') return 1;
281
- if (key === 'zero') return 0;
282
- if (key === 'yes') return 'yes';
283
- if (key === 'no') return 'no';
284
- return undefined;
285
- });
286
-
287
- // Act: Get as booleans
288
- const one = configService.getBoolean('one');
289
- const zero = configService.getBoolean('zero');
290
- const yes = configService.getBoolean('yes');
291
- const no = configService.getBoolean('no');
292
-
293
- // Assert: Values are converted to boolean
294
- expect(one).toBe(true);
295
- expect(zero).toBe(false);
296
- expect(yes).toBe(true);
297
- expect(no).toBe(false);
298
- });
299
- });
300
-
301
- describe('Edge Cases', () => {
302
- it('should handle null values', () => {
303
- // Arrange: Mock null value
304
- mockDriver.get = vi.fn(() => null);
305
-
306
- // Act: Get null value
307
- const value = configService.get('null.key');
308
-
309
- // Assert: Null is returned
310
- expect(value).toBeNull();
311
- });
312
-
313
- it('should handle empty string values', () => {
314
- // Arrange: Mock empty string
315
- mockDriver.get = vi.fn(() => '');
316
-
317
- // Act: Get empty string
318
- const value = configService.getString('empty.key');
319
-
320
- // Assert: Empty string is returned
321
- expect(value).toBe('');
322
- });
323
-
324
- it('should handle zero values', () => {
325
- // Arrange: Mock zero
326
- mockDriver.get = vi.fn(() => 0);
327
-
328
- // Act: Get zero
329
- const value = configService.getNumber('zero.key');
330
-
331
- // Assert: Zero is returned
332
- expect(value).toBe(0);
333
- });
334
- });
335
- });
@@ -1,11 +0,0 @@
1
- /**
2
- * @fileoverview Type declarations for Vitest test environment
3
- *
4
- * This file extends Vitest's type definitions to include custom matchers
5
- * and global test utilities.
6
- *
7
- * @module @abdokouta/config
8
- * @category Configuration
9
- */
10
-
11
- import 'vitest/globals';
@@ -1,30 +0,0 @@
1
- /**
2
- * @fileoverview Vitest setup file for @abdokouta/config package
3
- *
4
- * This file configures the testing environment before running tests.
5
- * It sets up container mocking for dependency injection tests.
6
- *
7
- * Setup Features:
8
- * - Container mocking for DI tests
9
- *
10
- * @module @abdokouta/config
11
- * @category Configuration
12
- */
13
-
14
- import { vi } from 'vitest';
15
-
16
- /**
17
- * Mock @abdokouta/react-di decorators
18
- *
19
- * This ensures that decorator metadata doesn't interfere with tests
20
- * and allows us to test module behavior in isolation.
21
- */
22
- vi.mock('@abdokouta/react-di', async () => {
23
- const actual = await vi.importActual('@abdokouta/react-di');
24
- return {
25
- ...actual,
26
- Injectable: () => (target: any) => target,
27
- Inject: () => (target: any, propertyKey: string, parameterIndex: number) => {},
28
- Module: (metadata: any) => (target: any) => target,
29
- };
30
- });
package/eslint.config.js DELETED
@@ -1,13 +0,0 @@
1
- import nesvelConfig from '@nesvel/eslint-config';
2
-
3
- export default [
4
- ...nesvelConfig,
5
- {
6
- ignores: ['dist/**', 'node_modules/**', '*.config.js', '*.config.ts'],
7
- },
8
- {
9
- rules: {
10
- // Add any package-specific rule overrides here
11
- },
12
- },
13
- ];