@adonisjs/env 4.2.0-4 → 4.2.0-6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/chunk-NSHYMAZE.js +95 -0
- package/build/index.d.ts +247 -5
- package/build/index.js +251 -13
- package/build/src/editor.d.ts +3 -2
- package/build/src/editor.js +67 -67
- package/package.json +29 -19
- package/build/src/debug.d.ts +0 -3
- package/build/src/debug.js +0 -10
- package/build/src/env.d.ts +0 -82
- package/build/src/env.js +0 -80
- package/build/src/exceptions.d.ts +0 -28
- package/build/src/exceptions.js +0 -18
- package/build/src/loader.d.ts +0 -36
- package/build/src/loader.js +0 -134
- package/build/src/parser.d.ts +0 -51
- package/build/src/parser.js +0 -166
- package/build/src/processor.d.ts +0 -12
- package/build/src/processor.js +0 -68
- package/build/src/validator.d.ts +0 -25
- package/build/src/validator.js +0 -48
package/README.md
CHANGED
|
@@ -110,7 +110,7 @@ env.get('NODE_ENV') // is unknown, hence a string or undefined
|
|
|
110
110
|
The Env editor can be used to edit dot-env files and persist changes on disk. Only the `.env` and `.env.example` files are updated (if exists).
|
|
111
111
|
|
|
112
112
|
```ts
|
|
113
|
-
import { EnvEditor } from '@adonisjs/env'
|
|
113
|
+
import { EnvEditor } from '@adonisjs/env/editor'
|
|
114
114
|
|
|
115
115
|
const editor = await EnvEditor.create(new URL('./', import.meta.url))
|
|
116
116
|
editor.add('PORT', 3000)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/loader.ts
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
import { isAbsolute, join } from "node:path";
|
|
11
|
+
|
|
12
|
+
// src/debug.ts
|
|
13
|
+
import { debuglog } from "node:util";
|
|
14
|
+
var debug_default = debuglog("adonisjs:env");
|
|
15
|
+
|
|
16
|
+
// src/loader.ts
|
|
17
|
+
var EnvLoader = class {
|
|
18
|
+
#appRoot;
|
|
19
|
+
#loadExampleFile;
|
|
20
|
+
constructor(appRoot, loadExampleFile = false) {
|
|
21
|
+
this.#appRoot = typeof appRoot === "string" ? appRoot : fileURLToPath(appRoot);
|
|
22
|
+
this.#loadExampleFile = loadExampleFile;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Optionally read a file from the disk
|
|
26
|
+
*/
|
|
27
|
+
async #loadFile(filePath) {
|
|
28
|
+
try {
|
|
29
|
+
const contents = await readFile(filePath, "utf-8");
|
|
30
|
+
return { contents, fileExists: true };
|
|
31
|
+
} catch (error) {
|
|
32
|
+
if (error.code !== "ENOENT") {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
return { contents: "", fileExists: false };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Load contents of the main dot-env file and the current
|
|
40
|
+
* environment dot-env file
|
|
41
|
+
*/
|
|
42
|
+
async load() {
|
|
43
|
+
const ENV_PATH = process.env.ENV_PATH;
|
|
44
|
+
const NODE_ENV = process.env.NODE_ENV;
|
|
45
|
+
const envFiles = [];
|
|
46
|
+
if (debug_default.enabled) {
|
|
47
|
+
debug_default("ENV_PATH variable is %s", ENV_PATH ? "set" : "not set");
|
|
48
|
+
debug_default("NODE_ENV variable is %s", NODE_ENV ? "set" : "not set");
|
|
49
|
+
}
|
|
50
|
+
const baseEnvPath = ENV_PATH ? isAbsolute(ENV_PATH) ? ENV_PATH : join(this.#appRoot, ENV_PATH) : this.#appRoot;
|
|
51
|
+
if (debug_default.enabled) {
|
|
52
|
+
debug_default('dot-env files base path "%s"', baseEnvPath);
|
|
53
|
+
}
|
|
54
|
+
if (NODE_ENV) {
|
|
55
|
+
const nodeEnvLocalFile = join(baseEnvPath, `.env.${NODE_ENV}.local`);
|
|
56
|
+
envFiles.push({
|
|
57
|
+
path: nodeEnvLocalFile,
|
|
58
|
+
...await this.#loadFile(nodeEnvLocalFile)
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (!NODE_ENV || !["test", "testing"].includes(NODE_ENV)) {
|
|
62
|
+
const envLocalFile = join(baseEnvPath, ".env.local");
|
|
63
|
+
envFiles.push({
|
|
64
|
+
path: envLocalFile,
|
|
65
|
+
...await this.#loadFile(envLocalFile)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (NODE_ENV) {
|
|
69
|
+
const nodeEnvFile = join(baseEnvPath, `.env.${NODE_ENV}`);
|
|
70
|
+
envFiles.push({
|
|
71
|
+
path: nodeEnvFile,
|
|
72
|
+
...await this.#loadFile(nodeEnvFile)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const envFile = join(baseEnvPath, ".env");
|
|
76
|
+
envFiles.push({
|
|
77
|
+
path: envFile,
|
|
78
|
+
...await this.#loadFile(envFile)
|
|
79
|
+
});
|
|
80
|
+
if (this.#loadExampleFile) {
|
|
81
|
+
const envExampleFile = join(baseEnvPath, ".env.example");
|
|
82
|
+
envFiles.push({
|
|
83
|
+
path: envExampleFile,
|
|
84
|
+
...await this.#loadFile(envExampleFile)
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return envFiles;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export {
|
|
92
|
+
__export,
|
|
93
|
+
debug_default,
|
|
94
|
+
EnvLoader
|
|
95
|
+
};
|
package/build/index.d.ts
CHANGED
|
@@ -1,5 +1,247 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import * as _poppinss_validator_lite_build_src_schema_oneOf_js from '@poppinss/validator-lite/build/src/schema/oneOf.js';
|
|
2
|
+
import * as _poppinss_validator_lite_build_src_schema_boolean_js from '@poppinss/validator-lite/build/src/schema/boolean.js';
|
|
3
|
+
import * as _poppinss_validator_lite_build_src_schema_string_js from '@poppinss/validator-lite/build/src/schema/string.js';
|
|
4
|
+
import * as _poppinss_validator_lite_build_src_schema_number_js from '@poppinss/validator-lite/build/src/schema/number.js';
|
|
5
|
+
import { ValidateFn } from '@poppinss/validator-lite';
|
|
6
|
+
import { DotenvParseOutput } from 'dotenv';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Exposes the API to validate environment variables against a
|
|
10
|
+
* pre-defined schema.
|
|
11
|
+
*
|
|
12
|
+
* The class is not exported in the main API and used internally.
|
|
13
|
+
*/
|
|
14
|
+
declare class EnvValidator<Schema extends {
|
|
15
|
+
[key: string]: ValidateFn<unknown>;
|
|
16
|
+
}> {
|
|
17
|
+
#private;
|
|
18
|
+
constructor(schema: Schema);
|
|
19
|
+
/**
|
|
20
|
+
* Accepts an object of values to validate against the pre-defined
|
|
21
|
+
* schema.
|
|
22
|
+
*
|
|
23
|
+
* The return value is a merged copy of the original object and the
|
|
24
|
+
* values mutated by the schema validator.
|
|
25
|
+
*/
|
|
26
|
+
validate(values: {
|
|
27
|
+
[K: string]: string | undefined;
|
|
28
|
+
}): {
|
|
29
|
+
[K in keyof Schema]: ReturnType<Schema[K]>;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A wrapper over "process.env" with types information.
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* const validate = Env.rules({
|
|
38
|
+
* PORT: Env.schema.number()
|
|
39
|
+
* })
|
|
40
|
+
*
|
|
41
|
+
* const validatedEnvVars = validate(process.env)
|
|
42
|
+
*
|
|
43
|
+
* const env = new EnvValues(validatedEnvVars)
|
|
44
|
+
* env.get('PORT') // type === number
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
declare class Env<EnvValues extends Record<string, any>> {
|
|
48
|
+
#private;
|
|
49
|
+
constructor(values: EnvValues);
|
|
50
|
+
/**
|
|
51
|
+
* Create an instance of the env class by validating the
|
|
52
|
+
* environment variables. Also, the `.env` files are
|
|
53
|
+
* loaded from the appRoot
|
|
54
|
+
*/
|
|
55
|
+
static create<Schema extends {
|
|
56
|
+
[key: string]: ValidateFn<unknown>;
|
|
57
|
+
}>(appRoot: URL, schema: Schema): Promise<Env<{
|
|
58
|
+
[K in keyof Schema]: ReturnType<Schema[K]>;
|
|
59
|
+
}>>;
|
|
60
|
+
/**
|
|
61
|
+
* The schema builder for defining validation rules
|
|
62
|
+
*/
|
|
63
|
+
static schema: {
|
|
64
|
+
number: typeof _poppinss_validator_lite_build_src_schema_number_js.number;
|
|
65
|
+
string: typeof _poppinss_validator_lite_build_src_schema_string_js.string;
|
|
66
|
+
boolean: typeof _poppinss_validator_lite_build_src_schema_boolean_js.boolean;
|
|
67
|
+
enum: typeof _poppinss_validator_lite_build_src_schema_oneOf_js.oneOf;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Define the validation rules for validating environment
|
|
71
|
+
* variables. The return value is an instance of the
|
|
72
|
+
* env validator
|
|
73
|
+
*/
|
|
74
|
+
static rules<T extends {
|
|
75
|
+
[key: string]: ValidateFn<unknown>;
|
|
76
|
+
}>(schema: T): EnvValidator<T>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the value of an environment variable by key. The values are
|
|
79
|
+
* lookedup inside the validated environment and "process.env"
|
|
80
|
+
* is used as a fallback.
|
|
81
|
+
*
|
|
82
|
+
* The second param is the default value, which is returned when
|
|
83
|
+
* the environment variable does not exist.
|
|
84
|
+
*
|
|
85
|
+
* ```ts
|
|
86
|
+
* Env.get('PORT')
|
|
87
|
+
*
|
|
88
|
+
* // With default value
|
|
89
|
+
* Env.get('PORT', 3000)
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
get<K extends keyof EnvValues>(key: K): EnvValues[K];
|
|
93
|
+
get<K extends keyof EnvValues>(key: K, defaultValue: Exclude<EnvValues[K], undefined>): Exclude<EnvValues[K], undefined>;
|
|
94
|
+
get(key: string): string | undefined;
|
|
95
|
+
get(key: string, defaultValue: string): string;
|
|
96
|
+
/**
|
|
97
|
+
* Update/set value of an environment variable.
|
|
98
|
+
*
|
|
99
|
+
* The value is not casted/validated using the validator, so make sure
|
|
100
|
+
* to set the correct data type.
|
|
101
|
+
*
|
|
102
|
+
* ```ts
|
|
103
|
+
* Env.set('PORT', 3000)
|
|
104
|
+
*
|
|
105
|
+
* Env.get('PORT') === 3000 // true
|
|
106
|
+
* process.env.PORT === '3000' // true
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
set<K extends keyof EnvValues>(key: K, value: EnvValues[K]): void;
|
|
110
|
+
set(key: string, value: string): void;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Env parser parses the environment variables from a string formatted
|
|
115
|
+
* as a key-value pair seperated using an `=`. For example:
|
|
116
|
+
*
|
|
117
|
+
* ```dotenv
|
|
118
|
+
* PORT=3333
|
|
119
|
+
* HOST=127.0.0.1
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* The variables can reference other environment variables as well using `$`.
|
|
123
|
+
* For example:
|
|
124
|
+
*
|
|
125
|
+
* ```dotenv
|
|
126
|
+
* PORT=3333
|
|
127
|
+
* REDIS_PORT=$PORT
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* The variables using characters other than letters can wrap variable
|
|
131
|
+
* named inside a curly brace.
|
|
132
|
+
*
|
|
133
|
+
* ```dotenv
|
|
134
|
+
* APP-PORT=3333
|
|
135
|
+
* REDIS_PORT=${APP-PORT}
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* You can escape the `$` sign with a backtick.
|
|
139
|
+
*
|
|
140
|
+
* ```dotenv
|
|
141
|
+
* REDIS_PASSWORD=foo\$123
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* ## Usage
|
|
145
|
+
*
|
|
146
|
+
* ```ts
|
|
147
|
+
* const parser = new EnvParser(envContents)
|
|
148
|
+
* const output = parser.parse()
|
|
149
|
+
*
|
|
150
|
+
* // The output is a key-value pair
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
declare class EnvParser {
|
|
154
|
+
#private;
|
|
155
|
+
constructor(envContents: string, options?: {
|
|
156
|
+
ignoreProcessEnv: boolean;
|
|
157
|
+
});
|
|
158
|
+
/**
|
|
159
|
+
* Parse the env string to an object of environment variables.
|
|
160
|
+
*/
|
|
161
|
+
parse(): DotenvParseOutput;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Read the contents of one or more dot-env files. Following is how the files
|
|
166
|
+
* are read.
|
|
167
|
+
*
|
|
168
|
+
* - Load file from the "ENV_PATH" environment file.
|
|
169
|
+
* (Raise error if file is missing)
|
|
170
|
+
*
|
|
171
|
+
* - If "ENV_PATH" is not defined, then find ".env" file in the app root.
|
|
172
|
+
* (Ignore if file is missing)
|
|
173
|
+
*
|
|
174
|
+
* - Find ".env.[NODE_ENV]" file in the app root.
|
|
175
|
+
* (Ignore if file is missing)
|
|
176
|
+
*
|
|
177
|
+
* ```ts
|
|
178
|
+
* const loader = new EnvLoader(new URL('./', import.meta.url))
|
|
179
|
+
*
|
|
180
|
+
* const { envContents, currentEnvContents } = await loader.load()
|
|
181
|
+
*
|
|
182
|
+
* // envContents: Contents of .env or file specified via ENV_PATH
|
|
183
|
+
* // currentEnvContents: Contents of .env.[NODE_ENV] file
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
declare class EnvLoader {
|
|
187
|
+
#private;
|
|
188
|
+
constructor(appRoot: string | URL, loadExampleFile?: boolean);
|
|
189
|
+
/**
|
|
190
|
+
* Load contents of the main dot-env file and the current
|
|
191
|
+
* environment dot-env file
|
|
192
|
+
*/
|
|
193
|
+
load(): Promise<{
|
|
194
|
+
contents: string;
|
|
195
|
+
path: string;
|
|
196
|
+
fileExists: boolean;
|
|
197
|
+
}[]>;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Exception raised when one or more env variables
|
|
202
|
+
* are invalid
|
|
203
|
+
*/
|
|
204
|
+
declare const E_INVALID_ENV_VARIABLES: {
|
|
205
|
+
new (message?: string | undefined, options?: (ErrorOptions & {
|
|
206
|
+
code?: string | undefined;
|
|
207
|
+
status?: number | undefined;
|
|
208
|
+
}) | undefined): {
|
|
209
|
+
help: string;
|
|
210
|
+
name: string;
|
|
211
|
+
code?: string | undefined;
|
|
212
|
+
status: number;
|
|
213
|
+
toString(): string;
|
|
214
|
+
readonly [Symbol.toStringTag]: string;
|
|
215
|
+
message: string;
|
|
216
|
+
stack?: string | undefined;
|
|
217
|
+
cause?: unknown;
|
|
218
|
+
};
|
|
219
|
+
message: string;
|
|
220
|
+
code: string;
|
|
221
|
+
help?: string | undefined;
|
|
222
|
+
status?: number | undefined;
|
|
223
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function | undefined): void;
|
|
224
|
+
prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
|
|
225
|
+
stackTraceLimit: number;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
declare const errors_E_INVALID_ENV_VARIABLES: typeof E_INVALID_ENV_VARIABLES;
|
|
229
|
+
declare namespace errors {
|
|
230
|
+
export {
|
|
231
|
+
errors_E_INVALID_ENV_VARIABLES as E_INVALID_ENV_VARIABLES,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Env processors loads, parses and process environment variables.
|
|
237
|
+
*/
|
|
238
|
+
declare class EnvProcessor {
|
|
239
|
+
#private;
|
|
240
|
+
constructor(appRoot: URL);
|
|
241
|
+
/**
|
|
242
|
+
* Process env variables
|
|
243
|
+
*/
|
|
244
|
+
process(): Promise<Record<string, any>>;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export { Env, EnvLoader, EnvParser, EnvProcessor, errors };
|
package/build/index.js
CHANGED
|
@@ -1,13 +1,251 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import {
|
|
2
|
+
EnvLoader,
|
|
3
|
+
__export,
|
|
4
|
+
debug_default
|
|
5
|
+
} from "./chunk-NSHYMAZE.js";
|
|
6
|
+
|
|
7
|
+
// src/env.ts
|
|
8
|
+
import { schema as envSchema } from "@poppinss/validator-lite";
|
|
9
|
+
|
|
10
|
+
// src/errors.ts
|
|
11
|
+
var errors_exports = {};
|
|
12
|
+
__export(errors_exports, {
|
|
13
|
+
E_INVALID_ENV_VARIABLES: () => E_INVALID_ENV_VARIABLES
|
|
14
|
+
});
|
|
15
|
+
import { Exception } from "@poppinss/utils";
|
|
16
|
+
var E_INVALID_ENV_VARIABLES = class EnvValidationException extends Exception {
|
|
17
|
+
static message = "Validation failed for one or more environment variables";
|
|
18
|
+
static code = "E_INVALID_ENV_VARIABLES";
|
|
19
|
+
help = "";
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// src/validator.ts
|
|
23
|
+
var EnvValidator = class {
|
|
24
|
+
#schema;
|
|
25
|
+
#error;
|
|
26
|
+
constructor(schema) {
|
|
27
|
+
this.#schema = schema;
|
|
28
|
+
this.#error = new E_INVALID_ENV_VARIABLES();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Accepts an object of values to validate against the pre-defined
|
|
32
|
+
* schema.
|
|
33
|
+
*
|
|
34
|
+
* The return value is a merged copy of the original object and the
|
|
35
|
+
* values mutated by the schema validator.
|
|
36
|
+
*/
|
|
37
|
+
validate(values) {
|
|
38
|
+
const help = [];
|
|
39
|
+
const validated = Object.keys(this.#schema).reduce(
|
|
40
|
+
(result, key) => {
|
|
41
|
+
const value = process.env[key] || values[key];
|
|
42
|
+
try {
|
|
43
|
+
result[key] = this.#schema[key](key, value);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
help.push(`- ${error.message}`);
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
},
|
|
49
|
+
{ ...values }
|
|
50
|
+
);
|
|
51
|
+
if (help.length) {
|
|
52
|
+
this.#error.help = help.join("\n");
|
|
53
|
+
throw this.#error;
|
|
54
|
+
}
|
|
55
|
+
return validated;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// src/parser.ts
|
|
60
|
+
import dotenv from "dotenv";
|
|
61
|
+
var EnvParser = class {
|
|
62
|
+
#envContents;
|
|
63
|
+
#preferProcessEnv = true;
|
|
64
|
+
constructor(envContents, options) {
|
|
65
|
+
if (options?.ignoreProcessEnv) {
|
|
66
|
+
this.#preferProcessEnv = false;
|
|
67
|
+
}
|
|
68
|
+
this.#envContents = envContents;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns the value from the parsed object
|
|
72
|
+
*/
|
|
73
|
+
#getValue(key, parsed) {
|
|
74
|
+
if (this.#preferProcessEnv && process.env[key]) {
|
|
75
|
+
return process.env[key];
|
|
76
|
+
}
|
|
77
|
+
if (parsed[key]) {
|
|
78
|
+
return this.#interpolate(parsed[key], parsed);
|
|
79
|
+
}
|
|
80
|
+
return process.env[key] || "";
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Interpolating the token wrapped inside the mustache braces.
|
|
84
|
+
*/
|
|
85
|
+
#interpolateMustache(token, parsed) {
|
|
86
|
+
const closingBrace = token.indexOf("}");
|
|
87
|
+
if (closingBrace === -1) {
|
|
88
|
+
return token;
|
|
89
|
+
}
|
|
90
|
+
const varReference = token.slice(1, closingBrace).trim();
|
|
91
|
+
return `${this.#getValue(varReference, parsed)}${token.slice(closingBrace + 1)}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Interpolating the variable reference starting with a
|
|
95
|
+
* `$`. We only capture numbers,letter and underscore.
|
|
96
|
+
* For other characters, one can use the mustache
|
|
97
|
+
* braces.
|
|
98
|
+
*/
|
|
99
|
+
#interpolateVariable(token, parsed) {
|
|
100
|
+
return token.replace(/[a-zA-Z0-9_]+/, (key) => {
|
|
101
|
+
return this.#getValue(key, parsed);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Interpolates the referenced values
|
|
106
|
+
*/
|
|
107
|
+
#interpolate(value, parsed) {
|
|
108
|
+
const tokens = value.split("$");
|
|
109
|
+
let newValue = "";
|
|
110
|
+
let skipNextToken = true;
|
|
111
|
+
tokens.forEach((token) => {
|
|
112
|
+
if (token === "\\") {
|
|
113
|
+
newValue += "$";
|
|
114
|
+
skipNextToken = true;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (skipNextToken) {
|
|
118
|
+
newValue += token.replace(/\\$/, "$");
|
|
119
|
+
if (token.endsWith("\\")) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
if (token.startsWith("{")) {
|
|
124
|
+
newValue += this.#interpolateMustache(token, parsed);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
newValue += this.#interpolateVariable(token, parsed);
|
|
128
|
+
}
|
|
129
|
+
skipNextToken = false;
|
|
130
|
+
});
|
|
131
|
+
return newValue;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Parse the env string to an object of environment variables.
|
|
135
|
+
*/
|
|
136
|
+
parse() {
|
|
137
|
+
const envCollection = dotenv.parse(this.#envContents.trim());
|
|
138
|
+
return Object.keys(envCollection).reduce((result, key) => {
|
|
139
|
+
result[key] = this.#getValue(key, envCollection);
|
|
140
|
+
return result;
|
|
141
|
+
}, {});
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// src/processor.ts
|
|
146
|
+
var EnvProcessor = class {
|
|
147
|
+
/**
|
|
148
|
+
* App root is needed to load files
|
|
149
|
+
*/
|
|
150
|
+
#appRoot;
|
|
151
|
+
constructor(appRoot) {
|
|
152
|
+
this.#appRoot = appRoot;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Parse env variables from raw contents
|
|
156
|
+
*/
|
|
157
|
+
#processContents(envContents, store) {
|
|
158
|
+
if (!envContents.trim()) {
|
|
159
|
+
return store;
|
|
160
|
+
}
|
|
161
|
+
const values = new EnvParser(envContents).parse();
|
|
162
|
+
Object.keys(values).forEach((key) => {
|
|
163
|
+
let value = process.env[key];
|
|
164
|
+
if (!value) {
|
|
165
|
+
value = values[key];
|
|
166
|
+
process.env[key] = values[key];
|
|
167
|
+
}
|
|
168
|
+
if (!store[key]) {
|
|
169
|
+
store[key] = value;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
return store;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Parse env variables by loading dot files.
|
|
176
|
+
*/
|
|
177
|
+
async #loadAndProcessDotFiles() {
|
|
178
|
+
const loader = new EnvLoader(this.#appRoot);
|
|
179
|
+
const envFiles = await loader.load();
|
|
180
|
+
if (debug_default.enabled) {
|
|
181
|
+
debug_default(
|
|
182
|
+
"processing .env files (priority from top to bottom) %O",
|
|
183
|
+
envFiles.map((file) => file.path)
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
const envValues = {};
|
|
187
|
+
envFiles.forEach(({ contents }) => this.#processContents(contents, envValues));
|
|
188
|
+
return envValues;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Process env variables
|
|
192
|
+
*/
|
|
193
|
+
async process() {
|
|
194
|
+
return this.#loadAndProcessDotFiles();
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// src/env.ts
|
|
199
|
+
var Env = class _Env {
|
|
200
|
+
/**
|
|
201
|
+
* A cache of env values
|
|
202
|
+
*/
|
|
203
|
+
#values;
|
|
204
|
+
constructor(values) {
|
|
205
|
+
this.#values = values;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Create an instance of the env class by validating the
|
|
209
|
+
* environment variables. Also, the `.env` files are
|
|
210
|
+
* loaded from the appRoot
|
|
211
|
+
*/
|
|
212
|
+
static async create(appRoot, schema) {
|
|
213
|
+
const values = await new EnvProcessor(appRoot).process();
|
|
214
|
+
const validator = this.rules(schema);
|
|
215
|
+
return new _Env(validator.validate(values));
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* The schema builder for defining validation rules
|
|
219
|
+
*/
|
|
220
|
+
static schema = envSchema;
|
|
221
|
+
/**
|
|
222
|
+
* Define the validation rules for validating environment
|
|
223
|
+
* variables. The return value is an instance of the
|
|
224
|
+
* env validator
|
|
225
|
+
*/
|
|
226
|
+
static rules(schema) {
|
|
227
|
+
const validator = new EnvValidator(schema);
|
|
228
|
+
return validator;
|
|
229
|
+
}
|
|
230
|
+
get(key, defaultValue) {
|
|
231
|
+
if (this.#values[key] !== void 0) {
|
|
232
|
+
return this.#values[key];
|
|
233
|
+
}
|
|
234
|
+
const envValue = process.env[key];
|
|
235
|
+
if (envValue) {
|
|
236
|
+
return envValue;
|
|
237
|
+
}
|
|
238
|
+
return defaultValue;
|
|
239
|
+
}
|
|
240
|
+
set(key, value) {
|
|
241
|
+
this.#values[key] = value;
|
|
242
|
+
process.env[key] = value;
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
export {
|
|
246
|
+
Env,
|
|
247
|
+
EnvLoader,
|
|
248
|
+
EnvParser,
|
|
249
|
+
EnvProcessor,
|
|
250
|
+
errors_exports as errors
|
|
251
|
+
};
|
package/build/src/editor.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export declare class EnvEditor {
|
|
1
|
+
declare class EnvEditor {
|
|
3
2
|
#private;
|
|
4
3
|
/**
|
|
5
4
|
* Creates an instance of env editor and loads .env files
|
|
@@ -25,3 +24,5 @@ export declare class EnvEditor {
|
|
|
25
24
|
*/
|
|
26
25
|
save(): Promise<void>;
|
|
27
26
|
}
|
|
27
|
+
|
|
28
|
+
export { EnvEditor };
|