@adonisjs/env 4.2.0-1 → 4.2.0-3
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/LICENSE.md +1 -1
- package/README.md +6 -12
- package/build/index.js +8 -0
- package/build/src/debug.d.ts +1 -1
- package/build/src/debug.js +8 -0
- package/build/src/editor.d.ts +15 -1
- package/build/src/editor.js +22 -0
- package/build/src/env.d.ts +56 -1
- package/build/src/env.js +47 -0
- package/build/src/exceptions.d.ts +5 -1
- package/build/src/exceptions.js +12 -0
- package/build/src/loader.d.ts +27 -1
- package/build/src/loader.js +59 -0
- package/build/src/parser.d.ts +43 -0
- package/build/src/parser.js +99 -0
- package/build/src/processor.d.ts +7 -1
- package/build/src/processor.js +29 -0
- package/build/src/validator.d.ts +13 -0
- package/build/src/validator.js +21 -0
- package/index.ts +15 -0
- package/package.json +33 -57
- package/src/debug.ts +11 -0
- package/src/editor.ts +84 -0
- package/src/env.ts +134 -0
- package/src/exceptions.ts +20 -0
- package/src/loader.ts +149 -0
- package/src/parser.ts +185 -0
- package/src/processor.ts +83 -0
- package/src/validator.ts +63 -0
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2023
|
|
3
|
+
Copyright (c) 2023 Harminder Virk
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
6
|
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @adonisjs/env
|
|
2
2
|
> Environment variables parser and validator used by the AdonisJS.
|
|
3
3
|
|
|
4
|
-
[![gh-workflow-image]][gh-workflow-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url]
|
|
4
|
+
[![gh-workflow-image]][gh-workflow-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url]
|
|
5
5
|
|
|
6
6
|
> **Note:** This package is framework agnostic and can also be used outside of AdonisJS.
|
|
7
7
|
|
|
@@ -46,12 +46,7 @@ Following is the list of loaded files. The array is ordered by the priority of t
|
|
|
46
46
|
The `EnvParser` class is responsible for parsing the contents of the `.env` file(s) and converting them into an object.
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
|
-
import {
|
|
50
|
-
|
|
51
|
-
const lookupPath = new URL('./', import.meta.url)
|
|
52
|
-
const loader = new EnvLoader(lookupPath)
|
|
53
|
-
const envFiles = await loader.load()
|
|
54
|
-
|
|
49
|
+
import { EnvParser } from '@adonisjs/env'
|
|
55
50
|
const envParser = new EnvParser(`
|
|
56
51
|
PORT=3000
|
|
57
52
|
HOST=localhost
|
|
@@ -92,6 +87,8 @@ The `Env.rules` method returns an instance of the validator to validate the envi
|
|
|
92
87
|
validator.validate(process.env)
|
|
93
88
|
```
|
|
94
89
|
|
|
90
|
+
## Complete example
|
|
91
|
+
|
|
95
92
|
Following is a complete example of loading dot-env files and validating them in one go.
|
|
96
93
|
|
|
97
94
|
> **Note**: Existing `process.env` variables have the top most priority over the variables defined in any of the files.
|
|
@@ -138,8 +135,8 @@ try {
|
|
|
138
135
|
}
|
|
139
136
|
```
|
|
140
137
|
|
|
141
|
-
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/env/
|
|
142
|
-
[gh-workflow-url]: https://github.com/adonisjs/env/actions/workflows/
|
|
138
|
+
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/env/checks.yml?style=for-the-badge
|
|
139
|
+
[gh-workflow-url]: https://github.com/adonisjs/env/actions/workflows/checks.yml "Github action"
|
|
143
140
|
|
|
144
141
|
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
|
|
145
142
|
[typescript-url]: "typescript"
|
|
@@ -149,6 +146,3 @@ try {
|
|
|
149
146
|
|
|
150
147
|
[license-image]: https://img.shields.io/npm/l/@adonisjs/env?color=blueviolet&style=for-the-badge
|
|
151
148
|
[license-url]: LICENSE.md "license"
|
|
152
|
-
|
|
153
|
-
[synk-image]: https://img.shields.io/snyk/vulnerabilities/github/adonisjs/env?label=Synk%20Vulnerabilities&style=for-the-badge
|
|
154
|
-
[synk-url]: https://snyk.io/test/github/adonisjs/env?targetFile=package.json "synk"
|
package/build/index.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/env
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
1
9
|
export { Env } from './src/env.js';
|
|
2
10
|
export { EnvParser } from './src/parser.js';
|
|
3
11
|
export { EnvLoader } from './src/loader.js';
|
package/build/src/debug.d.ts
CHANGED
package/build/src/debug.js
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/env
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
1
9
|
import { debuglog } from 'node:util';
|
|
2
10
|
export default debuglog('adonisjs:env');
|
package/build/src/editor.d.ts
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
1
|
+
/// <reference types="@types/node" resolution-mode="require"/>
|
|
2
2
|
export declare class EnvEditor {
|
|
3
3
|
#private;
|
|
4
|
+
/**
|
|
5
|
+
* Creates an instance of env editor and loads .env files
|
|
6
|
+
* contents.
|
|
7
|
+
*/
|
|
4
8
|
static create(appRoot: URL): Promise<EnvEditor>;
|
|
5
9
|
constructor(appRoot: URL);
|
|
10
|
+
/**
|
|
11
|
+
* Loads .env files for editing. Only ".env" and ".env.example"
|
|
12
|
+
* files are picked for editing.
|
|
13
|
+
*/
|
|
6
14
|
load(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Add key-value pair to the dot-env files.
|
|
17
|
+
*/
|
|
7
18
|
add(key: string, value: string | number | boolean): void;
|
|
8
19
|
toJSON(): {
|
|
9
20
|
contents: string[];
|
|
10
21
|
path: string;
|
|
11
22
|
}[];
|
|
23
|
+
/**
|
|
24
|
+
* Save changes to the disk
|
|
25
|
+
*/
|
|
12
26
|
save(): Promise<void>;
|
|
13
27
|
}
|
package/build/src/editor.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/env
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
1
9
|
import splitLines from 'split-lines';
|
|
2
10
|
import lodash from '@poppinss/utils/lodash';
|
|
3
11
|
import { writeFile } from 'node:fs/promises';
|
|
@@ -6,6 +14,10 @@ export class EnvEditor {
|
|
|
6
14
|
#appRoot;
|
|
7
15
|
#loader;
|
|
8
16
|
#files = [];
|
|
17
|
+
/**
|
|
18
|
+
* Creates an instance of env editor and loads .env files
|
|
19
|
+
* contents.
|
|
20
|
+
*/
|
|
9
21
|
static async create(appRoot) {
|
|
10
22
|
const editor = new EnvEditor(appRoot);
|
|
11
23
|
await editor.load();
|
|
@@ -15,6 +27,10 @@ export class EnvEditor {
|
|
|
15
27
|
this.#appRoot = appRoot;
|
|
16
28
|
this.#loader = new EnvLoader(this.#appRoot, true);
|
|
17
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Loads .env files for editing. Only ".env" and ".env.example"
|
|
32
|
+
* files are picked for editing.
|
|
33
|
+
*/
|
|
18
34
|
async load() {
|
|
19
35
|
const envFiles = await this.#loader.load();
|
|
20
36
|
this.#files = envFiles
|
|
@@ -27,6 +43,9 @@ export class EnvEditor {
|
|
|
27
43
|
};
|
|
28
44
|
});
|
|
29
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Add key-value pair to the dot-env files.
|
|
48
|
+
*/
|
|
30
49
|
add(key, value) {
|
|
31
50
|
this.#files.forEach((file) => {
|
|
32
51
|
let entryIndex = file.contents.findIndex((line) => line.startsWith(`${key}=`));
|
|
@@ -37,6 +56,9 @@ export class EnvEditor {
|
|
|
37
56
|
toJSON() {
|
|
38
57
|
return this.#files;
|
|
39
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Save changes to the disk
|
|
61
|
+
*/
|
|
40
62
|
async save() {
|
|
41
63
|
await Promise.all(this.#files.map((file) => {
|
|
42
64
|
return writeFile(file.path, file.contents.join('\n'));
|
package/build/src/env.d.ts
CHANGED
|
@@ -1,27 +1,82 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
1
|
+
/// <reference types="@types/node" resolution-mode="require"/>
|
|
2
2
|
import { type ValidateFn } from '@poppinss/validator-lite';
|
|
3
3
|
import { EnvValidator } from './validator.js';
|
|
4
|
+
/**
|
|
5
|
+
* A wrapper over "process.env" with types information.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* const validate = Env.rules({
|
|
9
|
+
* PORT: Env.schema.number()
|
|
10
|
+
* })
|
|
11
|
+
*
|
|
12
|
+
* const validatedEnvVars = validate(process.env)
|
|
13
|
+
*
|
|
14
|
+
* const env = new EnvValues(validatedEnvVars)
|
|
15
|
+
* env.get('PORT') // type === number
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
4
18
|
export declare class Env<EnvValues extends Record<string, any>> {
|
|
5
19
|
#private;
|
|
6
20
|
constructor(values: EnvValues);
|
|
21
|
+
/**
|
|
22
|
+
* Create an instance of the env class by validating the
|
|
23
|
+
* environment variables. Also, the `.env` files are
|
|
24
|
+
* loaded from the appRoot
|
|
25
|
+
*/
|
|
7
26
|
static create<Schema extends {
|
|
8
27
|
[key: string]: ValidateFn<unknown>;
|
|
9
28
|
}>(appRoot: URL, schema: Schema): Promise<Env<{
|
|
10
29
|
[K in keyof Schema]: ReturnType<Schema[K]>;
|
|
11
30
|
}>>;
|
|
31
|
+
/**
|
|
32
|
+
* The schema builder for defining validation rules
|
|
33
|
+
*/
|
|
12
34
|
static schema: {
|
|
13
35
|
number: typeof import("@poppinss/validator-lite/build/src/schema/number.js").number;
|
|
14
36
|
string: typeof import("@poppinss/validator-lite/build/src/schema/string.js").string;
|
|
15
37
|
boolean: typeof import("@poppinss/validator-lite/build/src/schema/boolean.js").boolean;
|
|
16
38
|
enum: typeof import("@poppinss/validator-lite/build/src/schema/oneOf.js").oneOf;
|
|
17
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Define the validation rules for validating environment
|
|
42
|
+
* variables. The return value is an instance of the
|
|
43
|
+
* env validator
|
|
44
|
+
*/
|
|
18
45
|
static rules<T extends {
|
|
19
46
|
[key: string]: ValidateFn<unknown>;
|
|
20
47
|
}>(schema: T): EnvValidator<T>;
|
|
48
|
+
/**
|
|
49
|
+
* Get the value of an environment variable by key. The values are
|
|
50
|
+
* lookedup inside the validated environment and "process.env"
|
|
51
|
+
* is used as a fallback.
|
|
52
|
+
*
|
|
53
|
+
* The second param is the default value, which is returned when
|
|
54
|
+
* the environment variable does not exist.
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* Env.get('PORT')
|
|
58
|
+
*
|
|
59
|
+
* // With default value
|
|
60
|
+
* Env.get('PORT', 3000)
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
21
63
|
get<K extends keyof EnvValues>(key: K): EnvValues[K];
|
|
22
64
|
get<K extends keyof EnvValues>(key: K, defaultValue: Exclude<EnvValues[K], undefined>): Exclude<EnvValues[K], undefined>;
|
|
23
65
|
get(key: string): string | undefined;
|
|
24
66
|
get(key: string, defaultValue: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Update/set value of an environment variable.
|
|
69
|
+
*
|
|
70
|
+
* The value is not casted/validated using the validator, so make sure
|
|
71
|
+
* to set the correct data type.
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* Env.set('PORT', 3000)
|
|
75
|
+
*
|
|
76
|
+
* Env.get('PORT') === 3000 // true
|
|
77
|
+
* process.env.PORT === '3000' // true
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
25
80
|
set<K extends keyof EnvValues>(key: K, value: EnvValues[K]): void;
|
|
26
81
|
set(key: string, value: string): void;
|
|
27
82
|
}
|
package/build/src/env.js
CHANGED
|
@@ -1,29 +1,76 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/env
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
1
9
|
import { schema as envSchema } from '@poppinss/validator-lite';
|
|
2
10
|
import { EnvValidator } from './validator.js';
|
|
3
11
|
import { EnvProcessor } from './processor.js';
|
|
12
|
+
/**
|
|
13
|
+
* A wrapper over "process.env" with types information.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* const validate = Env.rules({
|
|
17
|
+
* PORT: Env.schema.number()
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* const validatedEnvVars = validate(process.env)
|
|
21
|
+
*
|
|
22
|
+
* const env = new EnvValues(validatedEnvVars)
|
|
23
|
+
* env.get('PORT') // type === number
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
4
26
|
export class Env {
|
|
27
|
+
/**
|
|
28
|
+
* A cache of env values
|
|
29
|
+
*/
|
|
5
30
|
#values;
|
|
6
31
|
constructor(values) {
|
|
7
32
|
this.#values = values;
|
|
8
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Create an instance of the env class by validating the
|
|
36
|
+
* environment variables. Also, the `.env` files are
|
|
37
|
+
* loaded from the appRoot
|
|
38
|
+
*/
|
|
9
39
|
static async create(appRoot, schema) {
|
|
10
40
|
const values = await new EnvProcessor(appRoot).process();
|
|
11
41
|
const validator = this.rules(schema);
|
|
12
42
|
return new Env(validator.validate(values));
|
|
13
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* The schema builder for defining validation rules
|
|
46
|
+
*/
|
|
14
47
|
static schema = envSchema;
|
|
48
|
+
/**
|
|
49
|
+
* Define the validation rules for validating environment
|
|
50
|
+
* variables. The return value is an instance of the
|
|
51
|
+
* env validator
|
|
52
|
+
*/
|
|
15
53
|
static rules(schema) {
|
|
16
54
|
const validator = new EnvValidator(schema);
|
|
17
55
|
return validator;
|
|
18
56
|
}
|
|
19
57
|
get(key, defaultValue) {
|
|
58
|
+
/**
|
|
59
|
+
* Return cached value
|
|
60
|
+
*/
|
|
20
61
|
if (this.#values[key] !== undefined) {
|
|
21
62
|
return this.#values[key];
|
|
22
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Get value from "process.env" and update the cache
|
|
66
|
+
*/
|
|
23
67
|
const envValue = process.env[key];
|
|
24
68
|
if (envValue) {
|
|
25
69
|
return envValue;
|
|
26
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Return default value when unable to lookup any other value
|
|
73
|
+
*/
|
|
27
74
|
return defaultValue;
|
|
28
75
|
}
|
|
29
76
|
set(key, value) {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
1
|
+
/// <reference types="@types/node" resolution-mode="require"/>
|
|
2
|
+
/**
|
|
3
|
+
* Exception raised when one or more env variables
|
|
4
|
+
* are invalid
|
|
5
|
+
*/
|
|
2
6
|
export declare const E_INVALID_ENV_VARIABLES: {
|
|
3
7
|
new (message?: string | undefined, options?: (ErrorOptions & {
|
|
4
8
|
code?: string | undefined;
|
package/build/src/exceptions.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/env
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
1
9
|
import { Exception } from '@poppinss/utils';
|
|
10
|
+
/**
|
|
11
|
+
* Exception raised when one or more env variables
|
|
12
|
+
* are invalid
|
|
13
|
+
*/
|
|
2
14
|
export const E_INVALID_ENV_VARIABLES = class EnvValidationException extends Exception {
|
|
3
15
|
static message = 'Validation failed for one or more environment variables';
|
|
4
16
|
static code = 'E_INVALID_ENV_VARIABLES';
|
package/build/src/loader.d.ts
CHANGED
|
@@ -1,7 +1,33 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
1
|
+
/// <reference types="@types/node" resolution-mode="require"/>
|
|
2
|
+
/**
|
|
3
|
+
* Read the contents of one or more dot-env files. Following is how the files
|
|
4
|
+
* are read.
|
|
5
|
+
*
|
|
6
|
+
* - Load file from the "ENV_PATH" environment file.
|
|
7
|
+
* (Raise error if file is missing)
|
|
8
|
+
*
|
|
9
|
+
* - If "ENV_PATH" is not defined, then find ".env" file in the app root.
|
|
10
|
+
* (Ignore if file is missing)
|
|
11
|
+
*
|
|
12
|
+
* - Find ".env.[NODE_ENV]" file in the app root.
|
|
13
|
+
* (Ignore if file is missing)
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* const loader = new EnvLoader(new URL('./', import.meta.url))
|
|
17
|
+
*
|
|
18
|
+
* const { envContents, currentEnvContents } = await loader.load()
|
|
19
|
+
*
|
|
20
|
+
* // envContents: Contents of .env or file specified via ENV_PATH
|
|
21
|
+
* // currentEnvContents: Contents of .env.[NODE_ENV] file
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
2
24
|
export declare class EnvLoader {
|
|
3
25
|
#private;
|
|
4
26
|
constructor(appRoot: string | URL, loadExampleFile?: boolean);
|
|
27
|
+
/**
|
|
28
|
+
* Load contents of the main dot-env file and the current
|
|
29
|
+
* environment dot-env file
|
|
30
|
+
*/
|
|
5
31
|
load(): Promise<{
|
|
6
32
|
contents: string;
|
|
7
33
|
path: string;
|
package/build/src/loader.js
CHANGED
|
@@ -1,7 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/env
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
1
9
|
import { fileURLToPath } from 'node:url';
|
|
2
10
|
import { readFile } from 'node:fs/promises';
|
|
3
11
|
import { isAbsolute, join } from 'node:path';
|
|
4
12
|
import debug from './debug.js';
|
|
13
|
+
/**
|
|
14
|
+
* Read the contents of one or more dot-env files. Following is how the files
|
|
15
|
+
* are read.
|
|
16
|
+
*
|
|
17
|
+
* - Load file from the "ENV_PATH" environment file.
|
|
18
|
+
* (Raise error if file is missing)
|
|
19
|
+
*
|
|
20
|
+
* - If "ENV_PATH" is not defined, then find ".env" file in the app root.
|
|
21
|
+
* (Ignore if file is missing)
|
|
22
|
+
*
|
|
23
|
+
* - Find ".env.[NODE_ENV]" file in the app root.
|
|
24
|
+
* (Ignore if file is missing)
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* const loader = new EnvLoader(new URL('./', import.meta.url))
|
|
28
|
+
*
|
|
29
|
+
* const { envContents, currentEnvContents } = await loader.load()
|
|
30
|
+
*
|
|
31
|
+
* // envContents: Contents of .env or file specified via ENV_PATH
|
|
32
|
+
* // currentEnvContents: Contents of .env.[NODE_ENV] file
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
5
35
|
export class EnvLoader {
|
|
6
36
|
#appRoot;
|
|
7
37
|
#loadExampleFile;
|
|
@@ -9,18 +39,26 @@ export class EnvLoader {
|
|
|
9
39
|
this.#appRoot = typeof appRoot === 'string' ? appRoot : fileURLToPath(appRoot);
|
|
10
40
|
this.#loadExampleFile = loadExampleFile;
|
|
11
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Optionally read a file from the disk
|
|
44
|
+
*/
|
|
12
45
|
async #loadFile(filePath) {
|
|
13
46
|
try {
|
|
14
47
|
const contents = await readFile(filePath, 'utf-8');
|
|
15
48
|
return { contents, fileExists: true };
|
|
16
49
|
}
|
|
17
50
|
catch (error) {
|
|
51
|
+
/* c8 ignore next 3 */
|
|
18
52
|
if (error.code !== 'ENOENT') {
|
|
19
53
|
throw error;
|
|
20
54
|
}
|
|
21
55
|
return { contents: '', fileExists: false };
|
|
22
56
|
}
|
|
23
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Load contents of the main dot-env file and the current
|
|
60
|
+
* environment dot-env file
|
|
61
|
+
*/
|
|
24
62
|
async load() {
|
|
25
63
|
const ENV_PATH = process.env.ENV_PATH;
|
|
26
64
|
const NODE_ENV = process.env.NODE_ENV;
|
|
@@ -29,6 +67,9 @@ export class EnvLoader {
|
|
|
29
67
|
debug('ENV_PATH variable is %s', ENV_PATH ? 'set' : 'not set');
|
|
30
68
|
debug('NODE_ENV variable is %s', NODE_ENV ? 'set' : 'not set');
|
|
31
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Base path to load .env files from
|
|
72
|
+
*/
|
|
32
73
|
const baseEnvPath = ENV_PATH
|
|
33
74
|
? isAbsolute(ENV_PATH)
|
|
34
75
|
? ENV_PATH
|
|
@@ -37,6 +78,10 @@ export class EnvLoader {
|
|
|
37
78
|
if (debug.enabled) {
|
|
38
79
|
debug('dot-env files base path "%s"', baseEnvPath);
|
|
39
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* 1st
|
|
83
|
+
* The top most priority is given to the ".env.[NODE_ENV].local" file
|
|
84
|
+
*/
|
|
40
85
|
if (NODE_ENV) {
|
|
41
86
|
const nodeEnvLocalFile = join(baseEnvPath, `.env.${NODE_ENV}.local`);
|
|
42
87
|
envFiles.push({
|
|
@@ -44,6 +89,10 @@ export class EnvLoader {
|
|
|
44
89
|
...(await this.#loadFile(nodeEnvLocalFile)),
|
|
45
90
|
});
|
|
46
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* 2nd
|
|
94
|
+
* Next, we give priority to the ".env.local" file
|
|
95
|
+
*/
|
|
47
96
|
if (!NODE_ENV || !['test', 'testing'].includes(NODE_ENV)) {
|
|
48
97
|
const envLocalFile = join(baseEnvPath, '.env.local');
|
|
49
98
|
envFiles.push({
|
|
@@ -51,6 +100,10 @@ export class EnvLoader {
|
|
|
51
100
|
...(await this.#loadFile(envLocalFile)),
|
|
52
101
|
});
|
|
53
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* 3rd
|
|
105
|
+
* Next, we give priority to the ".env.[NODE_ENV]" file
|
|
106
|
+
*/
|
|
54
107
|
if (NODE_ENV) {
|
|
55
108
|
const nodeEnvFile = join(baseEnvPath, `.env.${NODE_ENV}`);
|
|
56
109
|
envFiles.push({
|
|
@@ -58,11 +111,17 @@ export class EnvLoader {
|
|
|
58
111
|
...(await this.#loadFile(nodeEnvFile)),
|
|
59
112
|
});
|
|
60
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Finally, we push the contents of the ".env" file.
|
|
116
|
+
*/
|
|
61
117
|
const envFile = join(baseEnvPath, '.env');
|
|
62
118
|
envFiles.push({
|
|
63
119
|
path: envFile,
|
|
64
120
|
...(await this.#loadFile(envFile)),
|
|
65
121
|
});
|
|
122
|
+
/**
|
|
123
|
+
* Load example file
|
|
124
|
+
*/
|
|
66
125
|
if (this.#loadExampleFile) {
|
|
67
126
|
const envExampleFile = join(baseEnvPath, '.env.example');
|
|
68
127
|
envFiles.push({
|
package/build/src/parser.d.ts
CHANGED
|
@@ -1,8 +1,51 @@
|
|
|
1
1
|
import { DotenvParseOutput } from 'dotenv';
|
|
2
|
+
/**
|
|
3
|
+
* Env parser parses the environment variables from a string formatted
|
|
4
|
+
* as a key-value pair seperated using an `=`. For example:
|
|
5
|
+
*
|
|
6
|
+
* ```dotenv
|
|
7
|
+
* PORT=3333
|
|
8
|
+
* HOST=127.0.0.1
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* The variables can reference other environment variables as well using `$`.
|
|
12
|
+
* For example:
|
|
13
|
+
*
|
|
14
|
+
* ```dotenv
|
|
15
|
+
* PORT=3333
|
|
16
|
+
* REDIS_PORT=$PORT
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* The variables using characters other than letters can wrap variable
|
|
20
|
+
* named inside a curly brace.
|
|
21
|
+
*
|
|
22
|
+
* ```dotenv
|
|
23
|
+
* APP-PORT=3333
|
|
24
|
+
* REDIS_PORT=${APP-PORT}
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* You can escape the `$` sign with a backtick.
|
|
28
|
+
*
|
|
29
|
+
* ```dotenv
|
|
30
|
+
* REDIS_PASSWORD=foo\$123
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ## Usage
|
|
34
|
+
*
|
|
35
|
+
* ```ts
|
|
36
|
+
* const parser = new EnvParser(envContents)
|
|
37
|
+
* const output = parser.parse()
|
|
38
|
+
*
|
|
39
|
+
* // The output is a key-value pair
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
2
42
|
export declare class EnvParser {
|
|
3
43
|
#private;
|
|
4
44
|
constructor(envContents: string, options?: {
|
|
5
45
|
ignoreProcessEnv: boolean;
|
|
6
46
|
});
|
|
47
|
+
/**
|
|
48
|
+
* Parse the env string to an object of environment variables.
|
|
49
|
+
*/
|
|
7
50
|
parse(): DotenvParseOutput;
|
|
8
51
|
}
|