envapt 4.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,86 +1,111 @@
1
- import { DotenvConfigOptions } from 'dotenv';
2
-
3
- /**
4
- * Enum for built-in converters
5
- * @public
6
- */
7
- declare enum Converters {
8
- String = "string",
9
- Number = "number",
10
- Boolean = "boolean",
11
- Bigint = "bigint",
12
- Symbol = "symbol",
13
- Integer = "integer",
14
- Float = "float",
15
- Json = "json",
16
- Array = "array",
17
- Url = "url",
18
- Regexp = "regexp",
19
- Date = "date",
20
- Time = "time"
21
- }
1
+ //#region src/converters/Converters.d.ts
2
+ declare const SCALAR: {
3
+ readonly String: "string";
4
+ readonly Number: "number";
5
+ readonly Boolean: "boolean";
6
+ readonly Bigint: "bigint";
7
+ readonly Symbol: "symbol";
8
+ readonly Integer: "integer";
9
+ readonly Float: "float";
10
+ readonly Json: "json";
11
+ readonly Url: "url";
12
+ readonly Regexp: "regexp";
13
+ readonly Date: "date";
14
+ readonly Time: "time";
15
+ };
22
16
  /**
23
- * Type alias for converter values to maintain compatibility with existing string-based API
24
- * @internal
17
+ * String tokens for every built-in scalar converter.
18
+ * @public
25
19
  */
26
- type ConverterValue = `${Converters}`;
20
+ type ConverterToken = (typeof SCALAR)[keyof typeof SCALAR];
27
21
  /**
28
- * Valid array element converter types (excludes array, json, regexp)
29
- * @internal
22
+ * Custom element converter for use inside {@link Converters.array}. Receives the trimmed,
23
+ * non-empty raw string for one array slot and returns the parsed value.
24
+ * @public
30
25
  */
31
- type ArrayElementConverter = Exclude<Converters, Converters.Array | Converters.Json | Converters.Regexp>;
26
+ type CustomElementConverter<TReturn = unknown> = (raw: string) => TReturn;
32
27
  /**
33
- * Type alias for array element converter values
34
- * @internal
28
+ * Valid element converters for {@link Converters.array}: any scalar token except
29
+ * `json` and `regexp` (those don't compose as array elements), or a custom function.
30
+ * @public
35
31
  */
36
- type ArrayElementConverterValue = `${ArrayElementConverter}`;
37
-
32
+ type ArrayElement = Exclude<ConverterToken, 'json' | 'regexp'> | CustomElementConverter;
38
33
  /**
39
- * User defined options for dotenv configuration
40
- *
41
- * "processEnv" and "path" are managed by Envapter and should not be included in user-defined config.
34
+ * Phantom-branded token produced by {@link Converters.array}. The `T` type parameter carries
35
+ * the element converter through any variable indirection so inference survives. The
36
+ * `__envaptKind` discriminant is present at runtime for dispatch.
42
37
  * @public
43
38
  */
44
- type PermittedDotenvConfig = Omit<DotenvConfigOptions, 'processEnv' | 'path'>;
39
+ interface ArrayOf<TElement extends ArrayElement = ArrayElement> {
40
+ readonly __envaptKind: 'array';
41
+ readonly of: TElement;
42
+ readonly delimiter: string;
43
+ }
45
44
  /**
46
- * Built-in converter types for common environment variable patterns
47
- * @public
45
+ * Runtime type guard for tokens produced by {@link Converters.array}.
46
+ * @internal
48
47
  */
49
- type BuiltInConverter = ConverterValue | Converters;
48
+ declare function isArrayOf(value: unknown): value is ArrayOf;
49
+ type ArrayScalarElement = Exclude<ConverterToken, 'json' | 'regexp'>;
50
+ declare function buildArrayConverter<TReturn>(opts: {
51
+ of: CustomElementConverter<TReturn>;
52
+ delimiter?: string;
53
+ }): ArrayOf<CustomElementConverter<TReturn>>;
54
+ declare function buildArrayConverter<TToken extends ArrayScalarElement>(opts: {
55
+ of: TToken;
56
+ delimiter?: string;
57
+ }): ArrayOf<TToken>;
58
+ declare function buildArrayConverter(opts?: {
59
+ delimiter?: string;
60
+ }): ArrayOf<'string'>;
50
61
  /**
51
- * Primitive types supported by Envapter
62
+ * Built-in converters for environment variables. Use the scalar tokens (e.g. `Converters.Number`)
63
+ * for primitive types and the {@link Converters.array} builder for delimited lists.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * \@Envapt('PORT', { converter: Converters.Number, fallback: 3000 })
68
+ * static readonly port: number;
69
+ *
70
+ * \@Envapt('TAGS', { converter: Converters.array({ of: Converters.String, delimiter: ' ' }) })
71
+ * static readonly tags: string[];
72
+ * ```
73
+ *
52
74
  * @public
53
75
  */
54
- type PrimitiveConstructor = typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol;
76
+ declare const Converters: {
77
+ readonly array: typeof buildArrayConverter;
78
+ readonly String: "string";
79
+ readonly Number: "number";
80
+ readonly Boolean: "boolean";
81
+ readonly Bigint: "bigint";
82
+ readonly Symbol: "symbol";
83
+ readonly Integer: "integer";
84
+ readonly Float: "float";
85
+ readonly Json: "json";
86
+ readonly Url: "url";
87
+ readonly Regexp: "regexp";
88
+ readonly Date: "date";
89
+ readonly Time: "time";
90
+ };
91
+ //#endregion
92
+ //#region src/types/Conversion.d.ts
55
93
  /**
56
- * Valid array converter element types (excludes array, json, regexp)
94
+ * Scalar built-in converter tokens (e.g. `'number'`, `'time'`).
95
+ * Excludes the array builder (see {@link ArrayOf}).
57
96
  * @public
58
97
  */
59
- type ValidArrayConverterBuiltInType = ArrayElementConverterValue | ArrayElementConverter;
98
+ type BuiltInConverter = ConverterToken;
60
99
  /**
61
- * Array converter configuration for custom delimiters and element types
100
+ * Primitive types supported by Envapter
62
101
  * @public
63
102
  */
64
- interface ArrayConverter {
65
- /**
66
- * Delimiter to split the string by
67
- */
68
- delimiter: string;
69
- /**
70
- * Type to convert each array element to (excludes array, json, and regexp types)
71
- */
72
- type?: ArrayElementConverter | ArrayElementConverterValue;
73
- }
103
+ type PrimitiveConstructor = typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol;
74
104
  /**
75
105
  * String value from a .env file or environment variable
76
106
  * @public
77
107
  */
78
108
  type BaseInput = string | undefined;
79
- /**
80
- * Accepted shape for environment variable lookups. Either a single key or an ordered list of keys.
81
- * @public
82
- */
83
- type EnvKeyInput = string | readonly [string, ...string[]];
84
109
  /**
85
110
  * Custom parser function type for environment variables
86
111
  * @param raw - Raw string value from environment
@@ -90,59 +115,40 @@ type EnvKeyInput = string | readonly [string, ...string[]];
90
115
  */
91
116
  type ConverterFunction<TFallback = unknown> = (raw: BaseInput, fallback?: TFallback) => TFallback;
92
117
  /**
93
- * Environment variable converter - can be a primitive constructor, built-in converter string, array converter object, or custom parser function
94
- * @see {@link PrimitiveConstructor} for primitive types
95
- * @see {@link Converters} for built-in types
96
- * @see {@link ArrayConverter} for array converter configuration
97
- * @see {@link ConverterFunction} for custom parser functions
118
+ * Environment variable converter: a primitive constructor, a built-in scalar token, an `ArrayOf<...>`
119
+ * produced by {@link Converters.array}, or a custom parser function.
98
120
  * @public
99
121
  */
100
- type EnvaptConverter<TFallback> = PrimitiveConstructor | Converters | ConverterValue | ArrayConverter | ConverterFunction<TFallback>;
101
- /**
102
- * Options for the \@Envapt decorator (modern API)
103
- * @public
104
- */
105
- interface EnvaptOptions<TFallback = string> {
106
- /**
107
- * Default value to use if environment variable is not found
108
- */
109
- fallback?: TFallback;
110
- /**
111
- * Built-in converter, custom converter function, or boxed-primitives (String, Number, Boolean, Symbol, BigInt)
112
- * @see {@link EnvaptConverter} for details
113
- */
114
- converter?: EnvaptConverter<TFallback>;
115
- }
122
+ type EnvaptConverter<TFallback> = PrimitiveConstructor | BuiltInConverter | ArrayOf | ConverterFunction<TFallback>;
116
123
  type JsonPrimitive = string | number | boolean | null;
117
124
  type JsonArray = JsonValue[];
118
125
  interface JsonObject {
119
- [key: string]: JsonValue;
126
+ [key: string]: JsonValue;
120
127
  }
121
128
  /**
122
129
  * JSON value types for custom converters
123
- * @internal
130
+ * @public
124
131
  */
125
132
  type JsonValue = JsonPrimitive | JsonArray | JsonObject;
126
133
  interface ConverterMap {
127
- string: string;
128
- number: number;
129
- boolean: boolean;
130
- bigint: bigint;
131
- symbol: symbol;
132
- integer: number;
133
- float: number;
134
- json: JsonValue;
135
- array: string[];
136
- url: URL;
137
- regexp: RegExp;
138
- date: Date;
139
- time: number;
134
+ string: string;
135
+ number: number;
136
+ boolean: boolean;
137
+ bigint: bigint;
138
+ symbol: symbol;
139
+ integer: number;
140
+ float: number;
141
+ json: JsonValue;
142
+ url: URL;
143
+ regexp: RegExp;
144
+ date: Date;
145
+ time: number;
140
146
  }
141
147
  /**
142
- * Type mapping for built-in converters to their return types
148
+ * Type mapping for built-in scalar converters to their return types
143
149
  * @internal
144
150
  */
145
- type BuiltInConverterReturnType<ConverterKey extends BuiltInConverter> = ConverterKey extends Converters ? ConverterMap[`${ConverterKey}`] : ConverterKey extends keyof ConverterMap ? ConverterMap[ConverterKey] : never;
151
+ type BuiltInConverterReturnType<ConverterKey extends BuiltInConverter> = ConverterMap[ConverterKey];
146
152
  /**
147
153
  * Return type for built-in converter functions
148
154
  * @internal
@@ -162,7 +168,12 @@ type MapOfConverterFunctions = Record<BuiltInConverter, BuiltInConverterFunction
162
168
  * Time unit types for duration conversions
163
169
  * @internal
164
170
  */
165
- type TimeUnit = 'ms' | 's' | 'm' | 'h';
171
+ type TimeUnit = 'ms' | 's' | 'm' | 'h' | 'd' | 'w';
172
+ /**
173
+ * Fallback type for time duration conversions
174
+ * @public
175
+ */
176
+ type TimeFallback = number | `${number}${TimeUnit}`;
166
177
  /**
167
178
  * Helper type for getter methods that conditionally return undefined based on whether a fallback is provided
168
179
  * If fallback is provided, return ReturnType. If no fallback (undefined), return ReturnType | undefined.
@@ -170,16 +181,27 @@ type TimeUnit = 'ms' | 's' | 'm' | 'h';
170
181
  */
171
182
  type ConditionalReturn<ReturnType, TFallback> = TFallback extends undefined ? ReturnType | undefined : ReturnType;
172
183
  /**
173
- * Advanced type inference for built-in and array converters
174
- * Maps converter types to their expected return types
184
+ * Inferred return type for a converter.
185
+ *
186
+ * - `ArrayOf<E>` resolves to the element type's return as an array. When `E` is a custom
187
+ * function, the function's return type drives the array element. When `E` is a scalar
188
+ * token, `ConverterMap` provides the element type.
189
+ * - Bare scalar tokens resolve through `ConverterMap`.
190
+ * @internal
191
+ */
192
+ type InferConverterReturnType<TConverter> = TConverter extends ArrayOf<infer Element> ? Element extends BuiltInConverter ? ConverterMap[Element][] : Element extends CustomElementConverter<infer Returned> ? Returned[] : never : TConverter extends BuiltInConverter ? BuiltInConverterReturnType<TConverter> : never;
193
+ /**
194
+ * Type inference for the *fallback* slot of a converter. `Converters.Time` (scalar or array
195
+ * element) accepts {@link TimeFallback} / `TimeFallback[]`; everything else mirrors the
196
+ * return type. Add future asymmetric fallback/return converters to this conditional.
175
197
  * @internal
176
198
  */
177
- type InferConverterReturnType<TConverter extends BuiltInConverter | ArrayConverter> = TConverter extends BuiltInConverter ? BuiltInConverterReturnType<TConverter> : TConverter extends ArrayConverter ? TConverter['type'] extends BuiltInConverter ? BuiltInConverterReturnType<TConverter['type']>[] : string[] : unknown[];
199
+ type InferConverterFallbackType<TConverter> = TConverter extends 'time' ? TimeFallback : TConverter extends ArrayOf<infer Element> ? Element extends 'time' ? TimeFallback[] : InferConverterReturnType<TConverter> : InferConverterReturnType<TConverter>;
178
200
  /**
179
201
  * Complete type inference for advanced converter methods
180
202
  * @internal
181
203
  */
182
- type AdvancedConverterReturn<TConverter extends BuiltInConverter | ArrayConverter, TFallback = undefined> = ConditionalReturn<InferConverterReturnType<TConverter>, TFallback>;
204
+ type AdvancedConverterReturn<TConverter, TFallback = undefined> = ConditionalReturn<InferConverterReturnType<TConverter>, TFallback>;
183
205
  /**
184
206
  * Type inference for primitive constructor return types
185
207
  * @internal
@@ -190,17 +212,404 @@ type InferPrimitiveReturnType<TConstructor extends PrimitiveConstructor> = TCons
190
212
  * @internal
191
213
  */
192
214
  type InferPrimitiveFallbackType<TFallback extends string | number | boolean | bigint | symbol | undefined> = TFallback extends string ? string : TFallback extends number ? number : TFallback extends boolean ? boolean : TFallback extends bigint ? bigint : TFallback extends symbol ? symbol : undefined;
193
-
215
+ //#endregion
216
+ //#region src/StandardSchema.d.ts
217
+ /**
218
+ * Standard Schema V1 interface. Inlined verbatim from the spec at https://standardschema.dev
219
+ * so envapt has zero runtime peer dependencies on any specific schema library
220
+ * (zod / valibot / arktype / etc).
221
+ *
222
+ * envapt narrows usage to SYNCHRONOUS schemas only: env loading is boot-time,
223
+ * `validate` returning `Promise<Result>` is rejected at the type level (see
224
+ * `SchemaMustBeSync` brand in `Types.ts`) and at runtime by the Parser dispatch.
225
+ *
226
+ * @public
227
+ */
228
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
229
+ readonly '~standard': StandardSchemaV1.Props<Input, Output>;
230
+ }
231
+ declare namespace StandardSchemaV1 {
232
+ interface Props<Input = unknown, Output = Input> {
233
+ readonly version: 1;
234
+ readonly vendor: string;
235
+ readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
236
+ readonly types?: Types<Input, Output> | undefined;
237
+ }
238
+ type Result<Output> = SuccessResult<Output> | FailureResult;
239
+ interface SuccessResult<Output> {
240
+ readonly value: Output;
241
+ readonly issues?: undefined;
242
+ }
243
+ interface FailureResult {
244
+ readonly issues: readonly Issue[];
245
+ }
246
+ interface Issue {
247
+ readonly message: string;
248
+ readonly path?: readonly (PropertyKey | PathSegment)[] | undefined;
249
+ }
250
+ interface PathSegment {
251
+ readonly key: PropertyKey;
252
+ }
253
+ interface Types<Input = unknown, Output = Input> {
254
+ readonly input: Input;
255
+ readonly output: Output;
256
+ }
257
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
258
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
259
+ }
260
+ /**
261
+ * Envapt-side alias for {@link StandardSchemaV1.InferOutput}. Re-exported under a friendlier
262
+ * name so consumers writing `declare static readonly x: InferSchemaOutput<typeof mySchema>`
263
+ * don't need the namespace path.
264
+ * @public
265
+ */
266
+ type InferSchemaOutput<Schema extends StandardSchemaV1> = StandardSchemaV1.InferOutput<Schema>;
267
+ /**
268
+ * Envapt-side alias for {@link StandardSchemaV1.InferInput}.
269
+ * @public
270
+ */
271
+ type InferSchemaInput<Schema extends StandardSchemaV1> = StandardSchemaV1.InferInput<Schema>;
272
+ //#endregion
273
+ //#region src/types/Schema.d.ts
274
+ declare const _envaptErrBrand: unique symbol;
275
+ type Err<Msg extends string> = Msg & {
276
+ readonly [_envaptErrBrand]: never;
277
+ };
278
+ type SchemaMustBeSync = Err<'Schema must be synchronous. envapt is boot-time config loading; async refinements (validate returning `Promise<Result>`) belong outside the env layer.'>;
279
+ type SchemaConstraint<Schema extends StandardSchemaV1> = ReturnType<Schema['~standard']['validate']> extends Promise<unknown> ? SchemaMustBeSync : Schema;
280
+ //#endregion
281
+ //#region src/Debug.d.ts
282
+ /**
283
+ * Debug log levels for {@link Envapter.debug}. `silent` (default) emits nothing.
284
+ * `warn` covers signals that might indicate misconfiguration: failed file reads,
285
+ * unresolved templates (when not strict), fallback values used in place of missing
286
+ * env. `verbose` adds every loaded file, per-file key count, per-key load lines, and
287
+ * effective-paths / cache-rebuild notices.
288
+ * @public
289
+ */
290
+ type DebugLevel = 'silent' | 'warn' | 'verbose';
291
+ //#endregion
292
+ //#region src/Dotenv.d.ts
293
+ /**
294
+ * Public options for the internal `.env` loader. Mirrors the subset of dotenv's
295
+ * `config()` options that envapt actually supports (no DOTENV_KEY, no quiet).
296
+ * For debug output, use `Envapter.debug` (or the `ENVAPT_DEBUG` env var).
297
+ *
298
+ * @public
299
+ */
300
+ interface EnvFileOptions {
301
+ /** Encoding for reading .env files. Defaults to 'utf8'. */
302
+ encoding?: BufferEncoding;
303
+ /** When true, later files override earlier ones (and existing processEnv values). Default false (first-wins). */
304
+ override?: boolean;
305
+ }
306
+ //#endregion
307
+ //#region src/core/EnvapterBase.d.ts
308
+ /**
309
+ * Base class for environment variable management
310
+ * Handles configuration, caching, and basic environment loading
311
+ * @internal
312
+ */
313
+ declare abstract class EnvapterBase {
314
+ protected static _envPaths: string[];
315
+ protected static _envPathsExplicitlySet: boolean;
316
+ protected static _baseDir: string | undefined;
317
+ protected static _userDefinedEnvFileOptions: EnvFileOptions;
318
+ protected static _strict: boolean;
319
+ protected static _syncProcessEnv: boolean;
320
+ protected static _dotenvAddedKeys: Set<string>;
321
+ /**
322
+ * Enable or disable strict mode. Default `false`. Setting refreshes the cache so
323
+ * previously-cached converted values get re-evaluated under the new rule.
324
+ */
325
+ static set strict(value: boolean);
326
+ static get strict(): boolean;
327
+ /**
328
+ * Set the debug log level. Defaults to `silent`. When unset, reads `ENVAPT_DEBUG` from
329
+ * `process.env` on first access; the setter overrides any env-var value. Output goes
330
+ * to stderr prefixed with `[envapt]`.
331
+ */
332
+ static set debug(level: DebugLevel);
333
+ static get debug(): DebugLevel;
334
+ /**
335
+ * Opt-in mirror of dotenv-loaded keys back to `process.env`. Default `false`.
336
+ *
337
+ * Only keys the loader actually wrote are mirrored, so collision behavior follows
338
+ * `envFileOptions.override`: with the default `false`, pre-existing `process.env` values
339
+ * are preserved; with `true`, the file value wins in both the cache and the mirror.
340
+ *
341
+ * Flipping `false → true` mirrors the existing tracked delta immediately (no cache
342
+ * refresh). Flipping `true → false` is one-way: previously mirrored keys remain in
343
+ * `process.env` until the process exits.
344
+ */
345
+ static set syncProcessEnv(value: boolean);
346
+ static get syncProcessEnv(): boolean;
347
+ protected static treatAsMissing(value: string | undefined): boolean;
348
+ /**
349
+ * Set custom .env file paths. Accepts either a single path or array of paths.
350
+ * Setting new paths clears the cache and reloads environment variables.
351
+ *
352
+ * When set, this takes absolute precedence. The dotenv-flow auto-cascade and any
353
+ * {@link configureProfiles} configuration are ignored.
354
+ */
355
+ static set envPaths(paths: string[] | string);
356
+ /**
357
+ * Get currently configured .env file paths
358
+ */
359
+ static get envPaths(): string[];
360
+ /**
361
+ * Set a base directory that relative `.env` paths resolve against instead of
362
+ * `process.cwd()`: the auto-cascade, {@link configureProfiles} paths, and relative
363
+ * `envPaths`. Absolute paths always bypass it. Pass a directory, or a module URL
364
+ * (`import.meta.url`, ESM) / `import.meta.dirname` / `__dirname` (CJS) to anchor
365
+ * resolution next to the calling file regardless of launch directory.
366
+ *
367
+ * Set this before `envPaths` so relative `envPaths` validate against the right directory.
368
+ * Unset (`undefined`) restores `process.cwd()` resolution.
369
+ */
370
+ static set baseDir(value: string | URL | undefined);
371
+ static get baseDir(): string | undefined;
372
+ private static normalizeBaseDir;
373
+ protected static resolveAgainstBase(candidate: string): string;
374
+ static set envFileOptions(config: EnvFileOptions);
375
+ /**
376
+ * Get current dotenv configuration options
377
+ */
378
+ static get envFileOptions(): EnvFileOptions;
379
+ protected static refreshCache(): void;
380
+ protected static mirrorToProcessEnv(): void;
381
+ /**
382
+ * Resolve the effective `.env` paths to load. Default implementation just returns the
383
+ * explicit `_envPaths` array; subclasses (`EnvironmentMethods`) override to layer in the
384
+ * dotenv-flow cascade and any {@link configureProfiles} overrides when `envPaths` was
385
+ * never explicitly set.
386
+ * @internal
387
+ */
388
+ protected static resolveEffectivePaths(): string[];
389
+ protected static resolveKeyInput(keyInput: EnvKeyInput): {
390
+ key: string;
391
+ value: string | undefined;
392
+ };
393
+ protected static get config(): Map<string, unknown>;
394
+ /**
395
+ * Eagerly load the `.env` cascade now instead of lazily on the first read. Idempotent: a no-op
396
+ * once the cache is built. Useful before mirroring to `process.env` (see {@link syncProcessEnv}),
397
+ * which is what the `envapt/config` side-effect entry does.
398
+ */
399
+ static load(): void;
400
+ /**
401
+ * Read an environment variable as its raw string, skipping parsing and conversion.
402
+ */
403
+ getRaw(key: EnvKeyInput): string | undefined;
404
+ }
405
+ //#endregion
406
+ //#region src/core/EnvironmentMethods.d.ts
407
+ /**
408
+ * Environment types supported by Envapter
409
+ * @public
410
+ */
411
+ declare enum Environment {
412
+ Development = 0,
413
+ Staging = 1,
414
+ Production = 2
415
+ }
416
+ /**
417
+ * Mixin for environment detection and checking methods
418
+ * @internal
419
+ */
420
+ declare class EnvironmentMethods extends EnvapterBase {
421
+ protected static _environment: Environment | undefined;
422
+ protected static _environmentExplicitlySet: boolean;
423
+ protected static _profiles: ProfilesConfig | undefined;
424
+ protected static determineEnvironment(env?: string | Environment): void;
425
+ private static getRawValue;
426
+ /**
427
+ * Get the current application environment
428
+ */
429
+ static get environment(): Environment;
430
+ /**
431
+ * Set the application environment. Accepts either Environment enum or string value.
432
+ */
433
+ static set environment(env: string | Environment);
434
+ /**
435
+ * @see {@link EnvironmentMethods.environment}
436
+ */
437
+ get environment(): Environment;
438
+ /**
439
+ * @see {@link EnvironmentMethods.environment}
440
+ */
441
+ set environment(env: string | Environment);
442
+ /**
443
+ * Check if the current environment is production
444
+ */
445
+ static get isProduction(): boolean;
446
+ /**
447
+ * @see {@link EnvironmentMethods.isProduction}
448
+ */
449
+ get isProduction(): boolean;
450
+ /**
451
+ * Check if the current environment is staging
452
+ */
453
+ static get isStaging(): boolean;
454
+ /**
455
+ * @see {@link EnvironmentMethods.isStaging}
456
+ */
457
+ get isStaging(): boolean;
458
+ /**
459
+ * Check if the current environment is development
460
+ */
461
+ static get isDevelopment(): boolean;
462
+ /**
463
+ * @see {@link EnvironmentMethods.isDevelopment}
464
+ */
465
+ get isDevelopment(): boolean;
466
+ protected static refreshCache(): void;
467
+ /**
468
+ * Configure per-environment `.env` path overrides on top of the dotenv-flow auto-cascade.
469
+ *
470
+ * When set, each `Environment` key's `paths` are loaded at higher precedence than the
471
+ * cascade for that environment. Unspecified environments still use the cascade as-is.
472
+ * Set `useDefaults: false` to disable the cascade entirely (load only the configured paths).
473
+ *
474
+ * Setting an explicit `Envapter.envPaths` value at any point overrides this configuration.
475
+ *
476
+ * @example
477
+ * ```ts
478
+ * Envapter.configureProfiles({
479
+ * [Environment.Staging]: { paths: 'config/staging.env' },
480
+ * [Environment.Production]: { paths: ['config/prod.env', 'secrets/prod.env'] }
481
+ * });
482
+ * ```
483
+ */
484
+ static configureProfiles(config: ProfilesConfig): void;
485
+ /**
486
+ * Reset all path-resolution configuration to defaults: clears any prior
487
+ * {@link configureProfiles} call AND any explicit `Envapter.envPaths` assignment.
488
+ * Returns the resolver to the pure dotenv-flow cascade.
489
+ */
490
+ static resetProfiles(): void;
491
+ /**
492
+ * Determine the current environment for cascade-file selection by reading `process.env`
493
+ * directly. Bypassing `this.config` to avoid a circular dependency (cascade selection
494
+ * happens before `.env` files are loaded). The post-load `Envapter.environment` value
495
+ * may differ if a loaded `.env` file declares its own `ENVIRONMENT`/`ENV`/`NODE_ENV`.
496
+ * @internal
497
+ */
498
+ protected static getCascadeEnvironment(): Environment;
499
+ /**
500
+ * Build the dotenv-flow cascade for a given environment, in dotenv first-wins precedence
501
+ * order (highest precedence first). Missing files are silently filtered.
502
+ *
503
+ * Precedence is **most-specific-wins** (matches Vite / Astro / Vocs):
504
+ * `.env.${env}.local` \> `.env.${env}` \> `.env.local` \> `.env`
505
+ *
506
+ * This differs from dotenv-flow / Next.js convention which puts `.env.local` above
507
+ * `.env.${env}`. We chose the most-specific-wins order so committed env-specific files
508
+ * (`.env.production`) are authoritative for that environment regardless of whether a
509
+ * stray `.env.local` is present.
510
+ * @internal
511
+ */
512
+ protected static buildCascadePaths(env: Environment): string[];
513
+ private static normalizeProfilePaths;
514
+ /**
515
+ * Override the base implementation to layer the dotenv-flow cascade + any
516
+ * {@link configureProfiles} overrides on top of `_envPaths` when the user has NOT
517
+ * explicitly set `envPaths`.
518
+ *
519
+ * Precedence (passed to dotenv with first-wins semantics):
520
+ * 1. profile-configured paths for the current env (if any)
521
+ * 2. `.env.${env}.local`
522
+ * 3. `.env.${env}`
523
+ * 4. `.env.local`
524
+ * 5. `.env`
525
+ *
526
+ * If `useDefaults: false` is set on the profiles config, only (1) is loaded — no cascade.
527
+ * If `envPaths` was explicitly set, only `envPaths` is loaded (everything else ignored).
528
+ * @internal
529
+ */
530
+ protected static resolveEffectivePaths(): string[];
531
+ }
532
+ //#endregion
533
+ //#region src/types/Options.d.ts
534
+ /**
535
+ * Options for the \@Envapt decorator (modern API). `required: true` is mutually exclusive
536
+ * with `fallback`; see the per-converter overloads in `Envapt.ts` for the type-level mutex.
537
+ * @public
538
+ */
539
+ interface EnvaptOptions<TFallback = string> {
540
+ fallback?: TFallback;
541
+ converter?: EnvaptConverter<TFallback>;
542
+ required?: boolean;
543
+ }
544
+ /**
545
+ * Per-environment profile entry passed to {@link configureProfiles}.
546
+ * @public
547
+ */
548
+ interface EnvProfile {
549
+ /** One or more `.env` paths to load for this environment. Order matters: earlier paths take precedence. */
550
+ paths: string | string[];
551
+ }
552
+ /**
553
+ * Configuration object for {@link configureProfiles}. Maps each `Environment` to an optional
554
+ * profile override. Unspecified environments fall through to the default cascade behavior
555
+ * (`.env.${env}.local`, `.env.local`, `.env.${env}`, `.env`).
556
+ * @public
557
+ */
558
+ type ProfilesConfig = Partial<Record<Environment, EnvProfile>> & {
559
+ /**
560
+ * When `false`, disables the default dotenv-flow cascade entirely. Only the explicitly
561
+ * configured paths are loaded. Defaults to `true` (cascade still runs, configured paths
562
+ * are layered on top with higher precedence).
563
+ */
564
+ useDefaults?: boolean;
565
+ };
566
+ //#endregion
567
+ //#region src/types/Env.d.ts
568
+ /**
569
+ * Accepted shape for environment variable lookups. Either a single key or an ordered list of keys.
570
+ * @public
571
+ */
572
+ type EnvKeyInput = string | readonly [string, ...string[]];
573
+ /**
574
+ * @internal
575
+ */
576
+ interface EnvapterService {
577
+ getRaw(key: EnvKeyInput): string | undefined;
578
+ get(key: EnvKeyInput, def?: string): string | undefined;
579
+ isStrict(): boolean;
580
+ }
581
+ //#endregion
582
+ //#region src/converters/ValueConverter.d.ts
194
583
  /**
195
- * Usage 1: Custom converter function with fallback provided
584
+ * Convert a resolved environment value to its declared type via built-in, primitive, array,
585
+ * custom, or Standard Schema converters.
586
+ * @internal
587
+ */
588
+ declare class ValueConverter {
589
+ private readonly envService;
590
+ constructor(envService: EnvapterService);
591
+ convertValue<TFallback>(key: EnvKeyInput, fallback: TFallback | undefined, converter: EnvaptConverter<TFallback> | undefined, hasFallback: boolean): TFallback | null | undefined;
592
+ private processFallbackForConverter;
593
+ private convertPrimitiveToString;
594
+ private processBuiltInConverter;
595
+ private processArrayConverter;
596
+ private processCustomConverter;
597
+ private resolveConverter;
598
+ convertWithSchema(key: EnvKeyInput, schema: StandardSchemaV1, fallback: unknown, hasFallback: boolean): unknown;
599
+ }
600
+ //#endregion
601
+ //#region src/decorators/Envapt.d.ts
602
+ /**
603
+ * Usage 1: Either a custom converter function + fallback (both required), OR a fallback
604
+ * only (no converter).
196
605
  *
197
- * @param key - Environment variable name to load (string or ordered array of strings)
198
- * @param options - Configuration options with custom converter and required fallback
606
+ * @param key - Environment variable name(s) to load
607
+ * @param options - Configuration options
199
608
  * @public
200
609
  * @example
201
610
  * ```ts
202
- * // Custom converter that validates a non-empty API key
203
611
  * class Config extends Envapter {
612
+ * // Custom converter that validates a non-empty API key
204
613
  * \@Envapt('API_KEY', {
205
614
  * fallback: 'default-key',
206
615
  * converter(raw, _fallback) {
@@ -209,39 +618,66 @@ type InferPrimitiveFallbackType<TFallback extends string | number | boolean | bi
209
618
  * }
210
619
  * })
211
620
  * static readonly apiKey: string;
621
+ *
622
+ * // Fallback-only (no converter): string fallback
623
+ * \@Envapt('LOG_FILE', { fallback: '/var/log/app.log' })
624
+ * static readonly logFile: string;
625
+ *
626
+ * // Fallback-only: arbitrary object fallback
627
+ * \@Envapt('RETRY_POLICY', { fallback: { retries: 3, backoff: 'exponential' } })
628
+ * static readonly retryPolicy: unknown;
212
629
  * }
213
630
  * ```
214
631
  */
215
632
  declare function Envapt<TFallback>(key: EnvKeyInput, options: {
216
- converter: (raw: string | undefined, fallback: TFallback) => TFallback;
217
- fallback: TFallback;
633
+ converter: (raw: string | undefined, fallback: TFallback) => TFallback;
634
+ fallback: TFallback;
635
+ } | {
636
+ fallback: TFallback;
637
+ converter?: undefined;
218
638
  }): PropertyDecorator;
219
639
  /**
220
- * Usage 2: Custom converter function without fallback
640
+ * Usage 2: Custom converter function without fallback. Either omit `required` (returns the
641
+ * converter's output, possibly `undefined`) or pass `required: true` to throw `MissingEnvValue`
642
+ * on missing/empty values.
221
643
  *
222
644
  * @param key - Environment variable name(s) to load
223
- * @param options - Configuration options with custom converter only
645
+ * @param options - Configuration options with custom converter only, with optional `required: true`
224
646
  * @public
225
647
  * @example
226
648
  * ```ts
227
- * // Custom converter without providing a fallback
228
649
  * class Config extends Envapter {
229
650
  * \@Envapt('FEATURE_FLAGS', { converter(raw) {
230
- * // raw may be undefined — handle that here
231
651
  * return raw ? raw.split('|').map(s => s.trim()) : [];
232
652
  * } })
233
653
  * static readonly featureFlags: string[];
654
+ *
655
+ * \@Envapt('JWT_SECRET', {
656
+ * converter: (raw) => Buffer.from(raw ?? '', 'base64'),
657
+ * required: true
658
+ * })
659
+ * declare static readonly jwtSecret: Buffer;
234
660
  * }
235
661
  * ```
236
662
  */
237
663
  declare function Envapt<TReturnType>(key: EnvKeyInput, options: {
238
- converter: ConverterFunction<TReturnType>;
664
+ converter: ConverterFunction<TReturnType>;
665
+ required?: false;
666
+ } | {
667
+ converter: ConverterFunction<TReturnType>;
668
+ required: true;
239
669
  }): PropertyDecorator;
240
670
  /**
241
- * Usage 3: Built-in converter with optional fallback
671
+ * Usage 3: Built-in or array converter with optional fallback OR `required: true`.
672
+ *
673
+ * `InferConverterFallbackType` handles asymmetric cases: scalar `Converters.Time` accepts
674
+ * `TimeFallback`, and `ArrayOf<'time'>` accepts `TimeFallback[]`. Every other converter
675
+ * reduces to `InferConverterReturnType`. The two object-shape branches are mutually
676
+ * exclusive: either provide a `fallback`, or pass `required: true` to throw
677
+ * `MissingEnvValue` on missing/empty values.
242
678
  *
243
679
  * @param key - Environment variable name(s) to load
244
- * @param options - Configuration options with built-in converter
680
+ * @param options - Configuration options
245
681
  * @public
246
682
  * @example
247
683
  * ```ts
@@ -252,53 +688,40 @@ declare function Envapt<TReturnType>(key: EnvKeyInput, options: {
252
688
  * \@Envapt('APP_PORT', { converter: Converters.Number, fallback: 3000 })
253
689
  * static readonly port: number;
254
690
  *
255
- * // Use Url converter with a string fallback (must match converter type)
256
- * \@Envapt('APP_URL', { converter: Converters.Url, fallback: 'http://localhost:3000' })
691
+ * // Url converter: the fallback is a URL instance, not a string
692
+ * \@Envapt('APP_URL', { converter: Converters.Url, fallback: new URL('http://localhost:3000') })
257
693
  * static readonly url: URL;
258
694
  *
259
695
  * // Prefer CANARY_URL when present, otherwise fall back to APP_URL
260
696
  * \@Envapt(['CANARY_URL', 'APP_URL'], { converter: Converters.Url })
261
697
  * static readonly canaryUrl: URL | null;
262
- * }
263
- * ```
264
- */
265
- declare function Envapt<TConverter extends BuiltInConverter>(key: EnvKeyInput, options: {
266
- converter: TConverter;
267
- fallback?: InferConverterReturnType<TConverter> | undefined;
268
- }): PropertyDecorator;
269
- /**
270
- * Usage 4: Array converter with optional fallback
271
698
  *
272
- * @param key - Environment variable name(s) to load
273
- * @param options - Configuration options with array converter
274
- * @public
275
- * @example
276
- * ```ts
277
- * import { Converters } from 'envapt';
699
+ * // `Converters.Time` accepts either a number (milliseconds) or a time-string fallback (`<integer><unit>`).
700
+ * \@Envapt('REQUEST_TIMEOUT', { converter: Converters.Time, fallback: '10s' })
701
+ * static readonly requestTimeout: number;
278
702
  *
279
- * class Config extends Envapter {
280
- * // Comma-separated list of origins -> string[]
703
+ * // Array converter: comma-separated list of origins -> string[]
281
704
  * \@Envapt('ALLOWED_ORIGINS', {
282
- * converter: { delimiter: ',', type: Converters.String },
705
+ * converter: Converters.array({ of: Converters.String }),
283
706
  * fallback: ['https://example.com']
284
707
  * })
285
708
  * static readonly allowedOrigins: string[];
286
709
  *
287
- * // Pipe-separated ports -> number[]
288
- * \@Envapt('PORTS', {
289
- * converter: { delimiter: '|', type: Converters.Number },
290
- * fallback: [3000]
291
- * })
292
- * static readonly ports: number[];
710
+ * \@Envapt('DATABASE_URL', { converter: Converters.Url, required: true })
711
+ * declare static readonly databaseUrl: URL;
293
712
  * }
294
713
  * ```
295
714
  */
296
- declare function Envapt<TConverter extends ArrayConverter>(key: EnvKeyInput, options: {
297
- converter: TConverter;
298
- fallback?: InferConverterReturnType<TConverter> | undefined;
715
+ declare function Envapt<TConverter extends BuiltInConverter | ArrayOf>(key: EnvKeyInput, options: {
716
+ converter: TConverter;
717
+ fallback?: InferConverterFallbackType<TConverter> | undefined;
718
+ required?: false;
719
+ } | {
720
+ converter: TConverter;
721
+ required: true;
299
722
  }): PropertyDecorator;
300
723
  /**
301
- * Usage 5: Primitive constructor with optional fallback
724
+ * Usage 4: Primitive constructor with optional fallback
302
725
  *
303
726
  * @param key - Environment variable name(s) to load
304
727
  * @param options - Configuration options with primitive constructor
@@ -316,35 +739,38 @@ declare function Envapt<TConverter extends ArrayConverter>(key: EnvKeyInput, opt
316
739
  * ```
317
740
  */
318
741
  declare function Envapt<TConstructor extends PrimitiveConstructor>(key: EnvKeyInput, options: {
319
- converter: TConstructor;
320
- fallback?: InferPrimitiveReturnType<TConstructor>;
742
+ converter: TConstructor;
743
+ fallback?: InferPrimitiveReturnType<TConstructor>;
744
+ required?: false;
745
+ } | {
746
+ converter: TConstructor;
747
+ required: true;
321
748
  }): PropertyDecorator;
322
749
  /**
323
- * Usage 6: Fallback only (no converter)
750
+ * Usage 5: Required, no converter (raw string). Throws `MissingEnvValue` on first access if
751
+ * the env value is missing or empty (post-trim). Independent of global `Envapter.strict`.
752
+ * Combining `required: true` with `fallback` fails to match any overload at compile time;
753
+ * the runtime Validator catches dynamic objects that bypass the types.
324
754
  *
325
755
  * @param key - Environment variable name(s) to load
326
- * @param options - Configuration options with fallback only
756
+ * @param options - `{ required: true }`
327
757
  * @public
328
758
  * @example
329
759
  * ```ts
330
- * // Fallback-only usage (no converter)
331
760
  * class Config extends Envapter {
332
- * \@Envapt('LOG_FILE', { fallback: '/var/log/app.log' })
333
- * static readonly logFile: string;
334
- *
335
- * \@Envapt('RETRY_POLICY', { fallback: { retries: 3, backoff: 'exponential' } })
336
- * static readonly retryPolicy: unknown;
761
+ * \@Envapt('API_KEY', { required: true })
762
+ * declare static readonly apiKey: string;
337
763
  * }
338
764
  * ```
339
765
  */
340
- declare function Envapt<TFallback>(key: EnvKeyInput, options: {
341
- fallback: TFallback;
342
- converter?: undefined;
766
+ declare function Envapt(key: EnvKeyInput, options: {
767
+ required: true;
343
768
  }): PropertyDecorator;
344
769
  /**
345
770
  * Classic API: No fallback
346
771
  *
347
772
  * @param key - Environment variable name(s) to load
773
+ * @public
348
774
  * @example
349
775
  * ```ts
350
776
  * // Classic API: no fallback — property will resolve from env or be null
@@ -362,6 +788,9 @@ declare function Envapt<_TReturnType = string | null>(key: EnvKeyInput): Propert
362
788
  * @param fallback - Default primitive value
363
789
  * @param converter - Optional primitive constructor (String, Number, etc.)
364
790
  * @public
791
+ * @deprecated - Use the options object: `@Envapt('KEY', { converter, fallback })`. The positional
792
+ * form only accepts primitive constructors and cannot express built-in tokens, array/custom
793
+ * converters, `schema`, or `required`. Deprecated in v5, removed in v6.
365
794
  * @example
366
795
  * ```ts
367
796
  * // Classic API with primitive fallback and optional primitive converter
@@ -377,227 +806,202 @@ declare function Envapt<_TReturnType = string | null>(key: EnvKeyInput): Propert
377
806
  * ```
378
807
  */
379
808
  declare function Envapt<TFallback extends string | number | boolean | bigint | symbol | undefined>(key: EnvKeyInput, fallback: InferPrimitiveFallbackType<TFallback>, converter?: PrimitiveConstructor): PropertyDecorator;
380
-
381
809
  /**
382
- * @internal
810
+ * Usage 6: Standard Schema v1 adapter (zod, valibot, arktype, hand-rolled). Synchronous
811
+ * schemas only; a Promise-returning `validate` triggers a runtime
812
+ * `InvalidUserDefinedConfig` throw. Combining `schema` with `converter` fails to match any
813
+ * overload at compile time; the runtime Validator catches dynamic objects that bypass the
814
+ * types.
815
+ * @public
383
816
  */
384
- interface EnvapterService {
385
- getRaw(key: EnvKeyInput): string | undefined;
386
- get(key: EnvKeyInput, def?: string): string | undefined;
387
- }
817
+ declare function Envapt<Schema extends StandardSchemaV1>(key: EnvKeyInput, options: {
818
+ schema: SchemaConstraint<Schema>;
819
+ fallback?: InferSchemaOutput<Schema>;
820
+ required?: false;
821
+ } | {
822
+ schema: SchemaConstraint<Schema>;
823
+ required: true;
824
+ }): PropertyDecorator;
825
+ //#endregion
826
+ //#region src/decorators/SugarDecorators.d.ts
388
827
  /**
389
- * Parser class for handling environment variable template resolution and type conversion
390
- * @internal
828
+ * Shorthand for `@Envapt(key, { converter: Converters.Boolean, fallback })`.
829
+ * @public
391
830
  */
392
- declare class Parser {
393
- private readonly envService;
394
- private readonly TEMPLATE_REGEX;
395
- constructor(envService: EnvapterService);
396
- /**
397
- * Resolve template variables in a string while handling circular references and missing variables
398
- * @internal
399
- */
400
- resolveTemplate(key: string, value: string, stack?: Set<string>): string;
401
- convertValue<TFallback>(key: EnvKeyInput, fallback: TFallback | undefined, converter: EnvaptConverter<TFallback> | undefined, hasFallback: boolean): TFallback | null | undefined;
402
- private processFallbackForConverter;
403
- private convertPrimitiveToString;
404
- private processBuiltInConverter;
405
- private processArrayConverter;
406
- private processCustomConverter;
407
- private resolveConverter;
408
- }
409
-
831
+ declare function EnvBool(key: EnvKeyInput, fallback?: boolean): PropertyDecorator;
410
832
  /**
411
- * Base class for environment variable management
412
- * Handles configuration, caching, and basic environment loading
413
- * @internal
833
+ * Shorthand for `@Envapt(key, { converter: Converters.Number, fallback })`.
834
+ * @public
414
835
  */
415
- declare abstract class EnvapterBase {
416
- protected static _envPaths: string[];
417
- protected static _userDefinedDotenvConfig: PermittedDotenvConfig;
418
- /**
419
- * Set custom .env file paths. Accepts either a single path or array of paths.
420
- * Setting new paths clears the cache and reloads environment variables.
421
- */
422
- static set envPaths(paths: string[] | string);
423
- /**
424
- * Get currently configured .env file paths
425
- */
426
- static get envPaths(): string[];
427
- /**
428
- * Set custom dotenv configuration options.
429
- */
430
- static set dotenvConfig(config: PermittedDotenvConfig);
431
- /**
432
- * Get current dotenv configuration options
433
- */
434
- static get dotenvConfig(): PermittedDotenvConfig;
435
- protected static refreshCache(): void;
436
- protected static resolveKeyInput(keyInput: EnvKeyInput): {
437
- key: string;
438
- value: string | undefined;
439
- };
440
- protected static get config(): Map<string, unknown>;
441
- /**
442
- * Get raw environment variable value without parsing or conversion.
443
- */
444
- getRaw(key: EnvKeyInput): string | undefined;
445
- }
446
-
836
+ declare function EnvNum(key: EnvKeyInput, fallback?: number): PropertyDecorator;
447
837
  /**
448
- * Environment types supported by Envapter
838
+ * Shorthand for `@Envapt(key, { converter: Converters.String, fallback })`.
449
839
  * @public
450
840
  */
451
- declare enum Environment {
452
- Development = 0,
453
- Staging = 1,
454
- Production = 2
455
- }
841
+ declare function EnvStr(key: EnvKeyInput, fallback?: string): PropertyDecorator;
456
842
  /**
457
- * Mixin for environment detection and checking methods
843
+ * Shorthand for `@Envapt(key, { converter: Converters.Time, fallback })`. The fallback is a
844
+ * millisecond number or a time string (`'15m'`); the resolved value is always milliseconds.
845
+ * @public
846
+ */
847
+ declare function EnvTime(key: EnvKeyInput, fallback?: TimeFallback): PropertyDecorator;
848
+ /**
849
+ * Shorthand for `@Envapt(key, { converter: Converters.Url, fallback })`. The fallback is a `URL`
850
+ * instance, not a URL string.
851
+ * @public
852
+ */
853
+ declare function EnvUrl(key: EnvKeyInput, fallback?: URL): PropertyDecorator;
854
+ //#endregion
855
+ //#region src/TemplateResolver.d.ts
856
+ /**
857
+ * Resolve `${VAR}` template references in environment values, guarding against circular
858
+ * references and missing variables.
458
859
  * @internal
459
860
  */
460
- declare class EnvironmentMethods extends EnvapterBase {
461
- protected static _environment: Environment | undefined;
462
- protected static determineEnvironment(env?: string | Environment): void;
463
- private static getRawValue;
464
- /**
465
- * Get the current application environment
466
- */
467
- static get environment(): Environment;
468
- /**
469
- * Set the application environment. Accepts either Environment enum or string value.
470
- */
471
- static set environment(env: string | Environment);
472
- /**
473
- * @see {@link EnvironmentMethods.environment}
474
- */
475
- get environment(): Environment;
476
- /**
477
- * @see {@link EnvironmentMethods.environment}
478
- */
479
- set environment(env: string | Environment);
480
- /**
481
- * Check if the current environment is production
482
- */
483
- static get isProduction(): boolean;
484
- /**
485
- * @see {@link EnvironmentMethods.isProduction}
486
- */
487
- get isProduction(): boolean;
488
- /**
489
- * Check if the current environment is staging
490
- */
491
- static get isStaging(): boolean;
492
- /**
493
- * @see {@link EnvironmentMethods.isStaging}
494
- */
495
- get isStaging(): boolean;
496
- /**
497
- * Check if the current environment is development
498
- */
499
- static get isDevelopment(): boolean;
500
- /**
501
- * @see {@link EnvironmentMethods.isDevelopment}
502
- */
503
- get isDevelopment(): boolean;
504
- protected static refreshCache(): void;
861
+ declare class TemplateResolver {
862
+ private readonly envService;
863
+ private readonly TEMPLATE_REGEX;
864
+ constructor(envService: EnvapterService);
865
+ resolveTemplate(key: string, value: string, stack?: Set<string>): string;
505
866
  }
506
-
867
+ //#endregion
868
+ //#region src/core/PrimitiveMethods.d.ts
507
869
  /**
508
- * Mixin for primitive environment variable getter methods
509
870
  * @internal
510
871
  */
511
872
  declare class PrimitiveMethods extends EnvironmentMethods implements EnvapterService {
512
- protected static readonly parser: Parser;
513
- private static _get;
514
- /**
515
- * Get a string environment variable with optional fallback.
516
- * Supports template variable resolution using `${VAR}` syntax.
517
- * Accepts a single key or an ordered array of keys (first match wins).
518
- */
519
- static get<Default extends string | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<string, Default>;
520
- /**
521
- * @see {@link PrimitiveMethods.get}
522
- */
523
- get(key: EnvKeyInput, def?: string): string | undefined;
524
- /**
525
- * Get a number environment variable with optional fallback.
526
- * Automatically converts string values to numbers.
527
- * Accepts a single key or an ordered array of keys (first match wins).
528
- */
529
- static getNumber<Default extends number | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<number, Default>;
530
- /**
531
- * @see {@link PrimitiveMethods.getNumber}
532
- */
533
- getNumber<Default extends number | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<number, Default>;
534
- /**
535
- * Get a boolean environment variable with optional fallback.
536
- * Recognizes: `1`, `yes`, `true`, 'on' as **true**; `0`, `no`, `false`, 'off' as **false** (case-insensitive).
537
- * Accepts a single key or an ordered array of keys (first match wins).
538
- */
539
- static getBoolean<Default extends boolean | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<boolean, Default>;
540
- /**
541
- * @see {@link PrimitiveMethods.getBoolean}
542
- */
543
- getBoolean<Default extends boolean | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<boolean, Default>;
544
- /**
545
- * Get a bigint environment variable with optional fallback.
546
- * Automatically converts string values to bigint.
547
- * Accepts a single key or an ordered array of keys (first match wins).
548
- */
549
- static getBigInt<Default extends bigint | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<bigint, Default>;
550
- /**
551
- * @see {@link PrimitiveMethods.getBigInt}
552
- */
553
- getBigInt<Default extends bigint | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<bigint, Default>;
554
- /**
555
- * Get a symbol environment variable with optional fallback.
556
- * Creates a symbol from the string value.
557
- * Accepts a single key or an ordered array of keys (first match wins).
558
- */
559
- static getSymbol<Default extends symbol | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<symbol, Default>;
560
- /**
561
- * @see {@link PrimitiveMethods.getSymbol}
562
- */
563
- getSymbol<Default extends symbol | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<symbol, Default>;
873
+ private static readonly service;
874
+ protected static readonly templateResolver: TemplateResolver;
875
+ protected static readonly valueConverter: ValueConverter;
876
+ isStrict(): boolean;
877
+ private static _get;
878
+ /**
879
+ * Get a string environment variable with optional fallback.
880
+ * Supports template variable resolution using `${VAR}` syntax.
881
+ * Accepts a single key or an ordered array of keys (first match wins).
882
+ */
883
+ static get<Default extends string | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<string, Default>;
884
+ /**
885
+ * @see {@link PrimitiveMethods.get}
886
+ */
887
+ get<Default extends string | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<string, Default>;
888
+ /**
889
+ * Get a number environment variable with optional fallback.
890
+ * Automatically converts string values to numbers.
891
+ * Accepts a single key or an ordered array of keys (first match wins).
892
+ */
893
+ static getNumber<Default extends number | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<number, Default>;
894
+ /**
895
+ * @see {@link PrimitiveMethods.getNumber}
896
+ */
897
+ getNumber<Default extends number | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<number, Default>;
898
+ /**
899
+ * Get a boolean environment variable with optional fallback.
900
+ * Recognizes: `1`, `yes`, `true`, `on` as **true**; `0`, `no`, `false`, `off` as **false** (case-insensitive).
901
+ * Accepts a single key or an ordered array of keys (first match wins).
902
+ */
903
+ static getBoolean<Default extends boolean | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<boolean, Default>;
904
+ /**
905
+ * @see {@link PrimitiveMethods.getBoolean}
906
+ */
907
+ getBoolean<Default extends boolean | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<boolean, Default>;
908
+ /**
909
+ * Get a bigint environment variable with optional fallback.
910
+ * Automatically converts string values to bigint.
911
+ * Accepts a single key or an ordered array of keys (first match wins).
912
+ */
913
+ static getBigInt<Default extends bigint | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<bigint, Default>;
914
+ /**
915
+ * @see {@link PrimitiveMethods.getBigInt}
916
+ */
917
+ getBigInt<Default extends bigint | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<bigint, Default>;
918
+ /**
919
+ * Get a symbol environment variable with optional fallback.
920
+ * Creates a symbol from the string value.
921
+ * Accepts a single key or an ordered array of keys (first match wins).
922
+ */
923
+ static getSymbol<Default extends symbol | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<symbol, Default>;
924
+ /**
925
+ * @see {@link PrimitiveMethods.getSymbol}
926
+ */
927
+ getSymbol<Default extends symbol | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<symbol, Default>;
928
+ }
929
+ //#endregion
930
+ //#region src/core/AdvancedMethods.d.ts
931
+ interface GetUsingRequiredOptions<TConverter> {
932
+ converter: TConverter;
933
+ required: true;
934
+ }
935
+ interface GetWithRequiredOptions<TReturnType> {
936
+ converter: ConverterFunction<TReturnType>;
937
+ required: true;
564
938
  }
565
-
566
939
  /**
567
940
  * Mixin for advanced methods for environment variable conversion using built-in and custom converters
568
941
  * @internal
569
942
  */
570
943
  declare class AdvancedMethods extends PrimitiveMethods {
571
- /**
572
- * Get an environment variable using a built-in converter.
573
- * Supports both Converter enum values and array converter configurations.
574
- * The key can be a single name or an ordered list; the first defined value wins.
575
- */
576
- static getUsing<TConverter extends BuiltInConverter | ArrayConverter, TFallback = undefined>(key: EnvKeyInput, converter: TConverter, fallback?: TFallback): AdvancedConverterReturn<TConverter, TFallback>;
577
- static getUsing<TReturn>(key: EnvKeyInput, converter: BuiltInConverter | ArrayConverter, fallback?: TReturn): TReturn;
578
- /**
579
- * @see {@link AdvancedMethods.getUsing}
580
- */
581
- getUsing<TConverter extends BuiltInConverter | ArrayConverter, TFallback = undefined>(key: EnvKeyInput, converter: TConverter, fallback?: TFallback): AdvancedConverterReturn<TConverter, TFallback>;
582
- getUsing<TReturn>(key: EnvKeyInput, converter: BuiltInConverter | ArrayConverter, fallback?: TReturn): TReturn;
583
- /**
584
- * Get an environment variable using a custom converter function.
585
- * Accepts a single key or an ordered list for automatic fallback.
586
- */
587
- static getWith<TReturnType, TFallback extends TReturnType | undefined = undefined>(key: EnvKeyInput, converter: ConverterFunction<TReturnType>, fallback?: TFallback): ConditionalReturn<TReturnType, TFallback>;
588
- /**
589
- * @see {@link AdvancedMethods.getWith}
590
- */
591
- getWith<TReturnType, TFallback extends TReturnType | undefined = undefined>(key: EnvKeyInput, converter: ConverterFunction<TReturnType>, fallback?: TFallback): ConditionalReturn<TReturnType, TFallback>;
944
+ /**
945
+ * Get an environment variable using a built-in converter.
946
+ *
947
+ * Supports both scalar tokens (e.g. `Converters.Number`) and `ArrayOf<...>` tokens
948
+ * produced by `Converters.array(...)`. The key can be a single name or an ordered list;
949
+ * the first defined value wins.
950
+ */
951
+ static getUsing<TFallback extends TimeFallback | undefined = undefined>(key: EnvKeyInput, converter: 'time', fallback?: TFallback): ConditionalReturn<number, TFallback>;
952
+ static getUsing<TConverter extends BuiltInConverter | ArrayOf, TFallback = undefined>(key: EnvKeyInput, converter: TConverter, fallback?: TFallback): AdvancedConverterReturn<TConverter, TFallback>;
953
+ static getUsing<TReturn>(key: EnvKeyInput, converter: BuiltInConverter | ArrayOf, fallback?: TReturn): TReturn;
954
+ static getUsing(key: EnvKeyInput, options: GetUsingRequiredOptions<'time'>): number;
955
+ static getUsing<TConverter extends BuiltInConverter | ArrayOf>(key: EnvKeyInput, options: GetUsingRequiredOptions<TConverter>): InferConverterReturnType<TConverter>;
956
+ /**
957
+ * @see {@link AdvancedMethods.getUsing}
958
+ */
959
+ getUsing<TFallback extends TimeFallback | undefined = undefined>(key: EnvKeyInput, converter: 'time', fallback?: TFallback): ConditionalReturn<number, TFallback>;
960
+ getUsing<TConverter extends BuiltInConverter | ArrayOf, TFallback = undefined>(key: EnvKeyInput, converter: TConverter, fallback?: TFallback): AdvancedConverterReturn<TConverter, TFallback>;
961
+ getUsing<TReturn>(key: EnvKeyInput, converter: BuiltInConverter | ArrayOf, fallback?: TReturn): TReturn;
962
+ getUsing(key: EnvKeyInput, options: GetUsingRequiredOptions<'time'>): number;
963
+ getUsing<TConverter extends BuiltInConverter | ArrayOf>(key: EnvKeyInput, options: GetUsingRequiredOptions<TConverter>): InferConverterReturnType<TConverter>;
964
+ /**
965
+ * Get an environment variable using a custom converter function.
966
+ * Accepts a single key or an ordered list for automatic fallback.
967
+ */
968
+ static getWith<TReturnType, TFallback extends TReturnType | undefined = undefined>(key: EnvKeyInput, converter: ConverterFunction<TReturnType>, fallback?: TFallback): ConditionalReturn<TReturnType, TFallback>;
969
+ static getWith<TReturnType>(key: EnvKeyInput, options: GetWithRequiredOptions<TReturnType>): TReturnType;
970
+ /**
971
+ * @see {@link AdvancedMethods.getWith}
972
+ */
973
+ getWith<TReturnType, TFallback extends TReturnType | undefined = undefined>(key: EnvKeyInput, converter: ConverterFunction<TReturnType>, fallback?: TFallback): ConditionalReturn<TReturnType, TFallback>;
974
+ getWith<TReturnType>(key: EnvKeyInput, options: GetWithRequiredOptions<TReturnType>): TReturnType;
975
+ /**
976
+ * Validate an environment variable through a {@link StandardSchemaV1}-conformant schema
977
+ * (zod, valibot, arktype, etc). Throws `MissingEnvValue` if the env value is absent and
978
+ * no fallback is provided. The fallback, when provided, is returned as-is on missing;
979
+ * it does NOT pass through the schema (mirrors custom-converter behavior).
980
+ *
981
+ * Synchronous schemas only. A Promise-returning `validate` triggers an
982
+ * `InvalidUserDefinedConfig` throw at the call site.
983
+ *
984
+ * @example
985
+ * ```ts
986
+ * import { z } from 'zod';
987
+ * const port = Envapter.parse('PORT', z.coerce.number().min(1024).max(65535), 3000);
988
+ * ```
989
+ */
990
+ static parse<Schema extends StandardSchemaV1>(key: EnvKeyInput, schema: SchemaConstraint<Schema>, fallback?: InferSchemaOutput<Schema>): InferSchemaOutput<Schema>;
991
+ /**
992
+ * @see {@link AdvancedMethods.parse}
993
+ */
994
+ parse<Schema extends StandardSchemaV1>(key: EnvKeyInput, schema: SchemaConstraint<Schema>, fallback?: InferSchemaOutput<Schema>): InferSchemaOutput<Schema>;
592
995
  }
593
-
996
+ //#endregion
997
+ //#region src/Envapter.d.ts
594
998
  /**
595
999
  * Main configuration class for environment variable management.
596
1000
  *
597
1001
  * Provides both static and instance methods for retrieving typed environment variables
598
1002
  * with support for template resolution, multiple .env files, and environment detection.
599
1003
  *
600
- * Extend your own classes from this to define properties with \@Envapt decorators and provide access to environment variables methods.
1004
+ * Extend your own classes from this to define properties with \@Envapt decorators and get access to environment-variable methods.
601
1005
  *
602
1006
  * @example
603
1007
  * ```ts
@@ -615,67 +1019,109 @@ declare class AdvancedMethods extends PrimitiveMethods {
615
1019
  * @public
616
1020
  */
617
1021
  declare class Envapter extends AdvancedMethods {
618
- /**
619
- * Tagged template literal for resolving environment variables in template strings.
620
- *
621
- * @example
622
- * ```ts
623
- * // Given API_HOST=api.example.com and API_PORT=8080 in environment
624
- * const endpoint = Envapter.resolve`Connecting to ${'API_HOST'}:${'API_PORT'}`;
625
- * // Returns: "Connecting to api.example.com:8080"
626
- *
627
- * // Works with template variables in .env too:
628
- * // API_URL=https://${API_HOST}:${API_PORT}
629
- * const message = Envapter.resolve`Service endpoint: ${'API_URL'}`;
630
- * // Returns: "Service endpoint: https://api.example.com:8080"
631
- * ```
632
- */
633
- static resolve(strings: TemplateStringsArray, ...keys: string[]): string;
634
- /**
635
- * @see {@link Envapter.resolve}
636
- */
637
- resolve(strings: TemplateStringsArray, ...keys: string[]): string;
1022
+ /**
1023
+ * Tagged template literal for resolving environment variables in template strings.
1024
+ *
1025
+ * @example
1026
+ * ```ts
1027
+ * // Given API_HOST=api.example.com and API_PORT=8080 in environment
1028
+ * const endpoint = Envapter.resolve`Connecting to ${'API_HOST'}:${'API_PORT'}`;
1029
+ * // Returns: "Connecting to api.example.com:8080"
1030
+ *
1031
+ * // Works with template variables in .env too:
1032
+ * // API_URL=https://${API_HOST}:${API_PORT}
1033
+ * const message = Envapter.resolve`Service endpoint: ${'API_URL'}`;
1034
+ * // Returns: "Service endpoint: https://api.example.com:8080"
1035
+ * ```
1036
+ */
1037
+ static resolve(strings: TemplateStringsArray, ...keys: string[]): string;
1038
+ /**
1039
+ * @see {@link Envapter.resolve}
1040
+ */
1041
+ resolve(strings: TemplateStringsArray, ...keys: string[]): string;
1042
+ /**
1043
+ * Assert that one or more environment variables are present and non-empty (post-trim,
1044
+ * after template resolution). Throws `MissingEnvValue` listing every missing key.
1045
+ *
1046
+ * For typed fail-fast in functional code, use `Envapter.getUsing(key, { converter, required: true })`.
1047
+ *
1048
+ * @example
1049
+ * ```ts
1050
+ * Envapter.require('DATABASE_URL');
1051
+ * Envapter.require('DATABASE_URL', 'API_KEY', 'SENTRY_DSN');
1052
+ * ```
1053
+ */
1054
+ static require(...keys: [string, ...string[]]): void;
1055
+ private static resolveAndValidate;
1056
+ /**
1057
+ * @see {@link Envapter.require}
1058
+ */
1059
+ require(...keys: [string, ...string[]]): void;
638
1060
  }
639
-
1061
+ //#endregion
1062
+ //#region src/Error.d.ts
640
1063
  declare enum EnvaptErrorCodes {
641
- /** Thrown when an invalid fallback value is provided */
642
- InvalidFallback = 101,
643
- /** Thrown when fallback value type doesn't match expected converter type */
644
- InvalidFallbackType = 102,
645
- /** Thrown when array fallback contains elements of wrong type */
646
- ArrayFallbackElementTypeMismatch = 103,
647
- /** Thrown when fallback type doesn't match the specified converter */
648
- FallbackConverterTypeMismatch = 104,
649
- /** Thrown when invalid array converter configuration is provided */
650
- InvalidArrayConverterType = 201,
651
- /** Thrown when an invalid built-in converter is specified */
652
- InvalidBuiltInConverter = 202,
653
- /** Thrown when a custom converter is not a function */
654
- InvalidCustomConverter = 203,
655
- /** Thrown when converter type is not recognized */
656
- InvalidConverterType = 204,
657
- /** Thrown when primitive type coercion on fallback value fails */
658
- PrimitiveCoercionFailed = 205,
659
- /** Thrown when delimiter is missing in array converter configuration */
660
- MissingDelimiter = 301,
661
- /** Thrown when invalid user-defined configuration is provided */
662
- InvalidUserDefinedConfig = 302,
663
- /** Thrown when specified environment files don't exist */
664
- EnvFilesNotFound = 303,
665
- /** Thrown when no valid environment key is provided */
666
- InvalidKeyInput = 304
1064
+ /** Thrown when an invalid fallback value is provided */
1065
+ InvalidFallback = 101,
1066
+ /** Thrown when fallback value type doesn't match expected converter type */
1067
+ InvalidFallbackType = 102,
1068
+ /** Thrown when array fallback contains elements of wrong type */
1069
+ ArrayFallbackElementTypeMismatch = 103,
1070
+ /** Thrown when fallback type doesn't match the specified converter */
1071
+ FallbackConverterTypeMismatch = 104,
1072
+ /** Thrown when a time-string fallback is malformed (does not match the required `<integer><unit>` format) */
1073
+ MalformedTimeFallback = 105,
1074
+ /** Thrown when invalid array converter configuration is provided */
1075
+ InvalidArrayConverterType = 201,
1076
+ /** Thrown when an invalid built-in converter is specified */
1077
+ InvalidBuiltInConverter = 202,
1078
+ /** Thrown when a custom converter is not a function */
1079
+ InvalidCustomConverter = 203,
1080
+ /** Thrown when converter type is not recognized */
1081
+ InvalidConverterType = 204,
1082
+ /** Thrown when primitive type coercion on fallback value fails */
1083
+ PrimitiveCoercionFailed = 205,
1084
+ /** Thrown when an array element fails to convert to the configured element type */
1085
+ ArrayElementConversionFailed = 206,
1086
+ /** Thrown under strict mode when an array element is empty or whitespace only */
1087
+ EmptyArrayElement = 207,
1088
+ /** Thrown when a Standard Schema returns issues for a non-empty env value */
1089
+ SchemaValidationFailed = 208,
1090
+ /** Thrown when a Standard Schema's `validate` itself throws (e.g. a refinement that crashes) */
1091
+ SchemaThrew = 209,
1092
+ /** Thrown when delimiter is missing in array converter configuration */
1093
+ MissingDelimiter = 301,
1094
+ /** Thrown when invalid user-defined configuration is provided */
1095
+ InvalidUserDefinedConfig = 302,
1096
+ /** Thrown when specified environment files don't exist */
1097
+ EnvFilesNotFound = 303,
1098
+ /** Thrown when no valid environment key is provided */
1099
+ InvalidKeyInput = 304,
1100
+ /** Thrown when a required environment value is missing or empty (post-trim) */
1101
+ MissingEnvValue = 305
1102
+ }
1103
+ interface EnvaptErrorOptions {
1104
+ issues?: readonly StandardSchemaV1.Issue[];
1105
+ cause?: unknown;
667
1106
  }
668
1107
  /**
669
1108
  * Custom error for better DX and debugging when using Envapt.
670
1109
  *
671
1110
  * @example
672
1111
  * ```ts
673
- * throw new EnvaptError(EnvaptErrorCode.InvalidFallback, "Invalid fallback value provided for environment variable.");
1112
+ * throw new EnvaptError(EnvaptErrorCodes.InvalidFallback, "Invalid fallback value provided for environment variable.");
674
1113
  * ```
675
1114
  */
676
1115
  declare class EnvaptError extends Error {
677
- readonly code: EnvaptErrorCodes;
678
- constructor(code: EnvaptErrorCodes, message: string);
1116
+ readonly code: EnvaptErrorCodes;
1117
+ /**
1118
+ * Populated only for {@link EnvaptErrorCodes.SchemaValidationFailed} (208). For every other
1119
+ * code this is `undefined`. Lets callers do `if (err.code === 208) err.issues?.forEach(...)`
1120
+ * without a type cast.
1121
+ */
1122
+ readonly issues: readonly StandardSchemaV1.Issue[] | undefined;
1123
+ constructor(code: EnvaptErrorCodes, message: string, options?: EnvaptErrorOptions);
679
1124
  }
680
-
681
- export { type AdvancedConverterReturn, type ArrayConverter, type BuiltInConverter, type BuiltInConverterFunction, type ConditionalReturn, type ConverterFunction, Converters, type EnvKeyInput, Envapt, type EnvaptConverter, EnvaptError, EnvaptErrorCodes, type EnvaptOptions, Envapter, Environment, type InferConverterReturnType, type InferPrimitiveFallbackType, type InferPrimitiveReturnType, type JsonValue, type MapOfConverterFunctions, type PermittedDotenvConfig, type PrimitiveConstructor, type TimeUnit, type ValidArrayConverterBuiltInType };
1125
+ //#endregion
1126
+ export { type AdvancedConverterReturn, type ArrayElement, type ArrayOf, type BuiltInConverter, type BuiltInConverterFunction, type ConditionalReturn, type ConverterFunction, type ConverterToken, Converters, type CustomElementConverter, type DebugLevel, EnvBool, type EnvFileOptions, type EnvKeyInput, EnvNum, type EnvProfile, EnvStr, EnvTime, EnvUrl, Envapt, type EnvaptConverter, EnvaptError, EnvaptErrorCodes, type EnvaptOptions, Envapter, Environment, type Err, type InferConverterFallbackType, type InferConverterReturnType, type InferPrimitiveFallbackType, type InferPrimitiveReturnType, type InferSchemaInput, type InferSchemaOutput, type JsonValue, type MapOfConverterFunctions, type PrimitiveConstructor, type ProfilesConfig, type SchemaConstraint, type SchemaMustBeSync, type StandardSchemaV1, type TimeFallback, type TimeUnit, isArrayOf };
1127
+ //# sourceMappingURL=index.d.cts.map