ezcfg 0.2.0 → 0.3.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/README.md +133 -64
- package/dist/computed-spec.d.ts +9 -0
- package/dist/computed-spec.d.ts.map +1 -0
- package/dist/computed-spec.js +20 -0
- package/dist/computed-spec.js.map +1 -0
- package/dist/config-spec.d.ts +10 -0
- package/dist/config-spec.d.ts.map +1 -0
- package/dist/config-spec.js +7 -0
- package/dist/config-spec.js.map +1 -0
- package/dist/database-config.d.ts +9 -0
- package/dist/database-config.d.ts.map +1 -0
- package/dist/database-config.js +2 -0
- package/dist/database-config.js.map +1 -0
- package/dist/define-config.d.ts +9 -0
- package/dist/define-config.d.ts.map +1 -0
- package/dist/define-config.js +45 -0
- package/dist/define-config.js.map +1 -0
- package/dist/env-spec.d.ts +18 -0
- package/dist/env-spec.d.ts.map +1 -0
- package/dist/env-spec.js +52 -0
- package/dist/env-spec.js.map +1 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/load-env-files.d.ts +5 -0
- package/dist/load-env-files.d.ts.map +1 -0
- package/dist/load-env-files.js +23 -0
- package/dist/load-env-files.js.map +1 -0
- package/dist/postgres-config-spec.d.ts +31 -0
- package/dist/postgres-config-spec.d.ts.map +1 -0
- package/dist/postgres-config-spec.js +43 -0
- package/dist/postgres-config-spec.js.map +1 -0
- package/dist/postgres-config.d.ts +43 -0
- package/dist/postgres-config.d.ts.map +1 -0
- package/dist/postgres-config.js +162 -0
- package/dist/postgres-config.js.map +1 -0
- package/dist/postgres.d.ts +3 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +3 -0
- package/dist/postgres.js.map +1 -0
- package/package.json +42 -41
package/README.md
CHANGED
|
@@ -9,8 +9,10 @@ Lite and easy configuration management for Node.js with full TypeScript support.
|
|
|
9
9
|
|
|
10
10
|
- **Type-safe configuration** - Full TypeScript support with automatic type inference
|
|
11
11
|
- **Automatic .env file loading** - Loads environment files based on `NODE_ENV`
|
|
12
|
+
- **Direct .env file parsing** - Read from a specific `.env` file without modifying `process.env`
|
|
12
13
|
- **Validation with clear error messages** - Collects all validation errors at once
|
|
13
|
-
- **
|
|
14
|
+
- **PostgreSQL config support** - Built-in `postgresConfig` spec via `ezcfg/postgres`
|
|
15
|
+
- **Extensible** - Implement `ConfigSpec` to add custom config types
|
|
14
16
|
- **Singleton pattern** - Config is lazily evaluated and cached (except in test environment)
|
|
15
17
|
|
|
16
18
|
## Installation
|
|
@@ -90,12 +92,40 @@ const config = getConfig(); // Lazily evaluated and cached
|
|
|
90
92
|
| `schema` | `Record<string, unknown>` | Object defining your configuration shape |
|
|
91
93
|
| `options.loadEnv` | `boolean` | Whether to load .env files automatically (default: `false`) |
|
|
92
94
|
| `options.envLoader` | `() => void` | Custom function to load environment variables |
|
|
95
|
+
| `options.fromEnvFile` | `string` | Path to a `.env` file to parse directly (does not modify `process.env`) |
|
|
93
96
|
|
|
94
97
|
**Behavior:**
|
|
95
98
|
|
|
96
99
|
- Returns a factory function that lazily evaluates and caches the config
|
|
97
100
|
- In test environment (`NODE_ENV=test`), config is re-evaluated on each call
|
|
98
101
|
- Throws `ConfigValidationError` if any required values are missing
|
|
102
|
+
- When `fromEnvFile` is set, the file is parsed into a local object and passed to each spec's `resolve()` — `process.env` is never modified
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### `parseEnvFile(filePath)`
|
|
107
|
+
|
|
108
|
+
Parses a `.env` file and returns its contents as a `Record<string, string>`. Does not modify `process.env`.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { parseEnvFile } from 'ezcfg';
|
|
112
|
+
|
|
113
|
+
const env = parseEnvFile('/path/to/.env');
|
|
114
|
+
// { DATABASE_URL: 'postgres://...', API_KEY: 'secret' }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Useful for injecting env vars into test runners:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// vitest.config.ts
|
|
121
|
+
import { parseEnvFile } from 'ezcfg';
|
|
122
|
+
|
|
123
|
+
export default defineConfig({
|
|
124
|
+
test: {
|
|
125
|
+
env: parseEnvFile(resolve(__dirname, '.env')),
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
```
|
|
99
129
|
|
|
100
130
|
---
|
|
101
131
|
|
|
@@ -216,6 +246,90 @@ loadEnvFiles({
|
|
|
216
246
|
});
|
|
217
247
|
```
|
|
218
248
|
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## `ezcfg/postgres`
|
|
252
|
+
|
|
253
|
+
PostgreSQL configuration support, available as a subpath import.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import { postgresConfig, PostgresConfig } from 'ezcfg/postgres';
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### `postgresConfig(prefix, mode?)`
|
|
260
|
+
|
|
261
|
+
A `ConfigSpec` implementation for PostgreSQL database configuration. Use with `defineConfig`.
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { defineConfig } from 'ezcfg';
|
|
265
|
+
import { postgresConfig } from 'ezcfg/postgres';
|
|
266
|
+
|
|
267
|
+
const getConfig = defineConfig({
|
|
268
|
+
db: postgresConfig('ORDER_DB'), // reads ORDER_DB_URL
|
|
269
|
+
db2: postgresConfig('PG', 'fields'), // reads PG_HOST, PG_PORT, etc.
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
getConfig().db.host; // "localhost"
|
|
273
|
+
getConfig().db.toString(); // "postgres://..."
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Parameters:**
|
|
277
|
+
|
|
278
|
+
| Parameter | Type | Default | Description |
|
|
279
|
+
|-----------|------|---------|-------------|
|
|
280
|
+
| `prefix` | `string` | — | Environment variable prefix |
|
|
281
|
+
| `mode` | `"url" \| "fields"` | `"url"` | `"url"` reads `{PREFIX}_URL`, `"fields"` reads individual fields |
|
|
282
|
+
|
|
283
|
+
**Fields mode** reads: `{PREFIX}_HOST`, `{PREFIX}_PORT`, `{PREFIX}_DATABASE`, `{PREFIX}_USER`, `{PREFIX}_PASSWORD`
|
|
284
|
+
|
|
285
|
+
### `PostgresConfig`
|
|
286
|
+
|
|
287
|
+
Immutable value object representing a PostgreSQL connection configuration.
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { PostgresConfig } from 'ezcfg/postgres';
|
|
291
|
+
|
|
292
|
+
// From URL
|
|
293
|
+
const config = PostgresConfig.fromUrl('postgres://user:pass@localhost:5432/mydb');
|
|
294
|
+
|
|
295
|
+
// From environment variables
|
|
296
|
+
const config = PostgresConfig.fromEnv('DATABASE'); // reads DATABASE_URL
|
|
297
|
+
const config = PostgresConfig.fromEnv('PG', { mode: 'fields' });
|
|
298
|
+
|
|
299
|
+
// Builder methods (each returns a new instance)
|
|
300
|
+
config.withDatabase('other_db');
|
|
301
|
+
config.withHost('remote-host');
|
|
302
|
+
config.withPort(5433);
|
|
303
|
+
config.withUser('admin');
|
|
304
|
+
config.withPassword('secret');
|
|
305
|
+
config.withPoolSize(10);
|
|
306
|
+
config.withConnectionTimeout(5000);
|
|
307
|
+
config.withIdleTimeout(30000);
|
|
308
|
+
|
|
309
|
+
// Connection string
|
|
310
|
+
config.toString(); // "postgres://user:pass@localhost:5432/mydb"
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Using with `fromEnvFile`
|
|
314
|
+
|
|
315
|
+
`postgresConfig` works with `fromEnvFile` — the `.env` file is parsed locally without modifying `process.env`:
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import { defineConfig } from 'ezcfg';
|
|
319
|
+
import { postgresConfig } from 'ezcfg/postgres';
|
|
320
|
+
|
|
321
|
+
const getConfig = defineConfig(
|
|
322
|
+
{ db: postgresConfig('DATABASE') },
|
|
323
|
+
{ fromEnvFile: resolve(__dirname, '.env') }
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
// .env contains: DATABASE_URL=postgres://user@localhost/mydb
|
|
327
|
+
const config = getConfig();
|
|
328
|
+
config.db.database; // "mydb"
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
219
333
|
## .env File Loading
|
|
220
334
|
|
|
221
335
|
When `loadEnv: true` is set, ezcfg automatically loads environment files in the following order (later files override earlier ones):
|
|
@@ -241,7 +355,7 @@ When `loadEnv: true` is set, ezcfg automatically loads environment files in the
|
|
|
241
355
|
When validation fails, ezcfg throws a `ConfigValidationError` with all errors collected:
|
|
242
356
|
|
|
243
357
|
```typescript
|
|
244
|
-
import { defineConfig, env, ConfigValidationError } from 'ezcfg';
|
|
358
|
+
import { defineConfig, env, envNumber, ConfigValidationError } from 'ezcfg';
|
|
245
359
|
|
|
246
360
|
const getConfig = defineConfig({
|
|
247
361
|
apiKey: env('API_KEY'),
|
|
@@ -297,7 +411,7 @@ const config = getConfig();
|
|
|
297
411
|
You can also extract the config type for use elsewhere:
|
|
298
412
|
|
|
299
413
|
```typescript
|
|
300
|
-
import { defineConfig, env, type InferConfigType } from 'ezcfg';
|
|
414
|
+
import { defineConfig, env, envNumber, type InferConfigType } from 'ezcfg';
|
|
301
415
|
|
|
302
416
|
const schema = {
|
|
303
417
|
apiKey: env('API_KEY'),
|
|
@@ -315,75 +429,30 @@ function initializeApp(config: AppConfig) {
|
|
|
315
429
|
}
|
|
316
430
|
```
|
|
317
431
|
|
|
318
|
-
##
|
|
319
|
-
|
|
320
|
-
### Database Configuration
|
|
321
|
-
|
|
322
|
-
```typescript
|
|
323
|
-
import { defineConfig, env, envNumber, envOptional } from 'ezcfg';
|
|
324
|
-
|
|
325
|
-
export const getDbConfig = defineConfig({
|
|
326
|
-
host: env('DB_HOST'),
|
|
327
|
-
port: envNumber('DB_PORT'),
|
|
328
|
-
database: env('DB_NAME'),
|
|
329
|
-
user: env('DB_USER'),
|
|
330
|
-
password: envOptional('DB_PASSWORD'),
|
|
331
|
-
}, { loadEnv: true });
|
|
332
|
-
|
|
333
|
-
// Usage
|
|
334
|
-
const db = getDbConfig();
|
|
335
|
-
const connectionString = `postgres://${db.user}:${db.password}@${db.host}:${db.port}/${db.database}`;
|
|
336
|
-
```
|
|
432
|
+
## Custom ConfigSpec
|
|
337
433
|
|
|
338
|
-
|
|
434
|
+
Implement the `ConfigSpec` interface to create your own config types:
|
|
339
435
|
|
|
340
436
|
```typescript
|
|
341
|
-
import {
|
|
342
|
-
|
|
343
|
-
export const getConfig = defineConfig({
|
|
344
|
-
// Server
|
|
345
|
-
port: envNumber('PORT'),
|
|
346
|
-
host: envOptional('HOST', '0.0.0.0'),
|
|
347
|
-
|
|
348
|
-
// API Keys
|
|
349
|
-
apiKey: env('API_KEY'),
|
|
350
|
-
secretKey: env('SECRET_KEY'),
|
|
351
|
-
|
|
352
|
-
// Features
|
|
353
|
-
debug: envBoolean('DEBUG', false),
|
|
354
|
-
enableMetrics: envBoolean('ENABLE_METRICS', true),
|
|
437
|
+
import type { ConfigSpec } from 'ezcfg';
|
|
355
438
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}, { loadEnv: true });
|
|
359
|
-
```
|
|
439
|
+
class RedisConfigSpec implements ConfigSpec<RedisConfig> {
|
|
440
|
+
readonly _type = 'redis';
|
|
360
441
|
|
|
361
|
-
|
|
442
|
+
constructor(private readonly prefix: string) {}
|
|
362
443
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
├── .env.local # Local secrets (gitignored)
|
|
367
|
-
├── .env.development # Development settings
|
|
368
|
-
├── .env.production # Production settings
|
|
369
|
-
└── .env.test # Test settings
|
|
370
|
-
```
|
|
444
|
+
resolve(errors: string[], envSource?: Record<string, string>): RedisConfig | undefined {
|
|
445
|
+
const source = envSource ?? process.env;
|
|
446
|
+
const url = source[`${this.prefix}_URL`];
|
|
371
447
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
448
|
+
if (!url) {
|
|
449
|
+
errors.push(`Missing ${this.prefix}_URL`);
|
|
450
|
+
return undefined;
|
|
451
|
+
}
|
|
376
452
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
# .env.production
|
|
382
|
-
DEBUG=false
|
|
383
|
-
API_URL=https://api.example.com
|
|
384
|
-
|
|
385
|
-
# .env.local (gitignored)
|
|
386
|
-
API_KEY=your-secret-key
|
|
453
|
+
return new RedisConfig(url);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
387
456
|
```
|
|
388
457
|
|
|
389
458
|
## License
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ConfigSpec } from "./config-spec.js";
|
|
2
|
+
export declare class ComputedSpec<T> implements ConfigSpec<T> {
|
|
3
|
+
private readonly factory;
|
|
4
|
+
readonly _type = "computed";
|
|
5
|
+
constructor(factory: () => T);
|
|
6
|
+
resolve(errors: string[], _envSource?: Record<string, string>): T | undefined;
|
|
7
|
+
}
|
|
8
|
+
export declare function computed<T>(factory: () => T): ComputedSpec<T>;
|
|
9
|
+
//# sourceMappingURL=computed-spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computed-spec.d.ts","sourceRoot":"","sources":["../src/computed-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,qBAAa,YAAY,CAAC,CAAC,CAAE,YAAW,UAAU,CAAC,CAAC,CAAC;IAGrC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,QAAQ,CAAC,KAAK,cAAc;IAE5B,YAA6B,OAAO,EAAE,MAAM,CAAC,EAAI;IAEjD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAO5E;CACJ;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAE7D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class ComputedSpec {
|
|
2
|
+
factory;
|
|
3
|
+
_type = "computed";
|
|
4
|
+
constructor(factory) {
|
|
5
|
+
this.factory = factory;
|
|
6
|
+
}
|
|
7
|
+
resolve(errors, _envSource) {
|
|
8
|
+
try {
|
|
9
|
+
return this.factory();
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
errors.push(`Computed value failed: ${e.message}`);
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function computed(factory) {
|
|
18
|
+
return new ComputedSpec(factory);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=computed-spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computed-spec.js","sourceRoot":"","sources":["../src/computed-spec.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,YAAY;IAGQ,OAAO;IAF3B,KAAK,GAAG,UAAU,CAAC;IAE5B,YAA6B,OAAgB,EAAE;uBAAlB,OAAO;IAAY,CAAC;IAEjD,OAAO,CAAC,MAAgB,EAAE,UAAmC,EAAiB;QAC1E,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,MAAM,CAAC,IAAI,CAAC,0BAA2B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,OAAO,SAAS,CAAC;QACrB,CAAC;IAAA,CACJ;CACJ;AAED,MAAM,UAAU,QAAQ,CAAI,OAAgB,EAAmB;IAC3D,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;AAAA,CACpC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ConfigSpec<T> {
|
|
2
|
+
readonly _type: string;
|
|
3
|
+
resolve(errors: string[], envSource?: Record<string, string>): T | undefined;
|
|
4
|
+
}
|
|
5
|
+
export type InferSpecType<S> = S extends ConfigSpec<infer T> ? T : S;
|
|
6
|
+
export type InferConfigType<S extends Record<string, unknown>> = {
|
|
7
|
+
readonly [K in keyof S]: InferSpecType<S[K]>;
|
|
8
|
+
};
|
|
9
|
+
export declare function isConfigSpec(value: unknown): value is ConfigSpec<unknown>;
|
|
10
|
+
//# sourceMappingURL=config-spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-spec.d.ts","sourceRoot":"","sources":["../src/config-spec.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU,CAAC,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;CAChF;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAErE,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAC7D,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAAC,OAAO,CAAC,CAOzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-spec.js","sourceRoot":"","sources":["../src/config-spec.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,YAAY,CAAC,KAAc,EAAgC;IACvE,OAAO,CACH,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,SAAS,IAAI,KAAK;QAClB,OAAQ,KAA6B,CAAC,OAAO,KAAK,UAAU,CAC/D,CAAC;AAAA,CACL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-config.d.ts","sourceRoot":"","sources":["../src/database-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,IAAI,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-config.js","sourceRoot":"","sources":["../src/database-config.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type InferConfigType } from "./config-spec.js";
|
|
2
|
+
export interface ConfigOptions {
|
|
3
|
+
loadEnv?: boolean;
|
|
4
|
+
envLoader?: () => void;
|
|
5
|
+
fromEnvFile?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function defineConfig<S extends Record<string, unknown>>(schema: S, options?: ConfigOptions): () => InferConfigType<S>;
|
|
8
|
+
export declare function parseEnvFile(filePath: string): Record<string, string>;
|
|
9
|
+
//# sourceMappingURL=define-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-config.d.ts","sourceRoot":"","sources":["../src/define-config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAAgB,MAAM,kBAAkB,CAAC;AAItE,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,aAAa,GACxB,MAAM,eAAe,CAAC,CAAC,CAAC,CAsC1B;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGrE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
import { isConfigSpec } from "./config-spec.js";
|
|
4
|
+
import { ConfigValidationError } from "./errors.js";
|
|
5
|
+
import { loadEnvFiles } from "./load-env-files.js";
|
|
6
|
+
export function defineConfig(schema, options) {
|
|
7
|
+
let instance = null;
|
|
8
|
+
return () => {
|
|
9
|
+
if (instance && process.env.NODE_ENV !== "test") {
|
|
10
|
+
return instance;
|
|
11
|
+
}
|
|
12
|
+
let envSource;
|
|
13
|
+
if (options?.fromEnvFile) {
|
|
14
|
+
envSource = parseEnvFile(options.fromEnvFile);
|
|
15
|
+
}
|
|
16
|
+
else if (options?.loadEnv) {
|
|
17
|
+
if (options.envLoader) {
|
|
18
|
+
options.envLoader();
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
loadEnvFiles();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const config = {};
|
|
25
|
+
const errors = [];
|
|
26
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
27
|
+
if (isConfigSpec(value)) {
|
|
28
|
+
config[key] = value.resolve(errors, envSource);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
config[key] = value;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (errors.length > 0) {
|
|
35
|
+
throw new ConfigValidationError(errors);
|
|
36
|
+
}
|
|
37
|
+
instance = config;
|
|
38
|
+
return instance;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function parseEnvFile(filePath) {
|
|
42
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
43
|
+
return dotenv.parse(content);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=define-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-config.js","sourceRoot":"","sources":["../src/define-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAwB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAQnD,MAAM,UAAU,YAAY,CACxB,MAAS,EACT,OAAuB,EACC;IACxB,IAAI,QAAQ,GAA8B,IAAI,CAAC;IAE/C,OAAO,GAAG,EAAE,CAAC;QACT,IAAI,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YAC9C,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,IAAI,SAA6C,CAAC;QAElD,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;YACvB,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;YAC1B,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACpB,OAAO,CAAC,SAAS,EAAE,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACJ,YAAY,EAAE,CAAC;YACnB,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,EAA6B,CAAC;QAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACxB,CAAC;QACL,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;QAED,QAAQ,GAAG,MAA4B,CAAC;QACxC,OAAO,QAAQ,CAAC;IAAA,CACnB,CAAC;AAAA,CACL;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB,EAA0B;IACnE,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAAA,CAChC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ConfigSpec } from "./config-spec.js";
|
|
2
|
+
export declare class EnvSpec<T> implements ConfigSpec<T> {
|
|
3
|
+
private readonly envKey;
|
|
4
|
+
private readonly required;
|
|
5
|
+
private readonly defaultValue?;
|
|
6
|
+
private readonly transform?;
|
|
7
|
+
readonly _type = "env";
|
|
8
|
+
constructor(envKey: string, required: boolean, defaultValue?: T | undefined, transform?: ((value: string) => T) | undefined);
|
|
9
|
+
resolve(errors: string[], envSource?: Record<string, string>): T | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function env(key: string): EnvSpec<string>;
|
|
12
|
+
export declare function envOptional(key: string, defaultValue?: string): EnvSpec<string | undefined>;
|
|
13
|
+
export declare function envNumber(key: string): EnvSpec<number>;
|
|
14
|
+
export declare function envNumberOptional(key: string, defaultValue?: number): EnvSpec<number | undefined>;
|
|
15
|
+
export declare function envBoolean(key: string, defaultValue?: boolean): EnvSpec<boolean>;
|
|
16
|
+
export declare function envJson<T>(key: string): EnvSpec<T>;
|
|
17
|
+
export declare function envJsonOptional<T>(key: string, defaultValue?: T): EnvSpec<T | undefined>;
|
|
18
|
+
//# sourceMappingURL=env-spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-spec.d.ts","sourceRoot":"","sources":["../src/env-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,qBAAa,OAAO,CAAC,CAAC,CAAE,YAAW,UAAU,CAAC,CAAC,CAAC;IAIxC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAN/B,QAAQ,CAAC,KAAK,SAAS;IAEvB,YACqB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,EACjB,YAAY,CAAC,eAAG,EAChB,SAAS,CAAC,oCAAsB,EACjD;IAEJ,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAkB3E;CACJ;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEhD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE3F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAEjG;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9E;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAElD;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAExF"}
|
package/dist/env-spec.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export class EnvSpec {
|
|
2
|
+
envKey;
|
|
3
|
+
required;
|
|
4
|
+
defaultValue;
|
|
5
|
+
transform;
|
|
6
|
+
_type = "env";
|
|
7
|
+
constructor(envKey, required, defaultValue, transform) {
|
|
8
|
+
this.envKey = envKey;
|
|
9
|
+
this.required = required;
|
|
10
|
+
this.defaultValue = defaultValue;
|
|
11
|
+
this.transform = transform;
|
|
12
|
+
}
|
|
13
|
+
resolve(errors, envSource) {
|
|
14
|
+
const rawValue = (envSource ?? process.env)[this.envKey];
|
|
15
|
+
if (!rawValue && this.required) {
|
|
16
|
+
errors.push(`Missing required env: ${this.envKey}`);
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
if (rawValue !== undefined) {
|
|
20
|
+
try {
|
|
21
|
+
return this.transform ? this.transform(rawValue) : rawValue;
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
errors.push(`Failed to transform ${this.envKey}: ${e.message}`);
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return this.defaultValue;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function env(key) {
|
|
32
|
+
return new EnvSpec(key, true);
|
|
33
|
+
}
|
|
34
|
+
export function envOptional(key, defaultValue) {
|
|
35
|
+
return new EnvSpec(key, false, defaultValue);
|
|
36
|
+
}
|
|
37
|
+
export function envNumber(key) {
|
|
38
|
+
return new EnvSpec(key, true, undefined, Number);
|
|
39
|
+
}
|
|
40
|
+
export function envNumberOptional(key, defaultValue) {
|
|
41
|
+
return new EnvSpec(key, false, defaultValue, (v) => (v ? Number(v) : undefined));
|
|
42
|
+
}
|
|
43
|
+
export function envBoolean(key, defaultValue = false) {
|
|
44
|
+
return new EnvSpec(key, false, defaultValue, (v) => v === "true" || v === "1");
|
|
45
|
+
}
|
|
46
|
+
export function envJson(key) {
|
|
47
|
+
return new EnvSpec(key, true, undefined, JSON.parse);
|
|
48
|
+
}
|
|
49
|
+
export function envJsonOptional(key, defaultValue) {
|
|
50
|
+
return new EnvSpec(key, false, defaultValue, (v) => (v ? JSON.parse(v) : undefined));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=env-spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-spec.js","sourceRoot":"","sources":["../src/env-spec.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,OAAO;IAIK,MAAM;IACN,QAAQ;IACR,YAAY;IACZ,SAAS;IANrB,KAAK,GAAG,KAAK,CAAC;IAEvB,YACqB,MAAc,EACd,QAAiB,EACjB,YAAgB,EAChB,SAAgC,EACnD;sBAJmB,MAAM;wBACN,QAAQ;4BACR,YAAY;yBACZ,SAAS;IAC3B,CAAC;IAEJ,OAAO,CAAC,MAAgB,EAAE,SAAkC,EAAiB;QACzE,MAAM,QAAQ,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEzD,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACpD,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC;gBACD,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAE,QAAc,CAAC;YACvE,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,MAAM,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,MAAM,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC3E,OAAO,SAAS,CAAC;YACrB,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC;IAAA,CAC5B;CACJ;AAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAmB;IAC9C,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAAA,CACjC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,YAAqB,EAA+B;IACzF,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;AAAA,CAChD;AAED,MAAM,UAAU,SAAS,CAAC,GAAW,EAAmB;IACpD,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAAA,CACpD;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,YAAqB,EAA+B;IAC/F,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAAA,CACpF;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,YAAY,GAAG,KAAK,EAAoB;IAC5E,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;AAAA,CAClF;AAED,MAAM,UAAU,OAAO,CAAI,GAAW,EAAc;IAChD,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AAAA,CACxD;AAED,MAAM,UAAU,eAAe,CAAI,GAAW,EAAE,YAAgB,EAA0B;IACtF,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAAA,CACxF"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,qBAAsB,SAAQ,KAAK;aAChB,MAAM,EAAE,MAAM,EAAE;IAA5C,YAA4B,MAAM,EAAE,MAAM,EAAE,EAG3C;CACJ"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAChB,MAAM;IAAlC,YAA4B,MAAgB,EAAE;QAC1C,KAAK,CAAC,kCAAkC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;sBADzC,MAAM;QAE9B,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IAAA,CACvC;CACJ"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { type ConfigSpec, type InferSpecType, type InferConfigType, isConfigSpec, } from "./config-spec.js";
|
|
2
|
+
export { ConfigValidationError } from "./errors.js";
|
|
3
|
+
export { defineConfig, parseEnvFile, type ConfigOptions } from "./define-config.js";
|
|
4
|
+
export { loadEnvFiles } from "./load-env-files.js";
|
|
5
|
+
export { EnvSpec, env, envOptional, envNumber, envNumberOptional, envBoolean, envJson, envJsonOptional, } from "./env-spec.js";
|
|
6
|
+
export { ComputedSpec, computed } from "./computed-spec.js";
|
|
7
|
+
export type { DatabaseConfig } from "./database-config.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,YAAY,GACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EACH,OAAO,EACP,GAAG,EACH,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,eAAe,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE5D,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { isConfigSpec, } from "./config-spec.js";
|
|
2
|
+
export { ConfigValidationError } from "./errors.js";
|
|
3
|
+
export { defineConfig, parseEnvFile } from "./define-config.js";
|
|
4
|
+
export { loadEnvFiles } from "./load-env-files.js";
|
|
5
|
+
export { EnvSpec, env, envOptional, envNumber, envNumberOptional, envBoolean, envJson, envJsonOptional, } from "./env-spec.js";
|
|
6
|
+
export { ComputedSpec, computed } from "./computed-spec.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,YAAY,GACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAsB,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EACH,OAAO,EACP,GAAG,EACH,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,eAAe,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-env-files.d.ts","sourceRoot":"","sources":["../src/load-env-files.ts"],"names":[],"mappings":"AAKA,wBAAgB,YAAY,CAAC,EACzB,QAAQ,EACR,OAAO,EACV,GAAE;IACC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAqBZ"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import dotenv from "dotenv";
|
|
4
|
+
export function loadEnvFiles({ basePath, nodeEnv, } = {}) {
|
|
5
|
+
const basePath_ = basePath ?? process.cwd();
|
|
6
|
+
const nodeEnv_ = nodeEnv ?? process.env.NODE_ENV ?? "development";
|
|
7
|
+
const envFiles = [
|
|
8
|
+
".env",
|
|
9
|
+
".env.local",
|
|
10
|
+
`.env.${nodeEnv_}`,
|
|
11
|
+
`.env.${nodeEnv_}.local`,
|
|
12
|
+
];
|
|
13
|
+
const loadEnvFile = (filePath) => {
|
|
14
|
+
if (fs.existsSync(filePath)) {
|
|
15
|
+
dotenv.config({ path: filePath });
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
envFiles.reverse().forEach((file) => {
|
|
19
|
+
const filePath = path.resolve(basePath_, file);
|
|
20
|
+
loadEnvFile(filePath);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=load-env-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-env-files.js","sourceRoot":"","sources":["../src/load-env-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,UAAU,YAAY,CAAC,EACzB,QAAQ,EACR,OAAO,GACV,GAGG,EAAE,EAAQ;IACV,MAAM,SAAS,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;IAElE,MAAM,QAAQ,GAAG;QACb,MAAM;QACN,YAAY;QACZ,QAAQ,QAAQ,EAAE;QAClB,QAAQ,QAAQ,QAAQ;KAC3B,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC;QACtC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtC,CAAC;IAAA,CACJ,CAAC;IAEF,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC/C,WAAW,CAAC,QAAQ,CAAC,CAAC;IAAA,CACzB,CAAC,CAAC;AAAA,CACN"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ConfigSpec } from "./config-spec.js";
|
|
2
|
+
import { PostgresConfig, type FromEnvOptions } from "./postgres-config.js";
|
|
3
|
+
export declare class PostgresConfigSpec implements ConfigSpec<PostgresConfig> {
|
|
4
|
+
private readonly prefix;
|
|
5
|
+
private readonly mode;
|
|
6
|
+
readonly _type = "postgres";
|
|
7
|
+
constructor(prefix: string, mode?: FromEnvOptions["mode"]);
|
|
8
|
+
resolve(errors: string[], envSource?: Record<string, string>): PostgresConfig | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* PostgreSQL database configuration from environment variables.
|
|
12
|
+
* Returns a PostgresConfig instance.
|
|
13
|
+
*
|
|
14
|
+
* @param prefix - Environment variable prefix
|
|
15
|
+
* @param mode - "url" reads {PREFIX}_URL, "fields" reads individual fields
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { defineConfig, postgresConfig } from "ezcfg";
|
|
20
|
+
*
|
|
21
|
+
* const getConfig = defineConfig({
|
|
22
|
+
* db: postgresConfig("ORDER_DB"), // reads ORDER_DB_URL
|
|
23
|
+
* db2: postgresConfig("PG", "fields"), // reads PG_HOST, PG_PORT, etc.
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* getConfig().db.host; // "localhost"
|
|
27
|
+
* getConfig().db.toString(); // "postgres://..."
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function postgresConfig(prefix: string, mode?: FromEnvOptions["mode"]): PostgresConfigSpec;
|
|
31
|
+
//# sourceMappingURL=postgres-config-spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-config-spec.d.ts","sourceRoot":"","sources":["../src/postgres-config-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3E,qBAAa,kBAAmB,YAAW,UAAU,CAAC,cAAc,CAAC;IAI7D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJzB,QAAQ,CAAC,KAAK,cAAc;IAE5B,YACqB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAc,CAAC,MAAM,CAAS,EACrD;IAEJ,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,cAAc,GAAG,SAAS,CAOxF;CACJ;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAc,CAAC,MAAM,CAAS,GACrC,kBAAkB,CAEpB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { PostgresConfig } from "./postgres-config.js";
|
|
2
|
+
export class PostgresConfigSpec {
|
|
3
|
+
prefix;
|
|
4
|
+
mode;
|
|
5
|
+
_type = "postgres";
|
|
6
|
+
constructor(prefix, mode = "url") {
|
|
7
|
+
this.prefix = prefix;
|
|
8
|
+
this.mode = mode;
|
|
9
|
+
}
|
|
10
|
+
resolve(errors, envSource) {
|
|
11
|
+
try {
|
|
12
|
+
return PostgresConfig.fromEnv(this.prefix, { mode: this.mode }, envSource);
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
errors.push(e.message);
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* PostgreSQL database configuration from environment variables.
|
|
22
|
+
* Returns a PostgresConfig instance.
|
|
23
|
+
*
|
|
24
|
+
* @param prefix - Environment variable prefix
|
|
25
|
+
* @param mode - "url" reads {PREFIX}_URL, "fields" reads individual fields
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* import { defineConfig, postgresConfig } from "ezcfg";
|
|
30
|
+
*
|
|
31
|
+
* const getConfig = defineConfig({
|
|
32
|
+
* db: postgresConfig("ORDER_DB"), // reads ORDER_DB_URL
|
|
33
|
+
* db2: postgresConfig("PG", "fields"), // reads PG_HOST, PG_PORT, etc.
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* getConfig().db.host; // "localhost"
|
|
37
|
+
* getConfig().db.toString(); // "postgres://..."
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function postgresConfig(prefix, mode = "url") {
|
|
41
|
+
return new PostgresConfigSpec(prefix, mode);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=postgres-config-spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-config-spec.js","sourceRoot":"","sources":["../src/postgres-config-spec.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAuB,MAAM,sBAAsB,CAAC;AAE3E,MAAM,OAAO,kBAAkB;IAIN,MAAM;IACN,IAAI;IAJhB,KAAK,GAAG,UAAU,CAAC;IAE5B,YACqB,MAAc,EACd,IAAI,GAA2B,KAAK,EACvD;sBAFmB,MAAM;oBACN,IAAI;IACtB,CAAC;IAEJ,OAAO,CAAC,MAAgB,EAAE,SAAkC,EAA8B;QACtF,IAAI,CAAC;YACD,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;QAC/E,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,MAAM,CAAC,IAAI,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;YAClC,OAAO,SAAS,CAAC;QACrB,CAAC;IAAA,CACJ;CACJ;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,cAAc,CAC1B,MAAc,EACd,IAAI,GAA2B,KAAK,EAClB;IAClB,OAAO,IAAI,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAAA,CAC/C"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { DatabaseConfig } from "./database-config.js";
|
|
2
|
+
export interface PoolOptions {
|
|
3
|
+
size?: number;
|
|
4
|
+
connectionTimeout?: number;
|
|
5
|
+
idleTimeout?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface FromEnvOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Environment variable loading mode.
|
|
10
|
+
* - "url": Load from {PREFIX}_URL (default)
|
|
11
|
+
* - "fields": Load from {PREFIX}_HOST, {PREFIX}_PORT, {PREFIX}_DATABASE, {PREFIX}_USER, {PREFIX}_PASSWORD
|
|
12
|
+
*/
|
|
13
|
+
mode?: "url" | "fields";
|
|
14
|
+
}
|
|
15
|
+
export declare class PostgresConfig implements DatabaseConfig {
|
|
16
|
+
readonly host: string;
|
|
17
|
+
readonly database: string;
|
|
18
|
+
readonly user: string;
|
|
19
|
+
readonly port: number;
|
|
20
|
+
readonly password?: string;
|
|
21
|
+
readonly pool?: PoolOptions;
|
|
22
|
+
constructor(config: {
|
|
23
|
+
database: string;
|
|
24
|
+
user?: string;
|
|
25
|
+
host?: string;
|
|
26
|
+
port?: number;
|
|
27
|
+
password?: string;
|
|
28
|
+
pool?: PoolOptions;
|
|
29
|
+
});
|
|
30
|
+
static fromUrl(value: string): PostgresConfig;
|
|
31
|
+
static fromEnv(prefix: string, options?: FromEnvOptions, envSource?: Record<string, string>): PostgresConfig;
|
|
32
|
+
private static parseUrl;
|
|
33
|
+
withDatabase(database: string): PostgresConfig;
|
|
34
|
+
withUser(user: string): PostgresConfig;
|
|
35
|
+
withPassword(password: string): PostgresConfig;
|
|
36
|
+
withHost(host: string): PostgresConfig;
|
|
37
|
+
withPort(port: number): PostgresConfig;
|
|
38
|
+
withPoolSize(size: number): PostgresConfig;
|
|
39
|
+
withConnectionTimeout(connectionTimeout: number): PostgresConfig;
|
|
40
|
+
withIdleTimeout(idleTimeout: number): PostgresConfig;
|
|
41
|
+
toString(): string;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=postgres-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-config.d.ts","sourceRoot":"","sources":["../src/postgres-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,WAAW,WAAW;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC3B;;;;OAIG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC3B;AAED,qBAAa,cAAe,YAAW,cAAc;IACjD,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClC,SAAgB,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnC,YAAY,MAAM,EAAE;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,WAAW,CAAC;KACtB,EAOA;IAED,OAAc,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAEnD;IAED,OAAc,OAAO,CACjB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,EACxB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,cAAc,CAgChB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ;IAqBhB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CASpD;IAEM,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS5C;IAEM,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CASpD;IAEM,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS5C;IAEM,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS5C;IAEM,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAShD;IAEM,qBAAqB,CAAC,iBAAiB,EAAE,MAAM,GAAG,cAAc,CAStE;IAEM,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAS1D;IAEM,QAAQ,IAAI,MAAM,CA0BxB;CACJ"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export class PostgresConfig {
|
|
2
|
+
host;
|
|
3
|
+
database;
|
|
4
|
+
user;
|
|
5
|
+
port;
|
|
6
|
+
password;
|
|
7
|
+
pool;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.database = config.database;
|
|
10
|
+
this.password = config.password;
|
|
11
|
+
this.host = config.host ?? "localhost";
|
|
12
|
+
this.user = config.user ?? "postgres";
|
|
13
|
+
this.port = config.port ?? 5432;
|
|
14
|
+
this.pool = config.pool;
|
|
15
|
+
}
|
|
16
|
+
static fromUrl(value) {
|
|
17
|
+
return new PostgresConfig(PostgresConfig.parseUrl(value));
|
|
18
|
+
}
|
|
19
|
+
static fromEnv(prefix, options, envSource) {
|
|
20
|
+
const source = envSource ?? process.env;
|
|
21
|
+
const mode = options?.mode ?? "url";
|
|
22
|
+
if (mode === "url") {
|
|
23
|
+
const envKey = `${prefix}_URL`;
|
|
24
|
+
const url = source[envKey];
|
|
25
|
+
if (!url) {
|
|
26
|
+
throw new Error(`Environment variable ${envKey} is not set`);
|
|
27
|
+
}
|
|
28
|
+
return PostgresConfig.fromUrl(url);
|
|
29
|
+
}
|
|
30
|
+
// fields mode
|
|
31
|
+
const database = source[`${prefix}_DATABASE`];
|
|
32
|
+
if (!database) {
|
|
33
|
+
throw new Error(`Environment variable ${prefix}_DATABASE is not set`);
|
|
34
|
+
}
|
|
35
|
+
return new PostgresConfig({
|
|
36
|
+
database,
|
|
37
|
+
host: source[`${prefix}_HOST`],
|
|
38
|
+
port: source[`${prefix}_PORT`]
|
|
39
|
+
? parseInt(source[`${prefix}_PORT`])
|
|
40
|
+
: undefined,
|
|
41
|
+
user: source[`${prefix}_USER`],
|
|
42
|
+
password: source[`${prefix}_PASSWORD`],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
static parseUrl(value) {
|
|
46
|
+
const regex = /postgres(ql)?:\/\/(?<user>[^:/]+)(:(?<password>[^@]+))?@(?<host>[^:/]+)(:(?<port>\d+))?\/(?<database>.+)/;
|
|
47
|
+
const matches = value.match(regex);
|
|
48
|
+
if (!matches?.groups) {
|
|
49
|
+
throw new Error(`Invalid postgres url: ${value}`);
|
|
50
|
+
}
|
|
51
|
+
const { user, password, host, port, database } = matches.groups;
|
|
52
|
+
return {
|
|
53
|
+
host,
|
|
54
|
+
database,
|
|
55
|
+
user,
|
|
56
|
+
port: port ? parseInt(port) : 5432,
|
|
57
|
+
password,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
withDatabase(database) {
|
|
61
|
+
return new PostgresConfig({
|
|
62
|
+
host: this.host,
|
|
63
|
+
database,
|
|
64
|
+
user: this.user,
|
|
65
|
+
port: this.port,
|
|
66
|
+
password: this.password,
|
|
67
|
+
pool: this.pool,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
withUser(user) {
|
|
71
|
+
return new PostgresConfig({
|
|
72
|
+
host: this.host,
|
|
73
|
+
database: this.database,
|
|
74
|
+
user,
|
|
75
|
+
port: this.port,
|
|
76
|
+
password: this.password,
|
|
77
|
+
pool: this.pool,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
withPassword(password) {
|
|
81
|
+
return new PostgresConfig({
|
|
82
|
+
host: this.host,
|
|
83
|
+
database: this.database,
|
|
84
|
+
user: this.user,
|
|
85
|
+
port: this.port,
|
|
86
|
+
password,
|
|
87
|
+
pool: this.pool,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
withHost(host) {
|
|
91
|
+
return new PostgresConfig({
|
|
92
|
+
host,
|
|
93
|
+
database: this.database,
|
|
94
|
+
user: this.user,
|
|
95
|
+
port: this.port,
|
|
96
|
+
password: this.password,
|
|
97
|
+
pool: this.pool,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
withPort(port) {
|
|
101
|
+
return new PostgresConfig({
|
|
102
|
+
host: this.host,
|
|
103
|
+
database: this.database,
|
|
104
|
+
user: this.user,
|
|
105
|
+
port,
|
|
106
|
+
password: this.password,
|
|
107
|
+
pool: this.pool,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
withPoolSize(size) {
|
|
111
|
+
return new PostgresConfig({
|
|
112
|
+
host: this.host,
|
|
113
|
+
database: this.database,
|
|
114
|
+
user: this.user,
|
|
115
|
+
port: this.port,
|
|
116
|
+
password: this.password,
|
|
117
|
+
pool: { ...this.pool, size },
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
withConnectionTimeout(connectionTimeout) {
|
|
121
|
+
return new PostgresConfig({
|
|
122
|
+
host: this.host,
|
|
123
|
+
database: this.database,
|
|
124
|
+
user: this.user,
|
|
125
|
+
port: this.port,
|
|
126
|
+
password: this.password,
|
|
127
|
+
pool: { ...this.pool, connectionTimeout },
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
withIdleTimeout(idleTimeout) {
|
|
131
|
+
return new PostgresConfig({
|
|
132
|
+
host: this.host,
|
|
133
|
+
database: this.database,
|
|
134
|
+
user: this.user,
|
|
135
|
+
port: this.port,
|
|
136
|
+
password: this.password,
|
|
137
|
+
pool: { ...this.pool, idleTimeout },
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
toString() {
|
|
141
|
+
let url = `postgres://${this.user}`;
|
|
142
|
+
if (this.password) {
|
|
143
|
+
url += `:${this.password}`;
|
|
144
|
+
}
|
|
145
|
+
url += `@${this.host}:${this.port}/${this.database}`;
|
|
146
|
+
const queryParams = [];
|
|
147
|
+
if (this.pool?.size !== undefined) {
|
|
148
|
+
queryParams.push(`pool_size=${this.pool.size}`);
|
|
149
|
+
}
|
|
150
|
+
if (this.pool?.connectionTimeout !== undefined) {
|
|
151
|
+
queryParams.push(`connection_timeout=${this.pool.connectionTimeout}`);
|
|
152
|
+
}
|
|
153
|
+
if (this.pool?.idleTimeout !== undefined) {
|
|
154
|
+
queryParams.push(`idle_timeout=${this.pool.idleTimeout}`);
|
|
155
|
+
}
|
|
156
|
+
if (queryParams.length > 0) {
|
|
157
|
+
url += `?${queryParams.join("&")}`;
|
|
158
|
+
}
|
|
159
|
+
return url;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=postgres-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-config.js","sourceRoot":"","sources":["../src/postgres-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,cAAc,GACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/postgres.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,GAGjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,43 +1,44 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"types": "./dist/index.d.ts",
|
|
13
|
-
"import": "./dist/index.mjs",
|
|
14
|
-
"require": "./dist/index.js"
|
|
15
|
-
}
|
|
2
|
+
"name": "ezcfg",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Lite and easy configuration management for Node.js",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Sangwoo Hyun <wkdny.hyun@gmail.com>",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
16
12
|
},
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
13
|
+
"./postgres": {
|
|
14
|
+
"types": "./dist/postgres.d.ts",
|
|
15
|
+
"import": "./dist/postgres.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"dotenv": "^17.2.3"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^25.1.0",
|
|
27
|
+
"@typescript/native-preview": "^7.0.0-dev",
|
|
28
|
+
"typescript": "^5.9.3",
|
|
29
|
+
"vitest": "^4.0.18"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"config",
|
|
33
|
+
"configuration",
|
|
34
|
+
"env",
|
|
35
|
+
"environment",
|
|
36
|
+
"typescript",
|
|
37
|
+
"type-safe"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsgo -p tsconfig.json",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:watch": "vitest"
|
|
43
|
+
}
|
|
44
|
+
}
|