dotenv-extended 2.9.0 → 3.1.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/README.md +157 -30
- package/dotenv-extended.d.ts +28 -5
- package/lib/bin/cli.js +310 -0
- package/lib/bin/index.js +312 -46
- package/lib/config.js +229 -30
- package/lib/index.js +209 -67
- package/package.json +59 -57
- package/CHANGELOG.md +0 -72
- package/CONTRIBUTING.md +0 -33
- package/lib/utils/config-from-env.js +0 -28
- package/lib/utils/load-environment-file.js +0 -30
- package/lib/utils/parse-command.js +0 -49
package/README.md
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# dotenv-extended
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](https://coveralls.io/github/keithmorris/node-dotenv-extended?branch=develop)
|
|
5
|
-
[](https://david-dm.org/keithmorris/node-dotenv-extended)
|
|
3
|
+
Extended `.env` loading with defaults and schema validation.
|
|
6
4
|
|
|
5
|
+
## Supported Node Versions
|
|
6
|
+
|
|
7
|
+
- Node `20.x`
|
|
8
|
+
- Node `22.x`
|
|
9
|
+
- Node `24.x`
|
|
7
10
|
|
|
8
11
|
I've been a big fan of the [dotenv] for a quite some time (in fact, this library uses [dotenv] under the hood for the `.env` file parsing). However, while working on some bigger projects, we realized that the managing of the `.env` files became a bit of a chore. As the files changed in the development environments, it became a tedious manual process to compare and figure out what needed to be added or removed in the other environments.
|
|
9
12
|
|
|
@@ -29,7 +32,6 @@ Common configuration defaults across all environments (commited to source contro
|
|
|
29
32
|
|
|
30
33
|
Defines a schema of what variables _should_ be defined in the combination of `.env` and `.env.defaults`. Optionally, you can have the library throw an error if all values are not configured or if there are extra values that shouldn't be there.
|
|
31
34
|
|
|
32
|
-
|
|
33
35
|
The `.env.schema` file should only have the name of the variable and the `=` without any value:
|
|
34
36
|
|
|
35
37
|
```
|
|
@@ -49,6 +51,24 @@ I have tried to stay as compatible as possible with the [dotenv] library but the
|
|
|
49
51
|
npm i --save dotenv-extended
|
|
50
52
|
```
|
|
51
53
|
|
|
54
|
+
## Development
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm run check
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`npm run check` runs linting, formatting checks, and tests.
|
|
61
|
+
|
|
62
|
+
Use individual commands only when needed:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm run build
|
|
66
|
+
npm run lint
|
|
67
|
+
npm run format
|
|
68
|
+
npm run test:unit
|
|
69
|
+
npm test
|
|
70
|
+
```
|
|
71
|
+
|
|
52
72
|
## Usage
|
|
53
73
|
|
|
54
74
|
As early as possible in your main script:
|
|
@@ -61,7 +81,7 @@ Or if you prefer import syntax:
|
|
|
61
81
|
|
|
62
82
|
```javascript
|
|
63
83
|
import dotEnvExtended from 'dotenv-extended';
|
|
64
|
-
dotEnvExtended.load();
|
|
84
|
+
dotEnvExtended.load();
|
|
65
85
|
```
|
|
66
86
|
|
|
67
87
|
Create a `.env` file in the root directory of your project. Add environment-specific variables on new lines in the form of `NAME=VALUE`.
|
|
@@ -80,7 +100,7 @@ MONGO_PASS=dbpassword!
|
|
|
80
100
|
```javascript
|
|
81
101
|
mongoose.connect('mongodb://' + process.env.MONGO_HOST + '/' + process.env.MONGO_DATABASE, {
|
|
82
102
|
user: process.env.MONGO_USER,
|
|
83
|
-
pass: process.env.MONGO_PASS
|
|
103
|
+
pass: process.env.MONGO_PASS,
|
|
84
104
|
});
|
|
85
105
|
```
|
|
86
106
|
|
|
@@ -98,28 +118,54 @@ Or to specify load options:
|
|
|
98
118
|
node -r dotenv-extended/config your_script.js dotenv_config_path=./env/.env dotenv_config_defaults=./env/.env.defaults
|
|
99
119
|
```
|
|
100
120
|
|
|
121
|
+
`dotenv_config_*` values are normalized to the same option names as `load()`, supporting both snake_case and kebab-case style keys.
|
|
122
|
+
|
|
101
123
|
### Load Environment Variables and pass to non-NodeJS script
|
|
102
124
|
|
|
103
125
|
New in 2.0.0, is a feature inspired by [cross-env](https://www.npmjs.com/package/cross-env) to allow you to load environment variables from your `.env` files and then pass them into a non-NodeJS script such as a shell script. This can simplify the process of maintaining variables used in both your Node app and other scripts. To use this command line executable, you will either need to install globally with the `-g` flag, or install `dotenv-extended` in your project and reference it from your npm scripts.
|
|
104
126
|
|
|
127
|
+
The package exposes two equivalent CLI commands:
|
|
128
|
+
|
|
129
|
+
- `dotenv-extended` (original)
|
|
130
|
+
- `dee` (short alias)
|
|
131
|
+
|
|
105
132
|
Install Globally:
|
|
106
133
|
|
|
107
134
|
```bash
|
|
108
135
|
npm install -g dotenv-extended
|
|
109
136
|
```
|
|
110
137
|
|
|
111
|
-
Now call your shell scripts through `
|
|
138
|
+
Now call your shell scripts through `dee` (this uses the defaults):
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
dee ./myshellscript.sh --whatever-flags-my-script-takes
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Configure `dee` (or `dotenv-extended`) by passing any of the dotenv-extended options before your command. Preceed each option with two dashes `--`:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
dee --path=/path/to/.env --defaults=/path/to/.env.defaults --errorOnMissing=true ./myshellscript.sh --whatever-flags-my-script-takes
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`--path` and `--defaults` also support comma-separated layered files:
|
|
112
151
|
|
|
113
152
|
```bash
|
|
114
|
-
|
|
153
|
+
dee \
|
|
154
|
+
--defaults=./env/.env.defaults.base,./env/.env.defaults.local \
|
|
155
|
+
--path=./env/.env.base,./env/.env.development \
|
|
156
|
+
./myshellscript.sh
|
|
115
157
|
```
|
|
116
158
|
|
|
117
|
-
|
|
159
|
+
You can also print the merged dotenv configuration (without full `process.env`) instead of executing a command:
|
|
118
160
|
|
|
119
161
|
```bash
|
|
120
|
-
|
|
162
|
+
dee --print
|
|
163
|
+
dee --print=dotenv
|
|
121
164
|
```
|
|
122
165
|
|
|
166
|
+
- `--print` outputs JSON
|
|
167
|
+
- `--print=dotenv` outputs `KEY=value` lines
|
|
168
|
+
|
|
123
169
|
The following are the flags you can pass to the `dotenv-extended` cli with their default values. these options detailed later in this document:
|
|
124
170
|
|
|
125
171
|
```bash
|
|
@@ -142,19 +188,23 @@ Defaults are shown below:
|
|
|
142
188
|
|
|
143
189
|
```javascript
|
|
144
190
|
require('dotenv-extended').load({
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
191
|
+
encoding: 'utf8',
|
|
192
|
+
silent: true,
|
|
193
|
+
path: '.env',
|
|
194
|
+
defaults: '.env.defaults',
|
|
195
|
+
schema: '.env.schema',
|
|
196
|
+
schemaExtends: undefined, // string | string[]
|
|
197
|
+
errorOnMissing: false,
|
|
198
|
+
errorOnExtra: false,
|
|
199
|
+
errorOnRegex: false,
|
|
200
|
+
errorOnMissingFiles: false,
|
|
201
|
+
includeProcessEnv: false,
|
|
202
|
+
returnSchemaOnly: false,
|
|
203
|
+
assignToProcessEnv: true,
|
|
204
|
+
overrideProcessEnv: false,
|
|
156
205
|
});
|
|
157
206
|
```
|
|
207
|
+
|
|
158
208
|
### Configure via Environment Variables (New in 2.8.0)
|
|
159
209
|
|
|
160
210
|
You may also set the configuration values via environment variables loaded from `process.env` shown below with defaults:
|
|
@@ -165,14 +215,19 @@ DOTENV_CONFIG_SILENT=true
|
|
|
165
215
|
DOTENV_CONFIG_PATH=.env
|
|
166
216
|
DOTENV_CONFIG_DEFAULTS=.env.defaults
|
|
167
217
|
DOTENV_CONFIG_SCHEMA=.env.schema
|
|
218
|
+
DOTENV_CONFIG_SCHEMA_EXTENDS=
|
|
168
219
|
DOTENV_CONFIG_ERROR_ON_MISSING=false
|
|
169
220
|
DOTENV_CONFIG_ERROR_ON_EXTRA=false
|
|
170
221
|
DOTENV_CONFIG_ERROR_ON_REGEX=false
|
|
222
|
+
DOTENV_CONFIG_ERROR_ON_MISSING_FILES=false
|
|
171
223
|
DOTENV_CONFIG_INCLUDE_PROCESS_ENV=false
|
|
224
|
+
DOTENV_CONFIG_RETURN_SCHEMA_ONLY=false
|
|
172
225
|
DOTENV_CONFIG_ASSIGN_TO_PROCESS_ENV=true
|
|
173
226
|
DOTENV_CONFIG_OVERRIDE_PROCESS_ENV=false
|
|
174
227
|
```
|
|
175
228
|
|
|
229
|
+
`DOTENV_CONFIG_PATH`, `DOTENV_CONFIG_DEFAULTS`, and `DOTENV_CONFIG_SCHEMA_EXTENDS` can each be set to comma-separated file paths for layered loading.
|
|
230
|
+
|
|
176
231
|
The `load()` function always returns an object containing the variables loaded from the `.env` and `.env.defaults` files. By default the returned object does not contain the properties held in `process.env` but rather only the ones that are loaded from the `.env` and `.env.defaults` files.
|
|
177
232
|
|
|
178
233
|
```javascript
|
|
@@ -191,14 +246,41 @@ Sets whether a log message is shown when missing the `.env` or `.env.defaults` f
|
|
|
191
246
|
|
|
192
247
|
The main `.env` file that contains your variables.
|
|
193
248
|
|
|
249
|
+
- Accepts `string` or `string[]` in code.
|
|
250
|
+
- Accepts comma-separated paths via environment variable:
|
|
251
|
+
- `DOTENV_CONFIG_PATH=./.env.base,./.env.dev`
|
|
252
|
+
- Merge order is deterministic:
|
|
253
|
+
- load each `path` entry in order
|
|
254
|
+
- later entries override earlier keys
|
|
255
|
+
|
|
194
256
|
### defaults (_default: .env.defaults_)
|
|
195
257
|
|
|
196
258
|
The file that default values are loaded from.
|
|
197
259
|
|
|
260
|
+
- Accepts `string` or `string[]` in code.
|
|
261
|
+
- Accepts comma-separated paths via environment variable:
|
|
262
|
+
- `DOTENV_CONFIG_DEFAULTS=./.env.defaults.base,./.env.defaults.shared`
|
|
263
|
+
- Merge order is deterministic:
|
|
264
|
+
- load each `defaults` entry in order
|
|
265
|
+
- later entries override earlier keys
|
|
266
|
+
- `path` layers are applied after all `defaults` layers, so `path` still overrides `defaults`
|
|
267
|
+
|
|
198
268
|
### schema (_default: .env.schema_)
|
|
199
269
|
|
|
200
270
|
The file that contains the schema of what values should be available from combining `.env` and `.env.defaults`
|
|
201
271
|
|
|
272
|
+
### schemaExtends (_default: undefined_)
|
|
273
|
+
|
|
274
|
+
Optional schema extension file(s) layered on top of `schema`.
|
|
275
|
+
|
|
276
|
+
- Accepts `string` or `string[]` in code.
|
|
277
|
+
- Accepts comma-separated paths via environment variable:
|
|
278
|
+
- `DOTENV_CONFIG_SCHEMA_EXTENDS=./.env.production.schema,./.env.region.schema`
|
|
279
|
+
- Merge order is deterministic:
|
|
280
|
+
- load base `schema` first
|
|
281
|
+
- then apply `schemaExtends` in order
|
|
282
|
+
- later layers override earlier keys
|
|
283
|
+
|
|
202
284
|
### errorOnMissing (_default: false_)
|
|
203
285
|
|
|
204
286
|
Causes the library to throw a `MISSING CONFIG VALUES` error listing all of the variables missing the combined `.env` and `.env.defaults` files.
|
|
@@ -211,18 +293,51 @@ Causes the library to throw a `EXTRA CONFIG VALUES` error listing all of the ext
|
|
|
211
293
|
|
|
212
294
|
Causes the library to throw a `REGEX MISMATCH` error listing all of the invalid variables from the combined `.env` and `.env.defaults` files. Also a `SyntaxError` is thrown in case `.env.schema` contains a syntactically invalid regex.
|
|
213
295
|
|
|
296
|
+
### errorOnMissingFiles (_default: false_)
|
|
297
|
+
|
|
298
|
+
Causes the library to throw a `MISSING CONFIG FILE` error when configured dotenv files cannot be found. This applies to `path`, `defaults`, and `schema` when they are loaded.
|
|
299
|
+
|
|
214
300
|
### includeProcessEnv (_default: false_)
|
|
215
301
|
|
|
216
302
|
Causes the library add process.env variables to error checking. The variables in process.env overrides the variables in .env and .env.defaults while checking
|
|
217
303
|
|
|
304
|
+
### returnSchemaOnly (_default: false_)
|
|
305
|
+
|
|
306
|
+
Causes the returned object to include only variables present in `.env.schema`. This is useful when using `includeProcessEnv` for validation but you only want schema-defined keys in the final result.
|
|
307
|
+
|
|
218
308
|
### assignToProcessEnv (_default: true_)
|
|
219
309
|
|
|
220
|
-
Sets whether the loaded values are assigned to the `process.env` object. If this is
|
|
310
|
+
Sets whether the loaded values are assigned to the `process.env` object. If this is `false`, values are only available in the returned object from `.load()`.
|
|
221
311
|
|
|
222
312
|
### overrideProcessEnv (_default: false_)
|
|
223
313
|
|
|
224
314
|
By defaut, `dotenv-entended` will not overwrite any varibles that are already set in the `process.env` object. If you would like to enable overwriting any already existing values, set this value to `true`.
|
|
225
315
|
|
|
316
|
+
### Layered File Precedence
|
|
317
|
+
|
|
318
|
+
When using multiple files, merge precedence is:
|
|
319
|
+
|
|
320
|
+
1. `defaults` layers in order (last wins)
|
|
321
|
+
2. `path` layers in order (last wins)
|
|
322
|
+
3. `process.env` values, if `includeProcessEnv` is true and `overrideProcessEnv` is false
|
|
323
|
+
|
|
324
|
+
Example:
|
|
325
|
+
|
|
326
|
+
```javascript
|
|
327
|
+
const config = require('dotenv-extended').load({
|
|
328
|
+
defaults: ['./env/.env.defaults.base', './env/.env.defaults.region'],
|
|
329
|
+
path: ['./env/.env.base', './env/.env.production'],
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Equivalent via environment variables:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
DOTENV_CONFIG_DEFAULTS=./env/.env.defaults.base,./env/.env.defaults.region \
|
|
337
|
+
DOTENV_CONFIG_PATH=./env/.env.base,./env/.env.production \
|
|
338
|
+
node app.js
|
|
339
|
+
```
|
|
340
|
+
|
|
226
341
|
## Examples
|
|
227
342
|
|
|
228
343
|
Consider the following three files:
|
|
@@ -255,18 +370,18 @@ API_KEY=
|
|
|
255
370
|
```javascript
|
|
256
371
|
const myConfig = require('dotenv-extended').load();
|
|
257
372
|
|
|
258
|
-
myConfig.DB_HOST === process.env.DB_HOST ===
|
|
259
|
-
myConfig.DB_USER === process.env.DB_USER ===
|
|
260
|
-
myConfig.DB_PASS === process.env.DB_PASS ===
|
|
261
|
-
myConfig.DB_DATABASE === process.env.DB_DATABASE ===
|
|
262
|
-
myConfig.SHARE_URL === process.env.SHARE_URL ===
|
|
373
|
+
(myConfig.DB_HOST === process.env.DB_HOST) === 'localhost';
|
|
374
|
+
(myConfig.DB_USER === process.env.DB_USER) === 'databaseuser-local';
|
|
375
|
+
(myConfig.DB_PASS === process.env.DB_PASS) === 'localhost';
|
|
376
|
+
(myConfig.DB_DATABASE === process.env.DB_DATABASE) === 'MyAppDB';
|
|
377
|
+
(myConfig.SHARE_URL === process.env.SHARE_URL) === 'http://www.example.com';
|
|
263
378
|
```
|
|
264
379
|
|
|
265
380
|
### Load files with `errorOnMissing`
|
|
266
381
|
|
|
267
382
|
```javascript
|
|
268
383
|
const myConfig = require('dotenv-extended').load({
|
|
269
|
-
errorOnMissing: true
|
|
384
|
+
errorOnMissing: true,
|
|
270
385
|
});
|
|
271
386
|
|
|
272
387
|
// Throws ERROR `MISSING CONFIG VALUES: API_KEY`
|
|
@@ -276,7 +391,7 @@ const myConfig = require('dotenv-extended').load({
|
|
|
276
391
|
|
|
277
392
|
```javascript
|
|
278
393
|
const myConfig = require('dotenv-extended').load({
|
|
279
|
-
errorOnExtra: true
|
|
394
|
+
errorOnExtra: true,
|
|
280
395
|
});
|
|
281
396
|
|
|
282
397
|
// Throws ERROR `EXTRA CONFIG VALUES: SHARE_URL`
|
|
@@ -286,7 +401,7 @@ const myConfig = require('dotenv-extended').load({
|
|
|
286
401
|
|
|
287
402
|
```javascript
|
|
288
403
|
const myConfig = require('dotenv-extended').load({
|
|
289
|
-
errorOnRegex: true
|
|
404
|
+
errorOnRegex: true,
|
|
290
405
|
});
|
|
291
406
|
|
|
292
407
|
// Throws ERROR `REGEX MISMATCH: DB_USER`
|
|
@@ -296,6 +411,18 @@ const myConfig = require('dotenv-extended').load({
|
|
|
296
411
|
|
|
297
412
|
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
298
413
|
|
|
414
|
+
## Migration Notes
|
|
415
|
+
|
|
416
|
+
### Migrating from legacy 2.x tooling
|
|
417
|
+
|
|
418
|
+
- Node `>=20` is now required.
|
|
419
|
+
- Build/test tooling no longer uses `gulp`, Babel, `esm`, or Mocha/NYC.
|
|
420
|
+
- The project now uses:
|
|
421
|
+
- `tsup` for build output in `lib/`
|
|
422
|
+
- `vitest` for tests
|
|
423
|
+
- modern `eslint` config and `prettier`
|
|
424
|
+
- Public API is kept compatible (`load`, `config`, `parse`, CLI behavior, and `dotenv-extended/config` preload entry).
|
|
425
|
+
|
|
299
426
|
## Change Log
|
|
300
427
|
|
|
301
428
|
See [CHANGELOG.md](CHANGELOG.md)
|
package/dotenv-extended.d.ts
CHANGED
|
@@ -27,17 +27,19 @@ export interface IDotenvExtendedOptions {
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Path to the main .env file that contains your variables.
|
|
30
|
+
* Can be a string path or layered string[] where later entries override earlier ones.
|
|
30
31
|
*
|
|
31
32
|
* @default '.env'
|
|
32
33
|
*/
|
|
33
|
-
path?: string;
|
|
34
|
+
path?: string | string[];
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* The path to the file that default values are loaded from.
|
|
38
|
+
* Can be a string path or layered string[] where later entries override earlier ones.
|
|
37
39
|
*
|
|
38
40
|
* @default '.env.defaults'
|
|
39
41
|
*/
|
|
40
|
-
defaults?: string;
|
|
42
|
+
defaults?: string | string[];
|
|
41
43
|
|
|
42
44
|
/**
|
|
43
45
|
* The path to the file that contains the schema of what values should be available
|
|
@@ -47,6 +49,12 @@ export interface IDotenvExtendedOptions {
|
|
|
47
49
|
*/
|
|
48
50
|
schema?: string;
|
|
49
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Optional schema extension path(s). These are layered on top of `schema` in order.
|
|
54
|
+
* Later entries override earlier keys (including base schema keys).
|
|
55
|
+
*/
|
|
56
|
+
schemaExtends?: string | string[];
|
|
57
|
+
|
|
50
58
|
/**
|
|
51
59
|
* Causes the library to throw a MISSING CONFIG VALUES error listing all of the variables
|
|
52
60
|
* missing the combined .env and .env.defaults files.
|
|
@@ -72,17 +80,32 @@ export interface IDotenvExtendedOptions {
|
|
|
72
80
|
errorOnRegex?: boolean;
|
|
73
81
|
|
|
74
82
|
/**
|
|
75
|
-
* Causes the library
|
|
83
|
+
* Causes the library to throw when a configured dotenv file path cannot be found.
|
|
84
|
+
* Applies to `path`, `defaults`, and `schema` when they are loaded.
|
|
85
|
+
*
|
|
86
|
+
* @default false
|
|
87
|
+
*/
|
|
88
|
+
errorOnMissingFiles?: boolean;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Causes the library add process.env variables to error checking. The variables in process.env overrides the
|
|
76
92
|
* variables in .env and .env.defaults while checking
|
|
77
93
|
*
|
|
78
94
|
* @default false
|
|
79
95
|
*/
|
|
80
96
|
includeProcessEnv?: boolean;
|
|
81
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Causes the returned object (and any process assignment) to include only variables present in the schema file.
|
|
100
|
+
* This is useful when `includeProcessEnv` is enabled for validation, but you only want schema-defined keys.
|
|
101
|
+
*
|
|
102
|
+
* @default false
|
|
103
|
+
*/
|
|
104
|
+
returnSchemaOnly?: boolean;
|
|
105
|
+
|
|
82
106
|
/**
|
|
83
107
|
* Sets whether the loaded values are assigned to the process.env object.
|
|
84
|
-
* If this is
|
|
85
|
-
* able to use your variables.
|
|
108
|
+
* If this is false, values are only available from the returned object.
|
|
86
109
|
*
|
|
87
110
|
* @default true
|
|
88
111
|
*/
|