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