@dotenvx/dotenvx 1.19.3 → 1.20.1

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/src/lib/main.js CHANGED
@@ -10,10 +10,7 @@ const { getColor, bold } = require('./../shared/colors')
10
10
  const Ls = require('./services/ls')
11
11
  const Get = require('./services/get')
12
12
  const Run = require('./services/run')
13
- const Sets = require('./services/sets')
14
13
  const Keypair = require('./services/keypair')
15
- const Encrypt = require('./services/encrypt')
16
- const Decrypt = require('./services/decrypt')
17
14
  const Genexample = require('./services/genexample')
18
15
 
19
16
  // helpers
@@ -196,21 +193,6 @@ const get = function (
196
193
  return new Get(key, envs, overload, DOTENV_KEY, all).run()
197
194
  }
198
195
 
199
- /** @type {import('./main').set} */
200
- const set = function (key, value, envFile, encrypt) {
201
- return new Sets(key, value, envFile, encrypt).run()
202
- }
203
-
204
- /** @type {import('./main').encrypt} */
205
- const encrypt = function (envFile, key, excludeKey) {
206
- return new Encrypt(envFile, key, excludeKey).run()
207
- }
208
-
209
- /** @type {import('./main').encrypt} */
210
- const decrypt = function (envFile, key, excludeKey) {
211
- return new Decrypt(envFile, key, excludeKey).run()
212
- }
213
-
214
196
  /** @type {import('./main').keypair} */
215
197
  const keypair = function (envFile, key) {
216
198
  return new Keypair(envFile, key).run()
@@ -222,11 +204,8 @@ module.exports = {
222
204
  configDotenv,
223
205
  parse,
224
206
  // actions related
225
- encrypt,
226
- decrypt,
227
207
  ls,
228
208
  get,
229
- set,
230
209
  keypair,
231
210
  genexample,
232
211
  // expose for libs depending on @dotenvx/dotenvx - like dotenvx-pro
@@ -3,113 +3,114 @@ const path = require('path')
3
3
  const dotenv = require('dotenv')
4
4
  const picomatch = require('picomatch')
5
5
 
6
- const smartDotenvPrivateKey = require('./../helpers/smartDotenvPrivateKey')
6
+ const TYPE_ENV_FILE = 'envFile'
7
+
7
8
  const guessPrivateKeyName = require('./../helpers/guessPrivateKeyName')
9
+ const findPrivateKey = require('./../helpers/findPrivateKey')
8
10
  const decryptValue = require('./../helpers/decryptValue')
9
11
  const isEncrypted = require('./../helpers/isEncrypted')
10
12
  const replace = require('./../helpers/replace')
13
+ const detectEncoding = require('./../helpers/detectEncoding')
14
+ const determineEnvs = require('./../helpers/determineEnvs')
11
15
 
12
16
  class Decrypt {
13
- /**
14
- * @param {string|string[]} [envFile]
15
- * @param {string|string[]} [key]
16
- * @param {string|string[]} [excludeKey]
17
- **/
18
- constructor (envFile = '.env', key = [], excludeKey = []) {
19
- this.envFile = envFile
17
+ constructor (envs = [], key = [], excludeKey = []) {
18
+ this.envs = determineEnvs(envs, process.env)
20
19
  this.key = key
21
20
  this.excludeKey = excludeKey
22
- this.processedEnvFiles = []
21
+
22
+ this.processedEnvs = []
23
23
  this.changedFilepaths = new Set()
24
24
  this.unchangedFilepaths = new Set()
25
25
  }
26
26
 
27
27
  run () {
28
- const envFilepaths = this._envFilepaths()
29
- const keys = this._keys()
28
+ // example
29
+ // envs [
30
+ // { type: 'envFile', value: '.env' }
31
+ // ]
32
+
33
+ this.keys = this._keys()
30
34
  const excludeKeys = this._excludeKeys()
31
- const exclude = picomatch(excludeKeys)
32
- const include = picomatch(keys, { ignore: excludeKeys })
33
-
34
- for (const envFilepath of envFilepaths) {
35
- const filepath = path.resolve(envFilepath)
36
-
37
- const row = {}
38
- row.keys = []
39
- row.filepath = filepath
40
- row.envFilepath = envFilepath
41
-
42
- try {
43
- // get the src
44
- let src = fsx.readFileX(filepath)
45
-
46
- // if DOTENV_PRIVATE_KEY_* already set in process.env then use it
47
- const privateKey = smartDotenvPrivateKey(envFilepath)
48
- row.privateKey = privateKey
49
- row.privateKeyName = guessPrivateKeyName(filepath)
50
-
51
- // track possible changes
52
- row.changed = false
53
-
54
- // iterate over all non-encrypted values and encrypt them
55
- const parsed = dotenv.parse(src)
56
- for (const [key, value] of Object.entries(parsed)) {
57
- // key excluded - don't decrypt it
58
- if (exclude(key)) {
59
- continue
60
- }
61
-
62
- // key effectively excluded (by not being in the list of includes) - don't encrypt it
63
- if (keys.length > 0 && !include(key)) {
64
- continue
65
- }
66
-
67
- const encrypted = isEncrypted(key, value)
68
- if (encrypted) {
69
- row.keys.push(key) // track key(s)
70
-
71
- const decryptedValue = decryptValue(value, privateKey)
72
- // once newSrc is built write it out
73
- src = replace(src, key, decryptedValue)
74
-
75
- row.changed = true // track change
76
- }
77
- }
78
35
 
79
- if (row.changed) {
80
- row.envSrc = src
81
- this.changedFilepaths.add(envFilepath)
82
- } else {
83
- row.envSrc = src
84
- this.unchangedFilepaths.add(envFilepath)
85
- }
86
- } catch (e) {
87
- if (e.code === 'ENOENT') {
88
- const error = new Error(`missing ${envFilepath} file (${filepath})`)
89
- error.code = 'MISSING_ENV_FILE'
90
-
91
- row.error = error
92
- } else {
93
- row.error = e
94
- }
95
- }
36
+ this.exclude = picomatch(excludeKeys)
37
+ this.include = picomatch(this.keys, { ignore: excludeKeys })
96
38
 
97
- this.processedEnvFiles.push(row)
39
+ for (const env of this.envs) {
40
+ if (env.type === TYPE_ENV_FILE) {
41
+ this._decryptEnvFile(env.value)
42
+ }
98
43
  }
99
44
 
100
45
  return {
101
- processedEnvFiles: this.processedEnvFiles,
46
+ processedEnvs: this.processedEnvs,
102
47
  changedFilepaths: [...this.changedFilepaths],
103
48
  unchangedFilepaths: [...this.unchangedFilepaths]
104
49
  }
105
50
  }
106
51
 
107
- _envFilepaths () {
108
- if (!Array.isArray(this.envFile)) {
109
- return [this.envFile]
52
+ _decryptEnvFile (envFilepath) {
53
+ const row = {}
54
+ row.keys = []
55
+ row.type = TYPE_ENV_FILE
56
+
57
+ const filepath = path.resolve(envFilepath)
58
+ row.filepath = filepath
59
+ row.envFilepath = envFilepath
60
+
61
+ try {
62
+ const encoding = this._detectEncoding(filepath)
63
+ let envSrc = fsx.readFileX(filepath, { encoding })
64
+ const envParsed = dotenv.parse(envSrc)
65
+
66
+ const privateKey = findPrivateKey(envFilepath)
67
+ const privateKeyName = guessPrivateKeyName(envFilepath)
68
+
69
+ row.privateKey = privateKey
70
+ row.privateKeyName = privateKeyName
71
+ row.changed = false // track possible changes
72
+
73
+ for (const [key, value] of Object.entries(envParsed)) {
74
+ // key excluded - don't decrypt it
75
+ if (this.exclude(key)) {
76
+ continue
77
+ }
78
+
79
+ // key effectively excluded (by not being in the list of includes) - don't decrypt it
80
+ if (this.keys.length > 0 && !this.include(key)) {
81
+ continue
82
+ }
83
+
84
+ const encrypted = isEncrypted(value)
85
+ if (encrypted) {
86
+ row.keys.push(key) // track key(s)
87
+
88
+ const decryptedValue = decryptValue(value, privateKey)
89
+ // once newSrc is built write it out
90
+ envSrc = replace(envSrc, key, decryptedValue)
91
+
92
+ row.changed = true // track change
93
+ }
94
+ }
95
+
96
+ row.envSrc = envSrc
97
+ if (row.changed) {
98
+ this.changedFilepaths.add(envFilepath)
99
+ } else {
100
+ this.unchangedFilepaths.add(envFilepath)
101
+ }
102
+ } catch (e) {
103
+ if (e.code === 'ENOENT') {
104
+ const error = new Error(`missing ${envFilepath} file (${filepath})`)
105
+ error.code = 'MISSING_ENV_FILE'
106
+
107
+ row.error = error
108
+ } else {
109
+ row.error = e
110
+ }
110
111
  }
111
112
 
112
- return this.envFile
113
+ this.processedEnvs.push(row)
113
114
  }
114
115
 
115
116
  _keys () {
@@ -127,6 +128,10 @@ class Decrypt {
127
128
 
128
129
  return this.excludeKey
129
130
  }
131
+
132
+ _detectEncoding (filepath) {
133
+ return detectEncoding(filepath)
134
+ }
130
135
  }
131
136
 
132
137
  module.exports = Decrypt
@@ -3,127 +3,194 @@ const path = require('path')
3
3
  const dotenv = require('dotenv')
4
4
  const picomatch = require('picomatch')
5
5
 
6
- const findOrCreatePublicKey = require('./../helpers/findOrCreatePublicKey')
6
+ const TYPE_ENV_FILE = 'envFile'
7
+
7
8
  const guessPrivateKeyName = require('./../helpers/guessPrivateKeyName')
9
+ const guessPublicKeyName = require('./../helpers/guessPublicKeyName')
8
10
  const encryptValue = require('./../helpers/encryptValue')
9
11
  const isEncrypted = require('./../helpers/isEncrypted')
10
- const isPublicKey = require('./../helpers/isPublicKey')
11
12
  const replace = require('./../helpers/replace')
13
+ const detectEncoding = require('./../helpers/detectEncoding')
14
+ const determineEnvs = require('./../helpers/determineEnvs')
15
+ const findPrivateKey = require('./../helpers/findPrivateKey')
16
+ const findPublicKey = require('./../helpers/findPublicKey')
17
+ const keyPair = require('./../helpers/keyPair')
18
+ const truncate = require('./../helpers/truncate')
19
+ const isPublicKey = require('./../helpers/isPublicKey')
12
20
 
13
21
  class Encrypt {
14
- /**
15
- * @param {string|string[]} [envFile]
16
- * @param {string|string[]} [key]
17
- * @param {string|string[]} [excludeKey]
18
- **/
19
- constructor (envFile = '.env', key = [], excludeKey = []) {
20
- this.envFile = envFile
22
+ constructor (envs = [], key = [], excludeKey = []) {
23
+ this.envs = determineEnvs(envs, process.env)
21
24
  this.key = key
22
25
  this.excludeKey = excludeKey
23
- this.processedEnvFiles = []
26
+
27
+ this.processedEnvs = []
24
28
  this.changedFilepaths = new Set()
25
29
  this.unchangedFilepaths = new Set()
26
30
  }
27
31
 
28
32
  run () {
29
- const envFilepaths = this._envFilepaths()
30
- const keys = this._keys()
33
+ // example
34
+ // envs [
35
+ // { type: 'envFile', value: '.env' }
36
+ // ]
37
+
38
+ this.keys = this._keys()
31
39
  const excludeKeys = this._excludeKeys()
32
- const exclude = picomatch(excludeKeys)
33
- const include = picomatch(keys, { ignore: excludeKeys })
34
40
 
35
- for (const envFilepath of envFilepaths) {
36
- const filepath = path.resolve(envFilepath)
41
+ this.exclude = picomatch(excludeKeys)
42
+ this.include = picomatch(this.keys, { ignore: excludeKeys })
37
43
 
38
- const row = {}
39
- row.keys = []
40
- row.filepath = filepath
41
- row.envFilepath = envFilepath
44
+ for (const env of this.envs) {
45
+ if (env.type === TYPE_ENV_FILE) {
46
+ this._encryptEnvFile(env.value)
47
+ }
48
+ }
49
+
50
+ return {
51
+ processedEnvs: this.processedEnvs,
52
+ changedFilepaths: [...this.changedFilepaths],
53
+ unchangedFilepaths: [...this.unchangedFilepaths]
54
+ }
55
+ }
42
56
 
43
- try {
44
- // get the original src
45
- let src = fsx.readFileX(filepath)
46
- // get/generate the public key
57
+ _encryptEnvFile (envFilepath) {
58
+ const row = {}
59
+ row.keys = []
60
+ row.type = TYPE_ENV_FILE
61
+
62
+ const filename = path.basename(envFilepath)
63
+ const filepath = path.resolve(envFilepath)
64
+ row.filepath = filepath
65
+ row.envFilepath = envFilepath
66
+
67
+ try {
68
+ const encoding = this._detectEncoding(filepath)
69
+ let envSrc = fsx.readFileX(filepath, { encoding })
70
+ const envParsed = dotenv.parse(envSrc)
71
+
72
+ let publicKey
73
+ let privateKey
74
+
75
+ const publicKeyName = guessPublicKeyName(envFilepath)
76
+ const privateKeyName = guessPrivateKeyName(envFilepath)
77
+ const existingPrivateKey = findPrivateKey(envFilepath)
78
+ const existingPublicKey = findPublicKey(envFilepath)
79
+
80
+ if (existingPrivateKey) {
81
+ const kp = keyPair(existingPrivateKey)
82
+ publicKey = kp.publicKey
83
+ privateKey = kp.privateKey
84
+
85
+ // if derivation doesn't match what's in the file (or preset in env)
86
+ if (existingPublicKey && existingPublicKey !== publicKey) {
87
+ const error = new Error(`derived public key (${truncate(publicKey)}) does not match the existing public key (${truncate(existingPublicKey)})`)
88
+ error.code = 'INVALID_DOTENV_PRIVATE_KEY'
89
+ error.help = `debug info: ${privateKeyName}=${truncate(existingPrivateKey)} (derived ${publicKeyName}=${truncate(publicKey)} vs existing ${publicKeyName}=${truncate(existingPublicKey)})`
90
+ throw error
91
+ }
92
+ } else if (existingPublicKey) {
93
+ publicKey = existingPublicKey
94
+ } else {
95
+ // .env.keys
96
+ let keysSrc = ''
47
97
  const envKeysFilepath = path.join(path.dirname(filepath), '.env.keys')
48
- const {
49
- envSrc,
50
- keysSrc,
51
- publicKey,
52
- privateKey,
53
- publicKeyAdded,
54
- privateKeyAdded
55
- } = findOrCreatePublicKey(filepath, envKeysFilepath)
56
-
57
- // handle .env.keys write
58
- fsx.writeFileX(envKeysFilepath, keysSrc)
98
+ if (fsx.existsSync(envKeysFilepath)) {
99
+ keysSrc = fsx.readFileX(envKeysFilepath)
100
+ }
59
101
 
60
- src = envSrc // src was potentially modified by findOrCreatePublicKey so we set it again here
61
-
62
- row.changed = publicKeyAdded // track change
63
- row.publicKey = publicKey
64
- row.privateKey = privateKey
65
- row.privateKeyAdded = privateKeyAdded
66
- row.privateKeyName = guessPrivateKeyName(filepath)
67
-
68
- // iterate over all non-encrypted values and encrypt them
69
- const parsed = dotenv.parse(src)
70
- for (const [key, value] of Object.entries(parsed)) {
71
- // key excluded - don't encrypt it
72
- if (exclude(key)) {
73
- continue
74
- }
75
-
76
- // key effectively excluded (by not being in the list of includes) - don't encrypt it
77
- if (keys.length > 0 && !include(key)) {
78
- continue
79
- }
80
-
81
- const encrypted = isEncrypted(key, value) || isPublicKey(key, value)
82
- if (!encrypted) {
83
- row.keys.push(key) // track key(s)
84
-
85
- const encryptedValue = encryptValue(value, publicKey)
86
- // once newSrc is built write it out
87
- src = replace(src, key, encryptedValue)
88
-
89
- row.changed = true // track change
90
- }
102
+ // preserve shebang
103
+ const [firstLine, ...remainingLines] = envSrc.split('\n')
104
+ let firstLinePreserved = ''
105
+ if (firstLine.startsWith('#!')) {
106
+ firstLinePreserved = firstLine + '\n'
107
+ envSrc = remainingLines.join('\n')
91
108
  }
92
109
 
93
- if (row.changed) {
94
- row.envSrc = src
95
- this.changedFilepaths.add(envFilepath)
96
- } else {
97
- row.envSrc = src
98
- this.unchangedFilepaths.add(envFilepath)
110
+ const kp = keyPair() // generates a fresh keypair in memory
111
+ publicKey = kp.publicKey
112
+ privateKey = kp.privateKey
113
+
114
+ // publicKey
115
+ const prependPublicKey = [
116
+ '#/-------------------[DOTENV_PUBLIC_KEY]--------------------/',
117
+ '#/ public-key encryption for .env files /',
118
+ '#/ [how it works](https://dotenvx.com/encryption) /',
119
+ '#/----------------------------------------------------------/',
120
+ `${publicKeyName}="${publicKey}"`,
121
+ '',
122
+ `# ${filename}`
123
+ ].join('\n')
124
+
125
+ // privateKey
126
+ const firstTimeKeysSrc = [
127
+ '#/------------------!DOTENV_PRIVATE_KEYS!-------------------/',
128
+ '#/ private decryption keys. DO NOT commit to source control /',
129
+ '#/ [how it works](https://dotenvx.com/encryption) /',
130
+ '#/----------------------------------------------------------/'
131
+ ].join('\n')
132
+ const appendPrivateKey = [
133
+ `# ${filename}`,
134
+ `${privateKeyName}="${privateKey}"`,
135
+ ''
136
+ ].join('\n')
137
+
138
+ envSrc = `${firstLinePreserved}${prependPublicKey}\n${envSrc}`
139
+ keysSrc = keysSrc.length > 1 ? keysSrc : `${firstTimeKeysSrc}\n`
140
+ keysSrc = `${keysSrc}\n${appendPrivateKey}`
141
+
142
+ // write to .env.keys
143
+ fsx.writeFileX(envKeysFilepath, keysSrc)
144
+
145
+ row.privateKeyAdded = true
146
+ }
147
+
148
+ row.publicKey = publicKey
149
+ row.privateKey = privateKey
150
+ row.privateKeyName = privateKeyName
151
+
152
+ // iterate over all non-encrypted values and encrypt them
153
+ for (const [key, value] of Object.entries(envParsed)) {
154
+ // key excluded - don't encrypt it
155
+ if (this.exclude(key)) {
156
+ continue
99
157
  }
100
- } catch (e) {
101
- if (e.code === 'ENOENT') {
102
- const error = new Error(`missing ${envFilepath} file (${filepath})`)
103
- error.code = 'MISSING_ENV_FILE'
104
-
105
- row.error = error
106
- } else {
107
- row.error = e
158
+
159
+ // key effectively excluded (by not being in the list of includes) - don't encrypt it
160
+ if (this.keys.length > 0 && !this.include(key)) {
161
+ continue
108
162
  }
109
- }
110
163
 
111
- this.processedEnvFiles.push(row)
112
- }
164
+ const encrypted = isEncrypted(value) || isPublicKey(key, value)
165
+ if (!encrypted) {
166
+ row.keys.push(key) // track key(s)
113
167
 
114
- return {
115
- processedEnvFiles: this.processedEnvFiles,
116
- changedFilepaths: [...this.changedFilepaths],
117
- unchangedFilepaths: [...this.unchangedFilepaths]
118
- }
119
- }
168
+ const encryptedValue = encryptValue(value, publicKey)
169
+ // once newSrc is built write it out
170
+ envSrc = replace(envSrc, key, encryptedValue)
171
+
172
+ row.changed = true // track change
173
+ }
174
+ }
120
175
 
121
- _envFilepaths () {
122
- if (!Array.isArray(this.envFile)) {
123
- return [this.envFile]
176
+ row.envSrc = envSrc
177
+ if (row.changed) {
178
+ this.changedFilepaths.add(envFilepath)
179
+ } else {
180
+ this.unchangedFilepaths.add(envFilepath)
181
+ }
182
+ } catch (e) {
183
+ if (e.code === 'ENOENT') {
184
+ const error = new Error(`missing ${envFilepath} file (${filepath})`)
185
+ error.code = 'MISSING_ENV_FILE'
186
+
187
+ row.error = error
188
+ } else {
189
+ row.error = e
190
+ }
124
191
  }
125
192
 
126
- return this.envFile
193
+ this.processedEnvs.push(row)
127
194
  }
128
195
 
129
196
  _keys () {
@@ -141,6 +208,10 @@ class Encrypt {
141
208
 
142
209
  return this.excludeKey
143
210
  }
211
+
212
+ _detectEncoding (filepath) {
213
+ return detectEncoding(filepath)
214
+ }
144
215
  }
145
216
 
146
217
  module.exports = Encrypt
@@ -1,28 +1,22 @@
1
1
  const fsx = require('./../helpers/fsx')
2
2
  const path = require('path')
3
3
  const dotenv = require('dotenv')
4
- const childProcess = require('child_process')
5
4
 
6
5
  const TYPE_ENV = 'env'
7
6
  const TYPE_ENV_FILE = 'envFile'
8
7
  const TYPE_ENV_VAULT_FILE = 'envVaultFile'
9
- const DEFAULT_ENVS = [{ type: TYPE_ENV_FILE, value: '.env' }]
10
- const DEFAULT_ENV_VAULTS = [{ type: TYPE_ENV_VAULT_FILE, value: '.env.vault' }]
11
8
 
12
9
  const inject = require('./../helpers/inject')
13
10
  const decrypt = require('./../helpers/decrypt')
14
11
  const parseDecryptEvalExpand = require('./../helpers/parseDecryptEvalExpand')
15
12
  const parseEnvironmentFromDotenvKey = require('./../helpers/parseEnvironmentFromDotenvKey')
16
- const guessPrivateKeyFilename = require('./../helpers/guessPrivateKeyFilename')
17
- const guessPrivateKeyName = require('./../helpers/guessPrivateKeyName')
18
13
  const detectEncoding = require('./../helpers/detectEncoding')
19
-
20
- const Keypair = require('./../services/keypair')
14
+ const findPrivateKey = require('./../helpers/findPrivateKey')
15
+ const determineEnvs = require('./../helpers/determineEnvs')
21
16
 
22
17
  class Run {
23
18
  constructor (envs = [], overload = false, DOTENV_KEY = '', processEnv = process.env) {
24
- this.dotenvPrivateKeyNames = Object.keys(processEnv).filter(key => key.startsWith('DOTENV_PRIVATE_KEY')) // important, must be first. used by determineEnvs
25
- this.envs = this._determineEnvs(envs, DOTENV_KEY)
19
+ this.envs = determineEnvs(envs, processEnv, DOTENV_KEY)
26
20
  this.overload = overload
27
21
  this.DOTENV_KEY = DOTENV_KEY
28
22
  this.processEnv = processEnv
@@ -43,7 +37,7 @@ class Run {
43
37
  // ]
44
38
 
45
39
  for (const env of this.envs) {
46
- if (env.type === TYPE_ENV_VAULT_FILE) {
40
+ if (env.type === TYPE_ENV_VAULT_FILE) { // deprecate someday - for deprecated .env.vault files
47
41
  this._injectEnvVaultFile(env.value)
48
42
  } else if (env.type === TYPE_ENV_FILE) {
49
43
  this._injectEnvFile(env.value)
@@ -96,7 +90,7 @@ class Run {
96
90
  const src = fsx.readFileX(filepath, { encoding })
97
91
  this.readableFilepaths.add(envFilepath)
98
92
 
99
- const privateKey = this._determinePrivateKey(envFilepath)
93
+ const privateKey = findPrivateKey(envFilepath)
100
94
  const { parsed, processEnv, warnings } = parseDecryptEvalExpand(src, privateKey, this.processEnv)
101
95
  row.parsed = parsed
102
96
  row.warnings = warnings
@@ -189,61 +183,6 @@ class Run {
189
183
  return inject(clonedProcessEnv, parsed, overload, processEnv)
190
184
  }
191
185
 
192
- _determineEnvsFromDotenvPrivateKey () {
193
- const envs = []
194
-
195
- for (const privateKeyName of this.dotenvPrivateKeyNames) {
196
- const filename = guessPrivateKeyFilename(privateKeyName)
197
- envs.push({ type: TYPE_ENV_FILE, value: filename })
198
- }
199
-
200
- return envs
201
- }
202
-
203
- _determineEnvs (envs = [], DOTENV_KEY = '') {
204
- if (!envs || envs.length <= 0) {
205
- // if process.env.DOTENV_PRIVATE_KEY or process.env.DOTENV_PRIVATE_KEY_${environment} is set, assume inline encryption methodology
206
- if (this.dotenvPrivateKeyNames.length > 0) {
207
- return this._determineEnvsFromDotenvPrivateKey()
208
- }
209
-
210
- if (DOTENV_KEY.length > 0) {
211
- // if DOTENV_KEY is set then default to look for .env.vault file
212
- return DEFAULT_ENV_VAULTS
213
- } else {
214
- return DEFAULT_ENVS // default to .env file expectation
215
- }
216
- } else {
217
- let fileAlreadySpecified = false // can be .env or .env.vault type
218
-
219
- for (const env of envs) {
220
- // if DOTENV_KEY set then we are checking if a .env.vault file is already specified
221
- if (DOTENV_KEY.length > 0 && env.type === TYPE_ENV_VAULT_FILE) {
222
- fileAlreadySpecified = true
223
- }
224
-
225
- // if DOTENV_KEY not set then we are checking if a .env file is already specified
226
- if (DOTENV_KEY.length <= 0 && env.type === TYPE_ENV_FILE) {
227
- fileAlreadySpecified = true
228
- }
229
- }
230
-
231
- // return early since envs array objects already contain 1 .env.vault or .env file
232
- if (fileAlreadySpecified) {
233
- return envs
234
- }
235
-
236
- // no .env.vault or .env file specified as a flag so we assume either .env.vault (if dotenv key is set) or a .env file
237
- if (DOTENV_KEY.length > 0) {
238
- // if DOTENV_KEY is set then default to look for .env.vault file
239
- return [...DEFAULT_ENV_VAULTS, ...envs]
240
- } else {
241
- // if no DOTENV_KEY then default to look for .env file
242
- return [...DEFAULT_ENVS, ...envs]
243
- }
244
- }
245
- }
246
-
247
186
  // handle scenario for comma separated keys - for use with key rotation
248
187
  // example: DOTENV_KEY="dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod"
249
188
  _dotenvKeys () {
@@ -271,29 +210,6 @@ class Run {
271
210
 
272
211
  return decrypt(ciphertext, dotenvKey)
273
212
  }
274
-
275
- _determinePrivateKey (envFilepath) {
276
- const privateKeyName = guessPrivateKeyName(envFilepath)
277
-
278
- let privateKey
279
- try {
280
- // if installed as sibling module
281
- const projectRoot = path.resolve(process.cwd())
282
- const dotenvxProPath = require.resolve('@dotenvx/dotenvx-pro', { paths: [projectRoot] })
283
- const { keypair } = require(dotenvxProPath)
284
- privateKey = keypair(envFilepath, privateKeyName)
285
- } catch (_e) {
286
- try {
287
- // if installed as binary cli
288
- privateKey = childProcess.execSync(`dotenvx-pro keypair ${privateKeyName} -f ${envFilepath}`, { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim()
289
- } catch (_e) {
290
- // fallback to local KeyPair - smart enough to handle process.env, .env.keys, etc
291
- privateKey = new Keypair(envFilepath, privateKeyName).run()
292
- }
293
- }
294
-
295
- return privateKey
296
- }
297
213
  }
298
214
 
299
215
  module.exports = Run