@dotenvx/dotenvx 1.18.0 → 1.19.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 CHANGED
@@ -2,13 +2,25 @@
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.18.0...main)
5
+ ## [Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.19.0...main)
6
+
7
+ ## 1.19.0
8
+
9
+ ### Added
10
+
11
+ * support key glob filtering for `encrypt` and `decrypt`. example: `dotenvx encrypt -ek "NEXT_PUBLIC_*"` ([#397](https://github.com/dotenvx/dotenvx/pull/397))
12
+
13
+ ## 1.18.1
14
+
15
+ ### Added
16
+
17
+ * escape user inputted regex groupings like `$1` or `$2`. ([#396](https://github.com/dotenvx/dotenvx/pull/396))
6
18
 
7
19
  ## 1.18.0
8
20
 
9
21
  ### Added
10
22
 
11
- * `set` and `encrypt` preserve leading spaces ([#395](https://github.com/dotenvx/dotenvx/pull/395/))
23
+ * `set` and `encrypt` preserve leading spaces ([#395](https://github.com/dotenvx/dotenvx/pull/395))
12
24
 
13
25
  ```sh
14
26
  HELLO=world
package/README.md CHANGED
@@ -1243,6 +1243,36 @@ More examples
1243
1243
  ✔ encrypted (.env)
1244
1244
  ```
1245
1245
 
1246
+ Even specify a glob pattern.
1247
+
1248
+ ```sh
1249
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1250
+
1251
+ $ dotenvx encrypt -k "HE*"
1252
+ ✔ encrypted (.env)
1253
+ ```
1254
+
1255
+ </details>
1256
+ * <details><summary>`encrypt -ek`</summary><br>
1257
+
1258
+ Specify the key(s) to NOT encrypt by passing `--exclude-key`.
1259
+
1260
+ ```sh
1261
+ $ echo "HELLO=World\nHELLO2=Universe" > .env
1262
+
1263
+ $ dotenvx encrypt -ek HELLO
1264
+ ✔ encrypted (.env)
1265
+ ```
1266
+
1267
+ Even specify a glob pattern.
1268
+
1269
+ ```sh
1270
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1271
+
1272
+ $ dotenvx encrypt -ek "HO*"
1273
+ ✔ encrypted (.env)
1274
+ ```
1275
+
1246
1276
  </details>
1247
1277
  * <details><summary>`encrypt --stdout`</summary><br>
1248
1278
 
@@ -1295,6 +1325,52 @@ More examples
1295
1325
  ✔ decrypted (.env.production)
1296
1326
  ```
1297
1327
 
1328
+ </details>
1329
+ * <details><summary>`decrypt -k`</summary><br>
1330
+
1331
+ Decrypt the contents of a specified key inside an encrypted `.env` file.
1332
+
1333
+ ```sh
1334
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1335
+ $ dotenvx encrypt
1336
+ ✔ encrypted (.env)
1337
+ $ dotenvx decrypt -k HELLO
1338
+ ✔ decrypted (.env)
1339
+ ```
1340
+
1341
+ Even specify a glob pattern.
1342
+
1343
+ ```sh
1344
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1345
+ $ dotenvx encrypt
1346
+ ✔ encrypted (.env)
1347
+ $ dotenvx decrypt -k "HE*"
1348
+ ✔ encrypted (.env)
1349
+ ```
1350
+
1351
+ </details>
1352
+ * <details><summary>`decrypt -ek`</summary><br>
1353
+
1354
+ Decrypt the contents inside an encrypted `.env` file except for an exluded key.
1355
+
1356
+ ```sh
1357
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1358
+ $ dotenvx encrypt
1359
+ ✔ encrypted (.env)
1360
+ $ dotenvx decrypt -ek HOLA
1361
+ ✔ decrypted (.env)
1362
+ ```
1363
+
1364
+ Even specify a glob pattern.
1365
+
1366
+ ```sh
1367
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1368
+ $ dotenvx encrypt
1369
+ ✔ encrypted (.env)
1370
+ $ dotenvx decrypt -ek "HO*"
1371
+ ✔ encrypted (.env)
1372
+ ```
1373
+
1298
1374
  </details>
1299
1375
  * <details><summary>`decrypt --stdout`</summary><br>
1300
1376
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.18.0",
2
+ "version": "1.19.0",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a better dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -0,0 +1,5 @@
1
+ function escapeDollarSigns (str) {
2
+ return str.replace(/\$/g, '$$$$')
3
+ }
4
+
5
+ module.exports = escapeDollarSigns
@@ -2,10 +2,12 @@ const util = require('util')
2
2
  const dotenv = require('dotenv')
3
3
 
4
4
  const escapeForRegex = require('./escapeForRegex')
5
+ const escapeDollarSigns = require('./escapeDollarSigns')
5
6
 
6
7
  function replace (src, key, replaceValue) {
7
8
  let output
8
9
  let escapedValue = util.inspect(replaceValue, { showHidden: false, depth: null, colors: false })
10
+
9
11
  if (replaceValue.includes('\n')) {
10
12
  escapedValue = JSON.stringify(replaceValue) // use JSON stringify if string contains newlines
11
13
  escapedValue = escapedValue.replace(/\\n/g, '\n') // fix up newlines
@@ -38,9 +40,11 @@ function replace (src, key, replaceValue) {
38
40
  'gm' // (g)lobal (m)ultiline
39
41
  )
40
42
 
43
+ const saferInput = escapeDollarSigns(newPart) // cleanse user inputted capture groups ($1, $2 etc)
44
+
41
45
  // $1 preserves spaces
42
46
  // $2 preserves export
43
- output = src.replace(currentPart, `$1$2${newPart}`)
47
+ output = src.replace(currentPart, `$1$2${saferInput}`)
44
48
  } else {
45
49
  // append
46
50
  if (src.endsWith('\n')) {
@@ -1,6 +1,7 @@
1
1
  const fs = require('fs')
2
2
  const path = require('path')
3
3
  const dotenv = require('dotenv')
4
+ const picomatch = require('picomatch')
4
5
 
5
6
  const smartDotenvPrivateKey = require('./../helpers/smartDotenvPrivateKey')
6
7
  const guessPrivateKeyName = require('./../helpers/guessPrivateKeyName')
@@ -29,6 +30,9 @@ class Decrypt {
29
30
  const envFilepaths = this._envFilepaths()
30
31
  const keys = this._keys()
31
32
  const excludeKeys = this._excludeKeys()
33
+ const exclude = picomatch(excludeKeys)
34
+ const include = picomatch(keys, { ignore: excludeKeys })
35
+
32
36
  for (const envFilepath of envFilepaths) {
33
37
  const filepath = path.resolve(envFilepath)
34
38
 
@@ -53,12 +57,12 @@ class Decrypt {
53
57
  const parsed = dotenv.parse(src)
54
58
  for (const [key, value] of Object.entries(parsed)) {
55
59
  // key excluded - don't decrypt it
56
- if (excludeKeys.includes(key)) {
60
+ if (exclude(key)) {
57
61
  continue
58
62
  }
59
63
 
60
64
  // key effectively excluded (by not being in the list of includes) - don't encrypt it
61
- if (keys.length > 0 && !keys.includes(key)) {
65
+ if (keys.length > 0 && !include(key)) {
62
66
  continue
63
67
  }
64
68
 
@@ -1,6 +1,7 @@
1
1
  const fs = require('fs')
2
2
  const path = require('path')
3
3
  const dotenv = require('dotenv')
4
+ const picomatch = require('picomatch')
4
5
 
5
6
  const findOrCreatePublicKey = require('./../helpers/findOrCreatePublicKey')
6
7
  const guessPrivateKeyName = require('./../helpers/guessPrivateKeyName')
@@ -30,6 +31,9 @@ class Encrypt {
30
31
  const envFilepaths = this._envFilepaths()
31
32
  const keys = this._keys()
32
33
  const excludeKeys = this._excludeKeys()
34
+ const exclude = picomatch(excludeKeys)
35
+ const include = picomatch(keys, { ignore: excludeKeys })
36
+
33
37
  for (const envFilepath of envFilepaths) {
34
38
  const filepath = path.resolve(envFilepath)
35
39
 
@@ -67,12 +71,12 @@ class Encrypt {
67
71
  const parsed = dotenv.parse(src)
68
72
  for (const [key, value] of Object.entries(parsed)) {
69
73
  // key excluded - don't encrypt it
70
- if (excludeKeys.includes(key)) {
74
+ if (exclude(key)) {
71
75
  continue
72
76
  }
73
77
 
74
78
  // key effectively excluded (by not being in the list of includes) - don't encrypt it
75
- if (keys.length > 0 && !keys.includes(key)) {
79
+ if (keys.length > 0 && !include(key)) {
76
80
  continue
77
81
  }
78
82