@dotenvx/dotenvx 1.16.1 → 1.18.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 +40 -1
- package/README.md +39 -0
- package/package.json +1 -1
- package/src/cli/actions/get.js +10 -3
- package/src/cli/dotenvx.js +1 -1
- package/src/lib/helpers/escape.js +5 -0
- package/src/lib/helpers/escapeForRegex.js +5 -0
- package/src/lib/helpers/replace.js +38 -21
- package/src/lib/services/genexample.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,46 @@
|
|
|
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.18.0...main)
|
|
6
|
+
|
|
7
|
+
## 1.18.0
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* `set` and `encrypt` preserve leading spaces ([#395](https://github.com/dotenvx/dotenvx/pull/395/))
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
HELLO=world
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
* improve escape and quote handling for `set`, `encrypt`, and `decrypt` ([#395](https://github.com/dotenvx/dotenvx/pull/395))
|
|
20
|
+
* 🐞 fix `encrypt`, then `decrypt`, then `encrypt` on a json value ([#377](https://github.com/dotenvx/dotenvx/issues/377))
|
|
21
|
+
|
|
22
|
+
Note: the underlying `replace` engine to support these changes now wraps your values in single quotes. the prior `replace` engine wrapped in double quotes.
|
|
23
|
+
|
|
24
|
+
So where your `.env` used to look like this with double quotes:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
HELLO="encrypted:1234"
|
|
28
|
+
API_KEY="encrypted:5678"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
It will now begin looking like this with single quotes:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
HELLO='encrypted:1234'
|
|
35
|
+
API_KEY='encrypted:5678'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
It's an aesthetic side effect only. Your values will continue to be decrypted and encrypted correctly.
|
|
39
|
+
|
|
40
|
+
## 1.17.0
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
* add `--format=eval` option for `get` ([#393](https://github.com/dotenvx/dotenvx/pull/393))
|
|
6
45
|
|
|
7
46
|
## 1.16.1
|
|
8
47
|
|
package/README.md
CHANGED
|
@@ -260,6 +260,18 @@ More examples
|
|
|
260
260
|
Hello World
|
|
261
261
|
```
|
|
262
262
|
|
|
263
|
+
</details>
|
|
264
|
+
* <details><summary>Kotlin 📐</summary><br>
|
|
265
|
+
|
|
266
|
+
```sh
|
|
267
|
+
$ echo "HELLO=World" > .env
|
|
268
|
+
$ echo 'fun main() { val hello = System.getenv("HELLO") ?: ""; println("Hello $hello") }' > index.kt
|
|
269
|
+
$ kotlinc index.kt -include-runtime -d index.jar
|
|
270
|
+
|
|
271
|
+
$ dotenvx run -- java -jar index.jar
|
|
272
|
+
Hello World
|
|
273
|
+
```
|
|
274
|
+
|
|
263
275
|
</details>
|
|
264
276
|
* <details><summary>.NET 🔵</summary><br>
|
|
265
277
|
|
|
@@ -1072,6 +1084,33 @@ More examples
|
|
|
1072
1084
|
```
|
|
1073
1085
|
|
|
1074
1086
|
</details>
|
|
1087
|
+
* <details><summary>`get --format eval`</summary><br>
|
|
1088
|
+
|
|
1089
|
+
Return an `eval`-ready shell formatted response of all key/value pairs in a `.env` file.
|
|
1090
|
+
|
|
1091
|
+
```sh
|
|
1092
|
+
$ echo "HELLO=World" > .env
|
|
1093
|
+
$ echo "KEY=value" >> .env
|
|
1094
|
+
|
|
1095
|
+
$ dotenvx get --format eval
|
|
1096
|
+
HELLO="World"
|
|
1097
|
+
KEY="value"
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1100
|
+
Note that this exports newlines and quoted strings.
|
|
1101
|
+
|
|
1102
|
+
This can be useful for more complex .env values (spaces, escaped characters, quotes, etc) combined with `eval` on the command line.
|
|
1103
|
+
|
|
1104
|
+
```sh
|
|
1105
|
+
$ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js
|
|
1106
|
+
$ eval $(dotenvx get --format=eval) node index.js
|
|
1107
|
+
Hello value World
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
Be careful with `eval` as it allows for arbitrary execution of commands. Prefer `dotenvx run --` but in some cases `eval` is a sharp knife that is useful to have.
|
|
1111
|
+
|
|
1112
|
+
</details>
|
|
1113
|
+
|
|
1075
1114
|
* <details><summary>`get --all`</summary><br>
|
|
1076
1115
|
|
|
1077
1116
|
Return preset machine envs as well.
|
package/package.json
CHANGED
package/src/cli/actions/get.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { logger } = require('./../../shared/logger')
|
|
2
2
|
|
|
3
3
|
const conventions = require('./../../lib/helpers/conventions')
|
|
4
|
+
const escape = require('./../../lib/helpers/escape')
|
|
4
5
|
|
|
5
6
|
const main = require('./../../lib/main')
|
|
6
7
|
|
|
@@ -23,8 +24,15 @@ function get (key) {
|
|
|
23
24
|
const results = main.get(key, envs, options.overload, process.env.DOTENV_KEY, options.all)
|
|
24
25
|
|
|
25
26
|
if (typeof results === 'object' && results !== null) {
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
if (options.format === 'eval') {
|
|
28
|
+
let inline = ''
|
|
29
|
+
for (const [key, value] of Object.entries(results)) {
|
|
30
|
+
inline += `${key}=${escape(value)}\n`
|
|
31
|
+
}
|
|
32
|
+
inline = inline.trim()
|
|
33
|
+
|
|
34
|
+
console.log(inline)
|
|
35
|
+
} else if (options.format === 'shell') {
|
|
28
36
|
let inline = ''
|
|
29
37
|
for (const [key, value] of Object.entries(results)) {
|
|
30
38
|
inline += `${key}=${value} `
|
|
@@ -32,7 +40,6 @@ function get (key) {
|
|
|
32
40
|
inline = inline.trim()
|
|
33
41
|
|
|
34
42
|
console.log(inline)
|
|
35
|
-
// json format
|
|
36
43
|
} else {
|
|
37
44
|
let space = 0
|
|
38
45
|
if (options.prettyPrint) {
|
package/src/cli/dotenvx.js
CHANGED
|
@@ -75,7 +75,7 @@ program.command('get')
|
|
|
75
75
|
.option('--convention <name>', 'load a .env convention (available conventions: [\'nextjs\'])')
|
|
76
76
|
.option('-a, --all', 'include all machine envs as well')
|
|
77
77
|
.option('-pp, --pretty-print', 'pretty print output')
|
|
78
|
-
.option('--format <type>', 'format of the output (json, shell)', 'json')
|
|
78
|
+
.option('--format <type>', 'format of the output (json, shell, eval)', 'json')
|
|
79
79
|
.action(function (...args) {
|
|
80
80
|
this.envs = envs
|
|
81
81
|
|
|
@@ -1,38 +1,55 @@
|
|
|
1
|
+
const util = require('util')
|
|
1
2
|
const dotenv = require('dotenv')
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
const escapeForRegex = require('./escapeForRegex')
|
|
5
|
+
|
|
6
|
+
function replace (src, key, replaceValue) {
|
|
4
7
|
let output
|
|
5
|
-
let
|
|
8
|
+
let escapedValue = util.inspect(replaceValue, { showHidden: false, depth: null, colors: false })
|
|
9
|
+
if (replaceValue.includes('\n')) {
|
|
10
|
+
escapedValue = JSON.stringify(replaceValue) // use JSON stringify if string contains newlines
|
|
11
|
+
escapedValue = escapedValue.replace(/\\n/g, '\n') // fix up newlines
|
|
12
|
+
escapedValue = escapedValue.replace(/\\r/g, '\r')
|
|
13
|
+
}
|
|
14
|
+
let newPart = `${key}=${escapedValue}`
|
|
6
15
|
|
|
7
16
|
const parsed = dotenv.parse(src)
|
|
8
17
|
if (Object.prototype.hasOwnProperty.call(parsed, key)) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'
|
|
18
|
+
const originalValue = parsed[key]
|
|
19
|
+
const escapedOriginalValue = escapeForRegex(originalValue)
|
|
20
|
+
|
|
21
|
+
// conditionally enforce end of line
|
|
22
|
+
let enforceEndOfLine = ''
|
|
23
|
+
if (escapedOriginalValue === '') {
|
|
24
|
+
enforceEndOfLine = '$' // EMPTY scenario
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const currentPart = new RegExp(
|
|
28
|
+
'^' + // start of line
|
|
29
|
+
'(\\s*)?' + // spaces
|
|
30
|
+
'(export\\s+)?' + // export
|
|
31
|
+
key + // KEY
|
|
32
|
+
'\\s*=\\s*' + // spaces (KEY = value)
|
|
33
|
+
'["\'`]?' + // open quote
|
|
34
|
+
escapedOriginalValue + // escaped value
|
|
35
|
+
'["\'`]?' + // close quote
|
|
36
|
+
enforceEndOfLine
|
|
37
|
+
,
|
|
38
|
+
'gm' // (g)lobal (m)ultiline
|
|
24
39
|
)
|
|
25
40
|
|
|
26
|
-
|
|
41
|
+
// $1 preserves spaces
|
|
42
|
+
// $2 preserves export
|
|
43
|
+
output = src.replace(currentPart, `$1$2${newPart}`)
|
|
27
44
|
} else {
|
|
28
45
|
// append
|
|
29
46
|
if (src.endsWith('\n')) {
|
|
30
|
-
|
|
47
|
+
newPart = newPart + '\n'
|
|
31
48
|
} else {
|
|
32
|
-
|
|
49
|
+
newPart = '\n' + newPart
|
|
33
50
|
}
|
|
34
51
|
|
|
35
|
-
output = src +
|
|
52
|
+
output = src + newPart
|
|
36
53
|
}
|
|
37
54
|
|
|
38
55
|
return output
|