@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.
Files changed (71) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/README.md +43 -45
  3. package/package.json +3 -3
  4. package/src/cli/actions/decrypt.js +2 -2
  5. package/src/cli/actions/encrypt.js +10 -14
  6. package/src/cli/actions/ext/genexample.js +3 -2
  7. package/src/cli/actions/ext/gitignore.js +2 -2
  8. package/src/cli/actions/get.js +4 -2
  9. package/src/cli/actions/keypair.js +3 -2
  10. package/src/cli/actions/rotate.js +19 -21
  11. package/src/cli/actions/run.js +1 -14
  12. package/src/cli/actions/set.js +16 -16
  13. package/src/cli/commands/ext.js +0 -3
  14. package/src/cli/dotenvx.js +29 -25
  15. package/src/cli/examples.js +2 -2
  16. package/src/db/session.js +21 -0
  17. package/src/lib/extensions/ops.js +98 -0
  18. package/src/lib/helpers/buildEnvs.js +2 -15
  19. package/src/lib/helpers/{decryptKeyValue.js → cryptography/decryptKeyValue.js} +1 -1
  20. package/src/lib/helpers/cryptography/index.js +14 -0
  21. package/src/lib/helpers/{isPublicKey.js → cryptography/isPublicKey.js} +1 -1
  22. package/src/lib/helpers/{keypair.js → cryptography/localKeypair.js} +2 -2
  23. package/src/lib/helpers/cryptography/mutateKeysSrc.js +38 -0
  24. package/src/lib/helpers/cryptography/mutateSrc.js +24 -0
  25. package/src/lib/helpers/cryptography/opsKeypair.js +14 -0
  26. package/src/lib/helpers/cryptography/provision.js +47 -0
  27. package/src/lib/helpers/cryptography/provisionWithPrivateKey.js +26 -0
  28. package/src/lib/helpers/envResolution/determine.js +46 -0
  29. package/src/lib/helpers/{guessEnvironment.js → envResolution/environment.js} +4 -6
  30. package/src/lib/helpers/envResolution/index.js +8 -0
  31. package/src/lib/helpers/errors.js +13 -0
  32. package/src/lib/helpers/executeDynamic.js +11 -14
  33. package/src/lib/helpers/findEnvFiles.js +1 -1
  34. package/src/lib/helpers/isFullyEncrypted.js +3 -3
  35. package/src/lib/helpers/keyResolution/index.js +13 -0
  36. package/src/lib/helpers/keyResolution/keyNames.js +24 -0
  37. package/src/lib/helpers/keyResolution/keyValues.js +85 -0
  38. package/src/lib/helpers/keyResolution/readFileKey.js +15 -0
  39. package/src/lib/helpers/keyResolution/readProcessKey.js +7 -0
  40. package/src/lib/helpers/localDisplayPath.js +11 -0
  41. package/src/lib/helpers/parse.js +1 -1
  42. package/src/lib/helpers/prependPublicKey.js +17 -0
  43. package/src/lib/helpers/preserveShebang.js +16 -0
  44. package/src/lib/main.d.ts +19 -3
  45. package/src/lib/main.js +23 -32
  46. package/src/lib/services/decrypt.js +23 -19
  47. package/src/lib/services/encrypt.js +41 -136
  48. package/src/lib/services/get.js +3 -3
  49. package/src/lib/services/keypair.js +12 -16
  50. package/src/lib/services/prebuild.js +2 -2
  51. package/src/lib/services/precommit.js +2 -2
  52. package/src/lib/services/rotate.js +59 -42
  53. package/src/lib/services/run.js +29 -112
  54. package/src/lib/services/sets.js +40 -124
  55. package/src/shared/colors.js +10 -0
  56. package/src/shared/logger.js +4 -3
  57. package/src/lib/helpers/decrypt.js +0 -31
  58. package/src/lib/helpers/deprecationNotice.js +0 -17
  59. package/src/lib/helpers/determineEnvs.js +0 -65
  60. package/src/lib/helpers/encrypt.js +0 -29
  61. package/src/lib/helpers/findPrivateKey.js +0 -25
  62. package/src/lib/helpers/findPublicKey.js +0 -15
  63. package/src/lib/helpers/guessPrivateKeyName.js +0 -18
  64. package/src/lib/helpers/guessPublicKeyName.js +0 -18
  65. package/src/lib/helpers/parseEncryptionKeyFromDotenvKey.js +0 -19
  66. package/src/lib/helpers/parseEnvironmentFromDotenvKey.js +0 -19
  67. package/src/lib/helpers/smartDotenvPrivateKey.js +0 -89
  68. package/src/lib/helpers/smartDotenvPublicKey.js +0 -42
  69. package/src/lib/services/ops.js +0 -136
  70. /package/src/lib/helpers/{encryptValue.js → cryptography/encryptValue.js} +0 -0
  71. /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.55.1...main)
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
- encrypted (.env)
635
+ encrypted (.env)
636
636
  ```
637
637
 
638
638
  [![encrypted .env](https://github.com/user-attachments/assets/46dfe1a7-a027-4d80-9207-789eccc325dc)](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
- encrypted (.env)
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
- encrypted (.env.production)
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
- encrypted (apps/app1/.env)
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
- encrypted (.env)
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
- encrypted (.env)
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
- encrypted (.env)
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
- encrypted (.env)
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
- encrypted (.env)
1685
+ encrypted (.env)
1688
1686
  $ dotenvx decrypt
1689
- decrypted (.env)
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
- encrypted (.env.production)
1700
+ encrypted (.env.production)
1703
1701
  $ dotenvx decrypt -f .env.production
1704
- decrypted (.env.production)
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
- encrypted (apps/app1/.env)
1715
+ encrypted (apps/app1/.env)
1718
1716
  $ dotenvx decrypt -fk .env.keys -f apps/app1/.env
1719
- decrypted (apps/app1/.env)
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
- encrypted (.env)
1728
+ encrypted (.env)
1731
1729
  $ dotenvx decrypt -k HELLO
1732
- decrypted (.env)
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
- encrypted (.env)
1738
+ encrypted (.env)
1741
1739
  $ dotenvx decrypt -k "HE*"
1742
- encrypted (.env)
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
- encrypted (.env)
1751
+ encrypted (.env)
1754
1752
  $ dotenvx decrypt -ek HOLA
1755
- decrypted (.env)
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
- encrypted (.env)
1761
+ encrypted (.env)
1764
1762
  $ dotenvx decrypt -ek "HO*"
1765
- encrypted (.env)
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
- encrypted (.env)
1934
+ encrypted (.env)
1937
1935
  $ dotenvx rotate
1938
- rotated (.env)
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
- encrypted (.env.production)
1949
+ encrypted (.env.production)
1952
1950
  $ dotenvx rotate -f .env.production
1953
- rotated (.env.production)
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
- encrypted (apps/app1/.env)
1964
+ encrypted (apps/app1/.env)
1967
1965
  $ dotenvx rotate -fk .env.keys -f apps/app1/.env
1968
- rotated (apps/app1/.env)
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
- encrypted (.env)
1977
+ encrypted (.env)
1980
1978
  $ dotenvx rotate -k HELLO
1981
- rotated (.env)
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
- encrypted (.env)
1987
+ encrypted (.env)
1990
1988
  $ dotenvx rotate -k "HE*"
1991
- rotated (.env)
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
- encrypted (.env)
2000
+ encrypted (.env)
2003
2001
  $ dotenvx rotate -ek HOLA
2004
- rotated (.env)
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
- encrypted (.env)
2010
+ encrypted (.env)
2013
2011
  $ dotenvx rotate -ek "HO*"
2014
- rotated (.env)
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
- updated .env.example (1)
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
- updated .env.example (2)
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
- updated .env.example (1)
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
- ignored .env* (.gitignore)
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
- ignored .env.keys (.gitignore)
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
- logged in [username] to this device and activated token [dxo_6kjPifI…]
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
- logged out [username] from this device and revoked token [dxo_5ZrwRXV…]
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.55.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(`✔ decrypted (${changedFilepaths.join(',')})`)
73
+ logger.success(`◇ decrypted (${changedFilepaths.join(',')})`)
74
74
  } else if (unchangedFilepaths.length > 0) {
75
- logger.info(`no changes (${unchangedFilepaths})`)
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 isIgnoringDotenvKeys = require('../../lib/helpers/isIgnoringDotenvKeys')
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
- logger.success(`✔ encrypted (${changedFilepaths.join(',')})`)
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(`no changes (${unchangedFilepaths})`)
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
- // Ops hook point (first-time key created for this env file):
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(`updated .env.example (${addedKeys.length})`)
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(`✔ ignored ${this.patterns} (${this.filename})`)
37
+ logger.success(`▣ ignored ${this.patterns} (${this.filename})`)
38
38
  } else {
39
- logger.info(`no changes (${this.filename})`)
39
+ logger.info(`○ no changes (${this.filename})`)
40
40
  }
41
41
  }
42
42
  }
@@ -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 { parsed, errors } = new Get(key, envs, options.overload, process.env.DOTENV_KEY, options.all, options.envKeysFile).run()
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 (options.prettyPrint) {
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 (options.prettyPrint) {
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 isIgnoringDotenvKeys = require('../../lib/helpers/isIgnoringDotenvKeys')
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
- console.log('')
24
- console.log(processedEnv.envKeysSrc)
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
- fsx.writeFileX(processedEnv.envKeysFilepath, processedEnv.envKeysSrc)
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
- logger.success(`✔ rotated (${changedFilepaths.join(',')})`)
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(`no changes (${unchangedFilepaths})`)
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)
@@ -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.DOTENV_KEY, process.env, options.envKeysFile, opsOn).run()
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
  }
@@ -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 isIgnoringDotenvKeys = require('../../lib/helpers/isIgnoringDotenvKeys')
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
- logger.success(`✔ set ${key}${withEncryption} (${changedFilepaths.join(',')})`)
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(`no changes (${unchangedFilepaths})`)
73
+ logger.info(`○ no changes (${unchangedFilepaths})`)
63
74
  } else {
64
75
  // do nothing
65
76
  }
66
77
 
67
- for (const processedEnv of processedEnvs) {
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)
@@ -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')