@dotenvx/dotenvx 1.37.0 → 1.38.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/lib/helpers/errors.js +12 -0
- package/src/lib/helpers/evalKeyValue.js +23 -0
- package/src/lib/helpers/parse.js +9 -11
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/v1.
|
|
5
|
+
[Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.38.0...main)
|
|
6
|
+
|
|
7
|
+
## [1.38.0](https://github.com/dotenvx/dotenvx/compare/v1.37.0...v1.38.0)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
* Command substitution failures no longer halt further processing of keys in a .env file ([#533](https://github.com/dotenvx/dotenvx/pull/533))
|
|
12
|
+
* A more helpful error is raised if a command substitution failure occurs ([#533](https://github.com/dotenvx/dotenvx/pull/533))
|
|
6
13
|
|
|
7
14
|
## [1.37.0](https://github.com/dotenvx/dotenvx/compare/v1.36.0...v1.37.0)
|
|
8
15
|
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ class Errors {
|
|
|
8
8
|
this.key = options.key
|
|
9
9
|
this.privateKey = options.privateKey
|
|
10
10
|
this.privateKeyName = options.privateKeyName
|
|
11
|
+
this.command = options.command
|
|
11
12
|
|
|
12
13
|
this.message = options.message
|
|
13
14
|
}
|
|
@@ -84,6 +85,17 @@ class Errors {
|
|
|
84
85
|
e.code = code
|
|
85
86
|
return e
|
|
86
87
|
}
|
|
88
|
+
|
|
89
|
+
commandSubstitutionFailed () {
|
|
90
|
+
const code = 'COMMAND_SUBSTITUTION_FAILED'
|
|
91
|
+
const message = `[${code}] could not eval ${this.key} containing command '${this.command}': ${this.message}`
|
|
92
|
+
const help = `[${code}] https://github.com/dotenvx/dotenvx/issues/532`
|
|
93
|
+
|
|
94
|
+
const e = new Error(message)
|
|
95
|
+
e.code = code
|
|
96
|
+
e.help = help
|
|
97
|
+
return e
|
|
98
|
+
}
|
|
87
99
|
}
|
|
88
100
|
|
|
89
101
|
module.exports = Errors
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const { execSync } = require('child_process')
|
|
2
|
+
const chomp = require('./chomp')
|
|
3
|
+
const Errors = require('./errors')
|
|
4
|
+
|
|
5
|
+
function evalKeyValue (key, value, processEnv, runningParsed) {
|
|
6
|
+
// Match everything between the outermost $() using a regex with non-capturing groups
|
|
7
|
+
const matches = value.match(/\$\(([^)]+(?:\)[^(]*)*)\)/g) || []
|
|
8
|
+
return matches.reduce((newValue, match) => {
|
|
9
|
+
const command = match.slice(2, -1) // Extract command by removing $() wrapper
|
|
10
|
+
let result
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
result = execSync(command, { env: { ...processEnv, ...runningParsed } }).toString() // execute command (including runningParsed)
|
|
14
|
+
} catch (e) {
|
|
15
|
+
throw new Errors({ key, command, message: e.message.trim() }).commandSubstitutionFailed()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
result = chomp(result) // chomp it
|
|
19
|
+
return newValue.replace(match, result) // Replace match with result
|
|
20
|
+
}, value)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = evalKeyValue
|
package/src/lib/helpers/parse.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const chomp = require('./chomp')
|
|
2
1
|
const decryptKeyValue = require('./decryptKeyValue')
|
|
2
|
+
const evalKeyValue = require('./evalKeyValue')
|
|
3
3
|
const resolveEscapeSequences = require('./resolveEscapeSequences')
|
|
4
|
-
const { execSync } = require('child_process')
|
|
5
4
|
|
|
6
5
|
class Parse {
|
|
7
6
|
static LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
|
|
@@ -49,7 +48,12 @@ class Parse {
|
|
|
49
48
|
let evaled = false
|
|
50
49
|
if (quote !== "'" && (!this.inProcessEnv(key) || this.processEnv[key] === this.parsed[key])) {
|
|
51
50
|
const priorEvaled = this.parsed[key]
|
|
52
|
-
|
|
51
|
+
// eval
|
|
52
|
+
try {
|
|
53
|
+
this.parsed[key] = this.eval(key, priorEvaled)
|
|
54
|
+
} catch (e) {
|
|
55
|
+
this.errors.push(e)
|
|
56
|
+
}
|
|
53
57
|
if (priorEvaled !== this.parsed[key]) {
|
|
54
58
|
evaled = true
|
|
55
59
|
}
|
|
@@ -133,14 +137,8 @@ class Parse {
|
|
|
133
137
|
return decryptKeyValue(key, value, this.privateKeyName, this.privateKey)
|
|
134
138
|
}
|
|
135
139
|
|
|
136
|
-
eval (value) {
|
|
137
|
-
|
|
138
|
-
const matches = value.match(/\$\(([^)]+(?:\)[^(]*)*)\)/g) || []
|
|
139
|
-
return matches.reduce((newValue, match) => {
|
|
140
|
-
const command = match.slice(2, -1) // Extract command by removing $() wrapper
|
|
141
|
-
const result = chomp(execSync(command, { env: { ...this.processEnv, ...this.runningParsed } }).toString()) // execute command (including runningParsed)
|
|
142
|
-
return newValue.replace(match, result) // Replace match with result
|
|
143
|
-
}, value)
|
|
140
|
+
eval (key, value) {
|
|
141
|
+
return evalKeyValue(key, value, this.processEnv, this.runningParsed)
|
|
144
142
|
}
|
|
145
143
|
|
|
146
144
|
expand (value) {
|