@dotenvx/dotenvx 1.38.4 → 1.39.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/CHANGELOG.md +18 -4
- package/README.md +50 -7
- package/package.json +1 -1
- package/src/cli/commands/ext.js +1 -1
- package/src/cli/dotenvx.js +3 -3
- package/src/lib/config.d.ts +1 -0
- package/src/lib/helpers/conventions.js +12 -3
- package/src/lib/main.d.ts +2 -2
- package/src/lib/services/precommit.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
-
[Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.
|
|
5
|
+
[Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.39.0...main)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
* Add `--convention flow` option to `dotenvx run` ([#551](https://github.com/dotenvx/dotenvx/pull/551))
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
* Fix typos ([#550](https://github.com/dotenvx/dotenvx/pull/550))
|
|
14
|
+
|
|
15
|
+
## [1.38.5](https://github.com/dotenvx/dotenvx/compare/v1.38.4...v1.38.5)
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
* 🐞 Add `config.d.ts` file to fix type error when loading `dotenvx/dotenvx/config` with dynamic import ([#547](https://github.com/dotenvx/dotenvx/pull/547))
|
|
6
20
|
|
|
7
21
|
## [1.38.4](https://github.com/dotenvx/dotenvx/compare/v1.38.3...v1.38.4)
|
|
8
22
|
|
|
@@ -300,7 +314,7 @@ FOO=${FOO}bar
|
|
|
300
314
|
|
|
301
315
|
### Changed
|
|
302
316
|
|
|
303
|
-
* for `--convention nextjs`
|
|
317
|
+
* for `--convention nextjs` ignore `.env.local` for TEST environment ([#425](https://github.com/dotenvx/dotenvx/pull/425))
|
|
304
318
|
* for `precommit` redirect missing `dotenvx` command using POSIX compliant redirection ([#424](https://github.com/dotenvx/dotenvx/pull/424))
|
|
305
319
|
* make parent `dotenvx help` command less noisy by removing `[options]`. run `dotenvx COMMAND -h` to list all available options like always ([#429](https://github.com/dotenvx/dotenvx/pull/429))
|
|
306
320
|
|
|
@@ -841,7 +855,7 @@ Learn more at [https://dotenvx.com/docs/quickstart#add-encryption]
|
|
|
841
855
|
|
|
842
856
|
### Added
|
|
843
857
|
|
|
844
|
-
* Support encryption
|
|
858
|
+
* Support encryption replacement of multiline values ([#220](https://github.com/dotenvx/dotenvx/pull/220))
|
|
845
859
|
|
|
846
860
|
## 0.40.0
|
|
847
861
|
|
|
@@ -894,7 +908,7 @@ Further notes:
|
|
|
894
908
|
|
|
895
909
|
* `DOTENV_PUBLIC_KEY` lives in the `.env` file. You can safely share this with whomever you wish.
|
|
896
910
|
* `DOTENV_PRIVATE_KEY` lives in your `.env.keys` file. Share this only with those you trust to decrypt your secrets.
|
|
897
|
-
* If using encrypted `.env` files like this it is safe to
|
|
911
|
+
* If using encrypted `.env` files like this it is safe to commit them to source code. This makes reviewing PRs that contain secrets much easier.
|
|
898
912
|
* Tell your contributors to contribute a secret using the command `dotenvx set HELLO world --encrypt`.
|
|
899
913
|
* Set your `DOTENV_PRIVATE_KEY` on your server to decrypt these values using `dotenvx run -- yourcommand`
|
|
900
914
|
* You can repeat all this per environment by modifying your set command to `dotenvx set HELLO production -f .env.production --encrypt` (for example)
|
package/README.md
CHANGED
|
@@ -604,7 +604,7 @@ More examples
|
|
|
604
604
|
</details>
|
|
605
605
|
* <details><summary>`--convention` flag</summary><br>
|
|
606
606
|
|
|
607
|
-
Load envs using [Next.js' convention](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order). Set `--convention` to `nextjs`:
|
|
607
|
+
Load envs using [Next.js' convention](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order) or [dotenv-flow convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `nextjs` or `flow`:
|
|
608
608
|
|
|
609
609
|
```sh
|
|
610
610
|
$ echo "HELLO=development local" > .env.development.local
|
|
@@ -741,6 +741,10 @@ More examples
|
|
|
741
741
|
> Become a `dotenvx` power user.
|
|
742
742
|
>
|
|
743
743
|
|
|
744
|
+
### CLI 📟
|
|
745
|
+
|
|
746
|
+
Advanced CLI commands.
|
|
747
|
+
|
|
744
748
|
* <details><summary>`run` - Variable Expansion</summary><br>
|
|
745
749
|
|
|
746
750
|
Reference and expand variables already on your machine for use in your .env file.
|
|
@@ -1025,6 +1029,31 @@ More examples
|
|
|
1025
1029
|
|
|
1026
1030
|
(more conventions available upon request)
|
|
1027
1031
|
|
|
1032
|
+
</details>
|
|
1033
|
+
* <details><summary>`run --convention=flow`</summary><br>
|
|
1034
|
+
|
|
1035
|
+
Load envs using [dotenv-flow's convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `flow`:
|
|
1036
|
+
|
|
1037
|
+
```sh
|
|
1038
|
+
$ echo "HELLO=development local" > .env.development.local
|
|
1039
|
+
$ echo "HELLO=development" > .env.development
|
|
1040
|
+
$ echo "HELLO=local" > .env.local
|
|
1041
|
+
$ echo "HELLO=env" > .env
|
|
1042
|
+
$ echo "console.log('Hello ' + process.env.HELLO)" > index.js
|
|
1043
|
+
|
|
1044
|
+
$ NODE_ENV=development dotenvx run --convention=flow -- node index.js
|
|
1045
|
+
[dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.development, .env.local, .env
|
|
1046
|
+
Hello development local
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
Further, we recommend using `DOTENV_ENV` over `NODE_ENV`– as `dotenvx` works everywhere, not just node.
|
|
1050
|
+
|
|
1051
|
+
```sh
|
|
1052
|
+
$ DOTENV_ENV=development dotenvx run --convention=flow -- node index.js
|
|
1053
|
+
[dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.development, .env.local, .env
|
|
1054
|
+
Hello development local
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1028
1057
|
</details>
|
|
1029
1058
|
* <details><summary>`run -fk`</summary><br>
|
|
1030
1059
|
|
|
@@ -1504,7 +1533,7 @@ More examples
|
|
|
1504
1533
|
</details>
|
|
1505
1534
|
* <details><summary>`decrypt -ek`</summary><br>
|
|
1506
1535
|
|
|
1507
|
-
Decrypt the contents inside an encrypted `.env` file except for an
|
|
1536
|
+
Decrypt the contents inside an encrypted `.env` file except for an excluded key.
|
|
1508
1537
|
|
|
1509
1538
|
```sh
|
|
1510
1539
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
@@ -1602,7 +1631,7 @@ More examples
|
|
|
1602
1631
|
</details>
|
|
1603
1632
|
* <details><summary>`keypair --format shell`</summary><br>
|
|
1604
1633
|
|
|
1605
|
-
Print a shell formatted
|
|
1634
|
+
Print a shell formatted response of public/private keys.
|
|
1606
1635
|
|
|
1607
1636
|
```sh
|
|
1608
1637
|
$ echo "HELLO=World" > .env
|
|
@@ -1753,7 +1782,7 @@ More examples
|
|
|
1753
1782
|
</details>
|
|
1754
1783
|
* <details><summary>`rotate -ek`</summary><br>
|
|
1755
1784
|
|
|
1756
|
-
Rotate the encrypted contents inside an encrypted `.env` file except for an
|
|
1785
|
+
Rotate the encrypted contents inside an encrypted `.env` file except for an excluded key.
|
|
1757
1786
|
|
|
1758
1787
|
```sh
|
|
1759
1788
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
@@ -1875,6 +1904,8 @@ More examples
|
|
|
1875
1904
|
|
|
1876
1905
|
### Extensions 🔌
|
|
1877
1906
|
|
|
1907
|
+
CLI extensions.
|
|
1908
|
+
|
|
1878
1909
|
* <details><summary>`ext genexample`</summary><br>
|
|
1879
1910
|
|
|
1880
1911
|
In one command, generate a `.env.example` file from your current `.env` file contents.
|
|
@@ -2006,7 +2037,9 @@ More examples
|
|
|
2006
2037
|
|
|
2007
2038
|
</details>
|
|
2008
2039
|
|
|
2009
|
-
###
|
|
2040
|
+
### Library 📦
|
|
2041
|
+
|
|
2042
|
+
Use dotenvx directly in code.
|
|
2010
2043
|
|
|
2011
2044
|
* <details><summary>`config()`</summary><br>
|
|
2012
2045
|
|
|
@@ -2204,7 +2237,7 @@ More examples
|
|
|
2204
2237
|
</details>
|
|
2205
2238
|
* <details><summary>`set(KEY, value)`</summary><br>
|
|
2206
2239
|
|
|
2207
|
-
|
|
2240
|
+
Programmatically set an environment variable.
|
|
2208
2241
|
|
|
2209
2242
|
```js
|
|
2210
2243
|
// index.js
|
|
@@ -2215,7 +2248,7 @@ More examples
|
|
|
2215
2248
|
</details>
|
|
2216
2249
|
* <details><summary>`get(KEY)` - <i>Decryption at Access</i></summary><br>
|
|
2217
2250
|
|
|
2218
|
-
|
|
2251
|
+
Programmatically get an environment variable at access/runtime.
|
|
2219
2252
|
|
|
2220
2253
|
```js
|
|
2221
2254
|
// index.js
|
|
@@ -2228,6 +2261,16 @@ More examples
|
|
|
2228
2261
|
|
|
2229
2262
|
</details>
|
|
2230
2263
|
|
|
2264
|
+
## Whitepaper
|
|
2265
|
+
|
|
2266
|
+
> **Dotenvx: Reducing Secrets Risk with Cryptographic Separation**
|
|
2267
|
+
>
|
|
2268
|
+
> Abstract. An ideal secrets solution would not only centralize secrets but also contain the fallout of a breach. While secrets managers offer centralized storage and distribution, their design creates a large blast radius, risking exposure of thousands or even millions of secrets. We propose a solution that reduces the blast radius by splitting secrets management into two distinct components: an encrypted secrets file and a separate decryption key.
|
|
2269
|
+
>
|
|
2270
|
+
> ...
|
|
2271
|
+
>
|
|
2272
|
+
> [Read the whitepaper](https://dotenvx.com/dotenvx.pdf)
|
|
2273
|
+
|
|
2231
2274
|
|
|
2232
2275
|
|
|
2233
2276
|
## Guides
|
package/package.json
CHANGED
package/src/cli/commands/ext.js
CHANGED
|
@@ -61,7 +61,7 @@ ext.command('scan')
|
|
|
61
61
|
.description('scan for leaked secrets')
|
|
62
62
|
.action(require('./../actions/ext/scan'))
|
|
63
63
|
|
|
64
|
-
//
|
|
64
|
+
// override helpInformation to hide dynamic commands
|
|
65
65
|
ext.helpInformation = function () {
|
|
66
66
|
const originalHelp = Command.prototype.helpInformation.call(this)
|
|
67
67
|
const lines = originalHelp.split('\n')
|
package/src/cli/dotenvx.js
CHANGED
|
@@ -60,7 +60,7 @@ program.command('run')
|
|
|
60
60
|
.option('-fv, --env-vault-file <paths...>', 'path(s) to your .env.vault file(s)', collectEnvs('envVaultFile'), [])
|
|
61
61
|
.option('-o, --overload', 'override existing env variables')
|
|
62
62
|
.option('--strict', 'process.exit(1) on any errors', false)
|
|
63
|
-
.option('--convention <name>', 'load a .env convention (available conventions: [\'nextjs\'])')
|
|
63
|
+
.option('--convention <name>', 'load a .env convention (available conventions: [\'nextjs\', \'flow\'])')
|
|
64
64
|
.option('--ignore <errorCodes...>', 'error code(s) to ignore (example: --ignore=MISSING_ENV_FILE)')
|
|
65
65
|
.action(function (...args) {
|
|
66
66
|
this.envs = envs
|
|
@@ -79,7 +79,7 @@ program.command('get')
|
|
|
79
79
|
.option('-fv, --env-vault-file <paths...>', 'path(s) to your .env.vault file(s)', collectEnvs('envVaultFile'), [])
|
|
80
80
|
.option('-o, --overload', 'override existing env variables')
|
|
81
81
|
.option('--strict', 'process.exit(1) on any errors', false)
|
|
82
|
-
.option('--convention <name>', 'load a .env convention (available conventions: [\'nextjs\'])')
|
|
82
|
+
.option('--convention <name>', 'load a .env convention (available conventions: [\'nextjs\', \'flow\'])')
|
|
83
83
|
.option('--ignore <errorCodes...>', 'error code(s) to ignore (example: --ignore=MISSING_ENV_FILE)')
|
|
84
84
|
.option('-a, --all', 'include all machine envs as well')
|
|
85
85
|
.option('-pp, --pretty-print', 'pretty print output')
|
|
@@ -219,7 +219,7 @@ program.command('precommit')
|
|
|
219
219
|
precommitAction.apply(this, args)
|
|
220
220
|
})
|
|
221
221
|
|
|
222
|
-
//
|
|
222
|
+
// override helpInformation to hide DEPRECATED and 'ext' commands
|
|
223
223
|
program.helpInformation = function () {
|
|
224
224
|
const originalHelp = Command.prototype.helpInformation.call(this)
|
|
225
225
|
const lines = originalHelp.split('\n')
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
function conventions (convention) {
|
|
2
|
+
const env = process.env.DOTENV_ENV || process.env.NODE_ENV || 'development'
|
|
3
|
+
|
|
2
4
|
if (convention === 'nextjs') {
|
|
3
|
-
const
|
|
4
|
-
const canonicalEnv = ['development', 'test', 'production'].includes(nodeEnv) && nodeEnv
|
|
5
|
+
const canonicalEnv = ['development', 'test', 'production'].includes(env) && env
|
|
5
6
|
|
|
6
7
|
return [
|
|
7
8
|
canonicalEnv && { type: 'envFile', value: `.env.${canonicalEnv}.local` },
|
|
@@ -9,8 +10,16 @@ function conventions (convention) {
|
|
|
9
10
|
canonicalEnv && { type: 'envFile', value: `.env.${canonicalEnv}` },
|
|
10
11
|
{ type: 'envFile', value: '.env' }
|
|
11
12
|
].filter(Boolean)
|
|
13
|
+
} else if (convention === 'flow') {
|
|
14
|
+
return [
|
|
15
|
+
{ type: 'envFile', value: `.env.${env}.local` },
|
|
16
|
+
{ type: 'envFile', value: `.env.${env}` },
|
|
17
|
+
{ type: 'envFile', value: '.env.local' },
|
|
18
|
+
{ type: 'envFile', value: '.env' },
|
|
19
|
+
{ type: 'envFile', value: '.env.defaults' }
|
|
20
|
+
]
|
|
12
21
|
} else {
|
|
13
|
-
throw new Error(`INVALID_CONVENTION: '${convention}'. permitted conventions: ['nextjs']`)
|
|
22
|
+
throw new Error(`INVALID_CONVENTION: '${convention}'. permitted conventions: ['nextjs', 'flow']`)
|
|
14
23
|
}
|
|
15
24
|
}
|
|
16
25
|
|
package/src/lib/main.d.ts
CHANGED
|
@@ -121,7 +121,7 @@ export interface DotenvConfigOptions {
|
|
|
121
121
|
DOTENV_KEY?: string;
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
* Load a .env convention (available conventions: 'nextjs')
|
|
124
|
+
* Load a .env convention (available conventions: 'nextjs, flow')
|
|
125
125
|
*/
|
|
126
126
|
convention?: string;
|
|
127
127
|
|
|
@@ -191,7 +191,7 @@ export interface SetOptions {
|
|
|
191
191
|
envKeysFile?: string;
|
|
192
192
|
|
|
193
193
|
/**
|
|
194
|
-
* Set a .env convention (available conventions: 'nextjs')
|
|
194
|
+
* Set a .env convention (available conventions: 'nextjs, flow')
|
|
195
195
|
*/
|
|
196
196
|
convention?: string;
|
|
197
197
|
|
|
@@ -46,7 +46,7 @@ class Precommit {
|
|
|
46
46
|
dotenvFiles.forEach(file => {
|
|
47
47
|
count += 1
|
|
48
48
|
|
|
49
|
-
// check if file is going to be
|
|
49
|
+
// check if file is going to be committed
|
|
50
50
|
if (this._isFileToBeCommitted(file)) {
|
|
51
51
|
// check if that file is being ignored
|
|
52
52
|
if (ig.ignores(file)) {
|