@epsilon-asi/foundation 0.0.11 → 0.0.13
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/build/decorators/environment/defaultSystem.d.ts +6 -0
- package/build/decorators/environment/defaultSystem.js +12 -0
- package/build/decorators/environment/dotenv.d.ts +48 -0
- package/build/decorators/environment/dotenv.js +77 -0
- package/build/decorators/environment/errors.d.ts +12 -0
- package/build/decorators/environment/errors.js +13 -0
- package/build/decorators/environment/index.d.ts +7 -164
- package/build/decorators/environment/index.js +19 -221
- package/build/decorators/environment/parse.d.ts +9 -0
- package/build/decorators/environment/parse.js +88 -0
- package/build/decorators/environment/system.d.ts +4 -0
- package/build/decorators/environment/system.js +133 -0
- package/build/decorators/environment/types.d.ts +160 -0
- package/build/decorators/environment/types.js +2 -0
- package/build/files/index.d.ts +4 -2
- package/build/files/index.js +13 -1
- package/build/files/layered.d.ts +45 -0
- package/build/files/layered.js +139 -0
- package/build/files/load.js +5 -26
- package/build/files/types.d.ts +31 -0
- package/build/files/util.d.ts +15 -1
- package/build/files/util.js +78 -1
- package/package.json +6 -5
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const envRegistry: import("../factory").DecoratorRegistry<import("./types").EnvDecoratorSchema>;
|
|
2
|
+
export declare const Env: import("./types").EnvConfigDecorator;
|
|
3
|
+
export declare const EnvConfig: import("./types").EnvConfigDecorator;
|
|
4
|
+
export declare const EnvVar: import("./types").EnvVarDecoratorApi;
|
|
5
|
+
export declare const loadEnv: <TClass extends import("../factory").Constructor>(target: TClass, options?: import("./types").LoadEnvOptions) => import("./types").EnvLoadResult<TClass>;
|
|
6
|
+
export declare const describeEnv: <TClass extends import("../factory").Constructor>(target: TClass, options?: import("./types").DescribeEnvOptions) => readonly import("./types").EnvVariableDefinition[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.describeEnv = exports.loadEnv = exports.EnvVar = exports.EnvConfig = exports.Env = exports.envRegistry = void 0;
|
|
4
|
+
const system_1 = require("./system");
|
|
5
|
+
/** The shared env system behind the top-level Env, EnvVar and loadEnv exports. */
|
|
6
|
+
const defaultEnvSystem = (0, system_1.createEnvSystem)();
|
|
7
|
+
exports.envRegistry = defaultEnvSystem.registry;
|
|
8
|
+
exports.Env = defaultEnvSystem.Env;
|
|
9
|
+
exports.EnvConfig = defaultEnvSystem.EnvConfig;
|
|
10
|
+
exports.EnvVar = defaultEnvSystem.EnvVar;
|
|
11
|
+
exports.loadEnv = defaultEnvSystem.loadEnv;
|
|
12
|
+
exports.describeEnv = defaultEnvSystem.describeEnv;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export declare const DEFAULT_DOTENV_PATH = ".env";
|
|
2
|
+
export interface DotenvOptions {
|
|
3
|
+
/**
|
|
4
|
+
* File or files to read, resolved against `cwd`. When several are listed, later files
|
|
5
|
+
* take precedence over earlier ones, e.g. ['.env', '.env.local'].
|
|
6
|
+
*
|
|
7
|
+
* Defaults to '.env'.
|
|
8
|
+
*/
|
|
9
|
+
path?: string | readonly string[];
|
|
10
|
+
/** Directory that relative paths resolve from. Defaults to process.cwd() at load time. */
|
|
11
|
+
cwd?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Whether dotenv values take precedence over the env source (process.env by default).
|
|
14
|
+
*
|
|
15
|
+
* Defaults to true.
|
|
16
|
+
*/
|
|
17
|
+
override?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Whether a listed file that does not exist is an error.
|
|
20
|
+
*
|
|
21
|
+
* Defaults to false, so a missing file is skipped.
|
|
22
|
+
*/
|
|
23
|
+
required?: boolean;
|
|
24
|
+
/** Defaults to 'utf8'. */
|
|
25
|
+
encoding?: BufferEncoding;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* How dotenv files feed loadEnv():
|
|
29
|
+
* - `undefined` or `true`: read the default '.env' file.
|
|
30
|
+
* - `false`: do not read any dotenv file.
|
|
31
|
+
* - a path or list of paths: read those files.
|
|
32
|
+
* - an options object: full control.
|
|
33
|
+
*/
|
|
34
|
+
export type DotenvSetting = boolean | string | readonly string[] | DotenvOptions;
|
|
35
|
+
export interface DotenvReadResult {
|
|
36
|
+
/** Merged values from every file that was read. */
|
|
37
|
+
readonly values: Readonly<Record<string, string>>;
|
|
38
|
+
/** Absolute paths of the files that were read, in load order. */
|
|
39
|
+
readonly files: readonly string[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Combines the class-level @Env({ dotenv }) setting with the loadEnv({ dotenv }) option.
|
|
43
|
+
* Dotenv is on unless one of them is `false`; the call's options are merged over the class's.
|
|
44
|
+
* Returns undefined when dotenv is turned off.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveDotenvOptions(classSetting: DotenvSetting | undefined, callSetting: DotenvSetting | undefined): DotenvOptions | undefined;
|
|
47
|
+
/** Reads and merges dotenv files without touching process.env. */
|
|
48
|
+
export declare function readDotenvFiles(options?: DotenvOptions): DotenvReadResult;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_DOTENV_PATH = void 0;
|
|
7
|
+
exports.resolveDotenvOptions = resolveDotenvOptions;
|
|
8
|
+
exports.readDotenvFiles = readDotenvFiles;
|
|
9
|
+
const node_fs_1 = require("node:fs");
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const dotenv_1 = require("dotenv");
|
|
12
|
+
const errors_1 = require("./errors");
|
|
13
|
+
exports.DEFAULT_DOTENV_PATH = '.env';
|
|
14
|
+
/**
|
|
15
|
+
* Combines the class-level @Env({ dotenv }) setting with the loadEnv({ dotenv }) option.
|
|
16
|
+
* Dotenv is on unless one of them is `false`; the call's options are merged over the class's.
|
|
17
|
+
* Returns undefined when dotenv is turned off.
|
|
18
|
+
*/
|
|
19
|
+
function resolveDotenvOptions(classSetting, callSetting) {
|
|
20
|
+
const fromClass = normalizeDotenvSetting(classSetting);
|
|
21
|
+
if (callSetting === undefined)
|
|
22
|
+
return fromClass;
|
|
23
|
+
const fromCall = normalizeDotenvSetting(callSetting);
|
|
24
|
+
if (fromCall === undefined)
|
|
25
|
+
return undefined;
|
|
26
|
+
return Object.assign(Object.assign({}, fromClass), definedOnly(fromCall));
|
|
27
|
+
}
|
|
28
|
+
/** Reads and merges dotenv files without touching process.env. */
|
|
29
|
+
function readDotenvFiles(options = {}) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
const cwd = (_a = options.cwd) !== null && _a !== void 0 ? _a : process.cwd();
|
|
32
|
+
const paths = isPathList(options.path) ? options.path : [(_b = options.path) !== null && _b !== void 0 ? _b : exports.DEFAULT_DOTENV_PATH];
|
|
33
|
+
const values = Object.create(null);
|
|
34
|
+
const files = [];
|
|
35
|
+
for (const entry of paths) {
|
|
36
|
+
const filePath = node_path_1.default.resolve(cwd, entry);
|
|
37
|
+
const text = readDotenvFile(filePath, options);
|
|
38
|
+
if (text === undefined)
|
|
39
|
+
continue;
|
|
40
|
+
Object.assign(values, (0, dotenv_1.parse)(text));
|
|
41
|
+
files.push(filePath);
|
|
42
|
+
}
|
|
43
|
+
return Object.freeze({
|
|
44
|
+
values: Object.freeze(values),
|
|
45
|
+
files: Object.freeze(files),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function readDotenvFile(filePath, options) {
|
|
49
|
+
var _a;
|
|
50
|
+
try {
|
|
51
|
+
return (0, node_fs_1.readFileSync)(filePath, { encoding: (_a = options.encoding) !== null && _a !== void 0 ? _a : 'utf8' });
|
|
52
|
+
}
|
|
53
|
+
catch (cause) {
|
|
54
|
+
if ((cause === null || cause === void 0 ? void 0 : cause.code) === 'ENOENT') {
|
|
55
|
+
if (options.required !== true)
|
|
56
|
+
return undefined;
|
|
57
|
+
throw new errors_1.EnvParseError(`Required dotenv file "${filePath}" does not exist.`, { filePath, cause });
|
|
58
|
+
}
|
|
59
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
60
|
+
throw new errors_1.EnvParseError(`Failed to read dotenv file "${filePath}": ${reason}`, { filePath, cause });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function normalizeDotenvSetting(setting) {
|
|
64
|
+
if (setting === false)
|
|
65
|
+
return undefined;
|
|
66
|
+
if (setting === undefined || setting === true)
|
|
67
|
+
return {};
|
|
68
|
+
if (typeof setting === 'string' || isPathList(setting))
|
|
69
|
+
return { path: setting };
|
|
70
|
+
return setting;
|
|
71
|
+
}
|
|
72
|
+
function isPathList(value) {
|
|
73
|
+
return Array.isArray(value);
|
|
74
|
+
}
|
|
75
|
+
function definedOnly(options) {
|
|
76
|
+
return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined));
|
|
77
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class EnvParseError extends Error {
|
|
2
|
+
readonly envName?: string;
|
|
3
|
+
readonly propertyName?: string;
|
|
4
|
+
/** The dotenv file involved, for errors raised while reading one. */
|
|
5
|
+
readonly filePath?: string;
|
|
6
|
+
constructor(message: string, details?: {
|
|
7
|
+
envName?: string;
|
|
8
|
+
propertyName?: string;
|
|
9
|
+
filePath?: string;
|
|
10
|
+
cause?: unknown;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EnvParseError = void 0;
|
|
4
|
+
class EnvParseError extends Error {
|
|
5
|
+
constructor(message, details = {}) {
|
|
6
|
+
super(message, details.cause === undefined ? undefined : { cause: details.cause });
|
|
7
|
+
this.name = 'EnvParseError';
|
|
8
|
+
this.envName = details.envName;
|
|
9
|
+
this.propertyName = details.propertyName;
|
|
10
|
+
this.filePath = details.filePath;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.EnvParseError = EnvParseError;
|
|
@@ -1,164 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export type
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
/**
|
|
9
|
-
* Optional prefix applied to every variable lookup.
|
|
10
|
-
*
|
|
11
|
-
* Example:
|
|
12
|
-
* prefix: 'APP_'
|
|
13
|
-
* @EnvVar.string('PORT')
|
|
14
|
-
* final lookup key: APP_PORT
|
|
15
|
-
*/
|
|
16
|
-
prefix?: string;
|
|
17
|
-
/** Optional human-readable description for docs/debug output. */
|
|
18
|
-
description?: string;
|
|
19
|
-
}
|
|
20
|
-
export type StringEnvVarMetadata = {
|
|
21
|
-
type: 'string';
|
|
22
|
-
name?: string;
|
|
23
|
-
required?: boolean;
|
|
24
|
-
default?: string;
|
|
25
|
-
description?: string;
|
|
26
|
-
};
|
|
27
|
-
export type NumberEnvVarMetadata = {
|
|
28
|
-
type: 'number';
|
|
29
|
-
name?: string;
|
|
30
|
-
required?: boolean;
|
|
31
|
-
default?: number;
|
|
32
|
-
min?: number;
|
|
33
|
-
max?: number;
|
|
34
|
-
integer?: boolean;
|
|
35
|
-
description?: string;
|
|
36
|
-
};
|
|
37
|
-
export type BooleanEnvVarMetadata = {
|
|
38
|
-
type: 'boolean';
|
|
39
|
-
name?: string;
|
|
40
|
-
required?: boolean;
|
|
41
|
-
default?: boolean;
|
|
42
|
-
description?: string;
|
|
43
|
-
};
|
|
44
|
-
export type EnvVarMetadata = StringEnvVarMetadata | NumberEnvVarMetadata | BooleanEnvVarMetadata;
|
|
45
|
-
export type EnvDecoratorSchema = {
|
|
46
|
-
class: {
|
|
47
|
-
envConfig: ClassDecoratorDefinition<EnvConfigMetadata | undefined>;
|
|
48
|
-
};
|
|
49
|
-
property: {
|
|
50
|
-
envVar: PropertyDecoratorDefinition<EnvVarMetadata, EnvPrimitiveOrUndefined>;
|
|
51
|
-
};
|
|
52
|
-
method: {};
|
|
53
|
-
accessor: {};
|
|
54
|
-
};
|
|
55
|
-
export type EnvSource = Record<string, string | undefined>;
|
|
56
|
-
export interface LoadEnvOptions {
|
|
57
|
-
/**
|
|
58
|
-
* Defaults to globalThis.process.env when available.
|
|
59
|
-
* Pass this in tests to avoid mutating or depending on the real process env.
|
|
60
|
-
*/
|
|
61
|
-
source?: EnvSource;
|
|
62
|
-
/**
|
|
63
|
-
* Whether @EnvVar fields must be static.
|
|
64
|
-
*
|
|
65
|
-
* Defaults to true because loadEnv mutates the class constructor in place.
|
|
66
|
-
*/
|
|
67
|
-
requireStatic?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Whether empty strings and whitespace-only strings should be treated as missing.
|
|
70
|
-
*
|
|
71
|
-
* Defaults to true.
|
|
72
|
-
*/
|
|
73
|
-
emptyStringAsMissing?: boolean;
|
|
74
|
-
/**
|
|
75
|
-
* Whether inherited metadata should be loaded.
|
|
76
|
-
*
|
|
77
|
-
* Defaults to true.
|
|
78
|
-
*/
|
|
79
|
-
includeInherited?: boolean;
|
|
80
|
-
}
|
|
81
|
-
export interface DescribeEnvOptions {
|
|
82
|
-
/** Defaults to true. */
|
|
83
|
-
includeInherited?: boolean;
|
|
84
|
-
}
|
|
85
|
-
export interface EnvVariableDefinition {
|
|
86
|
-
readonly propertyName: string;
|
|
87
|
-
readonly envName: string;
|
|
88
|
-
readonly static: boolean;
|
|
89
|
-
readonly private: boolean;
|
|
90
|
-
readonly metadata: EnvVarMetadata;
|
|
91
|
-
}
|
|
92
|
-
export interface EnvLoadResult<TClass extends Constructor> {
|
|
93
|
-
readonly target: TClass;
|
|
94
|
-
readonly definitions: readonly EnvVariableDefinition[];
|
|
95
|
-
readonly values: Readonly<Record<string, EnvPrimitiveOrUndefined>>;
|
|
96
|
-
readonly snapshot: RegistryMetadataSnapshot;
|
|
97
|
-
}
|
|
98
|
-
export declare class EnvParseError extends Error {
|
|
99
|
-
readonly envName?: string;
|
|
100
|
-
readonly propertyName?: string;
|
|
101
|
-
constructor(message: string, details?: {
|
|
102
|
-
envName?: string;
|
|
103
|
-
propertyName?: string;
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
export interface EnvConfigDecorator {
|
|
107
|
-
(metadata?: EnvConfigMetadata): <TClass extends Constructor>(value: TClass, context: ClassDecoratorContext<TClass>) => void;
|
|
108
|
-
}
|
|
109
|
-
export interface EnvVarDecoratorApi {
|
|
110
|
-
/**
|
|
111
|
-
* Generic form:
|
|
112
|
-
*
|
|
113
|
-
* @EnvVar({ name: 'PORT', type: 'number' })
|
|
114
|
-
* static port: number;
|
|
115
|
-
*/
|
|
116
|
-
(metadata: StringEnvVarMetadata): (value: undefined, context: ClassFieldDecoratorContext<any, string | undefined>) => void;
|
|
117
|
-
(metadata: NumberEnvVarMetadata): (value: undefined, context: ClassFieldDecoratorContext<any, number | undefined>) => void;
|
|
118
|
-
(metadata: BooleanEnvVarMetadata): (value: undefined, context: ClassFieldDecoratorContext<any, boolean | undefined>) => void;
|
|
119
|
-
/**
|
|
120
|
-
* @EnvVar.string('API_KEY')
|
|
121
|
-
* static apiKey: string;
|
|
122
|
-
*/
|
|
123
|
-
string(name?: string, options?: Omit<StringEnvVarMetadata, 'type' | 'name'>): (value: undefined, context: ClassFieldDecoratorContext<any, string | undefined>) => void;
|
|
124
|
-
/**
|
|
125
|
-
* @EnvVar.number('PORT', { default: 3000, integer: true })
|
|
126
|
-
* static port: number;
|
|
127
|
-
*/
|
|
128
|
-
number(name?: string, options?: Omit<NumberEnvVarMetadata, 'type' | 'name'>): (value: undefined, context: ClassFieldDecoratorContext<any, number | undefined>) => void;
|
|
129
|
-
/**
|
|
130
|
-
* @EnvVar.boolean('DEBUG', { default: false })
|
|
131
|
-
* static debug: boolean;
|
|
132
|
-
*/
|
|
133
|
-
boolean(name?: string, options?: Omit<BooleanEnvVarMetadata, 'type' | 'name'>): (value: undefined, context: ClassFieldDecoratorContext<any, boolean | undefined>) => void;
|
|
134
|
-
}
|
|
135
|
-
export interface EnvSystem {
|
|
136
|
-
readonly registry: DecoratorRegistry<EnvDecoratorSchema>;
|
|
137
|
-
/** Preferred class decorator name. */
|
|
138
|
-
readonly Env: EnvConfigDecorator;
|
|
139
|
-
/** Alias for Env, for users who prefer a more explicit name. */
|
|
140
|
-
readonly EnvConfig: EnvConfigDecorator;
|
|
141
|
-
readonly EnvVar: EnvVarDecoratorApi;
|
|
142
|
-
/**
|
|
143
|
-
* Mutates the provided class in place by assigning parsed values to static fields.
|
|
144
|
-
*/
|
|
145
|
-
loadEnv<TClass extends Constructor>(target: TClass, options?: LoadEnvOptions): EnvLoadResult<TClass>;
|
|
146
|
-
/** Reads env metadata without mutating the class. */
|
|
147
|
-
describeEnv<TClass extends Constructor>(target: TClass, options?: DescribeEnvOptions): readonly EnvVariableDefinition[];
|
|
148
|
-
}
|
|
149
|
-
export declare function createEnvSystem(): EnvSystem;
|
|
150
|
-
export declare function getEnvConfigMetadata(snapshot: RegistryMetadataSnapshot): EnvConfigMetadata | undefined;
|
|
151
|
-
export declare function toEnvKey(propertyName: string): string;
|
|
152
|
-
export declare function parseEnvValue(args: {
|
|
153
|
-
envName: string;
|
|
154
|
-
propertyName: string;
|
|
155
|
-
rawValue: string | undefined;
|
|
156
|
-
metadata: EnvVarMetadata;
|
|
157
|
-
emptyStringAsMissing: boolean;
|
|
158
|
-
}): EnvPrimitiveOrUndefined;
|
|
159
|
-
export declare const envRegistry: DecoratorRegistry<EnvDecoratorSchema>;
|
|
160
|
-
export declare const Env: EnvConfigDecorator;
|
|
161
|
-
export declare const EnvConfig: EnvConfigDecorator;
|
|
162
|
-
export declare const EnvVar: EnvVarDecoratorApi;
|
|
163
|
-
export declare const loadEnv: <TClass extends Constructor>(target: TClass, options?: LoadEnvOptions) => EnvLoadResult<TClass>;
|
|
164
|
-
export declare const describeEnv: <TClass extends Constructor>(target: TClass, options?: DescribeEnvOptions) => readonly EnvVariableDefinition[];
|
|
1
|
+
export type { BooleanEnvVarMetadata, DescribeEnvOptions, EnvBooleanFalseValue, EnvBooleanTrueValue, EnvConfigDecorator, EnvConfigMetadata, EnvDecoratorSchema, EnvLoadResult, EnvPrimitive, EnvPrimitiveOrUndefined, EnvSource, EnvSystem, EnvValueKind, EnvVarDecoratorApi, EnvVariableDefinition, EnvVarMetadata, LoadEnvOptions, NumberEnvVarMetadata, StringEnvVarMetadata, } from './types';
|
|
2
|
+
export type { DotenvOptions, DotenvReadResult, DotenvSetting } from './dotenv';
|
|
3
|
+
export { createEnvSystem, getEnvConfigMetadata } from './system';
|
|
4
|
+
export { describeEnv, Env, EnvConfig, envRegistry, EnvVar, loadEnv } from './defaultSystem';
|
|
5
|
+
export { parseEnvValue, toEnvKey } from './parse';
|
|
6
|
+
export { DEFAULT_DOTENV_PATH, readDotenvFiles } from './dotenv';
|
|
7
|
+
export { EnvParseError } from './errors';
|
|
@@ -1,223 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const RawEnvConfig = registry.class('envConfig');
|
|
23
|
-
const Env = ((metadata) => {
|
|
24
|
-
return metadata === undefined ? RawEnvConfig() : RawEnvConfig(metadata);
|
|
25
|
-
});
|
|
26
|
-
const EnvConfig = Env;
|
|
27
|
-
/**
|
|
28
|
-
* Broad scoped contract because this system decorates arbitrary env classes.
|
|
29
|
-
* The public EnvVar.string/number/boolean helper return types enforce the actual
|
|
30
|
-
* decorated property type.
|
|
31
|
-
*/
|
|
32
|
-
const Scoped = registry.for();
|
|
33
|
-
const RawEnvVar = Scoped.property('envVar');
|
|
34
|
-
const EnvVar = ((metadata) => RawEnvVar(metadata));
|
|
35
|
-
EnvVar.string = (name, options = {}) => {
|
|
36
|
-
return RawEnvVar(Object.assign(Object.assign({}, options), { name, type: 'string' }));
|
|
37
|
-
};
|
|
38
|
-
EnvVar.number = (name, options = {}) => {
|
|
39
|
-
return RawEnvVar(Object.assign(Object.assign({}, options), { name, type: 'number' }));
|
|
40
|
-
};
|
|
41
|
-
EnvVar.boolean = (name, options = {}) => {
|
|
42
|
-
return RawEnvVar(Object.assign(Object.assign({}, options), { name, type: 'boolean' }));
|
|
43
|
-
};
|
|
44
|
-
function describeEnv(target, options = {}) {
|
|
45
|
-
var _a, _b;
|
|
46
|
-
const includeInherited = (_a = options.includeInherited) !== null && _a !== void 0 ? _a : true;
|
|
47
|
-
const snapshot = registry.read(target, { includeInherited });
|
|
48
|
-
const classMetadata = getEnvConfigMetadata(snapshot);
|
|
49
|
-
const prefix = (_b = classMetadata === null || classMetadata === void 0 ? void 0 : classMetadata.prefix) !== null && _b !== void 0 ? _b : '';
|
|
50
|
-
return Object.freeze(snapshot.propertyRecords('envVar').map((record) => {
|
|
51
|
-
var _a;
|
|
52
|
-
if (record.memberName === undefined) {
|
|
53
|
-
throw new EnvParseError('EnvVar metadata record is missing memberName.');
|
|
54
|
-
}
|
|
55
|
-
if (typeof record.memberName === 'symbol') {
|
|
56
|
-
throw new EnvParseError(`EnvVar does not support symbol member keys: ${String(record.memberName)}.`);
|
|
57
|
-
}
|
|
58
|
-
const metadata = record.metadata;
|
|
59
|
-
const propertyName = record.memberName;
|
|
60
|
-
const envName = prefix + ((_a = metadata.name) !== null && _a !== void 0 ? _a : toEnvKey(propertyName));
|
|
61
|
-
return Object.freeze({
|
|
62
|
-
propertyName,
|
|
63
|
-
envName,
|
|
64
|
-
static: record.static,
|
|
65
|
-
private: record.private,
|
|
66
|
-
metadata,
|
|
67
|
-
});
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
function loadEnv(target, options = {}) {
|
|
71
|
-
var _a, _b, _c, _d;
|
|
72
|
-
const source = (_a = options.source) !== null && _a !== void 0 ? _a : getDefaultEnvSource();
|
|
73
|
-
const requireStatic = (_b = options.requireStatic) !== null && _b !== void 0 ? _b : true;
|
|
74
|
-
const emptyStringAsMissing = (_c = options.emptyStringAsMissing) !== null && _c !== void 0 ? _c : true;
|
|
75
|
-
const includeInherited = (_d = options.includeInherited) !== null && _d !== void 0 ? _d : true;
|
|
76
|
-
const snapshot = registry.read(target, { includeInherited });
|
|
77
|
-
const definitions = describeEnv(target, { includeInherited });
|
|
78
|
-
const values = {};
|
|
79
|
-
for (const definition of definitions) {
|
|
80
|
-
if (requireStatic && !definition.static) {
|
|
81
|
-
throw new EnvParseError(`@EnvVar field "${definition.propertyName}" must be static when using loadEnv().`, {
|
|
82
|
-
envName: definition.envName,
|
|
83
|
-
propertyName: definition.propertyName,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
if (definition.private) {
|
|
87
|
-
throw new EnvParseError(`@EnvVar field "${definition.propertyName}" cannot be private.`, {
|
|
88
|
-
envName: definition.envName,
|
|
89
|
-
propertyName: definition.propertyName,
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
const rawValue = source[definition.envName];
|
|
93
|
-
const parsedValue = parseEnvValue({
|
|
94
|
-
envName: definition.envName,
|
|
95
|
-
propertyName: definition.propertyName,
|
|
96
|
-
rawValue,
|
|
97
|
-
metadata: definition.metadata,
|
|
98
|
-
emptyStringAsMissing,
|
|
99
|
-
});
|
|
100
|
-
Object.defineProperty(target, definition.propertyName, {
|
|
101
|
-
configurable: true,
|
|
102
|
-
enumerable: true,
|
|
103
|
-
writable: true,
|
|
104
|
-
value: parsedValue,
|
|
105
|
-
});
|
|
106
|
-
values[definition.propertyName] = parsedValue;
|
|
107
|
-
}
|
|
108
|
-
return Object.freeze({
|
|
109
|
-
target,
|
|
110
|
-
definitions,
|
|
111
|
-
values: Object.freeze(Object.assign({}, values)),
|
|
112
|
-
snapshot,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
return Object.freeze({
|
|
116
|
-
registry,
|
|
117
|
-
Env,
|
|
118
|
-
EnvConfig,
|
|
119
|
-
EnvVar,
|
|
120
|
-
loadEnv,
|
|
121
|
-
describeEnv,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
function getEnvConfigMetadata(snapshot) {
|
|
125
|
-
const configRecords = snapshot.classRecords('envConfig');
|
|
126
|
-
const lastRecord = configRecords[configRecords.length - 1];
|
|
127
|
-
return lastRecord === null || lastRecord === void 0 ? void 0 : lastRecord.metadata;
|
|
128
|
-
}
|
|
129
|
-
function toEnvKey(propertyName) {
|
|
130
|
-
return propertyName
|
|
131
|
-
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
|
|
132
|
-
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
133
|
-
.replace(/[-\s]+/g, '_')
|
|
134
|
-
.toUpperCase();
|
|
135
|
-
}
|
|
136
|
-
function parseEnvValue(args) {
|
|
137
|
-
const { envName, propertyName, rawValue, metadata, emptyStringAsMissing } = args;
|
|
138
|
-
const missing = rawValue === undefined || (emptyStringAsMissing && rawValue.trim() === '');
|
|
139
|
-
if (missing) {
|
|
140
|
-
if ('default' in metadata)
|
|
141
|
-
return metadata.default;
|
|
142
|
-
if (metadata.required === false)
|
|
143
|
-
return undefined;
|
|
144
|
-
throw new EnvParseError(`Missing required environment variable "${envName}".`, {
|
|
145
|
-
envName,
|
|
146
|
-
propertyName,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
switch (metadata.type) {
|
|
150
|
-
case 'string':
|
|
151
|
-
return rawValue;
|
|
152
|
-
case 'number':
|
|
153
|
-
return parseNumberValue({
|
|
154
|
-
envName,
|
|
155
|
-
propertyName,
|
|
156
|
-
rawValue,
|
|
157
|
-
metadata,
|
|
158
|
-
});
|
|
159
|
-
case 'boolean':
|
|
160
|
-
return parseBooleanValue({
|
|
161
|
-
envName,
|
|
162
|
-
propertyName,
|
|
163
|
-
rawValue,
|
|
164
|
-
});
|
|
165
|
-
default:
|
|
166
|
-
return assertNever(metadata);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
function parseNumberValue(args) {
|
|
170
|
-
const { envName, propertyName, rawValue, metadata } = args;
|
|
171
|
-
const value = Number(rawValue);
|
|
172
|
-
if (!Number.isFinite(value)) {
|
|
173
|
-
throw new EnvParseError(`Environment variable "${envName}" must be a finite number. Received "${rawValue}".`, { envName, propertyName });
|
|
174
|
-
}
|
|
175
|
-
if (metadata.integer === true && !Number.isInteger(value)) {
|
|
176
|
-
throw new EnvParseError(`Environment variable "${envName}" must be an integer. Received "${rawValue}".`, { envName, propertyName });
|
|
177
|
-
}
|
|
178
|
-
if (metadata.min !== undefined && value < metadata.min) {
|
|
179
|
-
throw new EnvParseError(`Environment variable "${envName}" must be >= ${metadata.min}. Received "${rawValue}".`, { envName, propertyName });
|
|
180
|
-
}
|
|
181
|
-
if (metadata.max !== undefined && value > metadata.max) {
|
|
182
|
-
throw new EnvParseError(`Environment variable "${envName}" must be <= ${metadata.max}. Received "${rawValue}".`, { envName, propertyName });
|
|
183
|
-
}
|
|
184
|
-
return value;
|
|
185
|
-
}
|
|
186
|
-
function parseBooleanValue(args) {
|
|
187
|
-
const { envName, propertyName, rawValue } = args;
|
|
188
|
-
const normalized = rawValue.trim().toLowerCase();
|
|
189
|
-
if (isTruthyEnvValue(normalized))
|
|
190
|
-
return true;
|
|
191
|
-
if (isFalsyEnvValue(normalized))
|
|
192
|
-
return false;
|
|
193
|
-
throw new EnvParseError(`Environment variable "${envName}" must be a boolean. Received "${rawValue}".`, { envName, propertyName });
|
|
194
|
-
}
|
|
195
|
-
function isTruthyEnvValue(value) {
|
|
196
|
-
return value === 'true'
|
|
197
|
-
|| value === '1'
|
|
198
|
-
|| value === 'yes'
|
|
199
|
-
|| value === 'y'
|
|
200
|
-
|| value === 'on';
|
|
201
|
-
}
|
|
202
|
-
function isFalsyEnvValue(value) {
|
|
203
|
-
return value === 'false'
|
|
204
|
-
|| value === '0'
|
|
205
|
-
|| value === 'no'
|
|
206
|
-
|| value === 'n'
|
|
207
|
-
|| value === 'off';
|
|
208
|
-
}
|
|
209
|
-
function getDefaultEnvSource() {
|
|
210
|
-
var _a, _b;
|
|
211
|
-
const maybeGlobal = globalThis;
|
|
212
|
-
return (_b = (_a = maybeGlobal.process) === null || _a === void 0 ? void 0 : _a.env) !== null && _b !== void 0 ? _b : {};
|
|
213
|
-
}
|
|
214
|
-
function assertNever(value) {
|
|
215
|
-
throw new EnvParseError(`Unsupported env metadata: ${JSON.stringify(value)}`);
|
|
216
|
-
}
|
|
217
|
-
const defaultEnvSystem = createEnvSystem();
|
|
218
|
-
exports.envRegistry = defaultEnvSystem.registry;
|
|
219
|
-
exports.Env = defaultEnvSystem.Env;
|
|
220
|
-
exports.EnvConfig = defaultEnvSystem.EnvConfig;
|
|
221
|
-
exports.EnvVar = defaultEnvSystem.EnvVar;
|
|
222
|
-
exports.loadEnv = defaultEnvSystem.loadEnv;
|
|
223
|
-
exports.describeEnv = defaultEnvSystem.describeEnv;
|
|
3
|
+
exports.EnvParseError = exports.readDotenvFiles = exports.DEFAULT_DOTENV_PATH = exports.toEnvKey = exports.parseEnvValue = exports.loadEnv = exports.EnvVar = exports.envRegistry = exports.EnvConfig = exports.Env = exports.describeEnv = exports.getEnvConfigMetadata = exports.createEnvSystem = void 0;
|
|
4
|
+
var system_1 = require("./system");
|
|
5
|
+
Object.defineProperty(exports, "createEnvSystem", { enumerable: true, get: function () { return system_1.createEnvSystem; } });
|
|
6
|
+
Object.defineProperty(exports, "getEnvConfigMetadata", { enumerable: true, get: function () { return system_1.getEnvConfigMetadata; } });
|
|
7
|
+
var defaultSystem_1 = require("./defaultSystem");
|
|
8
|
+
Object.defineProperty(exports, "describeEnv", { enumerable: true, get: function () { return defaultSystem_1.describeEnv; } });
|
|
9
|
+
Object.defineProperty(exports, "Env", { enumerable: true, get: function () { return defaultSystem_1.Env; } });
|
|
10
|
+
Object.defineProperty(exports, "EnvConfig", { enumerable: true, get: function () { return defaultSystem_1.EnvConfig; } });
|
|
11
|
+
Object.defineProperty(exports, "envRegistry", { enumerable: true, get: function () { return defaultSystem_1.envRegistry; } });
|
|
12
|
+
Object.defineProperty(exports, "EnvVar", { enumerable: true, get: function () { return defaultSystem_1.EnvVar; } });
|
|
13
|
+
Object.defineProperty(exports, "loadEnv", { enumerable: true, get: function () { return defaultSystem_1.loadEnv; } });
|
|
14
|
+
var parse_1 = require("./parse");
|
|
15
|
+
Object.defineProperty(exports, "parseEnvValue", { enumerable: true, get: function () { return parse_1.parseEnvValue; } });
|
|
16
|
+
Object.defineProperty(exports, "toEnvKey", { enumerable: true, get: function () { return parse_1.toEnvKey; } });
|
|
17
|
+
var dotenv_1 = require("./dotenv");
|
|
18
|
+
Object.defineProperty(exports, "DEFAULT_DOTENV_PATH", { enumerable: true, get: function () { return dotenv_1.DEFAULT_DOTENV_PATH; } });
|
|
19
|
+
Object.defineProperty(exports, "readDotenvFiles", { enumerable: true, get: function () { return dotenv_1.readDotenvFiles; } });
|
|
20
|
+
var errors_1 = require("./errors");
|
|
21
|
+
Object.defineProperty(exports, "EnvParseError", { enumerable: true, get: function () { return errors_1.EnvParseError; } });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EnvPrimitiveOrUndefined, EnvVarMetadata } from './types';
|
|
2
|
+
export declare function toEnvKey(propertyName: string): string;
|
|
3
|
+
export declare function parseEnvValue(args: {
|
|
4
|
+
envName: string;
|
|
5
|
+
propertyName: string;
|
|
6
|
+
rawValue: string | undefined;
|
|
7
|
+
metadata: EnvVarMetadata;
|
|
8
|
+
emptyStringAsMissing: boolean;
|
|
9
|
+
}): EnvPrimitiveOrUndefined;
|