@dotenvx/dotenvx 1.56.0 → 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 CHANGED
@@ -2,14 +2,20 @@
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.56.0...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))
6
12
 
7
13
  ## [1.56.0](https://github.com/dotenvx/dotenvx/compare/v1.55.1...v1.56.0) (2026-03-19)
8
14
 
9
15
  ### Changed
10
16
 
11
- - `ops off` flag — now respected by `get`, `keypair`, `rotate`, and `encrypt` ([#750](https://github.com/dotenvx/dotenvx/pull/750))
12
- - `--pp` alias — added as shorthand for `--pretty-print`; toward sunsetting `-pp` ([#750](https://github.com/dotenvx/dotenvx/pull/750))
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))
13
19
 
14
20
  ### Removed
15
21
 
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.56.0",
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",
@@ -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,23 +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
- logger.success(`✔ key added to .env.keys (${processedEnv.privateKeyName})`)
66
- // logger.help('⮕ optional: [dotenvx ops backup] to securely backup private key')
67
-
68
- if (!isIgnoringDotenvKeys()) {
69
- logger.help('⮕ next run: [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys')
70
- }
71
-
72
- logger.help(`⮕ next run: [${processedEnv.privateKeyName}='${processedEnv.privateKey}' dotenvx run -- yourcommand] to test decryption locally`)
71
+ // intentionally quiet: success line already communicates key creation
73
72
  }
74
73
  }
75
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
  }
@@ -4,7 +4,7 @@ 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()
@@ -60,25 +60,18 @@ function rotate () {
60
60
  }
61
61
 
62
62
  if (changedFilepaths.length > 0) {
63
- 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)
64
70
  } else if (unchangedFilepaths.length > 0) {
65
- logger.info(`no changes (${unchangedFilepaths})`)
71
+ logger.info(`○ no changes (${unchangedFilepaths})`)
66
72
  } else {
67
73
  // do nothing - scenario when no .env files found
68
74
  }
69
-
70
- for (const processedEnv of processedEnvs) {
71
- if (processedEnv.privateKeyAdded) {
72
- logger.success(`✔ key added to .env.keys (${processedEnv.privateKeyName})`)
73
- // logger.help('⮕ optional: [dotenvx ops backup] to securely backup private key')
74
-
75
- if (!isIgnoringDotenvKeys()) {
76
- logger.help('⮕ next run: [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys')
77
- }
78
-
79
- logger.help(`⮕ next run: [${processedEnv.privateKeyName}='${processedEnv.privateKey}' dotenvx get] to test decryption locally`)
80
- }
81
- }
82
75
  } catch (error) {
83
76
  catchAndLog(error)
84
77
  process.exit(1)
@@ -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}`)
@@ -57,26 +57,25 @@ function set (key, value) {
57
57
  }
58
58
  }
59
59
 
60
+ const keyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.privateKeyAdded)
61
+ const keyAddedSuffix = keyAddedEnv ? ` + key (${localDisplayPath(keyAddedEnv.envKeysFilepath)})` : ''
62
+
60
63
  if (changedFilepaths.length > 0) {
61
- 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}`)
62
72
  } else if (unchangedFilepaths.length > 0) {
63
- logger.info(`no changes (${unchangedFilepaths})`)
73
+ logger.info(`○ no changes (${unchangedFilepaths})`)
64
74
  } else {
65
75
  // do nothing
66
76
  }
67
77
 
68
- for (const processedEnv of processedEnvs) {
69
- if (processedEnv.privateKeyAdded) { // TODO: change to localPrivateKeyAdded
70
- logger.success(`✔ key added to ${processedEnv.envKeysFilepath} (${processedEnv.privateKeyName})`)
71
- // logger.help('⮕ optional: [dotenvx ops backup] to securely backup private key')
72
-
73
- if (!isIgnoringDotenvKeys()) {
74
- logger.help('⮕ next run: [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys')
75
- }
76
-
77
- logger.help(`⮕ next run: [${processedEnv.privateKeyName}='${processedEnv.privateKey}' dotenvx get ${key}] to test decryption locally`)
78
- }
79
- }
78
+ // intentionally quiet: success line communicates key creation
80
79
  } catch (error) {
81
80
  catchAndLog(error)
82
81
  process.exit(1)
@@ -108,7 +108,7 @@ program.command('get')
108
108
  const setAction = require('./actions/set')
109
109
  program.command('set')
110
110
  .usage('<KEY> <value> [options]')
111
- .description('set a single environment variable')
111
+ .description('encrypt a single environment variable')
112
112
  .addHelpText('after', examples.set)
113
113
  .allowUnknownOption()
114
114
  .argument('KEY', 'KEY')
@@ -153,6 +153,21 @@ program.command('decrypt')
153
153
  decryptAction.apply(this, args)
154
154
  })
155
155
 
156
+ // dotenvx rotate
157
+ const rotateAction = require('./actions/rotate')
158
+ program.command('rotate')
159
+ .description('rotate keypair(s) and re-encrypt .env file(s)')
160
+ .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', collectEnvs('envFile'), [])
161
+ .option('-fk, --env-keys-file <path>', 'path to your .env.keys file (default: same path as your env file)')
162
+ .option('-k, --key <keys...>', 'keys(s) to encrypt (default: all keys in file)')
163
+ .option('-ek, --exclude-key <excludeKeys...>', 'keys(s) to exclude from encryption (default: none)')
164
+ .option('--ops-off', 'disable dotenvx-ops features', sesh.opsOff())
165
+ .option('--stdout', 'send to stdout')
166
+ .action(function (...args) {
167
+ this.envs = envs
168
+ rotateAction.apply(this, args)
169
+ })
170
+
156
171
  // dotenvx keypair
157
172
  const keypairAction = require('./actions/keypair')
158
173
  program.command('keypair')
@@ -176,21 +191,6 @@ program.command('ls')
176
191
  .option('-ef, --exclude-env-file <excludeFilenames...>', 'path(s) to exclude from your env file(s) (default: none)')
177
192
  .action(lsAction)
178
193
 
179
- // dotenvx rotate
180
- const rotateAction = require('./actions/rotate')
181
- program.command('rotate')
182
- .description('rotate keypair(s) and re-encrypt .env file(s)')
183
- .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', collectEnvs('envFile'), [])
184
- .option('-fk, --env-keys-file <path>', 'path to your .env.keys file (default: same path as your env file)')
185
- .option('-k, --key <keys...>', 'keys(s) to encrypt (default: all keys in file)')
186
- .option('-ek, --exclude-key <excludeKeys...>', 'keys(s) to exclude from encryption (default: none)')
187
- .option('--ops-off', 'disable dotenvx-ops features', sesh.opsOff())
188
- .option('--stdout', 'send to stdout')
189
- .action(function (...args) {
190
- this.envs = envs
191
- rotateAction.apply(this, args)
192
- })
193
-
194
194
  // dotenvx help
195
195
  program.command('help [command]')
196
196
  .description('display help for command')
@@ -252,7 +252,8 @@ program.helpInformation = function () {
252
252
  const filteredLines = lines.filter(line =>
253
253
  !line.includes('DEPRECATED') &&
254
254
  !line.includes('help [command]') &&
255
- !line.includes('🔌 extensions')
255
+ !line.includes('🔌 extensions') &&
256
+ !/^\s*ls\b/.test(line)
256
257
  )
257
258
 
258
259
  return filteredLines.join('\n')
@@ -66,11 +66,11 @@ Examples:
66
66
  $ dotenvx ext gitignore --pattern .env.keys
67
67
  \`\`\`
68
68
 
69
- Try it:
69
+ Try it:
70
70
 
71
71
  \`\`\`
72
72
  $ dotenvx ext gitignore
73
- ignored .env* (.gitignore)
73
+ ignored .env* (.gitignore)
74
74
  \`\`\`
75
75
  `
76
76
  }
@@ -23,20 +23,17 @@ function executeDynamic (program, command, rawArgs) {
23
23
  const result = childProcess.spawnSync(`dotenvx-${command}`, forwardedArgs, { stdio: 'inherit', env })
24
24
  if (result.error) {
25
25
  if (command === 'ops') {
26
- const ops = ` _______________________________________________________________________
27
- | |
28
- | dotenvx-ops: production grade dotenvx–with operational primitives |
29
- | |
30
- | ░▒▓██████▓▒░░▒▓███████▓▒░ ░▒▓███████▓▒░ |
31
- | ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ |
32
- | ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ |
33
- | ░▒▓█▓▒░░▒▓█▓▒░▒▓███████▓▒░ ░▒▓██████▓▒░ |
34
- | ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ |
35
- | ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ |
36
- | ░▒▓██████▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░ |
37
- | |
38
- | Learn more at https://dotenvx.com/ops |
39
- |_______________________________________________________________________|`
26
+ const ops = ` ___________________________________________________________________
27
+ | |
28
+ | ██████╗ ██████╗ ███████╗ |
29
+ | ██╔═══██╗██╔══██╗██╔════╝ |
30
+ | ██║ ██║██████╔╝███████╗ |
31
+ | ██║ ██║██╔═══╝ ╚════██║ |
32
+ | ╚██████╔╝██║ ███████║ |
33
+ | ╚═════╝ ╚═╝ ╚══════╝ |
34
+ | |
35
+ | Learn more at [https://dotenvx.com/ops] |
36
+ |___________________________________________________________________|`
40
37
 
41
38
  console.log(ops)
42
39
  console.log('')
@@ -0,0 +1,11 @@
1
+ const path = require('path')
2
+
3
+ function localDisplayPath (filepath) {
4
+ if (!filepath) return '.env.keys'
5
+ if (!path.isAbsolute(filepath)) return filepath
6
+
7
+ const relative = path.relative(process.cwd(), filepath)
8
+ return relative || path.basename(filepath)
9
+ }
10
+
11
+ module.exports = localDisplayPath
package/src/lib/main.js CHANGED
@@ -17,7 +17,7 @@ const Genexample = require('./services/genexample')
17
17
  const buildEnvs = require('./helpers/buildEnvs')
18
18
  const Parse = require('./helpers/parse')
19
19
  const fsx = require('./helpers/fsx')
20
- const isIgnoringDotenvKeys = require('./helpers/isIgnoringDotenvKeys')
20
+ const localDisplayPath = require('./helpers/localDisplayPath')
21
21
 
22
22
  /** @type {import('./main').config} */
23
23
  const config = function (options = {}) {
@@ -216,26 +216,25 @@ const set = function (key, value, options = {}) {
216
216
  }
217
217
  }
218
218
 
219
+ const keyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.privateKeyAdded)
220
+ const keyAddedSuffix = keyAddedEnv ? ` + key (${localDisplayPath(keyAddedEnv.envKeysFilepath)})` : ''
221
+
219
222
  if (changedFilepaths.length > 0) {
220
- logger.success(`✔ set ${key}${withEncryption} (${changedFilepaths.join(',')})`)
223
+ if (encrypt) {
224
+ logger.success(`◈ encrypted ${key} (${changedFilepaths.join(',')})${keyAddedSuffix}`)
225
+ } else {
226
+ logger.success(`◇ set ${key} (${changedFilepaths.join(',')})`)
227
+ }
228
+ } else if (encrypt && keyAddedEnv) {
229
+ const keyAddedEnvFilepath = keyAddedEnv.envFilepath || changedFilepaths[0] || '.env'
230
+ logger.success(`◈ encrypted ${key} (${keyAddedEnvFilepath})${keyAddedSuffix}`)
221
231
  } else if (unchangedFilepaths.length > 0) {
222
- logger.info(`no changes (${unchangedFilepaths})`)
232
+ logger.info(`○ no changes (${unchangedFilepaths})`)
223
233
  } else {
224
234
  // do nothing
225
235
  }
226
236
 
227
- for (const processedEnv of processedEnvs) {
228
- if (processedEnv.privateKeyAdded) {
229
- logger.success(`✔ key added to ${processedEnv.envKeysFilepath} (${processedEnv.privateKeyName})`)
230
- // logger.help('⮕ optional: [dotenvx ops backup] to securely backup private key')
231
-
232
- if (!isIgnoringDotenvKeys()) {
233
- logger.help('⮕ next run: [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys')
234
- }
235
-
236
- logger.help(`⮕ next run: [${processedEnv.privateKeyName}='${processedEnv.privateKey}' dotenvx get ${key}] to test decryption locally`)
237
- }
238
- }
237
+ // intentionally quiet: success line communicates key creation
239
238
 
240
239
  return {
241
240
  processedEnvs,
@@ -1,6 +1,7 @@
1
1
  const depth = require('../lib/helpers/colorDepth')
2
2
 
3
3
  const colors16 = new Map([
4
+ ['amber', 33],
4
5
  ['blue', 34],
5
6
  ['gray', 37],
6
7
  ['green', 32],
@@ -13,6 +14,7 @@ const colors16 = new Map([
13
14
  ])
14
15
 
15
16
  const colors256 = new Map([
17
+ ['amber', 136],
16
18
  ['blue', 21],
17
19
  ['gray', 244],
18
20
  ['green', 34],
@@ -24,11 +26,19 @@ const colors256 = new Map([
24
26
  ['dodgerblue', 33]
25
27
  ])
26
28
 
29
+ const colorsTrueColor = new Map([
30
+ ['amber', [236, 213, 63]]
31
+ ])
32
+
27
33
  function getColor (color) {
28
34
  const colorDepth = depth.getColorDepth()
29
35
  if (!colors256.has(color)) {
30
36
  throw new Error(`Invalid color ${color}`)
31
37
  }
38
+ if (colorDepth >= 24 && colorsTrueColor.has(color)) {
39
+ const [r, g, b] = colorsTrueColor.get(color)
40
+ return (message) => `\x1b[38;2;${r};${g};${b}m${message}\x1b[39m`
41
+ }
32
42
  if (colorDepth >= 8) {
33
43
  const code = colors256.get(color)
34
44
  return (message) => `\x1b[38;5;${code}m${message}\x1b[39m`
@@ -15,8 +15,9 @@ const levels = {
15
15
 
16
16
  const error = (m) => bold(getColor('red')(m))
17
17
  const warn = getColor('orangered')
18
- const success = getColor('green')
19
- const successv = getColor('olive') // yellow-ish tint that 'looks' like dotenv
18
+ const success = getColor('amber')
19
+ const successv = getColor('amber')
20
+ const info = getColor('gray')
20
21
  const help = getColor('dodgerblue')
21
22
  const verbose = getColor('plum')
22
23
  const debug = getColor('plum')
@@ -58,7 +59,7 @@ function formatMessage (level, message) {
58
59
  return successv(`[${currentName}@${currentVersion}] ${formattedMessage}`)
59
60
  // info
60
61
  case 'info':
61
- return formattedMessage
62
+ return info(formattedMessage)
62
63
  // help
63
64
  case 'help':
64
65
  return help(formattedMessage)