@dotenvx/dotenvx 2.7.3 → 2.8.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 +8 -1
- package/package.json +1 -1
- package/src/cli/actions/ext/prebuild.js +1 -1
- package/src/cli/actions/ext/precommit.js +1 -1
- package/src/cli/actions/get.js +1 -1
- package/src/cli/actions/run.js +1 -1
- package/src/lib/api/postArmorDecrypt.js +49 -0
- package/src/lib/decryptors/armor/index.js +21 -0
- package/src/lib/decryptors/decryptor-worker.js +6 -0
- package/src/lib/decryptors/index.js +69 -0
- package/src/lib/helpers/catchAndLog.js +5 -0
- package/src/lib/helpers/errors.js +14 -0
- package/src/lib/helpers/isNetworkError.js +21 -0
- package/src/lib/helpers/parseWithDecryptor.js +66 -0
- package/src/lib/main.js +5 -5
- package/src/lib/providers/armor/index.js +10 -1
- package/src/lib/providers/index.js +2 -2
- package/src/lib/providers/provider-worker.js +6 -0
- package/src/lib/resolvers/envs.js +32 -16
- package/src/lib/transforms/decrypt.js +5 -2
- package/src/lib/providers/worker.js +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,14 @@
|
|
|
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/v2.
|
|
5
|
+
[Unreleased](https://github.com/dotenvx/dotenvx/compare/v2.8.0...main)
|
|
6
|
+
|
|
7
|
+
## [2.8.0](https://github.com/dotenvx/dotenvx/compare/v2.7.3...v2.8.0) (2026-07-14)
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* Add `FILE_NOT_WRITABLE` error for user convenience ([#891](https://github.com/dotenvx/dotenvx/pull/891))
|
|
12
|
+
* Support Enclaved Armored Keys ([#892](https://github.com/dotenvx/dotenvx/pull/892))
|
|
6
13
|
|
|
7
14
|
## [2.7.3](https://github.com/dotenvx/dotenvx/compare/v2.7.2...v2.7.3) (2026-07-13)
|
|
8
15
|
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@ function precommit (directory) {
|
|
|
17
17
|
} = new Precommit(directory, options).run()
|
|
18
18
|
|
|
19
19
|
for (const warning of warnings) {
|
|
20
|
-
logger.warn(warning.messageWithHelp)
|
|
20
|
+
logger.warn(warning.messageWithHelp || warning.message)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
logger.success(successMessage)
|
package/src/cli/actions/get.js
CHANGED
package/src/cli/actions/run.js
CHANGED
|
@@ -151,7 +151,7 @@ async function run () {
|
|
|
151
151
|
if (error.code === 'MISSING_ENV_FILE' && options.convention) { // do not output error for conventions (too noisy)
|
|
152
152
|
// intentionally quiet
|
|
153
153
|
} else {
|
|
154
|
-
logger.error(error.messageWithHelp)
|
|
154
|
+
logger.error(error.messageWithHelp || error.message)
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const { http } = require('../helpers/http')
|
|
2
|
+
const buildApiError = require('../helpers/buildApiError')
|
|
3
|
+
const packageJson = require('../helpers/packageJson')
|
|
4
|
+
const normalizeToken = require('../helpers/normalizeToken')
|
|
5
|
+
|
|
6
|
+
class PostArmorDecrypt {
|
|
7
|
+
constructor (hostname, token, devicePublicKey, publicKey, src, grantToken) {
|
|
8
|
+
this.hostname = hostname || 'https://armor.dotenvx.com'
|
|
9
|
+
this.token = token
|
|
10
|
+
this.devicePublicKey = devicePublicKey
|
|
11
|
+
this.publicKey = publicKey
|
|
12
|
+
this.src = src
|
|
13
|
+
this.grantToken = grantToken
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async run () {
|
|
17
|
+
const token = normalizeToken(this.token)
|
|
18
|
+
const url = `${this.hostname}/api/armor/decrypt`
|
|
19
|
+
const body = {
|
|
20
|
+
device_public_key: this.devicePublicKey,
|
|
21
|
+
cli_version: packageJson.version,
|
|
22
|
+
public_key: this.publicKey,
|
|
23
|
+
src: this.src
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (this.grantToken) {
|
|
27
|
+
body.grant_token = this.grantToken
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const resp = await http(url, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: `Bearer ${token}`,
|
|
34
|
+
'Content-Type': 'application/json'
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify(body)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const json = await resp.body.json()
|
|
40
|
+
|
|
41
|
+
if (resp.statusCode >= 400) {
|
|
42
|
+
throw buildApiError(resp.statusCode, json)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return json
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = PostArmorDecrypt
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const Session = require('../../../db/session')
|
|
2
|
+
const PostArmorDecrypt = require('../../api/postArmorDecrypt')
|
|
3
|
+
|
|
4
|
+
async function index (src, options = {}) {
|
|
5
|
+
const sesh = new Session()
|
|
6
|
+
|
|
7
|
+
const hostname = sesh.hostname()
|
|
8
|
+
const token = sesh.token()
|
|
9
|
+
const devicePublicKey = sesh.devicePublicKey()
|
|
10
|
+
|
|
11
|
+
return await new PostArmorDecrypt(
|
|
12
|
+
hostname,
|
|
13
|
+
token,
|
|
14
|
+
devicePublicKey,
|
|
15
|
+
options.publicKey,
|
|
16
|
+
src,
|
|
17
|
+
options.grantToken
|
|
18
|
+
).run()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = index
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const Session = require('./../../db/session')
|
|
2
|
+
|
|
3
|
+
const armorDecryptor = require('./armor/index')
|
|
4
|
+
|
|
5
|
+
function syncArmorDecryptor (src, options) {
|
|
6
|
+
const { createSyncFn } = require('@dotenvx/tooling')
|
|
7
|
+
const runDecryptorSync = createSyncFn(require.resolve('./decryptor-worker.js'))
|
|
8
|
+
return runDecryptorSync(src, options)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function armorDecryptorForOptions (options) {
|
|
12
|
+
return (src, decryptOptions) => armorDecryptor(src, {
|
|
13
|
+
...decryptOptions,
|
|
14
|
+
onStatus: options.onStatus,
|
|
15
|
+
token: options.token,
|
|
16
|
+
command: options.command
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function syncArmorDecryptorForOptions (options) {
|
|
21
|
+
return (src, decryptOptions) => syncArmorDecryptor(src, {
|
|
22
|
+
...decryptOptions,
|
|
23
|
+
onStatus: options.onStatus,
|
|
24
|
+
token: options.token,
|
|
25
|
+
command: options.command
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function useArmor (options, noArmor) {
|
|
30
|
+
return options.noArmor !== true && options.armor !== false && !noArmor
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function decryptors (options = {}) {
|
|
34
|
+
if (Object.prototype.hasOwnProperty.call(options, 'decryptor')) {
|
|
35
|
+
return options.decryptor
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (options.noArmor === true || options.armor === false) {
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const sesh = new Session()
|
|
43
|
+
const noArmor = !options.token && await sesh.noArmor()
|
|
44
|
+
if (!useArmor(options, noArmor)) {
|
|
45
|
+
return null
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return armorDecryptorForOptions(options)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
decryptors.sync = function decryptorsSync (options = {}) {
|
|
52
|
+
if (Object.prototype.hasOwnProperty.call(options, 'decryptor')) {
|
|
53
|
+
return options.decryptor
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (options.noArmor === true || options.armor === false) {
|
|
57
|
+
return null
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const sesh = new Session()
|
|
61
|
+
const noArmor = !options.token && sesh.noArmorSync()
|
|
62
|
+
if (!useArmor(options, noArmor)) {
|
|
63
|
+
return null
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return syncArmorDecryptorForOptions(options)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = decryptors
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
const { logger } = require('./../../shared/logger')
|
|
2
|
+
const Errors = require('./errors')
|
|
2
3
|
|
|
3
4
|
function catchAndLog (error) {
|
|
5
|
+
if (error.code === 'EACCES' || error.code === 'EPERM') {
|
|
6
|
+
error = new Errors({ filepath: error.path }).fileNotWritable()
|
|
7
|
+
}
|
|
8
|
+
|
|
4
9
|
const msg = error.messageWithHelp || error.message
|
|
5
10
|
if (msg) {
|
|
6
11
|
logger.error(msg)
|
|
@@ -20,6 +20,7 @@ const ISSUE_BY_CODE = {
|
|
|
20
20
|
MISSING_PRIVATE_KEY: 'https://github.com/dotenvx/dotenvx/issues/464',
|
|
21
21
|
MISSING_PUBLIC_KEY: 'https://github.com/dotenvx/dotenvx/issues/865',
|
|
22
22
|
MISSING_VALUE: 'https://github.com/dotenvx/dotenvx/issues/864',
|
|
23
|
+
FILE_NOT_WRITABLE: 'https://github.com/dotenvx/dotenvx/issues/890',
|
|
23
24
|
PRECOMMIT_HOOK_MODIFY_FAILED: 'try again or report error',
|
|
24
25
|
WRONG_PRIVATE_KEY: 'https://github.com/dotenvx/dotenvx/issues/466'
|
|
25
26
|
}
|
|
@@ -279,6 +280,19 @@ class Errors {
|
|
|
279
280
|
return e
|
|
280
281
|
}
|
|
281
282
|
|
|
283
|
+
fileNotWritable () {
|
|
284
|
+
const code = 'FILE_NOT_WRITABLE'
|
|
285
|
+
const filepath = this.filepath || 'unknown'
|
|
286
|
+
const message = `[${code}] cannot write to file (${filepath})`
|
|
287
|
+
const help = `fix: [${ISSUE_BY_CODE[code]}]`
|
|
288
|
+
|
|
289
|
+
const e = new Error(message)
|
|
290
|
+
e.code = code
|
|
291
|
+
e.help = help
|
|
292
|
+
e.messageWithHelp = `${message}. ${help}`
|
|
293
|
+
return e
|
|
294
|
+
}
|
|
295
|
+
|
|
282
296
|
missingValue () {
|
|
283
297
|
const code = 'MISSING_VALUE'
|
|
284
298
|
const message = `[${code}] missing value (${this.key})`
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const NETWORK_ERROR_CODES = new Set([
|
|
2
|
+
'ECONNRESET',
|
|
3
|
+
'ECONNREFUSED',
|
|
4
|
+
'ENOTFOUND',
|
|
5
|
+
'ENETDOWN',
|
|
6
|
+
'ENETUNREACH',
|
|
7
|
+
'EHOSTDOWN',
|
|
8
|
+
'EHOSTUNREACH',
|
|
9
|
+
'EPIPE',
|
|
10
|
+
'ETIMEDOUT',
|
|
11
|
+
'UND_ERR_CONNECT_TIMEOUT',
|
|
12
|
+
'UND_ERR_HEADERS_TIMEOUT',
|
|
13
|
+
'UND_ERR_BODY_TIMEOUT',
|
|
14
|
+
'UND_ERR_SOCKET'
|
|
15
|
+
])
|
|
16
|
+
|
|
17
|
+
function isNetworkError (error) {
|
|
18
|
+
return NETWORK_ERROR_CODES.has(error && error.code) || NETWORK_ERROR_CODES.has(error && error.cause && error.cause.code)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = isNetworkError
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const { parse, parseSync } = require('@dotenvx/primitives')
|
|
2
|
+
const isNetworkError = require('./isNetworkError')
|
|
3
|
+
|
|
4
|
+
const SERVER_SIDE_DECRYPTION_REQUIRED = 'SERVER_SIDE_DECRYPTION_REQUIRED'
|
|
5
|
+
|
|
6
|
+
function decryptOptions (error) {
|
|
7
|
+
const meta = error.meta || {}
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
publicKey: meta.public_key,
|
|
11
|
+
grantToken: meta.grant_token,
|
|
12
|
+
error
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parseOptionsWithoutProvider (options) {
|
|
17
|
+
return {
|
|
18
|
+
...options,
|
|
19
|
+
provider: null,
|
|
20
|
+
decryptor: null
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function parseWithDecryptor (src, options = {}) {
|
|
25
|
+
try {
|
|
26
|
+
return await parse(src, options)
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (error.code !== SERVER_SIDE_DECRYPTION_REQUIRED || typeof options.decryptor !== 'function') {
|
|
29
|
+
throw error
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const result = await options.decryptor(src, decryptOptions(error))
|
|
34
|
+
return await parse(result.src, parseOptionsWithoutProvider(options))
|
|
35
|
+
} catch (decryptorError) {
|
|
36
|
+
if (isNetworkError(decryptorError)) {
|
|
37
|
+
return await parse(src, parseOptionsWithoutProvider(options))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
throw decryptorError
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
parseWithDecryptor.sync = function parseWithDecryptorSync (src, options = {}) {
|
|
46
|
+
try {
|
|
47
|
+
return parseSync(src, options)
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (error.code !== SERVER_SIDE_DECRYPTION_REQUIRED || typeof options.decryptor !== 'function') {
|
|
50
|
+
throw error
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const result = options.decryptor(src, decryptOptions(error))
|
|
55
|
+
return parseSync(result.src, parseOptionsWithoutProvider(options))
|
|
56
|
+
} catch (decryptorError) {
|
|
57
|
+
if (isNetworkError(decryptorError)) {
|
|
58
|
+
return parseSync(src, parseOptionsWithoutProvider(options))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
throw decryptorError
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = parseWithDecryptor
|
package/src/lib/main.js
CHANGED
|
@@ -115,10 +115,10 @@ const config = function (options = {}) {
|
|
|
115
115
|
|
|
116
116
|
if (error.code === 'MISSING_ENV_FILE') {
|
|
117
117
|
if (!options.convention) { // do not output error for conventions (too noisy)
|
|
118
|
-
logger.error(error.messageWithHelp)
|
|
118
|
+
logger.error(error.messageWithHelp || error.message)
|
|
119
119
|
}
|
|
120
120
|
} else {
|
|
121
|
-
logger.error(error.messageWithHelp)
|
|
121
|
+
logger.error(error.messageWithHelp || error.message)
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
@@ -155,7 +155,7 @@ const config = function (options = {}) {
|
|
|
155
155
|
} catch (error) {
|
|
156
156
|
if (strict) throw error // throw immediately if strict
|
|
157
157
|
|
|
158
|
-
logger.error(error.messageWithHelp)
|
|
158
|
+
logger.error(error.messageWithHelp || error.message)
|
|
159
159
|
|
|
160
160
|
return { parsed: {}, error }
|
|
161
161
|
}
|
|
@@ -209,7 +209,7 @@ const parse = function (src, options = {}) {
|
|
|
209
209
|
continue // ignore error
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
logger.error(error.messageWithHelp)
|
|
212
|
+
logger.error(error.messageWithHelp || error.message)
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
return parsed
|
|
@@ -347,7 +347,7 @@ const get = async function (key, options = {}) {
|
|
|
347
347
|
|
|
348
348
|
if (options.strict) throw error // throw immediately if strict
|
|
349
349
|
|
|
350
|
-
logger.error(error.messageWithHelp)
|
|
350
|
+
logger.error(error.messageWithHelp || error.message)
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
if (key) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const Session = require('../../../db/session')
|
|
2
2
|
const ArmorKeyring = require('../../services/armorKeyring')
|
|
3
3
|
const armoredKeyDisplay = require('../../helpers/armoredKeyDisplay')
|
|
4
|
+
const isNetworkError = require('../../helpers/isNetworkError')
|
|
4
5
|
|
|
5
6
|
async function index (publicKeyHex, options = {}) {
|
|
6
7
|
const sesh = new Session()
|
|
@@ -23,7 +24,15 @@ async function index (publicKeyHex, options = {}) {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
try {
|
|
28
|
+
return await keyring.run() // { "publicKey": "privateKey" }
|
|
29
|
+
} catch (error) {
|
|
30
|
+
if (isNetworkError(error)) {
|
|
31
|
+
return {}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
throw error
|
|
35
|
+
}
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
module.exports = index
|
|
@@ -5,8 +5,8 @@ const nativeProvider = require('./native/index')
|
|
|
5
5
|
|
|
6
6
|
function syncArmorProvider (publicKeyHex) {
|
|
7
7
|
const { createSyncFn } = require('@dotenvx/tooling')
|
|
8
|
-
const runProviderSync = createSyncFn(require.resolve('./worker.js'))
|
|
9
|
-
return runProviderSync(
|
|
8
|
+
const runProviderSync = createSyncFn(require.resolve('./provider-worker.js'))
|
|
9
|
+
return runProviderSync(publicKeyHex)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
function hasKey (keyring, publicKeyHex) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fsx = require('./../helpers/fsx')
|
|
2
2
|
const path = require('path')
|
|
3
|
-
const { encrypted
|
|
3
|
+
const { encrypted } = require('@dotenvx/primitives')
|
|
4
4
|
|
|
5
5
|
const TYPE_ENV = 'env'
|
|
6
6
|
const TYPE_ENV_FILE = 'envFile'
|
|
@@ -10,6 +10,8 @@ const detectEncoding = require('./../helpers/detectEncoding')
|
|
|
10
10
|
const detectEncodingSync = require('./../helpers/detectEncodingSync')
|
|
11
11
|
const keynames = require('./../conventions/keynames')
|
|
12
12
|
const providers = require('./../providers')
|
|
13
|
+
const decryptors = require('./../decryptors')
|
|
14
|
+
const parseWithDecryptor = require('./../helpers/parseWithDecryptor')
|
|
13
15
|
|
|
14
16
|
function unresolvedEncryptedErrors (parsed) {
|
|
15
17
|
const keys = []
|
|
@@ -48,7 +50,7 @@ function inject (processEnv, parsed) {
|
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
function buildParseOptions ({ processEnv, overload, envKeysFilepath, provider }) {
|
|
53
|
+
function buildParseOptions ({ processEnv, overload, envKeysFilepath, provider, decryptor }) {
|
|
52
54
|
const options = {
|
|
53
55
|
processEnv,
|
|
54
56
|
overload,
|
|
@@ -61,10 +63,14 @@ function buildParseOptions ({ processEnv, overload, envKeysFilepath, provider })
|
|
|
61
63
|
options.provider = null
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
if (decryptor) {
|
|
67
|
+
options.decryptor = decryptor
|
|
68
|
+
}
|
|
69
|
+
|
|
64
70
|
return options
|
|
65
71
|
}
|
|
66
72
|
|
|
67
|
-
async function injectEnv ({ env, overload, processEnv, envKeysFilepath, provider }) {
|
|
73
|
+
async function injectEnv ({ env, overload, processEnv, envKeysFilepath, provider, decryptor }) {
|
|
68
74
|
const row = {}
|
|
69
75
|
row.type = TYPE_ENV
|
|
70
76
|
row.string = env.value
|
|
@@ -79,7 +85,8 @@ async function injectEnv ({ env, overload, processEnv, envKeysFilepath, provider
|
|
|
79
85
|
processEnv: parseProcessEnv,
|
|
80
86
|
overload,
|
|
81
87
|
envKeysFilepath,
|
|
82
|
-
provider
|
|
88
|
+
provider,
|
|
89
|
+
decryptor
|
|
83
90
|
})
|
|
84
91
|
|
|
85
92
|
const {
|
|
@@ -87,7 +94,7 @@ async function injectEnv ({ env, overload, processEnv, envKeysFilepath, provider
|
|
|
87
94
|
errors,
|
|
88
95
|
injected,
|
|
89
96
|
existed
|
|
90
|
-
} = await
|
|
97
|
+
} = await parseWithDecryptor(env.value, parseOptions)
|
|
91
98
|
|
|
92
99
|
row.parsed = parsed
|
|
93
100
|
row.errors = decryptErrors(parsed, errors)
|
|
@@ -102,7 +109,7 @@ async function injectEnv ({ env, overload, processEnv, envKeysFilepath, provider
|
|
|
102
109
|
return row
|
|
103
110
|
}
|
|
104
111
|
|
|
105
|
-
function injectEnvSync ({ env, overload, processEnv, envKeysFilepath, provider }) {
|
|
112
|
+
function injectEnvSync ({ env, overload, processEnv, envKeysFilepath, provider, decryptor }) {
|
|
106
113
|
const row = {}
|
|
107
114
|
row.type = TYPE_ENV
|
|
108
115
|
row.string = env.value
|
|
@@ -117,7 +124,8 @@ function injectEnvSync ({ env, overload, processEnv, envKeysFilepath, provider }
|
|
|
117
124
|
processEnv: parseProcessEnv,
|
|
118
125
|
overload,
|
|
119
126
|
envKeysFilepath,
|
|
120
|
-
provider
|
|
127
|
+
provider,
|
|
128
|
+
decryptor
|
|
121
129
|
})
|
|
122
130
|
|
|
123
131
|
const {
|
|
@@ -125,7 +133,7 @@ function injectEnvSync ({ env, overload, processEnv, envKeysFilepath, provider }
|
|
|
125
133
|
errors,
|
|
126
134
|
injected,
|
|
127
135
|
existed
|
|
128
|
-
} =
|
|
136
|
+
} = parseWithDecryptor.sync(env.value, parseOptions)
|
|
129
137
|
|
|
130
138
|
row.parsed = parsed
|
|
131
139
|
row.errors = decryptErrors(parsed, errors)
|
|
@@ -140,7 +148,7 @@ function injectEnvSync ({ env, overload, processEnv, envKeysFilepath, provider }
|
|
|
140
148
|
return row
|
|
141
149
|
}
|
|
142
150
|
|
|
143
|
-
async function injectEnvFile ({ env, overload, processEnv, envKeysFilepath, provider, readableFilepaths }) {
|
|
151
|
+
async function injectEnvFile ({ env, overload, processEnv, envKeysFilepath, provider, decryptor, readableFilepaths }) {
|
|
144
152
|
const row = {}
|
|
145
153
|
row.type = TYPE_ENV_FILE
|
|
146
154
|
row.filepath = env.value
|
|
@@ -157,7 +165,8 @@ async function injectEnvFile ({ env, overload, processEnv, envKeysFilepath, prov
|
|
|
157
165
|
processEnv,
|
|
158
166
|
overload,
|
|
159
167
|
envKeysFilepath: fk,
|
|
160
|
-
provider
|
|
168
|
+
provider,
|
|
169
|
+
decryptor
|
|
161
170
|
})
|
|
162
171
|
|
|
163
172
|
const {
|
|
@@ -165,7 +174,7 @@ async function injectEnvFile ({ env, overload, processEnv, envKeysFilepath, prov
|
|
|
165
174
|
errors,
|
|
166
175
|
injected,
|
|
167
176
|
existed
|
|
168
|
-
} = await
|
|
177
|
+
} = await parseWithDecryptor(src, parseOptions)
|
|
169
178
|
|
|
170
179
|
row.src = src
|
|
171
180
|
row.parsed = parsed
|
|
@@ -185,7 +194,7 @@ async function injectEnvFile ({ env, overload, processEnv, envKeysFilepath, prov
|
|
|
185
194
|
return row
|
|
186
195
|
}
|
|
187
196
|
|
|
188
|
-
function injectEnvFileSync ({ env, overload, processEnv, envKeysFilepath, provider, readableFilepaths }) {
|
|
197
|
+
function injectEnvFileSync ({ env, overload, processEnv, envKeysFilepath, provider, decryptor, readableFilepaths }) {
|
|
189
198
|
const row = {}
|
|
190
199
|
row.type = TYPE_ENV_FILE
|
|
191
200
|
row.filepath = env.value
|
|
@@ -202,7 +211,8 @@ function injectEnvFileSync ({ env, overload, processEnv, envKeysFilepath, provid
|
|
|
202
211
|
processEnv,
|
|
203
212
|
overload,
|
|
204
213
|
envKeysFilepath: fk,
|
|
205
|
-
provider
|
|
214
|
+
provider,
|
|
215
|
+
decryptor
|
|
206
216
|
})
|
|
207
217
|
|
|
208
218
|
const {
|
|
@@ -210,7 +220,7 @@ function injectEnvFileSync ({ env, overload, processEnv, envKeysFilepath, provid
|
|
|
210
220
|
errors,
|
|
211
221
|
injected,
|
|
212
222
|
existed
|
|
213
|
-
} =
|
|
223
|
+
} = parseWithDecryptor.sync(src, parseOptions)
|
|
214
224
|
|
|
215
225
|
row.src = src
|
|
216
226
|
row.parsed = parsed
|
|
@@ -236,6 +246,7 @@ async function envs (options = {}) {
|
|
|
236
246
|
const processEnv = options.processEnv || process.env
|
|
237
247
|
const envKeysFilepath = options.envKeysFilepath || options.envKeysFile || null
|
|
238
248
|
const provider = await providers(options)
|
|
249
|
+
const decryptor = await decryptors(options)
|
|
239
250
|
|
|
240
251
|
for (const env of options.envs || []) {
|
|
241
252
|
if (env.type === TYPE_ENV_FILE) {
|
|
@@ -245,6 +256,7 @@ async function envs (options = {}) {
|
|
|
245
256
|
processEnv,
|
|
246
257
|
envKeysFilepath,
|
|
247
258
|
provider,
|
|
259
|
+
decryptor,
|
|
248
260
|
readableFilepaths
|
|
249
261
|
}))
|
|
250
262
|
} else if (env.type === TYPE_ENV) {
|
|
@@ -253,7 +265,8 @@ async function envs (options = {}) {
|
|
|
253
265
|
overload: options.overload,
|
|
254
266
|
processEnv,
|
|
255
267
|
envKeysFilepath,
|
|
256
|
-
provider
|
|
268
|
+
provider,
|
|
269
|
+
decryptor
|
|
257
270
|
}))
|
|
258
271
|
}
|
|
259
272
|
}
|
|
@@ -270,6 +283,7 @@ function envsSync (options = {}) {
|
|
|
270
283
|
const processEnv = options.processEnv || process.env
|
|
271
284
|
const envKeysFilepath = options.envKeysFilepath || options.envKeysFile || null
|
|
272
285
|
const provider = providers.sync(options)
|
|
286
|
+
const decryptor = decryptors.sync(options)
|
|
273
287
|
|
|
274
288
|
for (const env of options.envs || []) {
|
|
275
289
|
if (env.type === TYPE_ENV_FILE) {
|
|
@@ -279,6 +293,7 @@ function envsSync (options = {}) {
|
|
|
279
293
|
processEnv,
|
|
280
294
|
envKeysFilepath,
|
|
281
295
|
provider,
|
|
296
|
+
decryptor,
|
|
282
297
|
readableFilepaths
|
|
283
298
|
}))
|
|
284
299
|
} else if (env.type === TYPE_ENV) {
|
|
@@ -287,7 +302,8 @@ function envsSync (options = {}) {
|
|
|
287
302
|
overload: options.overload,
|
|
288
303
|
processEnv,
|
|
289
304
|
envKeysFilepath,
|
|
290
|
-
provider
|
|
305
|
+
provider,
|
|
306
|
+
decryptor
|
|
291
307
|
}))
|
|
292
308
|
}
|
|
293
309
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fsx = require('./../helpers/fsx')
|
|
2
2
|
const path = require('path')
|
|
3
|
-
const {
|
|
3
|
+
const { upsert } = require('@dotenvx/primitives')
|
|
4
4
|
|
|
5
5
|
const TYPE_ENV_FILE = 'envFile'
|
|
6
6
|
|
|
@@ -8,6 +8,8 @@ const Errors = require('./../helpers/errors')
|
|
|
8
8
|
const { determine } = require('./../helpers/envResolution')
|
|
9
9
|
const detectEncoding = require('./../helpers/detectEncoding')
|
|
10
10
|
const providers = require('./../providers')
|
|
11
|
+
const decryptors = require('./../decryptors')
|
|
12
|
+
const parseWithDecryptor = require('./../helpers/parseWithDecryptor')
|
|
11
13
|
|
|
12
14
|
function parseError (error) {
|
|
13
15
|
return new Errors({
|
|
@@ -23,6 +25,7 @@ async function decrypt (options = {}) {
|
|
|
23
25
|
const ek = options.ek
|
|
24
26
|
const fk = options.fk
|
|
25
27
|
const provider = await providers(options)
|
|
28
|
+
const decryptor = await decryptors(options)
|
|
26
29
|
|
|
27
30
|
const processedEnvs = []
|
|
28
31
|
const changedFilepaths = []
|
|
@@ -41,7 +44,7 @@ async function decrypt (options = {}) {
|
|
|
41
44
|
const encoding = await detectEncoding(filepath)
|
|
42
45
|
row.envSrc = await fsx.readFileX(filepath, { encoding })
|
|
43
46
|
|
|
44
|
-
const { parsed, errors } = await
|
|
47
|
+
const { parsed, errors } = await parseWithDecryptor(row.envSrc, { fk, ik, ek, array: true, provider, decryptor })
|
|
45
48
|
|
|
46
49
|
if (errors.length > 0) {
|
|
47
50
|
row.error = parseError(errors[0])
|