@dotenvx/dotenvx 1.75.1 → 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 (85) hide show
  1. package/CHANGELOG.md +24 -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 +0 -8
  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/keypairMetadata.js +1 -1
  25. package/src/lib/main.d.ts +2 -39
  26. package/src/lib/main.js +82 -45
  27. package/src/lib/providers/armor/index.js +29 -0
  28. package/src/lib/providers/index.js +46 -0
  29. package/src/lib/providers/worker.js +6 -0
  30. package/src/lib/resolvers/envs.js +302 -0
  31. package/src/lib/resolvers/get.js +69 -0
  32. package/src/lib/resolvers/keypair.js +81 -0
  33. package/src/lib/resolvers/ls.js +41 -0
  34. package/src/lib/services/armorDown.js +2 -2
  35. package/src/lib/services/{armorKeypair.js → armorKeyring.js} +14 -51
  36. package/src/lib/services/armorMove.js +2 -2
  37. package/src/lib/services/armorPull.js +2 -2
  38. package/src/lib/services/armorPush.js +2 -2
  39. package/src/lib/services/armorUp.js +2 -2
  40. package/src/lib/services/genexample.js +5 -6
  41. package/src/lib/services/login.js +25 -0
  42. package/src/lib/services/prebuild.js +9 -3
  43. package/src/lib/services/precommit.js +9 -3
  44. package/src/lib/transforms/decrypt.js +83 -0
  45. package/src/lib/transforms/encrypt.js +179 -0
  46. package/src/lib/transforms/set.js +179 -0
  47. package/src/shared/logger.js +5 -0
  48. package/src/cli/actions/normalizeArmorOptions.js +0 -10
  49. package/src/cli/actions/rotate.js +0 -87
  50. package/src/lib/helpers/append.js +0 -62
  51. package/src/lib/helpers/cryptography/armorKeypair.js +0 -42
  52. package/src/lib/helpers/cryptography/armorKeypairSync.js +0 -55
  53. package/src/lib/helpers/cryptography/encryptValue.js +0 -7
  54. package/src/lib/helpers/cryptography/localKeypair.js +0 -14
  55. package/src/lib/helpers/cryptography/mutateKeysSrcSync.js +0 -38
  56. package/src/lib/helpers/cryptography/provision.js +0 -56
  57. package/src/lib/helpers/cryptography/provisionSync.js +0 -51
  58. package/src/lib/helpers/cryptography/provisionWithPrivateKey.js +0 -26
  59. package/src/lib/helpers/escapeDollarSigns.js +0 -5
  60. package/src/lib/helpers/escapeForRegex.js +0 -5
  61. package/src/lib/helpers/evalKeyValue.js +0 -23
  62. package/src/lib/helpers/isIgnoringDotenvKeys.js +0 -19
  63. package/src/lib/helpers/keyResolution/index.js +0 -16
  64. package/src/lib/helpers/keyResolution/keyNamesForEnvFile.js +0 -24
  65. package/src/lib/helpers/keyResolution/keyValues.js +0 -99
  66. package/src/lib/helpers/keyResolution/keyValuesFromEnvSrc.js +0 -85
  67. package/src/lib/helpers/keyResolution/keyValuesSync.js +0 -103
  68. package/src/lib/helpers/keyResolution/readFileKey.js +0 -19
  69. package/src/lib/helpers/keyResolution/readFileKeySync.js +0 -17
  70. package/src/lib/helpers/keyResolution/readProcessKey.js +0 -7
  71. package/src/lib/helpers/localDisplayPath.js +0 -11
  72. package/src/lib/helpers/parse.js +0 -214
  73. package/src/lib/helpers/pluralize.js +0 -10
  74. package/src/lib/helpers/quotes.js +0 -36
  75. package/src/lib/helpers/replace.js +0 -82
  76. package/src/lib/helpers/resolveEscapeSequences.js +0 -5
  77. package/src/lib/services/decrypt.js +0 -156
  78. package/src/lib/services/encrypt.js +0 -213
  79. package/src/lib/services/get.js +0 -76
  80. package/src/lib/services/keypair.js +0 -60
  81. package/src/lib/services/loginPoll.js +0 -36
  82. package/src/lib/services/ls.js +0 -57
  83. package/src/lib/services/rotate.js +0 -197
  84. package/src/lib/services/run.js +0 -255
  85. package/src/lib/services/sets.js +0 -328
@@ -1,328 +0,0 @@
1
- const fsx = require('./../helpers/fsx')
2
- const path = require('path')
3
- const { encrypted, scan } = require('@dotenvx/primitives')
4
-
5
- const TYPE_ENV_FILE = 'envFile'
6
-
7
- const Errors = require('./../helpers/errors')
8
-
9
- const {
10
- determine
11
- } = require('./../helpers/envResolution')
12
-
13
- const {
14
- keyNamesForEnvFile,
15
- keyValues,
16
- keyValuesSync
17
- } = require('./../helpers/keyResolution')
18
-
19
- const {
20
- encryptValue,
21
- decryptKeyValue,
22
- provision,
23
- provisionSync,
24
- provisionWithPrivateKey
25
- } = require('./../helpers/cryptography')
26
-
27
- const replace = require('./../helpers/replace')
28
- const detectEncoding = require('./../helpers/detectEncoding')
29
- const detectEncodingSync = require('./../helpers/detectEncodingSync')
30
-
31
- function allValuesForKey (envSrc, key) {
32
- return scan(envSrc).parsed[key] || []
33
- }
34
-
35
- function finalValueForKey (envSrc, key) {
36
- const values = allValuesForKey(envSrc, key)
37
- return values.length > 0 ? values[values.length - 1] : null
38
- }
39
-
40
- class Sets {
41
- constructor (key, value, envs = [], encrypt = true, envKeysFilepath = null, noArmor = false, noCreate = false, options = {}) {
42
- this.envs = determine(envs, process.env)
43
- this.key = key
44
- this.value = value
45
- this.encrypt = encrypt
46
- this.envKeysFilepath = envKeysFilepath
47
- this.noArmor = noArmor
48
- this.noCreate = noCreate
49
- this.command = options.command
50
-
51
- this.processedEnvs = []
52
- this.changedFilepaths = new Set()
53
- this.unchangedFilepaths = new Set()
54
- this.readableFilepaths = new Set()
55
- }
56
-
57
- runSync () {
58
- // example
59
- // envs [
60
- // { type: 'envFile', value: '.env' }
61
- // ]
62
-
63
- for (const env of this.envs) {
64
- if (env.type === TYPE_ENV_FILE) {
65
- this._setEnvFileSync(env.value)
66
- }
67
- }
68
-
69
- return {
70
- processedEnvs: this.processedEnvs,
71
- changedFilepaths: [...this.changedFilepaths],
72
- unchangedFilepaths: [...this.unchangedFilepaths]
73
- }
74
- }
75
-
76
- async run () {
77
- // example
78
- // envs [
79
- // { type: 'envFile', value: '.env' }
80
- // ]
81
-
82
- for (const env of this.envs) {
83
- if (env.type === TYPE_ENV_FILE) {
84
- await this._setEnvFile(env.value)
85
- }
86
- }
87
-
88
- return {
89
- processedEnvs: this.processedEnvs,
90
- changedFilepaths: [...this.changedFilepaths],
91
- unchangedFilepaths: [...this.unchangedFilepaths]
92
- }
93
- }
94
-
95
- _setEnvFileSync (envFilepath) {
96
- const row = {}
97
- row.key = this.key || null
98
- row.value = this.value || null
99
- row.type = TYPE_ENV_FILE
100
-
101
- const filepath = path.resolve(envFilepath)
102
- row.filepath = filepath
103
- row.envFilepath = envFilepath
104
- row.changed = false
105
-
106
- try {
107
- let seededWithInitialKey = false
108
-
109
- if (!fsx.existsSync(filepath)) {
110
- if (this.noCreate) {
111
- detectEncodingSync(filepath) // throws ENOENT
112
- } else {
113
- fsx.writeFileXSync(filepath, '')
114
- }
115
- }
116
-
117
- const encoding = detectEncodingSync(filepath)
118
- let envSrc = fsx.readFileXSync(filepath, { encoding })
119
-
120
- // blank files seeded by `set` should contain only the key being set
121
- if (row.key && envSrc.trim().length === 0) {
122
- envSrc = `${row.key}="${this.value}"\n`
123
- seededWithInitialKey = true
124
- }
125
-
126
- row.originalValue = finalValueForKey(envSrc, row.key)
127
- if (seededWithInitialKey) {
128
- row.originalValue = null
129
- }
130
- const wasPlainText = !encrypted(row.originalValue)
131
- this.readableFilepaths.add(envFilepath)
132
-
133
- if (this.encrypt) {
134
- let publicKey
135
- let privateKey
136
-
137
- const { publicKeyName, privateKeyName } = keyNamesForEnvFile(filepath)
138
- const { publicKeyValue, privateKeyValue } = keyValuesSync(filepath, {
139
- keysFilepath: this.envKeysFilepath,
140
- noArmor: this.noArmor,
141
- command: this.command
142
- })
143
-
144
- // first pass - provisionSync
145
- if (!privateKeyValue && !publicKeyValue) {
146
- const prov = provisionSync({
147
- envSrc,
148
- envFilepath,
149
- keysFilepath: this.envKeysFilepath,
150
- noArmor: this.noArmor,
151
- command: this.command
152
- })
153
- envSrc = prov.envSrc
154
- publicKey = prov.publicKey
155
- privateKey = prov.privateKey
156
- row.envKeysFilepath = prov.envKeysFilepath
157
- row.localPrivateKeyAdded = prov.localPrivateKeyAdded
158
- row.remotePrivateKeyAdded = prov.remotePrivateKeyAdded
159
- } else if (privateKeyValue) {
160
- const prov = provisionWithPrivateKey({ envSrc, envFilepath, keysFilepath: this.envKeysFilepath, privateKeyValue, publicKeyValue, publicKeyName })
161
- publicKey = prov.publicKey
162
- privateKey = prov.privateKey
163
- envSrc = prov.envSrc
164
-
165
- if (row.originalValue) {
166
- row.originalValue = decryptKeyValue(row.key, row.originalValue, privateKeyName, privateKey)
167
- }
168
- } else if (publicKeyValue) {
169
- publicKey = publicKeyValue
170
- }
171
-
172
- row.publicKey = publicKey
173
- row.privateKey = privateKey
174
- try {
175
- row.encryptedValue = encryptValue(this.value, publicKey)
176
- } catch {
177
- throw new Errors({ publicKeyName, publicKey }).invalidPublicKey()
178
- }
179
- row.privateKeyName = privateKeyName
180
- }
181
-
182
- const goingFromPlainTextToEncrypted = wasPlainText && this.encrypt
183
- const valueChanged = this.value !== row.originalValue
184
- const duplicateKey = allValuesForKey(envSrc, row.key).length > 1
185
- const shouldPersistSeededPlainValue = seededWithInitialKey && !this.encrypt
186
-
187
- if (shouldPersistSeededPlainValue) {
188
- row.envSrc = envSrc
189
- this.changedFilepaths.add(envFilepath)
190
- row.changed = true
191
- } else if (goingFromPlainTextToEncrypted || valueChanged || duplicateKey) {
192
- row.envSrc = replace(envSrc, this.key, row.encryptedValue || this.value)
193
- this.changedFilepaths.add(envFilepath)
194
- row.changed = true
195
- } else {
196
- row.envSrc = envSrc
197
- this.unchangedFilepaths.add(envFilepath)
198
- row.changed = false
199
- }
200
- } catch (e) {
201
- if (e.code === 'ENOENT') {
202
- row.error = new Errors({ envFilepath, filepath }).missingEnvFile()
203
- } else {
204
- row.error = e
205
- }
206
- }
207
-
208
- this.processedEnvs.push(row)
209
- }
210
-
211
- async _setEnvFile (envFilepath) {
212
- const row = {}
213
- row.key = this.key || null
214
- row.value = this.value || null
215
- row.type = TYPE_ENV_FILE
216
-
217
- const filepath = path.resolve(envFilepath)
218
- row.filepath = filepath
219
- row.envFilepath = envFilepath
220
- row.changed = false
221
-
222
- try {
223
- let seededWithInitialKey = false
224
-
225
- if (!(await fsx.exists(filepath))) {
226
- if (this.noCreate) {
227
- await detectEncoding(filepath) // throws ENOENT
228
- } else {
229
- await fsx.writeFileX(filepath, '')
230
- }
231
- }
232
-
233
- const encoding = await detectEncoding(filepath)
234
- let envSrc = await fsx.readFileX(filepath, { encoding })
235
-
236
- // blank files seeded by `set` should contain only the key being set
237
- if (row.key && envSrc.trim().length === 0) {
238
- envSrc = `${row.key}="${this.value}"\n`
239
- seededWithInitialKey = true
240
- }
241
-
242
- row.originalValue = finalValueForKey(envSrc, row.key)
243
- if (seededWithInitialKey) {
244
- row.originalValue = null
245
- }
246
- const wasPlainText = !encrypted(row.originalValue)
247
- this.readableFilepaths.add(envFilepath)
248
-
249
- if (this.encrypt) {
250
- let publicKey
251
- let privateKey
252
-
253
- const { publicKeyName, privateKeyName } = keyNamesForEnvFile(filepath)
254
- const { publicKeyValue, privateKeyValue } = await keyValues(filepath, {
255
- keysFilepath: this.envKeysFilepath,
256
- noArmor: this.noArmor,
257
- command: this.command
258
- })
259
-
260
- // first pass - provision
261
- if (!privateKeyValue && !publicKeyValue) {
262
- const prov = await provision({
263
- envSrc,
264
- envFilepath,
265
- keysFilepath: this.envKeysFilepath,
266
- noArmor: this.noArmor,
267
- command: this.command
268
- })
269
- envSrc = prov.envSrc
270
- publicKey = prov.publicKey
271
- privateKey = prov.privateKey
272
- row.envKeysFilepath = prov.envKeysFilepath
273
- row.localPrivateKeyAdded = prov.localPrivateKeyAdded
274
- row.remotePrivateKeyAdded = prov.remotePrivateKeyAdded
275
- } else if (privateKeyValue) {
276
- const prov = provisionWithPrivateKey({ envSrc, envFilepath, keysFilepath: this.envKeysFilepath, privateKeyValue, publicKeyValue, publicKeyName })
277
- publicKey = prov.publicKey
278
- privateKey = prov.privateKey
279
- envSrc = prov.envSrc
280
-
281
- if (row.originalValue) {
282
- row.originalValue = decryptKeyValue(row.key, row.originalValue, privateKeyName, privateKey)
283
- }
284
- } else if (publicKeyValue) {
285
- publicKey = publicKeyValue
286
- }
287
-
288
- row.publicKey = publicKey
289
- row.privateKey = privateKey
290
- try {
291
- row.encryptedValue = encryptValue(this.value, publicKey)
292
- } catch {
293
- throw new Errors({ publicKeyName, publicKey }).invalidPublicKey()
294
- }
295
- row.privateKeyName = privateKeyName
296
- }
297
-
298
- const goingFromPlainTextToEncrypted = wasPlainText && this.encrypt
299
- const valueChanged = this.value !== row.originalValue
300
- const duplicateKey = allValuesForKey(envSrc, row.key).length > 1
301
- const shouldPersistSeededPlainValue = seededWithInitialKey && !this.encrypt
302
-
303
- if (shouldPersistSeededPlainValue) {
304
- row.envSrc = envSrc
305
- this.changedFilepaths.add(envFilepath)
306
- row.changed = true
307
- } else if (goingFromPlainTextToEncrypted || valueChanged || duplicateKey) {
308
- row.envSrc = replace(envSrc, this.key, row.encryptedValue || this.value)
309
- this.changedFilepaths.add(envFilepath)
310
- row.changed = true
311
- } else {
312
- row.envSrc = envSrc
313
- this.unchangedFilepaths.add(envFilepath)
314
- row.changed = false
315
- }
316
- } catch (e) {
317
- if (e.code === 'ENOENT') {
318
- row.error = new Errors({ envFilepath, filepath }).missingEnvFile()
319
- } else {
320
- row.error = e
321
- }
322
- }
323
-
324
- this.processedEnvs.push(row)
325
- }
326
- }
327
-
328
- module.exports = Sets