@dotenvx/dotenvx 1.75.0 → 1.75.1
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 +11 -1
- package/package.json +2 -2
- package/src/lib/helpers/append.js +4 -3
- package/src/lib/helpers/cryptography/index.js +1 -4
- package/src/lib/helpers/executeDynamic.js +1 -3
- package/src/lib/helpers/keyResolution/keyValues.js +2 -2
- package/src/lib/helpers/keyResolution/keyValuesFromEnvSrc.js +8 -3
- package/src/lib/helpers/keyResolution/keyValuesSync.js +2 -2
- package/src/lib/helpers/keyResolution/readFileKey.js +6 -4
- package/src/lib/helpers/keyResolution/readFileKeySync.js +6 -4
- package/src/lib/helpers/keypairMetadata.js +2 -2
- package/src/lib/helpers/readEnvKey.js +4 -3
- package/src/lib/helpers/replace.js +2 -2
- package/src/lib/services/decrypt.js +2 -3
- package/src/lib/services/encrypt.js +2 -3
- package/src/lib/services/genexample.js +15 -3
- package/src/lib/services/prebuild.js +2 -2
- package/src/lib/services/precommit.js +2 -2
- package/src/lib/services/rotate.js +2 -3
- package/src/lib/services/sets.js +9 -7
- package/src/lib/helpers/dotenvParse.js +0 -55
- package/src/lib/helpers/isFullyEncrypted.js +0 -27
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,17 @@
|
|
|
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.75.
|
|
5
|
+
[Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.75.1...main)
|
|
6
|
+
|
|
7
|
+
## [1.75.1](https://github.com/dotenvx/dotenvx/compare/v1.75.0...v1.75.1) (2026-06-20)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
* Publish as named binaries ([#851](https://github.com/dotenvx/dotenvx/pull/851))
|
|
12
|
+
|
|
13
|
+
### Removed
|
|
14
|
+
|
|
15
|
+
* Remove references to `dotenvx-vlt` (now dotenvx-armor) ([#849](https://github.com/dotenvx/dotenvx/pull/849))
|
|
6
16
|
|
|
7
17
|
## [1.75.0](https://github.com/dotenvx/dotenvx/compare/v1.74.4...v1.75.0) (2026-06-19)
|
|
8
18
|
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.75.
|
|
2
|
+
"version": "1.75.1",
|
|
3
3
|
"name": "@dotenvx/dotenvx",
|
|
4
4
|
"description": "a secure dotenv–from the creator of `dotenv`",
|
|
5
5
|
"author": "@motdotla",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"funding": "https://dotenvx.com",
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@dotenvx/primitives": "^0.
|
|
46
|
+
"@dotenvx/primitives": "^0.8.0",
|
|
47
47
|
"commander": "^11.1.0",
|
|
48
48
|
"conf": "^10.2.0",
|
|
49
49
|
"dotenv": "^17.2.1",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const quotes = require('./quotes')
|
|
2
|
-
const
|
|
2
|
+
const { scan } = require('@dotenvx/primitives')
|
|
3
3
|
const escapeForRegex = require('./escapeForRegex')
|
|
4
4
|
const escapeDollarSigns = require('./escapeDollarSigns')
|
|
5
5
|
|
|
@@ -7,11 +7,12 @@ function append (src, key, appendValue) {
|
|
|
7
7
|
let output
|
|
8
8
|
let newPart = ''
|
|
9
9
|
|
|
10
|
-
const parsed =
|
|
10
|
+
const { parsed } = scan(src, { expandDoubleQuotedNewlines: false, convertWindowsNewlines: false })
|
|
11
11
|
const _quotes = quotes(src)
|
|
12
12
|
if (Object.prototype.hasOwnProperty.call(parsed, key)) {
|
|
13
13
|
const quote = _quotes[key]
|
|
14
|
-
const
|
|
14
|
+
const values = parsed[key]
|
|
15
|
+
const originalValue = values[values.length - 1]
|
|
15
16
|
|
|
16
17
|
newPart += `${key}=${quote}${originalValue},${appendValue}${quote}`
|
|
17
18
|
|
|
@@ -10,8 +10,5 @@ module.exports = {
|
|
|
10
10
|
provision: require('./provision'),
|
|
11
11
|
provisionSync: require('./provisionSync'),
|
|
12
12
|
provisionWithPrivateKey: require('./provisionWithPrivateKey'),
|
|
13
|
-
mutateSrc: require('./mutateSrc')
|
|
14
|
-
|
|
15
|
-
// other
|
|
16
|
-
isFullyEncrypted: require('./../isFullyEncrypted')
|
|
13
|
+
mutateSrc: require('./mutateSrc')
|
|
17
14
|
}
|
|
@@ -45,7 +45,6 @@ function dynamicAttempts (command, forwardedArgs) {
|
|
|
45
45
|
if (command === 'vlt') {
|
|
46
46
|
return [
|
|
47
47
|
['dotenvx-armor', forwardedArgs],
|
|
48
|
-
['dotenvx-vlt', forwardedArgs],
|
|
49
48
|
['dotenvx-ops', forwardedArgs]
|
|
50
49
|
]
|
|
51
50
|
}
|
|
@@ -53,8 +52,7 @@ function dynamicAttempts (command, forwardedArgs) {
|
|
|
53
52
|
if (command === 'ops') {
|
|
54
53
|
return [
|
|
55
54
|
['dotenvx-armor', forwardedArgs],
|
|
56
|
-
['dotenvx-ops', forwardedArgs]
|
|
57
|
-
['dotenvx-vlt', forwardedArgs]
|
|
55
|
+
['dotenvx-ops', forwardedArgs]
|
|
58
56
|
]
|
|
59
57
|
}
|
|
60
58
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
|
+
const { scan } = require('@dotenvx/primitives')
|
|
2
3
|
|
|
3
4
|
const fsx = require('./../fsx')
|
|
4
|
-
const dotenvParse = require('./../dotenvParse')
|
|
5
5
|
const keyNamesForEnvFile = require('./keyNamesForEnvFile')
|
|
6
6
|
const readProcessKey = require('./readProcessKey')
|
|
7
7
|
const readFileKey = require('./readFileKey')
|
|
@@ -16,7 +16,7 @@ async function invertForPrivateKeyName (filepath) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const envSrc = await fsx.readFileX(filepath)
|
|
19
|
-
const envParsed =
|
|
19
|
+
const { parsed: envParsed } = scan(envSrc)
|
|
20
20
|
|
|
21
21
|
let publicKeyName
|
|
22
22
|
for (const keyName of Object.keys(envParsed)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
|
+
const { scan } = require('@dotenvx/primitives')
|
|
2
3
|
|
|
3
|
-
const dotenvParse = require('./../dotenvParse')
|
|
4
4
|
const readFileKeySync = require('./readFileKeySync')
|
|
5
5
|
const armorKeypairSync = require('../cryptography/armorKeypairSync')
|
|
6
6
|
|
|
@@ -23,14 +23,19 @@ function publicKeyNameFromEnvSrc (envParsed) {
|
|
|
23
23
|
return null
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function finalValue (parsed, keyName) {
|
|
27
|
+
const values = parsed[keyName]
|
|
28
|
+
return values ? values[values.length - 1] : undefined
|
|
29
|
+
}
|
|
30
|
+
|
|
26
31
|
function keyValuesFromEnvSrc (src, privateKeyName = null, opts = {}) {
|
|
27
32
|
let keysFilepath = opts.keysFilepath || null
|
|
28
33
|
const noArmor = opts.noArmor === true
|
|
29
34
|
const processEnv = opts.processEnv || process.env
|
|
30
|
-
const envParsed =
|
|
35
|
+
const { parsed: envParsed } = scan(src)
|
|
31
36
|
|
|
32
37
|
const publicKeyName = publicKeyNameFromEnvSrc(envParsed)
|
|
33
|
-
const publicKeyValue = publicKeyName ? readProcessKey(processEnv, publicKeyName) || envParsed
|
|
38
|
+
const publicKeyValue = publicKeyName ? readProcessKey(processEnv, publicKeyName) || finalValue(envParsed, publicKeyName) || null : null
|
|
34
39
|
|
|
35
40
|
if (!privateKeyName && publicKeyName) {
|
|
36
41
|
privateKeyName = publicKeyName.replace(PUBLIC_KEY_SCHEMA, PRIVATE_KEY_SCHEMA)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
|
+
const { scan } = require('@dotenvx/primitives')
|
|
2
3
|
|
|
3
4
|
const fsx = require('./../fsx')
|
|
4
|
-
const dotenvParse = require('./../dotenvParse')
|
|
5
5
|
const keyNamesForEnvFile = require('./keyNamesForEnvFile')
|
|
6
6
|
const readProcessKey = require('./readProcessKey')
|
|
7
7
|
const readFileKeySync = require('./readFileKeySync')
|
|
@@ -16,7 +16,7 @@ function invertForPrivateKeyName (filepath) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const envSrc = fsx.readFileXSync(filepath)
|
|
19
|
-
const envParsed =
|
|
19
|
+
const { parsed: envParsed } = scan(envSrc)
|
|
20
20
|
|
|
21
21
|
let publicKeyName
|
|
22
22
|
for (const keyName of Object.keys(envParsed)) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const fsx = require('./../fsx')
|
|
2
|
-
const
|
|
2
|
+
const { scan } = require('@dotenvx/primitives')
|
|
3
3
|
|
|
4
4
|
async function readFileKey (keyName, filepath) {
|
|
5
5
|
if (!(await fsx.exists(filepath))) {
|
|
@@ -7,10 +7,12 @@ async function readFileKey (keyName, filepath) {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const src = await fsx.readFileX(filepath)
|
|
10
|
-
const parsed =
|
|
10
|
+
const { parsed } = scan(src)
|
|
11
|
+
const values = parsed[keyName]
|
|
11
12
|
|
|
12
|
-
if (
|
|
13
|
-
|
|
13
|
+
if (values && values.length > 0) {
|
|
14
|
+
const value = values[values.length - 1]
|
|
15
|
+
return value || undefined
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
18
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
const fsx = require('./../fsx')
|
|
2
|
-
const
|
|
2
|
+
const { scan } = require('@dotenvx/primitives')
|
|
3
3
|
|
|
4
4
|
function readFileKeySync (keyName, filepath) {
|
|
5
5
|
if (fsx.existsSync(filepath)) {
|
|
6
6
|
const src = fsx.readFileXSync(filepath)
|
|
7
|
-
const parsed =
|
|
7
|
+
const { parsed } = scan(src)
|
|
8
|
+
const values = parsed[keyName]
|
|
8
9
|
|
|
9
|
-
if (
|
|
10
|
-
|
|
10
|
+
if (values && values.length > 0) {
|
|
11
|
+
const value = values[values.length - 1]
|
|
12
|
+
return value || undefined
|
|
11
13
|
}
|
|
12
14
|
}
|
|
13
15
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const fs = require('fs')
|
|
3
3
|
const execa = require('execa')
|
|
4
|
-
const
|
|
4
|
+
const { scan } = require('@dotenvx/primitives')
|
|
5
5
|
const canonicalEnvFilename = require('./canonicalEnvFilename')
|
|
6
6
|
const environment = require('./envResolution/environment')
|
|
7
7
|
const sanitizeCommandForMetadata = require('./sanitizeCommandForMetadata')
|
|
@@ -56,7 +56,7 @@ function envKeys (envFile) {
|
|
|
56
56
|
return null
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
const parsed =
|
|
59
|
+
const { parsed } = scan(src)
|
|
60
60
|
|
|
61
61
|
if (!parsed || Object.keys(parsed).length === 0) return null
|
|
62
62
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
|
-
const
|
|
2
|
+
const { scan } = require('@dotenvx/primitives')
|
|
3
3
|
const Errors = require('./errors')
|
|
4
4
|
|
|
5
5
|
function ignored (error, options) {
|
|
@@ -17,8 +17,9 @@ function readEnvKey (key, filepath, options = {}) {
|
|
|
17
17
|
return undefined
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const parsed =
|
|
21
|
-
const
|
|
20
|
+
const { parsed } = scan(src)
|
|
21
|
+
const values = parsed[key]
|
|
22
|
+
const value = values ? values[values.length - 1] : undefined
|
|
22
23
|
if (value === undefined) {
|
|
23
24
|
const error = new Errors({ key }).missingKey()
|
|
24
25
|
if (ignored(error, options)) return undefined
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { scan } = require('@dotenvx/primitives')
|
|
2
2
|
const escapeForRegex = require('./escapeForRegex')
|
|
3
3
|
|
|
4
4
|
function replaceExistingValue (src, key, originalValue, replaceValue) {
|
|
@@ -45,7 +45,7 @@ function replace (src, key, replaceValue) {
|
|
|
45
45
|
let output
|
|
46
46
|
let newPart = ''
|
|
47
47
|
|
|
48
|
-
const parsed =
|
|
48
|
+
const { parsed } = scan(src, { expandDoubleQuotedNewlines: false, convertWindowsNewlines: false })
|
|
49
49
|
if (Object.prototype.hasOwnProperty.call(parsed, key)) {
|
|
50
50
|
const allValues = parsed[key]
|
|
51
51
|
let duplicateOutput = src
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fsx = require('./../helpers/fsx')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const picomatch = require('picomatch')
|
|
4
|
-
const { encrypted } = require('@dotenvx/primitives')
|
|
4
|
+
const { encrypted, scan } = require('@dotenvx/primitives')
|
|
5
5
|
|
|
6
6
|
const TYPE_ENV_FILE = 'envFile'
|
|
7
7
|
|
|
@@ -21,7 +21,6 @@ const {
|
|
|
21
21
|
} = require('./../helpers/cryptography')
|
|
22
22
|
|
|
23
23
|
const replace = require('./../helpers/replace')
|
|
24
|
-
const dotenvParse = require('./../helpers/dotenvParse')
|
|
25
24
|
const detectEncoding = require('./../helpers/detectEncoding')
|
|
26
25
|
|
|
27
26
|
class Decrypt {
|
|
@@ -75,7 +74,7 @@ class Decrypt {
|
|
|
75
74
|
try {
|
|
76
75
|
const encoding = await detectEncoding(filepath)
|
|
77
76
|
let envSrc = await fsx.readFileX(filepath, { encoding })
|
|
78
|
-
const envParsed =
|
|
77
|
+
const envParsed = scan(envSrc).parsed
|
|
79
78
|
|
|
80
79
|
const { privateKeyName } = keyNamesForEnvFile(envFilepath)
|
|
81
80
|
const { privateKeyValue, privateKeySource } = await keyValues(envFilepath, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fsx = require('./../helpers/fsx')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const picomatch = require('picomatch')
|
|
4
|
-
const { encrypted } = require('@dotenvx/primitives')
|
|
4
|
+
const { encrypted, scan } = require('@dotenvx/primitives')
|
|
5
5
|
|
|
6
6
|
const TYPE_ENV_FILE = 'envFile'
|
|
7
7
|
|
|
@@ -24,7 +24,6 @@ const {
|
|
|
24
24
|
} = require('./../helpers/cryptography')
|
|
25
25
|
|
|
26
26
|
const replace = require('./../helpers/replace')
|
|
27
|
-
const dotenvParse = require('./../helpers/dotenvParse')
|
|
28
27
|
const detectEncoding = require('./../helpers/detectEncoding')
|
|
29
28
|
const SAMPLE_ENV_KIT = require('./../helpers/kits/sample')
|
|
30
29
|
|
|
@@ -97,7 +96,7 @@ class Encrypt {
|
|
|
97
96
|
row.kitCreated = 'sample'
|
|
98
97
|
row.changed = true
|
|
99
98
|
}
|
|
100
|
-
const envParsed =
|
|
99
|
+
const envParsed = scan(envSrc).parsed
|
|
101
100
|
|
|
102
101
|
let publicKey
|
|
103
102
|
let privateKey
|
|
@@ -4,7 +4,19 @@ const path = require('path')
|
|
|
4
4
|
const Errors = require('../helpers/errors')
|
|
5
5
|
const findEnvFiles = require('../helpers/findEnvFiles')
|
|
6
6
|
const replace = require('../helpers/replace')
|
|
7
|
-
const
|
|
7
|
+
const { scan } = require('@dotenvx/primitives')
|
|
8
|
+
|
|
9
|
+
function finalValues (src) {
|
|
10
|
+
const { parsed } = scan(src)
|
|
11
|
+
const result = {}
|
|
12
|
+
|
|
13
|
+
for (const key in parsed) {
|
|
14
|
+
const values = parsed[key]
|
|
15
|
+
result[key] = values[values.length - 1]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return result
|
|
19
|
+
}
|
|
8
20
|
|
|
9
21
|
class Genexample {
|
|
10
22
|
constructor (directory = '.', envFile) {
|
|
@@ -40,7 +52,7 @@ class Genexample {
|
|
|
40
52
|
|
|
41
53
|
// get the original src
|
|
42
54
|
let src = fsx.readFileXSync(filepath)
|
|
43
|
-
const parsed =
|
|
55
|
+
const parsed = finalValues(src)
|
|
44
56
|
for (const key in parsed) {
|
|
45
57
|
// used later
|
|
46
58
|
keys.add(key)
|
|
@@ -65,7 +77,7 @@ class Genexample {
|
|
|
65
77
|
// it already exists (which means the user might have it modified a way in which they prefer, so replace exampleSrc with their existing .env.example)
|
|
66
78
|
exampleSrc = fsx.readFileXSync(this.exampleFilepath)
|
|
67
79
|
|
|
68
|
-
const parsed =
|
|
80
|
+
const parsed = finalValues(exampleSrc)
|
|
69
81
|
for (const key of [...keys]) {
|
|
70
82
|
if (key in parsed) {
|
|
71
83
|
preExisted[key] = parsed[key]
|
|
@@ -5,8 +5,8 @@ const ignore = require('ignore')
|
|
|
5
5
|
|
|
6
6
|
const Ls = require('../services/ls')
|
|
7
7
|
const Errors = require('../helpers/errors')
|
|
8
|
+
const { sealed } = require('@dotenvx/primitives')
|
|
8
9
|
|
|
9
|
-
const isFullyEncrypted = require('./../helpers/isFullyEncrypted')
|
|
10
10
|
const MISSING_DOCKERIGNORE = '.env.keys' // by default only ignore .env.keys. all other .env* files COULD be included - as long as they are encrypted
|
|
11
11
|
|
|
12
12
|
class Prebuild {
|
|
@@ -54,7 +54,7 @@ class Prebuild {
|
|
|
54
54
|
} else {
|
|
55
55
|
if (file !== '.env.example' && file !== '.env.x') {
|
|
56
56
|
const src = fsx.readFileXSync(file)
|
|
57
|
-
const encrypted =
|
|
57
|
+
const encrypted = sealed(src)
|
|
58
58
|
|
|
59
59
|
// if contents are encrypted don't raise an error
|
|
60
60
|
if (!encrypted) {
|
|
@@ -4,8 +4,8 @@ const path = require('path')
|
|
|
4
4
|
const ignore = require('ignore')
|
|
5
5
|
|
|
6
6
|
const Ls = require('../services/ls')
|
|
7
|
+
const { sealed } = require('@dotenvx/primitives')
|
|
7
8
|
|
|
8
|
-
const isFullyEncrypted = require('./../helpers/isFullyEncrypted')
|
|
9
9
|
const InstallPrecommitHook = require('./../helpers/installPrecommitHook')
|
|
10
10
|
const Errors = require('./../helpers/errors')
|
|
11
11
|
const childProcess = require('child_process')
|
|
@@ -70,7 +70,7 @@ class Precommit {
|
|
|
70
70
|
} else {
|
|
71
71
|
if (file !== '.env.example' && file !== '.env.x') {
|
|
72
72
|
const src = fsx.readFileXSync(file)
|
|
73
|
-
const encrypted =
|
|
73
|
+
const encrypted = sealed(src)
|
|
74
74
|
|
|
75
75
|
// if contents are encrypted don't raise an error
|
|
76
76
|
if (!encrypted) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fsx = require('./../helpers/fsx')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const picomatch = require('picomatch')
|
|
4
|
-
const { encrypted } = require('@dotenvx/primitives')
|
|
4
|
+
const { encrypted, scan } = require('@dotenvx/primitives')
|
|
5
5
|
|
|
6
6
|
const TYPE_ENV_FILE = 'envFile'
|
|
7
7
|
|
|
@@ -25,7 +25,6 @@ const {
|
|
|
25
25
|
|
|
26
26
|
const append = require('./../helpers/append')
|
|
27
27
|
const replace = require('./../helpers/replace')
|
|
28
|
-
const dotenvParse = require('./../helpers/dotenvParse')
|
|
29
28
|
const detectEncoding = require('./../helpers/detectEncoding')
|
|
30
29
|
|
|
31
30
|
class Rotate {
|
|
@@ -81,7 +80,7 @@ class Rotate {
|
|
|
81
80
|
try {
|
|
82
81
|
const encoding = await detectEncoding(filepath)
|
|
83
82
|
let envSrc = await fsx.readFileX(filepath, { encoding })
|
|
84
|
-
const envParsed =
|
|
83
|
+
const envParsed = scan(envSrc).parsed
|
|
85
84
|
|
|
86
85
|
const { publicKeyName, privateKeyName } = keyNamesForEnvFile(envFilepath)
|
|
87
86
|
const { privateKeyValue } = await keyValues(envFilepath, {
|
package/src/lib/services/sets.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fsx = require('./../helpers/fsx')
|
|
2
2
|
const path = require('path')
|
|
3
|
-
const { encrypted } = require('@dotenvx/primitives')
|
|
3
|
+
const { encrypted, scan } = require('@dotenvx/primitives')
|
|
4
4
|
|
|
5
5
|
const TYPE_ENV_FILE = 'envFile'
|
|
6
6
|
|
|
@@ -25,12 +25,16 @@ const {
|
|
|
25
25
|
} = require('./../helpers/cryptography')
|
|
26
26
|
|
|
27
27
|
const replace = require('./../helpers/replace')
|
|
28
|
-
const dotenvParse = require('./../helpers/dotenvParse')
|
|
29
28
|
const detectEncoding = require('./../helpers/detectEncoding')
|
|
30
29
|
const detectEncodingSync = require('./../helpers/detectEncodingSync')
|
|
31
30
|
|
|
32
31
|
function allValuesForKey (envSrc, key) {
|
|
33
|
-
return
|
|
32
|
+
return scan(envSrc).parsed[key] || []
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function finalValueForKey (envSrc, key) {
|
|
36
|
+
const values = allValuesForKey(envSrc, key)
|
|
37
|
+
return values.length > 0 ? values[values.length - 1] : null
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
class Sets {
|
|
@@ -119,8 +123,7 @@ class Sets {
|
|
|
119
123
|
seededWithInitialKey = true
|
|
120
124
|
}
|
|
121
125
|
|
|
122
|
-
|
|
123
|
-
row.originalValue = envParsed[row.key] || null
|
|
126
|
+
row.originalValue = finalValueForKey(envSrc, row.key)
|
|
124
127
|
if (seededWithInitialKey) {
|
|
125
128
|
row.originalValue = null
|
|
126
129
|
}
|
|
@@ -236,8 +239,7 @@ class Sets {
|
|
|
236
239
|
seededWithInitialKey = true
|
|
237
240
|
}
|
|
238
241
|
|
|
239
|
-
|
|
240
|
-
row.originalValue = envParsed[row.key] || null
|
|
242
|
+
row.originalValue = finalValueForKey(envSrc, row.key)
|
|
241
243
|
if (seededWithInitialKey) {
|
|
242
244
|
row.originalValue = null
|
|
243
245
|
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// historical dotenv.parse - https://github.com/motdotla/dotenv)
|
|
2
|
-
const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
|
|
3
|
-
|
|
4
|
-
function dotenvParse (src, skipExpandForDoubleQuotes = false, skipConvertingWindowsNewlines = false, collectAllValues = false) {
|
|
5
|
-
const obj = {}
|
|
6
|
-
|
|
7
|
-
// Convert buffer to string
|
|
8
|
-
let lines = src.toString()
|
|
9
|
-
|
|
10
|
-
// Convert line breaks to same format
|
|
11
|
-
if (!skipConvertingWindowsNewlines) {
|
|
12
|
-
lines = lines.replace(/\r\n?/mg, '\n')
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let match
|
|
16
|
-
while ((match = LINE.exec(lines)) != null) {
|
|
17
|
-
const key = match[1]
|
|
18
|
-
|
|
19
|
-
// Default undefined or null to empty string
|
|
20
|
-
let value = (match[2] || '')
|
|
21
|
-
|
|
22
|
-
// Remove whitespace
|
|
23
|
-
value = value.trim()
|
|
24
|
-
|
|
25
|
-
// Check if double quoted
|
|
26
|
-
const maybeQuote = value[0]
|
|
27
|
-
|
|
28
|
-
// Remove surrounding quotes
|
|
29
|
-
value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2')
|
|
30
|
-
|
|
31
|
-
// Expand newlines if double quoted
|
|
32
|
-
if (maybeQuote === '"' && !skipExpandForDoubleQuotes) {
|
|
33
|
-
value = value.replace(/\\n/g, '\n') // newline
|
|
34
|
-
value = value.replace(/\\r/g, '\r') // carriage return
|
|
35
|
-
value = value.replace(/\\t/g, '\t') // tabs
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (collectAllValues) {
|
|
39
|
-
// handle scenario where user mistakenly includes plaintext duplicate in .env:
|
|
40
|
-
//
|
|
41
|
-
// # .env
|
|
42
|
-
// HELLO="World"
|
|
43
|
-
// HELLO="encrypted:1234"
|
|
44
|
-
obj[key] = obj[key] || []
|
|
45
|
-
obj[key].push(value)
|
|
46
|
-
} else {
|
|
47
|
-
// Add to object
|
|
48
|
-
obj[key] = value
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return obj
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
module.exports = dotenvParse
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const { encrypted } = require('@dotenvx/primitives')
|
|
2
|
-
const dotenvParse = require('./dotenvParse')
|
|
3
|
-
const isPublicKey = require('./cryptography/isPublicKey')
|
|
4
|
-
|
|
5
|
-
function isFullyEncrypted (src) {
|
|
6
|
-
const parsed = dotenvParse(src, false, false, true) // collect all values
|
|
7
|
-
|
|
8
|
-
for (const [key, values] of Object.entries(parsed)) {
|
|
9
|
-
// handle scenario where user mistakenly includes plaintext duplicate in .env:
|
|
10
|
-
//
|
|
11
|
-
// # .env
|
|
12
|
-
// HELLO="World"
|
|
13
|
-
// HELLO="encrypted:1234"
|
|
14
|
-
//
|
|
15
|
-
// key => [value1, ...]
|
|
16
|
-
for (const value of values) {
|
|
17
|
-
const result = encrypted(value) || isPublicKey(key)
|
|
18
|
-
if (!result) {
|
|
19
|
-
return false
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return true
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
module.exports = isFullyEncrypted
|