@dotenvx/dotenvx 2.1.1 → 2.1.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/CHANGELOG.md +13 -1
- package/README.md +70 -0
- package/package.json +1 -1
- package/src/lib/helpers/envResolution/determine.js +10 -7
- package/src/lib/transforms/encrypt.js +10 -2
- package/src/lib/transforms/set.js +10 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,19 @@
|
|
|
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/v2.1.
|
|
5
|
+
[Unreleased](https://github.com/dotenvx/dotenvx/compare/v2.1.3...main)
|
|
6
|
+
|
|
7
|
+
## [2.1.3](https://github.com/dotenvx/dotenvx/compare/v2.1.2...v2.1.3) (2026-07-02)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
* Patch edge case when custom unspecified `-f` and `--env` flag ([#868](https://github.com/dotenvx/dotenvx/pull/868))
|
|
12
|
+
|
|
13
|
+
## [2.1.2](https://github.com/dotenvx/dotenvx/compare/v2.1.1...v2.1.2) (2026-07-02)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
* Support restricted read permissions to `.env.keys` ([#676](https://github.com/dotenvx/dotenvx/issues/676), [#867](https://github.com/dotenvx/dotenvx/pull/867))
|
|
6
18
|
|
|
7
19
|
## [2.1.1](https://github.com/dotenvx/dotenvx/compare/v2.1.0...v2.1.1) (2026-07-02)
|
|
8
20
|
|
package/README.md
CHANGED
|
@@ -672,6 +672,13 @@ $ dotenvx run -f .env.production --quiet -- node index.js
|
|
|
672
672
|
Hello production
|
|
673
673
|
```
|
|
674
674
|
|
|
675
|
+
You can also set `DOTENV_CONFIG_QUIET=true`.
|
|
676
|
+
|
|
677
|
+
```sh
|
|
678
|
+
$ DOTENV_CONFIG_QUIET=true dotenvx run -f .env.production -- node index.js
|
|
679
|
+
Hello production
|
|
680
|
+
```
|
|
681
|
+
|
|
675
682
|
</details>
|
|
676
683
|
<details><summary>`--log-level` flag</summary><br>
|
|
677
684
|
|
|
@@ -723,6 +730,22 @@ $ dotenvx encrypt
|
|
|
723
730
|
|
|
724
731
|
> A `DOTENV_PUBLIC_KEY` (encryption key) and a `DOTENV_PRIVATE_KEY` (decryption key) are generated using the same public-key cryptography as [Bitcoin](https://en.bitcoin.it/wiki/Secp256k1).
|
|
725
732
|
|
|
733
|
+
### Protect `.env.keys` from agents
|
|
734
|
+
|
|
735
|
+
After encryption, `DOTENV_PUBLIC_KEY` lives in your encrypted `.env` file. This means agents and automation can keep running `dotenvx set` and `dotenvx encrypt` without reading `.env.keys`.
|
|
736
|
+
|
|
737
|
+
```sh
|
|
738
|
+
$ chmod a-r .env.keys
|
|
739
|
+
|
|
740
|
+
$ dotenvx set HELLO World
|
|
741
|
+
◈ encrypted HELLO (.env)
|
|
742
|
+
|
|
743
|
+
$ dotenvx encrypt
|
|
744
|
+
◈ encrypted (.env)
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
Keep `.env.keys` unreadable by agents, while still letting them safely update encrypted values.
|
|
748
|
+
|
|
726
749
|
More examples
|
|
727
750
|
|
|
728
751
|
<details><summary>`.env`</summary><br>
|
|
@@ -1231,6 +1254,13 @@ $ dotenvx run -f .env.production --quiet -- node index.js
|
|
|
1231
1254
|
Hello production
|
|
1232
1255
|
```
|
|
1233
1256
|
|
|
1257
|
+
You can also set `DOTENV_CONFIG_QUIET=true`.
|
|
1258
|
+
|
|
1259
|
+
```sh
|
|
1260
|
+
$ DOTENV_CONFIG_QUIET=true dotenvx run -f .env.production -- node index.js
|
|
1261
|
+
Hello production
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1234
1264
|
</details>
|
|
1235
1265
|
<details><summary>`run --log-level`</summary><br>
|
|
1236
1266
|
|
|
@@ -1572,6 +1602,8 @@ $ dotenvx set HELLO Dotenvx
|
|
|
1572
1602
|
set HELLO with encryption (.env)
|
|
1573
1603
|
```
|
|
1574
1604
|
|
|
1605
|
+
Works with unreadable `.env.keys` when `.env` already contains `DOTENV_PUBLIC_KEY`.
|
|
1606
|
+
|
|
1575
1607
|
</details>
|
|
1576
1608
|
<details><summary>`set KEY value -f`</summary><br>
|
|
1577
1609
|
|
|
@@ -1646,6 +1678,20 @@ $ dotenvx set HELLO Dotenvx --plain
|
|
|
1646
1678
|
set HELLO (.env)
|
|
1647
1679
|
```
|
|
1648
1680
|
|
|
1681
|
+
</details>
|
|
1682
|
+
<details><summary>`set KEY_PLAIN value`</summary><br>
|
|
1683
|
+
|
|
1684
|
+
Set a plaintext key/value inside an encrypted `.env` file by ending the key with `_PLAIN`.
|
|
1685
|
+
|
|
1686
|
+
```sh
|
|
1687
|
+
$ touch .env
|
|
1688
|
+
|
|
1689
|
+
$ dotenvx set HELLO_PLAIN Dotenvx
|
|
1690
|
+
set HELLO_PLAIN (.env)
|
|
1691
|
+
```
|
|
1692
|
+
|
|
1693
|
+
Keys ending in `_PLAIN` are not encrypted by `dotenvx set` or `dotenvx encrypt`.
|
|
1694
|
+
|
|
1649
1695
|
</details>
|
|
1650
1696
|
<details><summary>`encrypt`</summary><br>
|
|
1651
1697
|
|
|
@@ -1660,6 +1706,8 @@ $ dotenvx encrypt
|
|
|
1660
1706
|
⮕ next run [DOTENV_PRIVATE_KEY='122...0b8' dotenvx run -- yourcommand] to test decryption locally
|
|
1661
1707
|
```
|
|
1662
1708
|
|
|
1709
|
+
Works with unreadable `.env.keys` when `.env` already contains `DOTENV_PUBLIC_KEY`.
|
|
1710
|
+
|
|
1663
1711
|
</details>
|
|
1664
1712
|
<details><summary>`encrypt -f`</summary><br>
|
|
1665
1713
|
|
|
@@ -1755,6 +1803,20 @@ $ dotenvx encrypt -ek "HO*"
|
|
|
1755
1803
|
◈ encrypted (.env)
|
|
1756
1804
|
```
|
|
1757
1805
|
|
|
1806
|
+
</details>
|
|
1807
|
+
<details><summary>`encrypt KEY_PLAIN`</summary><br>
|
|
1808
|
+
|
|
1809
|
+
Skip encryption for keys ending in `_PLAIN`.
|
|
1810
|
+
|
|
1811
|
+
```sh
|
|
1812
|
+
$ echo "HELLO=Dotenvx\nHELLO_PLAIN=visible" > .env
|
|
1813
|
+
|
|
1814
|
+
$ dotenvx encrypt
|
|
1815
|
+
◈ encrypted (.env)
|
|
1816
|
+
```
|
|
1817
|
+
|
|
1818
|
+
`HELLO` is encrypted. `HELLO_PLAIN` stays plaintext.
|
|
1819
|
+
|
|
1758
1820
|
</details>
|
|
1759
1821
|
<details><summary>`encrypt --stdout`</summary><br>
|
|
1760
1822
|
|
|
@@ -2398,6 +2460,14 @@ Error: [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)
|
|
|
2398
2460
|
Hello Dotenvx
|
|
2399
2461
|
```
|
|
2400
2462
|
|
|
2463
|
+
You can also set `DOTENV_CONFIG_QUIET=true`.
|
|
2464
|
+
|
|
2465
|
+
```sh
|
|
2466
|
+
$ DOTENV_CONFIG_QUIET=true node index.js
|
|
2467
|
+
Error: [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)
|
|
2468
|
+
Hello Dotenvx
|
|
2469
|
+
```
|
|
2470
|
+
|
|
2401
2471
|
</details>
|
|
2402
2472
|
<details><summary>`config(strict: true)` - strict</summary><br>
|
|
2403
2473
|
|
package/package.json
CHANGED
|
@@ -17,13 +17,16 @@ function envsFromDotenvPrivateKey (privateKeyNames) {
|
|
|
17
17
|
|
|
18
18
|
function determine (envs = [], processEnv) {
|
|
19
19
|
const privateKeyNames = dotenvPrivateKeyNames(processEnv)
|
|
20
|
-
if (!envs || envs.length <= 0) {
|
|
21
|
-
// if process.env.DOTENV_PRIVATE_KEY or process.env.DOTENV_PRIVATE_KEY_${environment} is set, assume inline encryption methodology
|
|
22
|
-
if (privateKeyNames.length > 0) {
|
|
23
|
-
return envsFromDotenvPrivateKey(privateKeyNames)
|
|
24
|
-
}
|
|
25
20
|
|
|
26
|
-
|
|
21
|
+
// https://github.com/dotenvx/dotenvx/issues/670
|
|
22
|
+
let defaults = DEFAULT_ENVS // default to .env file expectation
|
|
23
|
+
// if process.env.DOTENV_PRIVATE_KEY or process.env.DOTENV_PRIVATE_KEY_${environment} is set, assume inline encryption methodology
|
|
24
|
+
if (privateKeyNames.length > 0) {
|
|
25
|
+
defaults = envsFromDotenvPrivateKey(privateKeyNames)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!envs || envs.length <= 0) {
|
|
29
|
+
return defaults
|
|
27
30
|
} else {
|
|
28
31
|
let fileAlreadySpecified = false
|
|
29
32
|
|
|
@@ -39,7 +42,7 @@ function determine (envs = [], processEnv) {
|
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
// no .env file specified as a flag so default to .env
|
|
42
|
-
return [...
|
|
45
|
+
return [...defaults, ...envs]
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
|
|
@@ -45,8 +45,16 @@ async function encryptTransform (options = {}) {
|
|
|
45
45
|
// set up keysSrc
|
|
46
46
|
let keysSrc
|
|
47
47
|
if (await fsx.exists(fk)) {
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
try {
|
|
49
|
+
const encoding = await detectEncoding(fk)
|
|
50
|
+
keysSrc = await fsx.readFileX(fk, { encoding })
|
|
51
|
+
} catch (err) {
|
|
52
|
+
if (err.code === 'EACCES' || err.code === 'EPERM') {
|
|
53
|
+
// do nothing (scenario: chmod a-r .env.keys)
|
|
54
|
+
} else {
|
|
55
|
+
throw err
|
|
56
|
+
}
|
|
57
|
+
}
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
for (const env of determine(envs, process.env)) {
|
|
@@ -46,8 +46,16 @@ async function setTransform (options = {}) {
|
|
|
46
46
|
// set up keysSrc
|
|
47
47
|
let keysSrc
|
|
48
48
|
if (await fsx.exists(fk)) {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
try {
|
|
50
|
+
const encoding = await detectEncoding(fk)
|
|
51
|
+
keysSrc = await fsx.readFileX(fk, { encoding })
|
|
52
|
+
} catch (err) {
|
|
53
|
+
if (err.code === 'EACCES' || err.code === 'EPERM') {
|
|
54
|
+
// do nothing (scenario: chmod a-r .env.keys)
|
|
55
|
+
} else {
|
|
56
|
+
throw err
|
|
57
|
+
}
|
|
58
|
+
}
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
for (const env of determine(envs, process.env)) {
|