@dotenvx/dotenvx 1.75.0 → 2.0.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 (89) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/README.md +4 -114
  3. package/package.json +8 -7
  4. package/src/cli/actions/decrypt.js +35 -17
  5. package/src/cli/actions/doctor.js +2 -2
  6. package/src/cli/actions/encrypt.js +64 -85
  7. package/src/cli/actions/ext/genexample.js +2 -2
  8. package/src/cli/actions/get.js +16 -7
  9. package/src/cli/actions/keypair.js +55 -42
  10. package/src/cli/actions/login.js +4 -3
  11. package/src/cli/actions/normalizeArmorAliases.js +9 -0
  12. package/src/cli/actions/run.js +65 -22
  13. package/src/cli/actions/set.js +51 -37
  14. package/src/cli/dotenvx.js +6 -21
  15. package/src/lib/api/{postKeypair.js → postArmorKeyring.js} +4 -14
  16. package/src/lib/{helpers/envResolution → conventions}/environment.js +1 -1
  17. package/src/lib/conventions/filepaths.js +9 -0
  18. package/src/lib/conventions/keynames.js +38 -0
  19. package/src/lib/helpers/catchAndLog.js +4 -1
  20. package/src/lib/helpers/cryptography/index.js +1 -12
  21. package/src/lib/helpers/cryptography/mutateKeysSrc.js +5 -21
  22. package/src/lib/helpers/envResolution/index.js +1 -1
  23. package/src/lib/helpers/errors.js +13 -0
  24. package/src/lib/helpers/executeDynamic.js +1 -3
  25. package/src/lib/helpers/keypairMetadata.js +3 -3
  26. package/src/lib/helpers/readEnvKey.js +4 -3
  27. package/src/lib/main.d.ts +2 -39
  28. package/src/lib/main.js +82 -45
  29. package/src/lib/providers/armor/index.js +29 -0
  30. package/src/lib/providers/index.js +46 -0
  31. package/src/lib/providers/worker.js +6 -0
  32. package/src/lib/resolvers/envs.js +302 -0
  33. package/src/lib/resolvers/get.js +69 -0
  34. package/src/lib/resolvers/keypair.js +81 -0
  35. package/src/lib/resolvers/ls.js +41 -0
  36. package/src/lib/services/armorDown.js +2 -2
  37. package/src/lib/services/{armorKeypair.js → armorKeyring.js} +14 -51
  38. package/src/lib/services/armorMove.js +2 -2
  39. package/src/lib/services/armorPull.js +2 -2
  40. package/src/lib/services/armorPush.js +2 -2
  41. package/src/lib/services/armorUp.js +2 -2
  42. package/src/lib/services/genexample.js +19 -8
  43. package/src/lib/services/login.js +25 -0
  44. package/src/lib/services/prebuild.js +11 -5
  45. package/src/lib/services/precommit.js +11 -5
  46. package/src/lib/transforms/decrypt.js +83 -0
  47. package/src/lib/transforms/encrypt.js +179 -0
  48. package/src/lib/transforms/set.js +179 -0
  49. package/src/shared/logger.js +5 -0
  50. package/src/cli/actions/normalizeArmorOptions.js +0 -10
  51. package/src/cli/actions/rotate.js +0 -87
  52. package/src/lib/helpers/append.js +0 -61
  53. package/src/lib/helpers/cryptography/armorKeypair.js +0 -42
  54. package/src/lib/helpers/cryptography/armorKeypairSync.js +0 -55
  55. package/src/lib/helpers/cryptography/encryptValue.js +0 -7
  56. package/src/lib/helpers/cryptography/localKeypair.js +0 -14
  57. package/src/lib/helpers/cryptography/mutateKeysSrcSync.js +0 -38
  58. package/src/lib/helpers/cryptography/provision.js +0 -56
  59. package/src/lib/helpers/cryptography/provisionSync.js +0 -51
  60. package/src/lib/helpers/cryptography/provisionWithPrivateKey.js +0 -26
  61. package/src/lib/helpers/dotenvParse.js +0 -55
  62. package/src/lib/helpers/escapeDollarSigns.js +0 -5
  63. package/src/lib/helpers/escapeForRegex.js +0 -5
  64. package/src/lib/helpers/evalKeyValue.js +0 -23
  65. package/src/lib/helpers/isFullyEncrypted.js +0 -27
  66. package/src/lib/helpers/isIgnoringDotenvKeys.js +0 -19
  67. package/src/lib/helpers/keyResolution/index.js +0 -16
  68. package/src/lib/helpers/keyResolution/keyNamesForEnvFile.js +0 -24
  69. package/src/lib/helpers/keyResolution/keyValues.js +0 -99
  70. package/src/lib/helpers/keyResolution/keyValuesFromEnvSrc.js +0 -80
  71. package/src/lib/helpers/keyResolution/keyValuesSync.js +0 -103
  72. package/src/lib/helpers/keyResolution/readFileKey.js +0 -17
  73. package/src/lib/helpers/keyResolution/readFileKeySync.js +0 -15
  74. package/src/lib/helpers/keyResolution/readProcessKey.js +0 -7
  75. package/src/lib/helpers/localDisplayPath.js +0 -11
  76. package/src/lib/helpers/parse.js +0 -214
  77. package/src/lib/helpers/pluralize.js +0 -10
  78. package/src/lib/helpers/quotes.js +0 -36
  79. package/src/lib/helpers/replace.js +0 -82
  80. package/src/lib/helpers/resolveEscapeSequences.js +0 -5
  81. package/src/lib/services/decrypt.js +0 -157
  82. package/src/lib/services/encrypt.js +0 -214
  83. package/src/lib/services/get.js +0 -76
  84. package/src/lib/services/keypair.js +0 -60
  85. package/src/lib/services/loginPoll.js +0 -36
  86. package/src/lib/services/ls.js +0 -57
  87. package/src/lib/services/rotate.js +0 -198
  88. package/src/lib/services/run.js +0 -255
  89. package/src/lib/services/sets.js +0 -326
package/CHANGELOG.md CHANGED
@@ -2,7 +2,40 @@
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.75.0...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx/compare/v2.0.0...main)
6
+
7
+ ## [2.0.0](https://github.com/dotenvx/dotenvx/compare/v1.76.0...v2.0.0) (2026-06-30)
8
+
9
+ ### Changed
10
+
11
+ * BREAKING: lib/main#`set` async only ([#855](https://github.com/dotenvx/dotenvx/pull/855))
12
+ * BREAKING: lib/main#`get` async only ([#855](https://github.com/dotenvx/dotenvx/pull/855))
13
+ * New keyring support - for local and armor providers and to unlock future providers ([#855](https://github.com/dotenvx/dotenvx/pull/855))
14
+ * Route `run`, `config`, and `get` through shared env and keypair resolvers backed by `@dotenvx/primitives` ([#855](https://github.com/dotenvx/dotenvx/pull/855))
15
+ * Route `set`, `encrypt`, and `decrypt` through shared transforms that operate on primitive scan, parse, encrypt, and upsert results ([#855](https://github.com/dotenvx/dotenvx/pull/855))
16
+ * Update library `parse` to use primitive parsing while preserving dotenvx-style encrypted value errors ([#855](https://github.com/dotenvx/dotenvx/pull/855))
17
+
18
+ ### Removed
19
+
20
+ * BREAKING: Remove the `rotate` command (it will return in 2.1 or 2.2 soon with a more complete implementation for local and armored keys) ([#855](https://github.com/dotenvx/dotenvx/pull/855))
21
+ * BREAKING: Remove the library `doctor`, `keypair`, and `genexample` exports from `lib/main` ([#855](https://github.com/dotenvx/dotenvx/pull/855))
22
+
23
+ ## [1.76.0](https://github.com/dotenvx/dotenvx/compare/v1.75.1...v1.76.0) (2026-06-24)
24
+
25
+ ### Changed
26
+
27
+ * Support dotenvx across powershell ([#856](https://github.com/dotenvx/dotenvx/pull/856))
28
+ * BREAKING: Remove variadic `-f`. You can still do `dotenvx run -f .env1 -f .env2` but ambiguos variadic like `dotenvx run -f .env1 .env2 ...` is removed ([#856](https://github.com/dotenvx/dotenvx/pull/856))
29
+
30
+ ## [1.75.1](https://github.com/dotenvx/dotenvx/compare/v1.75.0...v1.75.1) (2026-06-20)
31
+
32
+ ### Changed
33
+
34
+ * Publish as named binaries ([#851](https://github.com/dotenvx/dotenvx/pull/851))
35
+
36
+ ### Removed
37
+
38
+ * Remove references to `dotenvx-vlt` (now dotenvx-armor) ([#849](https://github.com/dotenvx/dotenvx/pull/849))
6
39
 
7
40
  ## [1.75.0](https://github.com/dotenvx/dotenvx/compare/v1.74.4...v1.75.0) (2026-06-19)
8
41
 
package/README.md CHANGED
@@ -58,7 +58,9 @@ dotenvx encrypt
58
58
  <details><summary>with brew 🍺</summary><br>
59
59
 
60
60
  ```sh
61
- brew install dotenvx/brew/dotenvx
61
+ brew tap dotenvx/brew
62
+ brew trust dotenvx/brew
63
+ brew install dotenvx
62
64
  dotenvx encrypt
63
65
  ```
64
66
 
@@ -2026,117 +2028,6 @@ $ dotenvx ls -ef '**/.env.prod*'
2026
2028
  └─ .env
2027
2029
  ```
2028
2030
 
2029
- </details>
2030
- <details><summary>`rotate`</summary><br>
2031
-
2032
- Rotate public/private keys for `.env` file and re-encrypt all encrypted values.
2033
-
2034
- ```sh
2035
- $ echo "HELLO=Dotenvx" > .env
2036
- $ dotenvx encrypt
2037
- ◈ encrypted (.env)
2038
- $ dotenvx rotate
2039
- ⟳ rotated (.env)
2040
- ```
2041
-
2042
- </details>
2043
- <details><summary>`rotate -f`</summary><br>
2044
-
2045
- Rotate public/private keys for a specified encrypted `.env` file and re-encrypt all encrypted values.
2046
-
2047
- ```sh
2048
- $ echo "HELLO=Dotenvx" > .env
2049
- $ echo "HELLO=Production" > .env.production
2050
-
2051
- $ dotenvx encrypt -f .env.production
2052
- ◈ encrypted (.env.production)
2053
- $ dotenvx rotate -f .env.production
2054
- ⟳ rotated (.env.production)
2055
- ```
2056
-
2057
- </details>
2058
- <details><summary>`rotate -fk`</summary><br>
2059
-
2060
- Specify path to `.env.keys`. This is useful with monorepos.
2061
-
2062
- ```sh
2063
- $ mkdir -p apps/app1
2064
- $ echo "HELLO=Dotenvx" > apps/app1/.env
2065
-
2066
- $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
2067
- ◈ encrypted (apps/app1/.env)
2068
- $ dotenvx rotate -fk .env.keys -f apps/app1/.env
2069
- ⟳ rotated (apps/app1/.env)
2070
- ```
2071
-
2072
- </details>
2073
- <details><summary>`rotate -k`</summary><br>
2074
-
2075
- Rotate the contents of a specified key inside an encrypted `.env` file.
2076
-
2077
- ```sh
2078
- $ echo "HELLO=Dotenvx\nHOLA=Mundo" > .env
2079
- $ dotenvx encrypt
2080
- ◈ encrypted (.env)
2081
- $ dotenvx rotate -k HELLO
2082
- ⟳ rotated (.env)
2083
- ```
2084
-
2085
- Even specify a glob pattern.
2086
-
2087
- ```sh
2088
- $ echo "HELLO=Dotenvx\nHOLA=Mundo" > .env
2089
- $ dotenvx encrypt
2090
- ◈ encrypted (.env)
2091
- $ dotenvx rotate -k "HE*"
2092
- ⟳ rotated (.env)
2093
- ```
2094
-
2095
- </details>
2096
- <details><summary>`rotate -ek`</summary><br>
2097
-
2098
- Rotate the encrypted contents inside an encrypted `.env` file except for an excluded key.
2099
-
2100
- ```sh
2101
- $ echo "HELLO=Dotenvx\nHOLA=Mundo" > .env
2102
- $ dotenvx encrypt
2103
- ◈ encrypted (.env)
2104
- $ dotenvx rotate -ek HOLA
2105
- ⟳ rotated (.env)
2106
- ```
2107
-
2108
- Even specify a glob pattern.
2109
-
2110
- ```sh
2111
- $ echo "HELLO=Dotenvx\nHOLA=Mundo" > .env
2112
- $ dotenvx encrypt
2113
- ◈ encrypted (.env)
2114
- $ dotenvx rotate -ek "HO*"
2115
- ⟳ rotated (.env)
2116
- ```
2117
-
2118
- </details>
2119
- <details><summary>`rotate --stdout`</summary><br>
2120
-
2121
- Rotate the contents of an encrypted `.env` file and send to stdout.
2122
-
2123
- ```sh
2124
- $ dotenvx rotate --stdout
2125
- #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
2126
- #/ public-key encryption for .env files /
2127
- #/ [how it works](https://dotenvx.com/encryption) /
2128
- #/----------------------------------------------------------/
2129
- DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45"
2130
- # .env
2131
- HELLO="encrypted:12345"
2132
- ```
2133
-
2134
- or send to a file:
2135
-
2136
- ```sh
2137
- $ dotenvx rotate --stdout > somefile.txt
2138
- ```
2139
-
2140
2031
  </details>
2141
2032
  <details><summary>`help`</summary><br>
2142
2033
 
@@ -2162,7 +2053,6 @@ Commands:
2162
2053
  set <KEY> <value> set a single environment variable
2163
2054
  encrypt encrypt .env file(s)
2164
2055
  decrypt decrypt .env file(s)
2165
- rotate rotate keypair(s) and re-encrypt .env file(s)
2166
2056
  keypair [KEY] print public/private keys for .env file(s)
2167
2057
  ls [directory] print all .env files in a tree structure
2168
2058
  gitignore append to .gitignore
@@ -2703,7 +2593,7 @@ Programmatically get an environment variable at access/runtime.
2703
2593
  ```js
2704
2594
  // index.js
2705
2595
  const dotenvx = require('@dotenvx/dotenvx')
2706
- const decryptedValue = dotenvx.get('HELLO')
2596
+ const decryptedValue = await dotenvx.get('HELLO')
2707
2597
  console.log(decryptedValue)
2708
2598
  ```
2709
2599
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.75.0",
2
+ "version": "2.0.0",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a secure dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -43,22 +43,23 @@
43
43
  },
44
44
  "funding": "https://dotenvx.com",
45
45
  "dependencies": {
46
- "@dotenvx/primitives": "^0.7.1",
46
+ "@dotenvx/primitives": "^1.7.0",
47
47
  "commander": "^11.1.0",
48
48
  "conf": "^10.2.0",
49
- "dotenv": "^17.2.1",
49
+ "dotenv": "^17.4.2",
50
50
  "enquirer": "^2.4.1",
51
51
  "env-paths": "^2.2.1",
52
52
  "execa": "^5.1.1",
53
53
  "fdir": "^6.2.0",
54
- "ignore": "^5.3.0",
54
+ "ignore": "^7.0.5",
55
55
  "object-treeify": "1.1.33",
56
56
  "open": "^8.4.2",
57
57
  "picomatch": "^4.0.4",
58
- "systeminformation": "^5.22.11",
58
+ "synckit": "0.11.13",
59
+ "systeminformation": "^5.31.11",
59
60
  "undici": "^7.11.0",
60
- "which": "^4.0.0",
61
- "yocto-spinner": "^1.1.0"
61
+ "which": "^6.0.1",
62
+ "yocto-spinner": "^1.2.0"
62
63
  },
63
64
  "devDependencies": {
64
65
  "@yao-pkg/pkg": "^6.12.0",
@@ -1,14 +1,15 @@
1
1
  const fsx = require('./../../lib/helpers/fsx')
2
2
  const { logger } = require('./../../shared/logger')
3
3
 
4
- const Decrypt = require('./../../lib/services/decrypt')
5
4
  const catchAndLog = require('../../lib/helpers/catchAndLog')
6
5
  const createSpinner = require('../../lib/helpers/createSpinner')
7
6
  const Session = require('../../db/session')
8
- const normalizeArmorOptions = require('./normalizeArmorOptions')
7
+ const normalizeArmorAliases = require('./normalizeArmorAliases')
8
+
9
+ const decryptTransform = require('./../../lib/transforms/decrypt')
9
10
 
10
11
  async function decrypt () {
11
- const options = normalizeArmorOptions(this.opts())
12
+ const options = normalizeArmorAliases(this.opts())
12
13
  const spinner = await createSpinner({ ...options, text: 'decrypting' })
13
14
 
14
15
  logger.debug(`options: ${JSON.stringify(options)}`)
@@ -21,17 +22,26 @@ async function decrypt () {
21
22
 
22
23
  // stdout - should not have a try so that exit codes can surface to stdout
23
24
  if (options.stdout) {
24
- if (spinner) spinner.stop()
25
25
  const {
26
26
  processedEnvs
27
- } = await new Decrypt(envs, options.key, options.excludeKey, options.envKeysFile, noArmor, {
28
- command: process.argv.slice(2)
29
- }).run()
27
+ } = await decryptTransform({
28
+ envs,
29
+ ik: options.key,
30
+ ek: options.excludeKey,
31
+ fk: options.envKeysFile,
32
+ noArmor,
33
+ onStatus: (text) => {
34
+ if (spinner && text) {
35
+ spinner.text = text
36
+ }
37
+ }
38
+ })
39
+
30
40
  if (spinner) spinner.stop()
31
41
  for (const processedEnv of processedEnvs) {
32
42
  if (processedEnv.error) {
33
43
  errorCount += 1
34
- logger.error(processedEnv.error.messageWithHelp)
44
+ logger.error(processedEnv.error.messageWithHelp || processedEnv.error.message)
35
45
  } else {
36
46
  console.log(processedEnv.envSrc)
37
47
  }
@@ -44,22 +54,32 @@ async function decrypt () {
44
54
  }
45
55
  } else {
46
56
  try {
47
- if (spinner) spinner.stop()
48
57
  const {
49
58
  processedEnvs,
50
59
  changedFilepaths,
51
60
  unchangedFilepaths
52
- } = await new Decrypt(envs, options.key, options.excludeKey, options.envKeysFile, noArmor, {
53
- command: process.argv.slice(2)
54
- }).run()
61
+ } = await decryptTransform({
62
+ envs,
63
+ ik: options.key,
64
+ ek: options.excludeKey,
65
+ fk: options.envKeysFile,
66
+ noArmor,
67
+ onStatus: (text) => {
68
+ if (spinner && text) {
69
+ spinner.text = text
70
+ }
71
+ }
72
+ })
55
73
 
56
74
  for (const processedEnv of processedEnvs) {
57
75
  logger.verbose(`decrypting ${processedEnv.envFilepath} (${processedEnv.filepath})`)
58
76
 
59
77
  if (processedEnv.error) {
60
78
  errorCount += 1
61
- logger.error(processedEnv.error.messageWithHelp)
62
- } else if (processedEnv.changed) {
79
+ logger.error(processedEnv.error.messageWithHelp || processedEnv.error.message)
80
+ }
81
+
82
+ if (processedEnv.changed) {
63
83
  await fsx.writeFileX(processedEnv.filepath, processedEnv.envSrc)
64
84
 
65
85
  logger.verbose(`decrypted ${processedEnv.envFilepath} (${processedEnv.filepath})`)
@@ -69,10 +89,8 @@ async function decrypt () {
69
89
  }
70
90
 
71
91
  if (spinner) spinner.stop()
72
- const armoredPrivateKeyUsed = processedEnvs.some((processedEnv) => processedEnv.armoredPrivateKeyUsed)
73
- const keyUsedSuffix = armoredPrivateKeyUsed ? ' · armored ⛨' : ''
74
92
  if (changedFilepaths.length > 0) {
75
- logger.success(`◇ decrypted (${changedFilepaths.join(',')})${keyUsedSuffix}`)
93
+ logger.success(`◇ decrypted (${changedFilepaths.join(',')})`)
76
94
  } else if (unchangedFilepaths.length > 0) {
77
95
  logger.info(`○ no change (${unchangedFilepaths})`)
78
96
  } else {
@@ -1,10 +1,10 @@
1
1
  const { logger } = require('./../../shared/logger')
2
- const main = require('./../../lib/main')
2
+ const Doctor = require('./../../lib/services/doctor')
3
3
 
4
4
  function doctor (directory = '.') {
5
5
  logger.debug(`directory: ${directory}`)
6
6
 
7
- const findings = main.doctor(directory)
7
+ const findings = new Doctor(directory).run()
8
8
  logger.debug(`findings: ${JSON.stringify(findings)}`)
9
9
 
10
10
  if (findings.length === 0) {
@@ -1,114 +1,93 @@
1
1
  const fsx = require('./../../lib/helpers/fsx')
2
2
  const { logger } = require('./../../shared/logger')
3
3
 
4
- const Encrypt = require('./../../lib/services/encrypt')
4
+ const encryptTransform = require('./../../lib/transforms/encrypt')
5
5
 
6
6
  const catchAndLog = require('../../lib/helpers/catchAndLog')
7
7
  const createSpinner = require('../../lib/helpers/createSpinner')
8
- const prompts = require('../../lib/helpers/prompts')
9
8
  const Session = require('../../db/session')
10
- const normalizeArmorOptions = require('./normalizeArmorOptions')
9
+ const normalizeArmorAliases = require('./normalizeArmorAliases')
11
10
 
12
- function keyStorageSelector () {
13
- let selected
14
-
15
- return async function selectKeyStorage () {
16
- if (selected) return selected
17
-
18
- selected = await prompts.select({
19
- message: 'Choose private key storage',
20
- choices: [
21
- { name: '◫ File (.env.keys)', value: 'file' },
22
- { name: '⛨ Armor (armor.dotenvx.com)', value: 'armored' }
23
- ]
24
- }, {
25
- input: process.stdin,
26
- output: process.stderr
27
- })
28
-
29
- return selected
30
- }
31
- }
32
-
33
- function encryptOptions (noArmor) {
34
- const options = {}
35
-
36
- if (!noArmor) {
37
- options.selectKeyStorage = keyStorageSelector()
38
- }
39
-
40
- return options
41
- }
42
-
43
- async function encrypt () {
44
- const options = normalizeArmorOptions(this.opts())
11
+ async function encryptAction () {
12
+ const options = normalizeArmorAliases(this.opts())
45
13
  const spinner = await createSpinner({ ...options, text: 'encrypting' })
14
+ const sesh = new Session()
46
15
 
47
16
  logger.debug(`options: ${JSON.stringify(options)}`)
48
17
 
49
- const envs = this.envs
50
- const sesh = new Session()
51
- const noArmor = options.armor === false || (!options.token && (await sesh.noArmor()))
18
+ const envs = this.envs || []
19
+ const ik = options.key
20
+ const ek = options.excludeKey
21
+ const fk = options.envKeysFile || '.env.keys'
52
22
  const noCreate = options.create === false
23
+ const noArmor = options.armor === false || (!options.token && (await sesh.noArmor()))
24
+
25
+ let errorCount = 0
53
26
 
54
27
  // stdout - should not have a try so that exit codes can surface to stdout
55
28
  if (options.stdout) {
56
- if (spinner) spinner.stop()
57
- const {
58
- processedEnvs
59
- } = await new Encrypt(envs, options.key, options.excludeKey, options.envKeysFile, noArmor, noCreate, options.token, {
60
- ...encryptOptions(noArmor),
61
- command: process.argv.slice(2)
62
- }).run()
29
+ const { processedEnvs } = await encryptTransform({ envs, ik, ek, fk, noArmor, noCreate })
30
+
63
31
  if (spinner) spinner.stop()
64
32
  for (const processedEnv of processedEnvs) {
65
- console.log(processedEnv.envSrc)
33
+ if (processedEnv.error) {
34
+ errorCount += 1
35
+ logger.error(processedEnv.error.messageWithHelp || processedEnv.error.message)
36
+ }
37
+ if (processedEnv.envSrc) {
38
+ console.log(processedEnv.envSrc)
39
+ }
40
+ }
41
+
42
+ if (errorCount > 0) {
43
+ process.exit(1)
44
+ } else {
45
+ process.exit(0) // exit early
66
46
  }
67
- process.exit(0) // exit early
68
- } else {
69
- try {
70
- if (spinner) spinner.stop()
71
- const {
72
- processedEnvs,
73
- changedFilepaths,
74
- unchangedFilepaths
75
- } = await new Encrypt(envs, options.key, options.excludeKey, options.envKeysFile, noArmor, noCreate, options.token, {
76
- ...encryptOptions(noArmor),
77
- command: process.argv.slice(2)
78
- }).run()
47
+ }
79
48
 
80
- for (const processedEnv of processedEnvs) {
81
- logger.verbose(`encrypting ${processedEnv.envFilepath} (${processedEnv.filepath})`)
82
- if (processedEnv.error) {
83
- logger.warn(processedEnv.error.messageWithHelp)
84
- } else if (processedEnv.changed) {
85
- await fsx.writeFileX(processedEnv.filepath, processedEnv.envSrc)
49
+ try {
50
+ const { keysSrc, processedEnvs, changedFilepaths, unchangedFilepaths } = await encryptTransform({ envs, ik, ek, fk, noArmor, noCreate })
86
51
 
87
- logger.verbose(`encrypted ${processedEnv.envFilepath} (${processedEnv.filepath})`)
88
- } else {
89
- logger.verbose(`no change ${processedEnv.envFilepath} (${processedEnv.filepath})`)
90
- }
91
- }
52
+ if (keysSrc) {
53
+ await fsx.writeFileX(fk, keysSrc)
54
+ }
92
55
 
93
- if (spinner) spinner.stop()
94
- if (changedFilepaths.length > 0) {
95
- const remoteKeyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.remotePrivateKeyAdded)
96
- let msg = `◈ encrypted (${changedFilepaths.join(',')})`
97
- if (remoteKeyAddedEnv) {
98
- msg += ' · armored ⛨'
99
- }
100
- logger.success(msg)
101
- } else if (unchangedFilepaths.length > 0) {
102
- logger.info(`○ no change (${unchangedFilepaths})`)
56
+ if (spinner) spinner.stop()
57
+ for (const processedEnv of processedEnvs) {
58
+ logger.verbose(`encrypting ${processedEnv.envFilepath} (${processedEnv.filepath})`)
59
+ if (processedEnv.error) {
60
+ errorCount += 1
61
+ logger.error(processedEnv.error.messageWithHelp || processedEnv.error.message)
62
+ } else if (processedEnv.changed) {
63
+ await fsx.writeFileX(processedEnv.filepath, processedEnv.envSrc)
64
+ logger.verbose(`encrypted ${processedEnv.envFilepath} (${processedEnv.filepath})`)
103
65
  } else {
104
- // do nothing - scenario when no .env files found
66
+ logger.verbose(`no change ${processedEnv.envFilepath} (${processedEnv.filepath})`)
105
67
  }
106
- } catch (error) {
107
- if (spinner) spinner.stop()
108
- catchAndLog(error)
68
+ }
69
+
70
+ if (changedFilepaths.length > 0) {
71
+ // const remoteKeyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.remotePrivateKeyAdded)
72
+ const msg = `◈ encrypted (${changedFilepaths.join(',')})`
73
+ // if (remoteKeyAddedEnv) {
74
+ // msg += ' · armored ⛨'
75
+ // }
76
+ logger.success(msg)
77
+ } else if (unchangedFilepaths.length > 0) {
78
+ logger.info(`○ no change (${unchangedFilepaths})`)
79
+ } else {
80
+ // do nothing - scenario when no .env files found
81
+ }
82
+
83
+ if (errorCount > 0) {
109
84
  process.exit(1)
110
85
  }
86
+ } catch (error) {
87
+ if (spinner) spinner.stop()
88
+ catchAndLog(error)
89
+ process.exit(1)
111
90
  }
112
91
  }
113
92
 
114
- module.exports = encrypt
93
+ module.exports = encryptAction
@@ -1,6 +1,6 @@
1
1
  const fsx = require('./../../../lib/helpers/fsx')
2
2
  const path = require('path')
3
- const main = require('./../../../lib/main')
3
+ const Genexample = require('./../../../lib/services/genexample')
4
4
  const { logger } = require('./../../../shared/logger')
5
5
  const catchAndLog = require('./../../../lib/helpers/catchAndLog')
6
6
 
@@ -16,7 +16,7 @@ function genexample (directory) {
16
16
  envFile,
17
17
  exampleFilepath,
18
18
  addedKeys
19
- } = main.genexample(directory, options.envFile)
19
+ } = new Genexample(directory, options.envFile).run()
20
20
 
21
21
  logger.verbose(`loading env from ${envFile}`)
22
22
 
@@ -5,11 +5,11 @@ const escape = require('./../../lib/helpers/escape')
5
5
  const catchAndLog = require('./../../lib/helpers/catchAndLog')
6
6
  const createSpinner = require('../../lib/helpers/createSpinner')
7
7
  const Session = require('../../db/session')
8
- const Get = require('./../../lib/services/get')
9
- const normalizeArmorOptions = require('./normalizeArmorOptions')
8
+ const getResolver = require('./../../lib/resolvers/get')
9
+ const normalizeArmorAliases = require('./normalizeArmorAliases')
10
10
 
11
11
  async function get (key) {
12
- const options = normalizeArmorOptions(this.opts())
12
+ const options = normalizeArmorAliases(this.opts())
13
13
  const spinner = await createSpinner({ ...options, text: 'decrypting' })
14
14
 
15
15
  logger.debug(`options: ${JSON.stringify(options)}`)
@@ -31,10 +31,19 @@ async function get (key) {
31
31
  try {
32
32
  const sesh = new Session()
33
33
  const noArmor = options.armor === false || (await sesh.noArmor())
34
- if (spinner) spinner.stop()
35
- const { parsed, errors } = await new Get(key, envs, options.overload, options.all, options.envKeysFile, noArmor, {
36
- command: process.argv.slice(2)
37
- }).run()
34
+ const { parsed, errors } = await getResolver({
35
+ key,
36
+ envs,
37
+ overload: options.overload,
38
+ all: options.all,
39
+ envKeysFile: options.envKeysFile,
40
+ noArmor,
41
+ onStatus: (text) => {
42
+ if (spinner && text) {
43
+ spinner.text = text
44
+ }
45
+ }
46
+ })
38
47
 
39
48
  for (const error of errors || []) {
40
49
  if (options.strict) throw error // throw immediately if strict