@dotenvx/dotenvx 1.22.2 → 1.23.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 +7 -1
- package/package.json +1 -1
- package/src/lib/helpers/dotenvExpand.js +29 -34
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,13 @@
|
|
|
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.23.0...main)
|
|
6
|
+
|
|
7
|
+
## 1.23.0
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* deeper variable expansion support and protection against self-referencing variables 🛡️ ([#439](https://github.com/dotenvx/dotenvx/pull/439))
|
|
6
12
|
|
|
7
13
|
## 1.22.2
|
|
8
14
|
|
package/package.json
CHANGED
|
@@ -1,44 +1,39 @@
|
|
|
1
|
-
// * /
|
|
2
|
-
// * (\\)? # is it escaped with a backslash?
|
|
3
|
-
// * (\$) # literal $
|
|
4
|
-
// * (?!\() # shouldnt be followed by parenthesis
|
|
5
|
-
// * (\{?) # first brace wrap opening
|
|
6
|
-
// * ([\w.]+) # key
|
|
7
|
-
// * (?::-((?:\$\{(?:\$\{(?:\$\{[^}]*\}|[^}])*}|[^}])*}|[^}])+))? # optional default nested 3 times
|
|
8
|
-
// * (\}?) # last brace warp closing
|
|
9
|
-
// * /xi
|
|
10
|
-
|
|
11
|
-
const DOTENV_SUBSTITUTION_REGEX = /(\\)?(\$)(?!\()(\{?)([\w.]+)(?::?-((?:\$\{(?:\$\{(?:\$\{[^}]*\}|[^}])*}|[^}])*}|[^}])+))?(\}?)/gi
|
|
12
|
-
|
|
13
1
|
function _resolveEscapeSequences (value) {
|
|
14
2
|
return value.replace(/\\\$/g, '$')
|
|
15
3
|
}
|
|
16
4
|
|
|
17
|
-
function interpolate (value,
|
|
18
|
-
|
|
19
|
-
if (escaped === '\\') {
|
|
20
|
-
return match.slice(1)
|
|
21
|
-
} else {
|
|
22
|
-
if (lookups[key]) {
|
|
23
|
-
// avoid recursion from EXPAND_SELF=$EXPAND_SELF
|
|
24
|
-
if (lookups[key] === value) {
|
|
25
|
-
return lookups[key]
|
|
26
|
-
} else {
|
|
27
|
-
return interpolate(lookups[key], lookups)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
5
|
+
function interpolate (value, env) {
|
|
6
|
+
const regex = /(?<!\\)\${([^{}]+)}|(?<!\\)\$([A-Za-z_][A-Za-z0-9_]*)/g
|
|
30
7
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
8
|
+
let result = value
|
|
9
|
+
let match
|
|
10
|
+
const seen = new Set() // self-referential checker
|
|
11
|
+
|
|
12
|
+
while ((match = regex.exec(result)) !== null) {
|
|
13
|
+
seen.add(result)
|
|
14
|
+
|
|
15
|
+
const [template, bracedExpression, unbracedExpression] = match
|
|
16
|
+
const expression = bracedExpression || unbracedExpression
|
|
17
|
+
const r = expression.split(/:-|-/)
|
|
18
|
+
const key = r.shift()
|
|
19
|
+
const defaultValue = r.join('-')
|
|
20
|
+
const value = env[key]
|
|
38
21
|
|
|
39
|
-
|
|
22
|
+
if (value) {
|
|
23
|
+
// self-referential check
|
|
24
|
+
if (seen.has(value)) {
|
|
25
|
+
result = result.replace(template, defaultValue)
|
|
26
|
+
} else {
|
|
27
|
+
result = result.replace(template, value)
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
result = result.replace(template, defaultValue)
|
|
40
31
|
}
|
|
41
|
-
|
|
32
|
+
|
|
33
|
+
regex.lastIndex = 0 // reset regex search position to re-evaluate after each replacement
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return result
|
|
42
37
|
}
|
|
43
38
|
|
|
44
39
|
function expand (options) {
|