@dotenvx/dotenvx 1.20.0 → 1.21.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,7 +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.20.0...main)
5
+ ## [Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.21.0...main)
6
+
7
+ ## 1.21.0
8
+
9
+ ### Changed
10
+
11
+ * treat single quotes literally ([#423](https://github.com/dotenvx/dotenvx/pull/423))
12
+ * respect user chosen quotes ([#423](https://github.com/dotenvx/dotenvx/pull/423) [#377](https://github.com/dotenvx/dotenvx/issues/377))
13
+
14
+ 🎓 now if you choose to single quote, double quote, no quote, or backtick your value it will be respected - including for encrypted values. this more intuitively handles complex cases like escaped characters, literals, and json.
15
+
16
+ ## 1.20.1
17
+
18
+ ### Changed
19
+
20
+ * update [eciesjs](https://github.com/ecies/js/issues/802) ([#421](https://github.com/dotenvx/dotenvx/pull/421))
21
+ * remove default values for ts interface - no longer permitted by latest ts ([#419](https://github.com/dotenvx/dotenvx/pull/419))
22
+
23
+ ## 1.20.0
6
24
 
7
25
  ### Changed
8
26
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.20.0",
2
+ "version": "1.21.0",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a better dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -38,7 +38,7 @@
38
38
  "dependencies": {
39
39
  "commander": "^11.1.0",
40
40
  "dotenv": "^16.4.5",
41
- "eciesjs": "^0.4.6",
41
+ "eciesjs": "^0.4.10",
42
42
  "execa": "^5.1.1",
43
43
  "fdir": "^6.2.0",
44
44
  "ignore": "^5.3.0",
@@ -3,6 +3,7 @@ const dotenvEval = require('./dotenvEval')
3
3
  const dotenvExpand = require('./dotenvExpand')
4
4
  const decryptValue = require('./decryptValue')
5
5
  const truncate = require('./truncate')
6
+ const quotes = require('./quotes')
6
7
 
7
8
  function warning (e, key, privateKey = null) {
8
9
  const warning = new Error(`[${e.code}] could not decrypt ${key} using private key '${truncate(privateKey)}'`)
@@ -15,8 +16,10 @@ function warning (e, key, privateKey = null) {
15
16
  function parseDecryptEvalExpand (src, privateKey = null, processEnv = process.env) {
16
17
  const warnings = []
17
18
 
18
- // parse
19
+ // parse and quotes
19
20
  const parsed = dotenv.parse(src)
21
+ const _quotes = quotes(src)
22
+ const originalParsed = { ...parsed }
20
23
  for (const key in parsed) {
21
24
  try {
22
25
  const decryptedValue = decryptValue(parsed[key], privateKey)
@@ -39,7 +42,13 @@ function parseDecryptEvalExpand (src, privateKey = null, processEnv = process.en
39
42
  parsed: evaled
40
43
  }
41
44
  const expanded = dotenvExpand.expand(inputEvaled)
45
+
42
46
  for (const key in expanded.parsed) {
47
+ // unset eval and expansion for single quotes
48
+ if (_quotes[key] === "'") {
49
+ expanded.parsed[key] = originalParsed[key] // reset to original
50
+ }
51
+
43
52
  try {
44
53
  const decryptedValue = decryptValue(expanded.parsed[key], privateKey)
45
54
  expanded.parsed[key] = decryptedValue
@@ -48,6 +57,11 @@ function parseDecryptEvalExpand (src, privateKey = null, processEnv = process.en
48
57
  }
49
58
  }
50
59
  for (const key in processEnv) {
60
+ // unset eval and expansion for single quotes
61
+ if (_quotes[key] === "'") {
62
+ processEnv[key] = originalParsed[key] // reset to original
63
+ }
64
+
51
65
  try {
52
66
  const decryptedValue = decryptValue(processEnv[key], privateKey)
53
67
  processEnv[key] = decryptedValue
@@ -0,0 +1,36 @@
1
+ const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
2
+
3
+ function quotes (src) {
4
+ const obj = {}
5
+ // Convert buffer to string
6
+ let lines = src.toString()
7
+
8
+ // Convert line breaks to same format
9
+ lines = lines.replace(/\r\n?/mg, '\n')
10
+
11
+ let match
12
+ while ((match = LINE.exec(lines)) != null) {
13
+ const key = match[1]
14
+
15
+ // Default undefined or null to empty string
16
+ let value = (match[2] || '')
17
+
18
+ // Remove whitespace
19
+ value = value.trim()
20
+
21
+ // Check if double quoted
22
+ const maybeQuote = value[0]
23
+
24
+ value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2')
25
+
26
+ if (maybeQuote === value[0]) {
27
+ obj[key] = ''
28
+ } else {
29
+ obj[key] = maybeQuote
30
+ }
31
+ }
32
+
33
+ return obj
34
+ }
35
+
36
+ module.exports = quotes
@@ -1,28 +1,19 @@
1
- const util = require('util')
2
1
  const dotenv = require('dotenv')
3
2
 
3
+ const quotes = require('./quotes')
4
4
  const escapeForRegex = require('./escapeForRegex')
5
5
  const escapeDollarSigns = require('./escapeDollarSigns')
6
6
 
7
7
  function replace (src, key, replaceValue) {
8
8
  let output
9
- let escapedValue = util.inspect(replaceValue, { showHidden: false, depth: null, colors: false })
10
-
11
- if (replaceValue.includes('\n')) {
12
- escapedValue = JSON.stringify(replaceValue) // use JSON stringify if string contains newlines
13
- escapedValue = escapedValue.replace(/\\n/g, '\n') // fix up newlines
14
- escapedValue = escapedValue.replace(/\\r/g, '\r')
15
- }
16
-
17
- // prevents test\test (and similar) from becoming test\\test and then test\\\\test, etc recursively after each encrypt/decrypt combo
18
- if (replaceValue.includes('\\')) {
19
- escapedValue = escapedValue.replace(/\\\\/g, '\\')
20
- }
21
-
22
- let newPart = `${key}=${escapedValue}`
9
+ let newPart = ''
23
10
 
24
11
  const parsed = dotenv.parse(src)
12
+ const _quotes = quotes(src)
25
13
  if (Object.prototype.hasOwnProperty.call(parsed, key)) {
14
+ const quote = _quotes[key]
15
+ newPart += `${key}=${quote}${replaceValue}${quote}`
16
+
26
17
  const originalValue = parsed[key]
27
18
  const escapedOriginalValue = escapeForRegex(originalValue)
28
19
 
@@ -52,6 +43,8 @@ function replace (src, key, replaceValue) {
52
43
  // $2 preserves export
53
44
  output = src.replace(currentPart, `$1$2${saferInput}`)
54
45
  } else {
46
+ newPart += `${key}="${replaceValue}"`
47
+
55
48
  // append
56
49
  if (src.endsWith('\n')) {
57
50
  newPart = newPart + '\n'
package/src/lib/main.d.ts CHANGED
@@ -203,10 +203,10 @@ export function ls(
203
203
  */
204
204
  export function get(
205
205
  key?: string,
206
- envs: string[] = [],
207
- overload = false,
208
- DOTENV_KEY = '',
209
- all = false
206
+ envs?: string[],
207
+ overload?: boolean,
208
+ DOTENV_KEY?: string,
209
+ all?: boolean
210
210
  ): Record<string, string | undefined> | string | undefined;
211
211
 
212
212
  export type SetOutput = {