@dotenvx/dotenvx 1.55.1 → 1.57.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 -1
- package/README.md +43 -45
- package/package.json +3 -3
- package/src/cli/actions/decrypt.js +2 -2
- package/src/cli/actions/encrypt.js +10 -14
- package/src/cli/actions/ext/genexample.js +3 -2
- package/src/cli/actions/ext/gitignore.js +2 -2
- package/src/cli/actions/get.js +4 -2
- package/src/cli/actions/keypair.js +3 -2
- package/src/cli/actions/rotate.js +19 -21
- package/src/cli/actions/run.js +1 -14
- package/src/cli/actions/set.js +16 -16
- package/src/cli/commands/ext.js +0 -3
- package/src/cli/dotenvx.js +29 -25
- package/src/cli/examples.js +2 -2
- package/src/db/session.js +21 -0
- package/src/lib/extensions/ops.js +98 -0
- package/src/lib/helpers/buildEnvs.js +2 -15
- package/src/lib/helpers/{decryptKeyValue.js → cryptography/decryptKeyValue.js} +1 -1
- package/src/lib/helpers/cryptography/index.js +14 -0
- package/src/lib/helpers/{isPublicKey.js → cryptography/isPublicKey.js} +1 -1
- package/src/lib/helpers/{keypair.js → cryptography/localKeypair.js} +2 -2
- package/src/lib/helpers/cryptography/mutateKeysSrc.js +38 -0
- package/src/lib/helpers/cryptography/mutateSrc.js +24 -0
- package/src/lib/helpers/cryptography/opsKeypair.js +14 -0
- package/src/lib/helpers/cryptography/provision.js +47 -0
- package/src/lib/helpers/cryptography/provisionWithPrivateKey.js +26 -0
- package/src/lib/helpers/envResolution/determine.js +46 -0
- package/src/lib/helpers/{guessEnvironment.js → envResolution/environment.js} +4 -6
- package/src/lib/helpers/envResolution/index.js +8 -0
- package/src/lib/helpers/errors.js +13 -0
- package/src/lib/helpers/executeDynamic.js +11 -14
- package/src/lib/helpers/findEnvFiles.js +1 -1
- package/src/lib/helpers/isFullyEncrypted.js +3 -3
- package/src/lib/helpers/keyResolution/index.js +13 -0
- package/src/lib/helpers/keyResolution/keyNames.js +24 -0
- package/src/lib/helpers/keyResolution/keyValues.js +85 -0
- package/src/lib/helpers/keyResolution/readFileKey.js +15 -0
- package/src/lib/helpers/keyResolution/readProcessKey.js +7 -0
- package/src/lib/helpers/localDisplayPath.js +11 -0
- package/src/lib/helpers/parse.js +1 -1
- package/src/lib/helpers/prependPublicKey.js +17 -0
- package/src/lib/helpers/preserveShebang.js +16 -0
- package/src/lib/main.d.ts +19 -3
- package/src/lib/main.js +23 -32
- package/src/lib/services/decrypt.js +23 -19
- package/src/lib/services/encrypt.js +41 -136
- package/src/lib/services/get.js +3 -3
- package/src/lib/services/keypair.js +12 -16
- package/src/lib/services/prebuild.js +2 -2
- package/src/lib/services/precommit.js +2 -2
- package/src/lib/services/rotate.js +59 -42
- package/src/lib/services/run.js +29 -112
- package/src/lib/services/sets.js +40 -124
- package/src/shared/colors.js +10 -0
- package/src/shared/logger.js +4 -3
- package/src/lib/helpers/decrypt.js +0 -31
- package/src/lib/helpers/deprecationNotice.js +0 -17
- package/src/lib/helpers/determineEnvs.js +0 -65
- package/src/lib/helpers/encrypt.js +0 -29
- package/src/lib/helpers/findPrivateKey.js +0 -25
- package/src/lib/helpers/findPublicKey.js +0 -15
- package/src/lib/helpers/guessPrivateKeyName.js +0 -18
- package/src/lib/helpers/guessPublicKeyName.js +0 -18
- package/src/lib/helpers/parseEncryptionKeyFromDotenvKey.js +0 -19
- package/src/lib/helpers/parseEnvironmentFromDotenvKey.js +0 -19
- package/src/lib/helpers/smartDotenvPrivateKey.js +0 -89
- package/src/lib/helpers/smartDotenvPublicKey.js +0 -42
- package/src/lib/services/ops.js +0 -136
- /package/src/lib/helpers/{encryptValue.js → cryptography/encryptValue.js} +0 -0
- /package/src/lib/helpers/{isEncrypted.js → cryptography/isEncrypted.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,24 @@
|
|
|
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.57.0...main)
|
|
6
|
+
|
|
7
|
+
## [1.57.0](https://github.com/dotenvx/dotenvx/compare/v1.56.0...v1.57.0) (2026-03-19)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
* color and formatting changes to outputs ([#754](https://github.com/dotenvx/dotenvx/pull/754))
|
|
12
|
+
|
|
13
|
+
## [1.56.0](https://github.com/dotenvx/dotenvx/compare/v1.55.1...v1.56.0) (2026-03-19)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
* `ops off` flag — now respected by `get`, `keypair`, `rotate`, and `encrypt` ([#750](https://github.com/dotenvx/dotenvx/pull/750))
|
|
18
|
+
* `--pp` alias — added as shorthand for `--pretty-print`; toward sunsetting `-pp` ([#750](https://github.com/dotenvx/dotenvx/pull/750))
|
|
19
|
+
|
|
20
|
+
### Removed
|
|
21
|
+
|
|
22
|
+
* Remove support for `.env.vault` files ([#750](https://github.com/dotenvx/dotenvx/pull/750))
|
|
6
23
|
|
|
7
24
|
## [1.55.1](https://github.com/dotenvx/dotenvx/compare/v1.55.0...v1.55.1) (2026-03-13)
|
|
8
25
|
|
package/README.md
CHANGED
|
@@ -632,7 +632,7 @@ Hello development local
|
|
|
632
632
|
|
|
633
633
|
```sh
|
|
634
634
|
$ dotenvx encrypt
|
|
635
|
-
|
|
635
|
+
◈ encrypted (.env)
|
|
636
636
|
```
|
|
637
637
|
|
|
638
638
|
[](https://dotenvx.com)
|
|
@@ -1562,8 +1562,7 @@ Encrypt the contents of a `.env` file to an encrypted `.env` file.
|
|
|
1562
1562
|
$ echo "HELLO=World" > .env
|
|
1563
1563
|
|
|
1564
1564
|
$ dotenvx encrypt
|
|
1565
|
-
|
|
1566
|
-
✔ key added to .env.keys (DOTENV_PRIVATE_KEY)
|
|
1565
|
+
◈ encrypted (.env) + key (.env.keys)
|
|
1567
1566
|
⮕ next run [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys
|
|
1568
1567
|
⮕ next run [DOTENV_PRIVATE_KEY='122...0b8' dotenvx run -- yourcommand] to test decryption locally
|
|
1569
1568
|
```
|
|
@@ -1578,8 +1577,7 @@ $ echo "HELLO=World" > .env
|
|
|
1578
1577
|
$ echo "HELLO=Production" > .env.production
|
|
1579
1578
|
|
|
1580
1579
|
$ dotenvx encrypt -f .env.production
|
|
1581
|
-
|
|
1582
|
-
✔ key added to .env.keys (DOTENV_PRIVATE_KEY_PRODUCTION)
|
|
1580
|
+
◈ encrypted (.env.production) + key (.env.keys)
|
|
1583
1581
|
⮕ next run [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys
|
|
1584
1582
|
⮕ next run [DOTENV_PRIVATE_KEY='bff...bc4' dotenvx run -- yourcommand] to test decryption locally
|
|
1585
1583
|
```
|
|
@@ -1594,7 +1592,7 @@ $ mkdir -p apps/app1
|
|
|
1594
1592
|
$ echo "HELLO=World" > apps/app1/.env
|
|
1595
1593
|
|
|
1596
1594
|
$ dotenvx encrypt -fk .env.keys -f apps/app1/.env
|
|
1597
|
-
|
|
1595
|
+
◈ encrypted (apps/app1/.env)
|
|
1598
1596
|
```
|
|
1599
1597
|
|
|
1600
1598
|
Put it to use.
|
|
@@ -1619,7 +1617,7 @@ Specify the key(s) to encrypt by passing `--key`.
|
|
|
1619
1617
|
$ echo "HELLO=World\nHELLO2=Universe" > .env
|
|
1620
1618
|
|
|
1621
1619
|
$ dotenvx encrypt -k HELLO2
|
|
1622
|
-
|
|
1620
|
+
◈ encrypted (.env)
|
|
1623
1621
|
```
|
|
1624
1622
|
|
|
1625
1623
|
Even specify a glob pattern.
|
|
@@ -1628,7 +1626,7 @@ Even specify a glob pattern.
|
|
|
1628
1626
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
1629
1627
|
|
|
1630
1628
|
$ dotenvx encrypt -k "HE*"
|
|
1631
|
-
|
|
1629
|
+
◈ encrypted (.env)
|
|
1632
1630
|
```
|
|
1633
1631
|
|
|
1634
1632
|
</details>
|
|
@@ -1640,7 +1638,7 @@ Specify the key(s) to NOT encrypt by passing `--exclude-key`.
|
|
|
1640
1638
|
$ echo "HELLO=World\nHELLO2=Universe" > .env
|
|
1641
1639
|
|
|
1642
1640
|
$ dotenvx encrypt -ek HELLO
|
|
1643
|
-
|
|
1641
|
+
◈ encrypted (.env)
|
|
1644
1642
|
```
|
|
1645
1643
|
|
|
1646
1644
|
Even specify a glob pattern.
|
|
@@ -1649,7 +1647,7 @@ Even specify a glob pattern.
|
|
|
1649
1647
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
1650
1648
|
|
|
1651
1649
|
$ dotenvx encrypt -ek "HO*"
|
|
1652
|
-
|
|
1650
|
+
◈ encrypted (.env)
|
|
1653
1651
|
```
|
|
1654
1652
|
|
|
1655
1653
|
</details>
|
|
@@ -1684,9 +1682,9 @@ Decrypt the contents of an encrypted `.env` file to an unencrypted `.env` file.
|
|
|
1684
1682
|
```sh
|
|
1685
1683
|
$ echo "HELLO=World" > .env
|
|
1686
1684
|
$ dotenvx encrypt
|
|
1687
|
-
|
|
1685
|
+
◈ encrypted (.env)
|
|
1688
1686
|
$ dotenvx decrypt
|
|
1689
|
-
|
|
1687
|
+
◇ decrypted (.env)
|
|
1690
1688
|
```
|
|
1691
1689
|
|
|
1692
1690
|
</details>
|
|
@@ -1699,9 +1697,9 @@ $ echo "HELLO=World" > .env
|
|
|
1699
1697
|
$ echo "HELLO=Production" > .env.production
|
|
1700
1698
|
|
|
1701
1699
|
$ dotenvx encrypt -f .env.production
|
|
1702
|
-
|
|
1700
|
+
◈ encrypted (.env.production)
|
|
1703
1701
|
$ dotenvx decrypt -f .env.production
|
|
1704
|
-
|
|
1702
|
+
◇ decrypted (.env.production)
|
|
1705
1703
|
```
|
|
1706
1704
|
|
|
1707
1705
|
</details>
|
|
@@ -1714,9 +1712,9 @@ $ mkdir -p apps/app1
|
|
|
1714
1712
|
$ echo "HELLO=World" > apps/app1/.env
|
|
1715
1713
|
|
|
1716
1714
|
$ dotenvx encrypt -fk .env.keys -f apps/app1/.env
|
|
1717
|
-
|
|
1715
|
+
◈ encrypted (apps/app1/.env)
|
|
1718
1716
|
$ dotenvx decrypt -fk .env.keys -f apps/app1/.env
|
|
1719
|
-
|
|
1717
|
+
◇ decrypted (apps/app1/.env)
|
|
1720
1718
|
```
|
|
1721
1719
|
|
|
1722
1720
|
</details>
|
|
@@ -1727,9 +1725,9 @@ Decrypt the contents of a specified key inside an encrypted `.env` file.
|
|
|
1727
1725
|
```sh
|
|
1728
1726
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
1729
1727
|
$ dotenvx encrypt
|
|
1730
|
-
|
|
1728
|
+
◈ encrypted (.env)
|
|
1731
1729
|
$ dotenvx decrypt -k HELLO
|
|
1732
|
-
|
|
1730
|
+
◇ decrypted (.env)
|
|
1733
1731
|
```
|
|
1734
1732
|
|
|
1735
1733
|
Even specify a glob pattern.
|
|
@@ -1737,9 +1735,9 @@ Even specify a glob pattern.
|
|
|
1737
1735
|
```sh
|
|
1738
1736
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
1739
1737
|
$ dotenvx encrypt
|
|
1740
|
-
|
|
1738
|
+
◈ encrypted (.env)
|
|
1741
1739
|
$ dotenvx decrypt -k "HE*"
|
|
1742
|
-
|
|
1740
|
+
◇ decrypted (.env)
|
|
1743
1741
|
```
|
|
1744
1742
|
|
|
1745
1743
|
</details>
|
|
@@ -1750,9 +1748,9 @@ Decrypt the contents inside an encrypted `.env` file except for an excluded key.
|
|
|
1750
1748
|
```sh
|
|
1751
1749
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
1752
1750
|
$ dotenvx encrypt
|
|
1753
|
-
|
|
1751
|
+
◈ encrypted (.env)
|
|
1754
1752
|
$ dotenvx decrypt -ek HOLA
|
|
1755
|
-
|
|
1753
|
+
◇ decrypted (.env)
|
|
1756
1754
|
```
|
|
1757
1755
|
|
|
1758
1756
|
Even specify a glob pattern.
|
|
@@ -1760,9 +1758,9 @@ Even specify a glob pattern.
|
|
|
1760
1758
|
```sh
|
|
1761
1759
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
1762
1760
|
$ dotenvx encrypt
|
|
1763
|
-
|
|
1761
|
+
◈ encrypted (.env)
|
|
1764
1762
|
$ dotenvx decrypt -ek "HO*"
|
|
1765
|
-
|
|
1763
|
+
◇ decrypted (.env)
|
|
1766
1764
|
```
|
|
1767
1765
|
|
|
1768
1766
|
</details>
|
|
@@ -1933,9 +1931,9 @@ Rotate public/private keys for `.env` file and re-encrypt all encrypted values.
|
|
|
1933
1931
|
```sh
|
|
1934
1932
|
$ echo "HELLO=World" > .env
|
|
1935
1933
|
$ dotenvx encrypt
|
|
1936
|
-
|
|
1934
|
+
◈ encrypted (.env)
|
|
1937
1935
|
$ dotenvx rotate
|
|
1938
|
-
|
|
1936
|
+
⟳ rotated (.env)
|
|
1939
1937
|
```
|
|
1940
1938
|
|
|
1941
1939
|
</details>
|
|
@@ -1948,9 +1946,9 @@ $ echo "HELLO=World" > .env
|
|
|
1948
1946
|
$ echo "HELLO=Production" > .env.production
|
|
1949
1947
|
|
|
1950
1948
|
$ dotenvx encrypt -f .env.production
|
|
1951
|
-
|
|
1949
|
+
◈ encrypted (.env.production)
|
|
1952
1950
|
$ dotenvx rotate -f .env.production
|
|
1953
|
-
|
|
1951
|
+
⟳ rotated (.env.production)
|
|
1954
1952
|
```
|
|
1955
1953
|
|
|
1956
1954
|
</details>
|
|
@@ -1963,9 +1961,9 @@ $ mkdir -p apps/app1
|
|
|
1963
1961
|
$ echo "HELLO=World" > apps/app1/.env
|
|
1964
1962
|
|
|
1965
1963
|
$ dotenvx encrypt -fk .env.keys -f apps/app1/.env
|
|
1966
|
-
|
|
1964
|
+
◈ encrypted (apps/app1/.env)
|
|
1967
1965
|
$ dotenvx rotate -fk .env.keys -f apps/app1/.env
|
|
1968
|
-
|
|
1966
|
+
⟳ rotated (apps/app1/.env)
|
|
1969
1967
|
```
|
|
1970
1968
|
|
|
1971
1969
|
</details>
|
|
@@ -1976,9 +1974,9 @@ Rotate the contents of a specified key inside an encrypted `.env` file.
|
|
|
1976
1974
|
```sh
|
|
1977
1975
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
1978
1976
|
$ dotenvx encrypt
|
|
1979
|
-
|
|
1977
|
+
◈ encrypted (.env)
|
|
1980
1978
|
$ dotenvx rotate -k HELLO
|
|
1981
|
-
|
|
1979
|
+
⟳ rotated (.env)
|
|
1982
1980
|
```
|
|
1983
1981
|
|
|
1984
1982
|
Even specify a glob pattern.
|
|
@@ -1986,9 +1984,9 @@ Even specify a glob pattern.
|
|
|
1986
1984
|
```sh
|
|
1987
1985
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
1988
1986
|
$ dotenvx encrypt
|
|
1989
|
-
|
|
1987
|
+
◈ encrypted (.env)
|
|
1990
1988
|
$ dotenvx rotate -k "HE*"
|
|
1991
|
-
|
|
1989
|
+
⟳ rotated (.env)
|
|
1992
1990
|
```
|
|
1993
1991
|
|
|
1994
1992
|
</details>
|
|
@@ -1999,9 +1997,9 @@ Rotate the encrypted contents inside an encrypted `.env` file except for an excl
|
|
|
1999
1997
|
```sh
|
|
2000
1998
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
2001
1999
|
$ dotenvx encrypt
|
|
2002
|
-
|
|
2000
|
+
◈ encrypted (.env)
|
|
2003
2001
|
$ dotenvx rotate -ek HOLA
|
|
2004
|
-
|
|
2002
|
+
⟳ rotated (.env)
|
|
2005
2003
|
```
|
|
2006
2004
|
|
|
2007
2005
|
Even specify a glob pattern.
|
|
@@ -2009,9 +2007,9 @@ Even specify a glob pattern.
|
|
|
2009
2007
|
```sh
|
|
2010
2008
|
$ echo "HELLO=World\nHOLA=Mundo" > .env
|
|
2011
2009
|
$ dotenvx encrypt
|
|
2012
|
-
|
|
2010
|
+
◈ encrypted (.env)
|
|
2013
2011
|
$ dotenvx rotate -ek "HO*"
|
|
2014
|
-
|
|
2012
|
+
⟳ rotated (.env)
|
|
2015
2013
|
```
|
|
2016
2014
|
|
|
2017
2015
|
</details>
|
|
@@ -2126,7 +2124,7 @@ In one command, generate a `.env.example` file from your current `.env` file con
|
|
|
2126
2124
|
$ echo "HELLO=World" > .env
|
|
2127
2125
|
|
|
2128
2126
|
$ dotenvx ext genexample
|
|
2129
|
-
|
|
2127
|
+
▣ generated (.env.example)
|
|
2130
2128
|
```
|
|
2131
2129
|
|
|
2132
2130
|
```ini
|
|
@@ -2144,7 +2142,7 @@ $ echo "HELLO=World" > .env
|
|
|
2144
2142
|
$ echo "DB_HOST=example.com" > .env.production
|
|
2145
2143
|
|
|
2146
2144
|
$ dotenvx ext genexample -f .env -f .env.production
|
|
2147
|
-
|
|
2145
|
+
▣ generated (.env.example)
|
|
2148
2146
|
```
|
|
2149
2147
|
|
|
2150
2148
|
```ini
|
|
@@ -2164,7 +2162,7 @@ $ mkdir -p apps/backend
|
|
|
2164
2162
|
$ echo "HELLO=Backend" > apps/backend/.env
|
|
2165
2163
|
|
|
2166
2164
|
$ dotenvx ext genexample apps/backend
|
|
2167
|
-
|
|
2165
|
+
▣ generated (.env.example)
|
|
2168
2166
|
```
|
|
2169
2167
|
|
|
2170
2168
|
```ini
|
|
@@ -2179,7 +2177,7 @@ Gitignore your `.env` files.
|
|
|
2179
2177
|
|
|
2180
2178
|
```sh
|
|
2181
2179
|
$ dotenvx ext gitignore
|
|
2182
|
-
|
|
2180
|
+
▣ ignored .env* (.gitignore)
|
|
2183
2181
|
```
|
|
2184
2182
|
|
|
2185
2183
|
</details>
|
|
@@ -2189,7 +2187,7 @@ Gitignore specific pattern(s) of `.env` files.
|
|
|
2189
2187
|
|
|
2190
2188
|
```sh
|
|
2191
2189
|
$ dotenvx ext gitignore --pattern .env.keys
|
|
2192
|
-
|
|
2190
|
+
▣ ignored .env.keys (.gitignore)
|
|
2193
2191
|
```
|
|
2194
2192
|
|
|
2195
2193
|
</details>
|
|
@@ -2623,7 +2621,7 @@ Log in.
|
|
|
2623
2621
|
$ dotenvx-ops login
|
|
2624
2622
|
press Enter to open [https://ops.dotenvx.com/login/device] and enter code [D9C1-03BC]... (Y/n)
|
|
2625
2623
|
⠹ waiting on browser authorization
|
|
2626
|
-
|
|
2624
|
+
◈ logged in [username] to this device and activated token [dxo_6kjPifI…]
|
|
2627
2625
|
```
|
|
2628
2626
|
|
|
2629
2627
|
</details>
|
|
@@ -2633,7 +2631,7 @@ Log out.
|
|
|
2633
2631
|
|
|
2634
2632
|
```sh
|
|
2635
2633
|
$ dotenvx ops logout
|
|
2636
|
-
|
|
2634
|
+
◈ logged out [username] from this device and revoked token [dxo_5ZrwRXV…]
|
|
2637
2635
|
```
|
|
2638
2636
|
|
|
2639
2637
|
</details>
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.57.0",
|
|
3
3
|
"name": "@dotenvx/dotenvx",
|
|
4
4
|
"description": "a secure dotenv–from the creator of `dotenv`",
|
|
5
5
|
"author": "@motdotla",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"scripts": {
|
|
36
36
|
"standard": "standard",
|
|
37
37
|
"standard:fix": "standard --fix",
|
|
38
|
-
"test": "tap run --allow-empty-coverage --disable-coverage --timeout=60000",
|
|
39
|
-
"test-coverage": "tap run --show-full-coverage --timeout=60000",
|
|
38
|
+
"test": "tap run --test-env=DOTENVX_OPS_OFF=true --allow-empty-coverage --disable-coverage --timeout=60000",
|
|
39
|
+
"test-coverage": "tap run --test-env=DOTENVX_OPS_OFF=true --show-full-coverage --timeout=60000",
|
|
40
40
|
"testshell": "bash shellspec",
|
|
41
41
|
"prerelease": "npm test && npm run testshell",
|
|
42
42
|
"release": "standard-version"
|
|
@@ -70,9 +70,9 @@ function decrypt () {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
if (changedFilepaths.length > 0) {
|
|
73
|
-
logger.success(
|
|
73
|
+
logger.success(`◇ decrypted (${changedFilepaths.join(',')})`)
|
|
74
74
|
} else if (unchangedFilepaths.length > 0) {
|
|
75
|
-
logger.info(
|
|
75
|
+
logger.info(`○ no changes (${unchangedFilepaths})`)
|
|
76
76
|
} else {
|
|
77
77
|
// do nothing - scenario when no .env files found
|
|
78
78
|
}
|
|
@@ -4,7 +4,7 @@ const { logger } = require('./../../shared/logger')
|
|
|
4
4
|
const Encrypt = require('./../../lib/services/encrypt')
|
|
5
5
|
|
|
6
6
|
const catchAndLog = require('../../lib/helpers/catchAndLog')
|
|
7
|
-
const
|
|
7
|
+
const localDisplayPath = require('../../lib/helpers/localDisplayPath')
|
|
8
8
|
|
|
9
9
|
function encrypt () {
|
|
10
10
|
const options = this.opts()
|
|
@@ -53,26 +53,22 @@ function encrypt () {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
if (changedFilepaths.length > 0) {
|
|
56
|
-
|
|
56
|
+
const keyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.privateKeyAdded)
|
|
57
|
+
let msg = `◈ encrypted (${changedFilepaths.join(',')})`
|
|
58
|
+
if (keyAddedEnv) {
|
|
59
|
+
const envKeysFilepath = localDisplayPath(keyAddedEnv.envKeysFilepath)
|
|
60
|
+
msg += ` + key (${envKeysFilepath})`
|
|
61
|
+
}
|
|
62
|
+
logger.success(msg)
|
|
57
63
|
} else if (unchangedFilepaths.length > 0) {
|
|
58
|
-
logger.info(
|
|
64
|
+
logger.info(`○ no changes (${unchangedFilepaths})`)
|
|
59
65
|
} else {
|
|
60
66
|
// do nothing - scenario when no .env files found
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
for (const processedEnv of processedEnvs) {
|
|
64
70
|
if (processedEnv.privateKeyAdded) {
|
|
65
|
-
//
|
|
66
|
-
// gate with `opsOn` and an Ops-installed check before calling your
|
|
67
|
-
// Ops service (for example: backup/register processedEnv.privateKey).
|
|
68
|
-
logger.success(`✔ key added to .env.keys (${processedEnv.privateKeyName})`)
|
|
69
|
-
// logger.help('⮕ optional: [dotenvx ops backup] to securely backup private key')
|
|
70
|
-
|
|
71
|
-
if (!isIgnoringDotenvKeys()) {
|
|
72
|
-
logger.help('⮕ next run: [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys')
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
logger.help(`⮕ next run: [${processedEnv.privateKeyName}='${processedEnv.privateKey}' dotenvx run -- yourcommand] to test decryption locally`)
|
|
71
|
+
// intentionally quiet: success line already communicates key creation
|
|
76
72
|
}
|
|
77
73
|
}
|
|
78
74
|
} catch (error) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const fsx = require('./../../../lib/helpers/fsx')
|
|
2
|
+
const path = require('path')
|
|
2
3
|
const main = require('./../../../lib/main')
|
|
3
4
|
const { logger } = require('./../../../shared/logger')
|
|
4
5
|
|
|
@@ -21,9 +22,9 @@ function genexample (directory) {
|
|
|
21
22
|
fsx.writeFileX(exampleFilepath, envExampleFile)
|
|
22
23
|
|
|
23
24
|
if (addedKeys.length > 0) {
|
|
24
|
-
logger.success(
|
|
25
|
+
logger.success(`▣ generated (${path.basename(exampleFilepath)})`)
|
|
25
26
|
} else {
|
|
26
|
-
logger.info('no changes (.env.example)')
|
|
27
|
+
logger.info('○ no changes (.env.example)')
|
|
27
28
|
}
|
|
28
29
|
} catch (error) {
|
|
29
30
|
logger.error(error.message)
|
|
@@ -34,9 +34,9 @@ class Generic {
|
|
|
34
34
|
})
|
|
35
35
|
|
|
36
36
|
if (changedPatterns.length > 0) {
|
|
37
|
-
logger.success(
|
|
37
|
+
logger.success(`▣ ignored ${this.patterns} (${this.filename})`)
|
|
38
38
|
} else {
|
|
39
|
-
logger.info(
|
|
39
|
+
logger.info(`○ no changes (${this.filename})`)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/cli/actions/get.js
CHANGED
|
@@ -12,6 +12,7 @@ function get (key) {
|
|
|
12
12
|
|
|
13
13
|
const options = this.opts()
|
|
14
14
|
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
15
|
+
const prettyPrint = options.prettyPrint || options.pp
|
|
15
16
|
|
|
16
17
|
const ignore = options.ignore || []
|
|
17
18
|
|
|
@@ -24,7 +25,8 @@ function get (key) {
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
try {
|
|
27
|
-
const
|
|
28
|
+
const opsOn = options.opsOff !== true
|
|
29
|
+
const { parsed, errors } = new Get(key, envs, options.overload, options.all, options.envKeysFile, opsOn).run()
|
|
28
30
|
|
|
29
31
|
for (const error of errors || []) {
|
|
30
32
|
if (options.strict) throw error // throw immediately if strict
|
|
@@ -65,7 +67,7 @@ function get (key) {
|
|
|
65
67
|
console.log(inline)
|
|
66
68
|
} else {
|
|
67
69
|
let space = 0
|
|
68
|
-
if (
|
|
70
|
+
if (prettyPrint) {
|
|
69
71
|
space = 2
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -9,8 +9,9 @@ function keypair (key) {
|
|
|
9
9
|
|
|
10
10
|
const options = this.opts()
|
|
11
11
|
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
12
|
+
const prettyPrint = options.prettyPrint || options.pp
|
|
12
13
|
|
|
13
|
-
const results = main.keypair(options.envFile, key, options.envKeysFile)
|
|
14
|
+
const results = main.keypair(options.envFile, key, options.envKeysFile, options.opsOff)
|
|
14
15
|
|
|
15
16
|
if (typeof results === 'object' && results !== null) {
|
|
16
17
|
// inline shell format - env $(dotenvx keypair --format=shell) your-command
|
|
@@ -25,7 +26,7 @@ function keypair (key) {
|
|
|
25
26
|
// json format
|
|
26
27
|
} else {
|
|
27
28
|
let space = 0
|
|
28
|
-
if (
|
|
29
|
+
if (prettyPrint) {
|
|
29
30
|
space = 2
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -4,24 +4,27 @@ const { logger } = require('./../../shared/logger')
|
|
|
4
4
|
const Rotate = require('./../../lib/services/rotate')
|
|
5
5
|
|
|
6
6
|
const catchAndLog = require('../../lib/helpers/catchAndLog')
|
|
7
|
-
const
|
|
7
|
+
const localDisplayPath = require('../../lib/helpers/localDisplayPath')
|
|
8
8
|
|
|
9
9
|
function rotate () {
|
|
10
10
|
const options = this.opts()
|
|
11
11
|
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
12
12
|
|
|
13
13
|
const envs = this.envs
|
|
14
|
+
const opsOn = options.opsOff !== true
|
|
14
15
|
|
|
15
16
|
// stdout - should not have a try so that exit codes can surface to stdout
|
|
16
17
|
if (options.stdout) {
|
|
17
18
|
const {
|
|
18
19
|
processedEnvs
|
|
19
|
-
} = new Rotate(envs, options.key, options.excludeKey, options.envKeysFile).run()
|
|
20
|
+
} = new Rotate(envs, options.key, options.excludeKey, options.envKeysFile, opsOn).run()
|
|
20
21
|
|
|
21
22
|
for (const processedEnv of processedEnvs) {
|
|
22
23
|
console.log(processedEnv.envSrc)
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
if (processedEnv.privateKeyAdded) {
|
|
25
|
+
console.log('')
|
|
26
|
+
console.log(processedEnv.envKeysSrc)
|
|
27
|
+
}
|
|
25
28
|
}
|
|
26
29
|
process.exit(0) // exit early
|
|
27
30
|
} else {
|
|
@@ -30,7 +33,7 @@ function rotate () {
|
|
|
30
33
|
processedEnvs,
|
|
31
34
|
changedFilepaths,
|
|
32
35
|
unchangedFilepaths
|
|
33
|
-
} = new Rotate(envs, options.key, options.excludeKey, options.envKeysFile).run()
|
|
36
|
+
} = new Rotate(envs, options.key, options.excludeKey, options.envKeysFile, opsOn).run()
|
|
34
37
|
|
|
35
38
|
for (const processedEnv of processedEnvs) {
|
|
36
39
|
logger.verbose(`rotating ${processedEnv.envFilepath} (${processedEnv.filepath})`)
|
|
@@ -46,7 +49,9 @@ function rotate () {
|
|
|
46
49
|
}
|
|
47
50
|
} else if (processedEnv.changed) {
|
|
48
51
|
fsx.writeFileX(processedEnv.filepath, processedEnv.envSrc)
|
|
49
|
-
|
|
52
|
+
if (processedEnv.privateKeyAdded) {
|
|
53
|
+
fsx.writeFileX(processedEnv.envKeysFilepath, processedEnv.envKeysSrc)
|
|
54
|
+
}
|
|
50
55
|
|
|
51
56
|
logger.verbose(`rotated ${processedEnv.envFilepath} (${processedEnv.filepath})`)
|
|
52
57
|
} else {
|
|
@@ -55,25 +60,18 @@ function rotate () {
|
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
if (changedFilepaths.length > 0) {
|
|
58
|
-
|
|
63
|
+
const keyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.privateKeyAdded)
|
|
64
|
+
let msg = `⟳ rotated (${changedFilepaths.join(',')})`
|
|
65
|
+
if (keyAddedEnv) {
|
|
66
|
+
const envKeysFilepath = localDisplayPath(keyAddedEnv.envKeysFilepath)
|
|
67
|
+
msg += ` + key (${envKeysFilepath})`
|
|
68
|
+
}
|
|
69
|
+
logger.success(msg)
|
|
59
70
|
} else if (unchangedFilepaths.length > 0) {
|
|
60
|
-
logger.info(
|
|
71
|
+
logger.info(`○ no changes (${unchangedFilepaths})`)
|
|
61
72
|
} else {
|
|
62
73
|
// do nothing - scenario when no .env files found
|
|
63
74
|
}
|
|
64
|
-
|
|
65
|
-
for (const processedEnv of processedEnvs) {
|
|
66
|
-
if (processedEnv.privateKeyAdded) {
|
|
67
|
-
logger.success(`✔ key added to .env.keys (${processedEnv.privateKeyName})`)
|
|
68
|
-
// logger.help('⮕ optional: [dotenvx ops backup] to securely backup private key')
|
|
69
|
-
|
|
70
|
-
if (!isIgnoringDotenvKeys()) {
|
|
71
|
-
logger.help('⮕ next run: [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys')
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
logger.help(`⮕ next run: [${processedEnv.privateKeyName}='${processedEnv.privateKey}' dotenvx get] to test decryption locally`)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
75
|
} catch (error) {
|
|
78
76
|
catchAndLog(error)
|
|
79
77
|
process.exit(1)
|
package/src/cli/actions/run.js
CHANGED
|
@@ -5,7 +5,6 @@ const executeCommand = require('./../../lib/helpers/executeCommand')
|
|
|
5
5
|
const Run = require('./../../lib/services/run')
|
|
6
6
|
|
|
7
7
|
const conventions = require('./../../lib/helpers/conventions')
|
|
8
|
-
const DeprecationNotice = require('./../../lib/helpers/deprecationNotice')
|
|
9
8
|
|
|
10
9
|
async function run () {
|
|
11
10
|
const commandArgs = this.args
|
|
@@ -41,26 +40,14 @@ async function run () {
|
|
|
41
40
|
envs = this.envs
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
new DeprecationNotice().dotenvKey() // DEPRECATION NOTICE
|
|
45
|
-
|
|
46
43
|
const {
|
|
47
44
|
processedEnvs,
|
|
48
45
|
readableStrings,
|
|
49
46
|
readableFilepaths,
|
|
50
47
|
uniqueInjectedKeys
|
|
51
|
-
} = new Run(envs, options.overload, process.env
|
|
52
|
-
|
|
53
|
-
if (opsOn) {
|
|
54
|
-
// removed radar feature for now. contact me at mot@dotenvx.com if still needed for your organization.
|
|
55
|
-
// try { new Ops().observe({ beforeEnv, processedEnvs, afterEnv }) } catch {}
|
|
56
|
-
}
|
|
48
|
+
} = new Run(envs, options.overload, process.env, options.envKeysFile, opsOn).run()
|
|
57
49
|
|
|
58
50
|
for (const processedEnv of processedEnvs) {
|
|
59
|
-
if (processedEnv.type === 'envVaultFile') {
|
|
60
|
-
logger.verbose(`loading env from encrypted ${processedEnv.filepath} (${path.resolve(processedEnv.filepath)})`)
|
|
61
|
-
logger.debug(`decrypting encrypted env from ${processedEnv.filepath} (${path.resolve(processedEnv.filepath)})`)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
51
|
if (processedEnv.type === 'envFile') {
|
|
65
52
|
logger.verbose(`loading env from ${processedEnv.filepath} (${path.resolve(processedEnv.filepath)})`)
|
|
66
53
|
}
|
package/src/cli/actions/set.js
CHANGED
|
@@ -4,7 +4,7 @@ const { logger } = require('./../../shared/logger')
|
|
|
4
4
|
const Sets = require('./../../lib/services/sets')
|
|
5
5
|
|
|
6
6
|
const catchAndLog = require('../../lib/helpers/catchAndLog')
|
|
7
|
-
const
|
|
7
|
+
const localDisplayPath = require('../../lib/helpers/localDisplayPath')
|
|
8
8
|
|
|
9
9
|
function set (key, value) {
|
|
10
10
|
logger.debug(`key: ${key}`)
|
|
@@ -22,12 +22,13 @@ function set (key, value) {
|
|
|
22
22
|
try {
|
|
23
23
|
const envs = this.envs
|
|
24
24
|
const envKeysFilepath = options.envKeysFile
|
|
25
|
+
const opsOn = options.opsOff !== true
|
|
25
26
|
|
|
26
27
|
const {
|
|
27
28
|
processedEnvs,
|
|
28
29
|
changedFilepaths,
|
|
29
30
|
unchangedFilepaths
|
|
30
|
-
} = new Sets(key, value, envs, encrypt, envKeysFilepath).run()
|
|
31
|
+
} = new Sets(key, value, envs, encrypt, envKeysFilepath, opsOn).run()
|
|
31
32
|
|
|
32
33
|
let withEncryption = ''
|
|
33
34
|
|
|
@@ -56,26 +57,25 @@ function set (key, value) {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
const keyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.privateKeyAdded)
|
|
61
|
+
const keyAddedSuffix = keyAddedEnv ? ` + key (${localDisplayPath(keyAddedEnv.envKeysFilepath)})` : ''
|
|
62
|
+
|
|
59
63
|
if (changedFilepaths.length > 0) {
|
|
60
|
-
|
|
64
|
+
if (encrypt) {
|
|
65
|
+
logger.success(`◈ encrypted ${key} (${changedFilepaths.join(',')})${keyAddedSuffix}`)
|
|
66
|
+
} else {
|
|
67
|
+
logger.success(`◇ set ${key} (${changedFilepaths.join(',')})`)
|
|
68
|
+
}
|
|
69
|
+
} else if (encrypt && keyAddedEnv) {
|
|
70
|
+
const keyAddedEnvFilepath = keyAddedEnv.envFilepath || changedFilepaths[0] || '.env'
|
|
71
|
+
logger.success(`◈ encrypted ${key} (${keyAddedEnvFilepath})${keyAddedSuffix}`)
|
|
61
72
|
} else if (unchangedFilepaths.length > 0) {
|
|
62
|
-
logger.info(
|
|
73
|
+
logger.info(`○ no changes (${unchangedFilepaths})`)
|
|
63
74
|
} else {
|
|
64
75
|
// do nothing
|
|
65
76
|
}
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
if (processedEnv.privateKeyAdded) {
|
|
69
|
-
logger.success(`✔ key added to ${processedEnv.envKeysFilepath} (${processedEnv.privateKeyName})`)
|
|
70
|
-
// logger.help('⮕ optional: [dotenvx ops backup] to securely backup private key')
|
|
71
|
-
|
|
72
|
-
if (!isIgnoringDotenvKeys()) {
|
|
73
|
-
logger.help('⮕ next run: [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys')
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
logger.help(`⮕ next run: [${processedEnv.privateKeyName}='${processedEnv.privateKey}' dotenvx get ${key}] to test decryption locally`)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
78
|
+
// intentionally quiet: success line communicates key creation
|
|
79
79
|
} catch (error) {
|
|
80
80
|
catchAndLog(error)
|
|
81
81
|
process.exit(1)
|
package/src/cli/commands/ext.js
CHANGED
|
@@ -10,9 +10,6 @@ ext
|
|
|
10
10
|
.description('🔌 extensions')
|
|
11
11
|
.allowUnknownOption()
|
|
12
12
|
|
|
13
|
-
// list known extensions here you want to display
|
|
14
|
-
ext.addHelpText('after', ' vault 🔐 manage .env.vault files')
|
|
15
|
-
|
|
16
13
|
ext
|
|
17
14
|
.argument('[command]', 'dynamic ext command')
|
|
18
15
|
.argument('[args...]', 'dynamic ext command arguments')
|