@dotenvx/dotenvx 1.75.0 → 2.0.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/README.md +4 -114
  3. package/package.json +8 -7
  4. package/src/cli/actions/decrypt.js +35 -17
  5. package/src/cli/actions/doctor.js +2 -2
  6. package/src/cli/actions/encrypt.js +64 -85
  7. package/src/cli/actions/ext/genexample.js +2 -2
  8. package/src/cli/actions/get.js +16 -7
  9. package/src/cli/actions/keypair.js +55 -42
  10. package/src/cli/actions/login.js +4 -3
  11. package/src/cli/actions/normalizeArmorAliases.js +9 -0
  12. package/src/cli/actions/run.js +65 -22
  13. package/src/cli/actions/set.js +51 -37
  14. package/src/cli/dotenvx.js +6 -21
  15. package/src/lib/api/{postKeypair.js → postArmorKeyring.js} +4 -14
  16. package/src/lib/{helpers/envResolution → conventions}/environment.js +1 -1
  17. package/src/lib/conventions/filepaths.js +9 -0
  18. package/src/lib/conventions/keynames.js +38 -0
  19. package/src/lib/helpers/catchAndLog.js +4 -1
  20. package/src/lib/helpers/cryptography/index.js +1 -12
  21. package/src/lib/helpers/cryptography/mutateKeysSrc.js +5 -21
  22. package/src/lib/helpers/envResolution/index.js +1 -1
  23. package/src/lib/helpers/errors.js +13 -0
  24. package/src/lib/helpers/executeDynamic.js +1 -3
  25. package/src/lib/helpers/keypairMetadata.js +3 -3
  26. package/src/lib/helpers/readEnvKey.js +4 -3
  27. package/src/lib/main.d.ts +2 -39
  28. package/src/lib/main.js +82 -45
  29. package/src/lib/providers/armor/index.js +29 -0
  30. package/src/lib/providers/index.js +46 -0
  31. package/src/lib/providers/worker.js +6 -0
  32. package/src/lib/resolvers/envs.js +302 -0
  33. package/src/lib/resolvers/get.js +69 -0
  34. package/src/lib/resolvers/keypair.js +81 -0
  35. package/src/lib/resolvers/ls.js +41 -0
  36. package/src/lib/services/armorDown.js +2 -2
  37. package/src/lib/services/{armorKeypair.js → armorKeyring.js} +14 -51
  38. package/src/lib/services/armorMove.js +2 -2
  39. package/src/lib/services/armorPull.js +2 -2
  40. package/src/lib/services/armorPush.js +2 -2
  41. package/src/lib/services/armorUp.js +2 -2
  42. package/src/lib/services/genexample.js +19 -8
  43. package/src/lib/services/login.js +25 -0
  44. package/src/lib/services/prebuild.js +11 -5
  45. package/src/lib/services/precommit.js +11 -5
  46. package/src/lib/transforms/decrypt.js +83 -0
  47. package/src/lib/transforms/encrypt.js +179 -0
  48. package/src/lib/transforms/set.js +179 -0
  49. package/src/shared/logger.js +5 -0
  50. package/src/cli/actions/normalizeArmorOptions.js +0 -10
  51. package/src/cli/actions/rotate.js +0 -87
  52. package/src/lib/helpers/append.js +0 -61
  53. package/src/lib/helpers/cryptography/armorKeypair.js +0 -42
  54. package/src/lib/helpers/cryptography/armorKeypairSync.js +0 -55
  55. package/src/lib/helpers/cryptography/encryptValue.js +0 -7
  56. package/src/lib/helpers/cryptography/localKeypair.js +0 -14
  57. package/src/lib/helpers/cryptography/mutateKeysSrcSync.js +0 -38
  58. package/src/lib/helpers/cryptography/provision.js +0 -56
  59. package/src/lib/helpers/cryptography/provisionSync.js +0 -51
  60. package/src/lib/helpers/cryptography/provisionWithPrivateKey.js +0 -26
  61. package/src/lib/helpers/dotenvParse.js +0 -55
  62. package/src/lib/helpers/escapeDollarSigns.js +0 -5
  63. package/src/lib/helpers/escapeForRegex.js +0 -5
  64. package/src/lib/helpers/evalKeyValue.js +0 -23
  65. package/src/lib/helpers/isFullyEncrypted.js +0 -27
  66. package/src/lib/helpers/isIgnoringDotenvKeys.js +0 -19
  67. package/src/lib/helpers/keyResolution/index.js +0 -16
  68. package/src/lib/helpers/keyResolution/keyNamesForEnvFile.js +0 -24
  69. package/src/lib/helpers/keyResolution/keyValues.js +0 -99
  70. package/src/lib/helpers/keyResolution/keyValuesFromEnvSrc.js +0 -80
  71. package/src/lib/helpers/keyResolution/keyValuesSync.js +0 -103
  72. package/src/lib/helpers/keyResolution/readFileKey.js +0 -17
  73. package/src/lib/helpers/keyResolution/readFileKeySync.js +0 -15
  74. package/src/lib/helpers/keyResolution/readProcessKey.js +0 -7
  75. package/src/lib/helpers/localDisplayPath.js +0 -11
  76. package/src/lib/helpers/parse.js +0 -214
  77. package/src/lib/helpers/pluralize.js +0 -10
  78. package/src/lib/helpers/quotes.js +0 -36
  79. package/src/lib/helpers/replace.js +0 -82
  80. package/src/lib/helpers/resolveEscapeSequences.js +0 -5
  81. package/src/lib/services/decrypt.js +0 -157
  82. package/src/lib/services/encrypt.js +0 -214
  83. package/src/lib/services/get.js +0 -76
  84. package/src/lib/services/keypair.js +0 -60
  85. package/src/lib/services/loginPoll.js +0 -36
  86. package/src/lib/services/ls.js +0 -57
  87. package/src/lib/services/rotate.js +0 -198
  88. package/src/lib/services/run.js +0 -255
  89. package/src/lib/services/sets.js +0 -326
@@ -1,87 +0,0 @@
1
- const fsx = require('./../../lib/helpers/fsx')
2
- const { logger } = require('./../../shared/logger')
3
-
4
- const Rotate = require('./../../lib/services/rotate')
5
-
6
- const catchAndLog = require('../../lib/helpers/catchAndLog')
7
- const createSpinner = require('../../lib/helpers/createSpinner')
8
- const Session = require('../../db/session')
9
- const normalizeArmorOptions = require('./normalizeArmorOptions')
10
-
11
- async function rotate () {
12
- const options = normalizeArmorOptions(this.opts())
13
- const spinner = await createSpinner({ ...options, text: 'rotating', frames: ['⟳', '⤾', '⥁'] })
14
-
15
- logger.debug(`options: ${JSON.stringify(options)}`)
16
-
17
- const envs = this.envs
18
- const sesh = new Session()
19
- const noArmor = options.armor === false || (await sesh.noArmor())
20
-
21
- // stdout - should not have a try so that exit codes can surface to stdout
22
- if (options.stdout) {
23
- if (spinner) spinner.stop()
24
- const {
25
- processedEnvs
26
- } = await new Rotate(envs, options.key, options.excludeKey, options.envKeysFile, noArmor, {
27
- command: process.argv.slice(2)
28
- }).run()
29
- if (spinner) spinner.stop()
30
- for (const processedEnv of processedEnvs) {
31
- console.log(processedEnv.envSrc)
32
- if (processedEnv.localPrivateKeyAdded) {
33
- console.log('')
34
- console.log(processedEnv.envKeysSrc)
35
- }
36
- }
37
- process.exit(0) // exit early
38
- } else {
39
- try {
40
- if (spinner) spinner.stop()
41
- const {
42
- processedEnvs,
43
- changedFilepaths,
44
- unchangedFilepaths
45
- } = await new Rotate(envs, options.key, options.excludeKey, options.envKeysFile, noArmor, {
46
- command: process.argv.slice(2)
47
- }).run()
48
-
49
- for (const processedEnv of processedEnvs) {
50
- logger.verbose(`rotating ${processedEnv.envFilepath} (${processedEnv.filepath})`)
51
- if (processedEnv.error) {
52
- logger.warn(processedEnv.error.messageWithHelp)
53
- } else if (processedEnv.changed) {
54
- await fsx.writeFileX(processedEnv.filepath, processedEnv.envSrc)
55
- if (processedEnv.localPrivateKeyAdded) {
56
- await fsx.writeFileX(processedEnv.envKeysFilepath, processedEnv.envKeysSrc)
57
- }
58
-
59
- logger.verbose(`rotated ${processedEnv.envFilepath} (${processedEnv.filepath})`)
60
- } else {
61
- logger.verbose(`no change ${processedEnv.envFilepath} (${processedEnv.filepath})`)
62
- }
63
- }
64
-
65
- if (spinner) spinner.stop()
66
- if (changedFilepaths.length > 0) {
67
- const remoteKeyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.remotePrivateKeyAdded)
68
-
69
- let msg = `⟳ rotated (${changedFilepaths.join(',')})`
70
- if (remoteKeyAddedEnv) {
71
- msg += ' · armored ⛨'
72
- }
73
- logger.success(msg)
74
- } else if (unchangedFilepaths.length > 0) {
75
- logger.info(`○ no change (${unchangedFilepaths})`)
76
- } else {
77
- // do nothing - scenario when no .env files found
78
- }
79
- } catch (error) {
80
- if (spinner) spinner.stop()
81
- catchAndLog(error)
82
- process.exit(1)
83
- }
84
- }
85
- }
86
-
87
- module.exports = rotate
@@ -1,61 +0,0 @@
1
- const quotes = require('./quotes')
2
- const dotenvParse = require('./dotenvParse')
3
- const escapeForRegex = require('./escapeForRegex')
4
- const escapeDollarSigns = require('./escapeDollarSigns')
5
-
6
- function append (src, key, appendValue) {
7
- let output
8
- let newPart = ''
9
-
10
- const parsed = dotenvParse(src, true, true) // skip expanding \n and skip converting \r\n
11
- const _quotes = quotes(src)
12
- if (Object.prototype.hasOwnProperty.call(parsed, key)) {
13
- const quote = _quotes[key]
14
- const originalValue = parsed[key]
15
-
16
- newPart += `${key}=${quote}${originalValue},${appendValue}${quote}`
17
-
18
- const escapedOriginalValue = escapeForRegex(originalValue)
19
-
20
- // conditionally enforce end of line
21
- let enforceEndOfLine = ''
22
- if (escapedOriginalValue === '') {
23
- enforceEndOfLine = '$' // EMPTY scenario
24
- }
25
-
26
- const currentPart = new RegExp(
27
- '^' + // start of line
28
- '(\\s*)?' + // spaces
29
- '(export\\s+)?' + // export
30
- key + // KEY
31
- '\\s*=\\s*' + // spaces (KEY = value)
32
- '["\'`]?' + // open quote
33
- escapedOriginalValue + // escaped value
34
- '["\'`]?' + // close quote
35
- enforceEndOfLine
36
- ,
37
- 'gm' // (g)lobal (m)ultiline
38
- )
39
-
40
- const saferInput = escapeDollarSigns(newPart) // cleanse user inputted capture groups ($1, $2 etc)
41
-
42
- // $1 preserves spaces
43
- // $2 preserves export
44
- output = src.replace(currentPart, `$1$2${saferInput}`)
45
- } else {
46
- newPart += `${key}="${appendValue}"`
47
-
48
- // append
49
- if (src.endsWith('\n')) {
50
- newPart = newPart + '\n'
51
- } else {
52
- newPart = '\n' + newPart
53
- }
54
-
55
- output = src + newPart
56
- }
57
-
58
- return output
59
- }
60
-
61
- module.exports = append
@@ -1,42 +0,0 @@
1
- const Session = require('../../../db/session')
2
- const ArmorKeypair = require('../../services/armorKeypair')
3
- const sanitizeCommandForMetadata = require('../sanitizeCommandForMetadata')
4
-
5
- function metadataFromOptions (options) {
6
- if (options.metadata) return options.metadata
7
- if (!options.command) return undefined
8
-
9
- return JSON.stringify({
10
- command: sanitizeCommandForMetadata(options.command)
11
- })
12
- }
13
-
14
- async function armorKeypair (existingPublicKey, options = {}) {
15
- const sesh = new Session()
16
- const token = options.token || sesh.token()
17
- if (!token) {
18
- return {
19
- publicKey: undefined,
20
- privateKey: undefined
21
- }
22
- }
23
-
24
- const json = await new ArmorKeypair(
25
- options.hostname || sesh.hostname(),
26
- token,
27
- sesh.devicePublicKey(),
28
- existingPublicKey,
29
- {
30
- envFile: options.envFilepath,
31
- team: options.team,
32
- metadata: metadataFromOptions(options)
33
- }
34
- ).run()
35
-
36
- return {
37
- publicKey: json.public_key,
38
- privateKey: json.private_key
39
- }
40
- }
41
-
42
- module.exports = armorKeypair
@@ -1,55 +0,0 @@
1
- const path = require('path')
2
- const childProcess = require('child_process')
3
-
4
- const EXEC_TIMEOUT = 5 * 60 * 1000
5
-
6
- function cliPath () {
7
- return path.resolve(__dirname, '../../../cli/dotenvx.js')
8
- }
9
-
10
- function execEnv () {
11
- const env = { ...process.env }
12
- env._TAPJS_PROCESSINFO_COVERAGE_ = '0'
13
-
14
- if (env.NODE_OPTIONS && env.NODE_OPTIONS.includes('@tapjs/processinfo')) {
15
- const nodeOptions = env.NODE_OPTIONS
16
- .split(/\s+/)
17
- .filter((option) => !option.includes('@tapjs/processinfo'))
18
- .join(' ')
19
- .trim()
20
-
21
- if (nodeOptions) {
22
- env.NODE_OPTIONS = nodeOptions
23
- } else {
24
- delete env.NODE_OPTIONS
25
- }
26
- }
27
-
28
- return env
29
- }
30
-
31
- function armorKeypairSync (_existingPublicKey, options = {}) {
32
- const args = [cliPath(), 'keypair', '--format', 'json']
33
- if (options.envFilepath) args.push('-f', options.envFilepath)
34
-
35
- let keypairs = {}
36
- try {
37
- keypairs = JSON.parse(childProcess.execFileSync(process.execPath, args, {
38
- env: execEnv(),
39
- stdio: ['inherit', 'pipe', 'inherit'],
40
- timeout: EXEC_TIMEOUT
41
- }).toString().trim())
42
- } catch (_error) {
43
- keypairs = {}
44
- }
45
-
46
- const publicKeyName = Object.keys(keypairs).find((key) => key === 'DOTENV_PUBLIC_KEY' || key.startsWith('DOTENV_PUBLIC_KEY_'))
47
- const privateKeyName = Object.keys(keypairs).find((key) => key === 'DOTENV_PRIVATE_KEY' || key.startsWith('DOTENV_PRIVATE_KEY_'))
48
-
49
- return {
50
- publicKey: keypairs[publicKeyName],
51
- privateKey: keypairs[privateKeyName]
52
- }
53
- }
54
-
55
- module.exports = armorKeypairSync
@@ -1,7 +0,0 @@
1
- const { encrypt } = require('@dotenvx/primitives')
2
-
3
- function encryptValue (value, publicKey) {
4
- return encrypt(publicKey, value)
5
- }
6
-
7
- module.exports = encryptValue
@@ -1,14 +0,0 @@
1
- const { derive, keypair } = require('@dotenvx/primitives')
2
-
3
- function localKeypair (existingPrivateKey) {
4
- if (existingPrivateKey) {
5
- return {
6
- publicKey: derive(existingPrivateKey),
7
- privateKey: existingPrivateKey
8
- }
9
- }
10
-
11
- return keypair()
12
- }
13
-
14
- module.exports = localKeypair
@@ -1,38 +0,0 @@
1
- const FIRST_TIME_KEYS_SRC = [
2
- '#/------------------!DOTENV_PRIVATE_KEYS!-------------------/',
3
- '#/ private decryption keys. DO NOT commit to source control /',
4
- '#/ [how it works](https://dotenvx.com/encryption) /',
5
- '#/ ⛨ ARMORED KEYS: `dotenvx armor up` /',
6
- '#/----------------------------------------------------------/'
7
- ].join('\n')
8
-
9
- const path = require('path')
10
- const fsx = require('./../fsx')
11
-
12
- function mutateKeysSrcSync ({ envFilepath, keysFilepath, privateKeyName, privateKeyValue }) {
13
- const filename = path.basename(envFilepath)
14
- const filepath = path.resolve(envFilepath)
15
- let resolvedKeysFilepath = path.join(path.dirname(filepath), '.env.keys')
16
- if (keysFilepath) {
17
- resolvedKeysFilepath = path.resolve(keysFilepath)
18
- }
19
- const appendPrivateKey = [`# ${filename}`, `${privateKeyName}=${privateKeyValue}`, ''].join('\n')
20
-
21
- let keysSrc = ''
22
- if (fsx.existsSync(resolvedKeysFilepath)) {
23
- keysSrc = fsx.readFileXSync(resolvedKeysFilepath)
24
- }
25
- keysSrc = keysSrc.length > 1 ? keysSrc : `${FIRST_TIME_KEYS_SRC}\n`
26
- keysSrc = `${keysSrc}\n${appendPrivateKey}`
27
-
28
- fsx.writeFileXSync(resolvedKeysFilepath, keysSrc) // TODO: don't write if armor
29
-
30
- const envKeysFilepath = keysFilepath || path.join(path.dirname(envFilepath), path.basename(resolvedKeysFilepath))
31
-
32
- return {
33
- keysSrc,
34
- envKeysFilepath
35
- }
36
- }
37
-
38
- module.exports = mutateKeysSrcSync
@@ -1,56 +0,0 @@
1
- const mutateSrc = require('./mutateSrc')
2
- const mutateKeysSrc = require('./mutateKeysSrc')
3
- const armorKeypair = require('./armorKeypair')
4
- const localKeypair = require('./localKeypair')
5
- const { keyNamesForEnvFile } = require('../keyResolution')
6
-
7
- async function provision ({ envSrc, envFilepath, keysFilepath, noArmor, token, selectKeyStorage, command }) {
8
- noArmor = noArmor !== false
9
- if (!noArmor && selectKeyStorage) {
10
- noArmor = await selectKeyStorage() !== 'armored'
11
- }
12
-
13
- const { publicKeyName, privateKeyName } = keyNamesForEnvFile(envFilepath)
14
-
15
- let publicKey
16
- let privateKey
17
- let keysSrc
18
- let envKeysFilepath
19
- let localPrivateKeyAdded = false
20
- let remotePrivateKeyAdded = false
21
-
22
- if (noArmor) {
23
- const kp = localKeypair()
24
- publicKey = kp.publicKey
25
- privateKey = kp.privateKey
26
- } else {
27
- const armorOptions = { token, envFilepath, command }
28
- const kp = await armorKeypair(undefined, armorOptions)
29
- publicKey = kp.publicKey
30
- privateKey = kp.privateKey
31
- }
32
-
33
- const mutated = mutateSrc({ envSrc, envFilepath, keysFilepath, publicKeyName, publicKeyValue: publicKey })
34
- envSrc = mutated.envSrc
35
-
36
- if (noArmor) {
37
- const mutated = await mutateKeysSrc({ envFilepath, keysFilepath, privateKeyName, privateKeyValue: privateKey })
38
- keysSrc = mutated.keysSrc
39
- envKeysFilepath = mutated.envKeysFilepath
40
- localPrivateKeyAdded = true
41
- } else {
42
- remotePrivateKeyAdded = true
43
- }
44
-
45
- return {
46
- envSrc,
47
- keysSrc,
48
- publicKey,
49
- privateKey,
50
- envKeysFilepath,
51
- localPrivateKeyAdded,
52
- remotePrivateKeyAdded
53
- }
54
- }
55
-
56
- module.exports = provision
@@ -1,51 +0,0 @@
1
- const mutateSrc = require('./mutateSrc')
2
- const mutateKeysSrcSync = require('./mutateKeysSrcSync')
3
- const armorKeypairSync = require('./armorKeypairSync')
4
- const localKeypair = require('./localKeypair')
5
- const { keyNamesForEnvFile } = require('../keyResolution')
6
-
7
- function provisionSync ({ envSrc, envFilepath, keysFilepath, noArmor, command }) {
8
- noArmor = noArmor !== false
9
- const { publicKeyName, privateKeyName } = keyNamesForEnvFile(envFilepath)
10
-
11
- let publicKey
12
- let privateKey
13
- let keysSrc
14
- let envKeysFilepath
15
- let localPrivateKeyAdded = false
16
- let remotePrivateKeyAdded = false
17
-
18
- if (noArmor) {
19
- const kp = localKeypair()
20
- publicKey = kp.publicKey
21
- privateKey = kp.privateKey
22
- } else {
23
- const kp = armorKeypairSync(undefined, { envFilepath, command })
24
- publicKey = kp.publicKey
25
- privateKey = kp.privateKey
26
- }
27
-
28
- const mutated = mutateSrc({ envSrc, envFilepath, keysFilepath, publicKeyName, publicKeyValue: publicKey })
29
- envSrc = mutated.envSrc
30
-
31
- if (noArmor) {
32
- const mutated = mutateKeysSrcSync({ envFilepath, keysFilepath, privateKeyName, privateKeyValue: privateKey })
33
- keysSrc = mutated.keysSrc
34
- envKeysFilepath = mutated.envKeysFilepath
35
- localPrivateKeyAdded = true
36
- } else {
37
- remotePrivateKeyAdded = true
38
- }
39
-
40
- return {
41
- envSrc,
42
- keysSrc,
43
- publicKey,
44
- privateKey,
45
- envKeysFilepath,
46
- localPrivateKeyAdded,
47
- remotePrivateKeyAdded
48
- }
49
- }
50
-
51
- module.exports = provisionSync
@@ -1,26 +0,0 @@
1
- const Errors = require('./../errors')
2
- const mutateSrc = require('./mutateSrc')
3
- const localKeypair = require('./localKeypair')
4
-
5
- function provisionWithPrivateKey ({ envSrc, envFilepath, keysFilepath, privateKeyValue, publicKeyValue, publicKeyName }) {
6
- const { publicKey, privateKey } = localKeypair(privateKeyValue) // noArmor doesn't matter here since privateKeyValue was already discovered prior (via armor and local) and passed as privateKeyValue
7
-
8
- // if derivation doesn't match what's in the file (or preset in env)
9
- if (publicKeyValue && publicKeyValue !== publicKey) {
10
- throw new Errors({ publicKey, publicKeyExisting: publicKeyValue }).mispairedPrivateKey()
11
- }
12
-
13
- // scenario when encrypting a monorepo second .env file from a prior generated -fk .env.keys file
14
- if (!publicKeyValue) {
15
- const mutated = mutateSrc({ envSrc, envFilepath, keysFilepath, publicKeyName, publicKeyValue: publicKey })
16
- envSrc = mutated.envSrc
17
- }
18
-
19
- return {
20
- envSrc,
21
- publicKey,
22
- privateKey
23
- }
24
- }
25
-
26
- module.exports = provisionWithPrivateKey
@@ -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,5 +0,0 @@
1
- function escapeDollarSigns (str) {
2
- return str.replace(/\$/g, '$$$$')
3
- }
4
-
5
- module.exports = escapeDollarSigns
@@ -1,5 +0,0 @@
1
- function escapeForRegex (str) {
2
- return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
3
- }
4
-
5
- module.exports = escapeForRegex
@@ -1,23 +0,0 @@
1
- const { execSync } = require('child_process')
2
- const chomp = require('./chomp')
3
- const Errors = require('./errors')
4
-
5
- function evalKeyValue (key, value, processEnv, runningParsed) {
6
- // Match everything between the outermost $() using a regex with non-capturing groups
7
- const matches = value.match(/\$\(([^)]+(?:\)[^(]*)*)\)/g) || []
8
- return matches.reduce((newValue, match) => {
9
- const command = match.slice(2, -1) // Extract command by removing $() wrapper
10
- let result
11
-
12
- try {
13
- result = execSync(command, { env: { ...processEnv, ...runningParsed } }).toString() // execute command (including runningParsed)
14
- } catch (e) {
15
- throw new Errors({ key, command, message: e.message.trim() }).commandSubstitutionFailed()
16
- }
17
-
18
- result = chomp(result) // chomp it
19
- return newValue.replace(match, result) // Replace match with result
20
- }, value)
21
- }
22
-
23
- module.exports = evalKeyValue
@@ -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
@@ -1,19 +0,0 @@
1
- const fsx = require('./fsx')
2
- const ignore = require('ignore')
3
-
4
- function isIgnoringDotenvKeys () {
5
- if (!fsx.existsSync('.gitignore')) {
6
- return false
7
- }
8
-
9
- const gitignore = fsx.readFileXSync('.gitignore')
10
- const ig = ignore(gitignore).add(gitignore)
11
-
12
- if (!ig.ignores('.env.keys')) {
13
- return false
14
- }
15
-
16
- return true
17
- }
18
-
19
- module.exports = isIgnoringDotenvKeys
@@ -1,16 +0,0 @@
1
- module.exports = {
2
- keyNamesForEnvFile: require('./keyNamesForEnvFile'),
3
- keyValues: require('./keyValues'),
4
- keyValuesSync: require('./keyValuesSync'),
5
- keyValuesFromEnvSrc: require('./keyValuesFromEnvSrc'),
6
-
7
- // private
8
- // private keys are resolved via keyValuesSync()
9
-
10
- // other
11
- readProcessKey: require('./readProcessKey'),
12
- readFileKey: require('./readFileKey'),
13
- readFileKeySync: require('./readFileKeySync'),
14
- guessPrivateKeyFilename: require('./../guessPrivateKeyFilename'),
15
- dotenvPrivateKeyNames: require('./../dotenvPrivateKeyNames')
16
- }
@@ -1,24 +0,0 @@
1
- const canonicalEnvFilename = require('./../canonicalEnvFilename')
2
- const environment = require('./../envResolution/environment')
3
-
4
- function keyNamesForEnvFile (filepath) {
5
- const filename = canonicalEnvFilename(filepath)
6
-
7
- // .env
8
- if (filename === '.env') {
9
- return {
10
- publicKeyName: 'DOTENV_PUBLIC_KEY',
11
- privateKeyName: 'DOTENV_PRIVATE_KEY'
12
- }
13
- }
14
-
15
- // .env.ENVIRONMENT
16
- const resolvedEnvironment = environment(filename).toUpperCase()
17
-
18
- return {
19
- publicKeyName: `DOTENV_PUBLIC_KEY_${resolvedEnvironment}`,
20
- privateKeyName: `DOTENV_PRIVATE_KEY_${resolvedEnvironment}`
21
- }
22
- }
23
-
24
- module.exports = keyNamesForEnvFile