@dotenvx/dotenvx 1.61.5 → 1.62.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 +26 -1
- package/package.json +1 -1
- package/src/cli/actions/run.js +2 -0
- package/src/lib/helpers/buildEnvs.js +4 -0
- package/src/lib/helpers/executeExtension.js +1 -1
- package/src/lib/helpers/parse.js +5 -2
- package/src/lib/main.d.ts +24 -0
- package/src/lib/main.js +6 -2
- package/src/lib/services/get.js +5 -2
- package/src/lib/services/run.js +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,32 @@
|
|
|
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.62.0...main)
|
|
6
|
+
|
|
7
|
+
## [1.62.0](https://github.com/dotenvx/dotenvx/compare/v1.61.6...v1.62.0) (2026-04-23)
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* Add support for `config({ envs })`. unlocks simpler cloudflare worker integration ([#803](https://github.com/dotenvx/dotenvx/pull/803))
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import envSrc from '../.env.txt'
|
|
15
|
+
import dotenvx from '@dotenvx/dotenvx'
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
async fetch(request, env, ctx) {
|
|
19
|
+
dotenvx.config({ envs: [{ type: 'env', value: envSrc, privateKeyName: 'DOTENV_PRIVATE_KEY' }] processEnv: env })
|
|
20
|
+
|
|
21
|
+
return new Response(`Hello ${env.HELLO}`)
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## [1.61.6](https://github.com/dotenvx/dotenvx/compare/v1.61.5...v1.61.6) (2026-04-23)
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
* Guard against command substitution following `encrypted:` ([#802](https://github.com/dotenvx/dotenvx/pull/802))
|
|
6
31
|
|
|
7
32
|
## [1.61.5](https://github.com/dotenvx/dotenvx/compare/v1.61.4...v1.61.5) (2026-04-22)
|
|
8
33
|
|
package/package.json
CHANGED
package/src/cli/actions/run.js
CHANGED
|
@@ -8,6 +8,7 @@ const createSpinner = require('../../lib/helpers/createSpinner')
|
|
|
8
8
|
const Session = require('../../db/session')
|
|
9
9
|
|
|
10
10
|
const conventions = require('./../../lib/helpers/conventions')
|
|
11
|
+
const { determine } = require('./../../lib/helpers/envResolution')
|
|
11
12
|
|
|
12
13
|
async function run () {
|
|
13
14
|
const options = this.opts()
|
|
@@ -45,6 +46,7 @@ async function run () {
|
|
|
45
46
|
} else {
|
|
46
47
|
envs = this.envs
|
|
47
48
|
}
|
|
49
|
+
envs = determine(envs, process.env)
|
|
48
50
|
|
|
49
51
|
const {
|
|
50
52
|
processedEnvs,
|
|
@@ -2,6 +2,10 @@ const conventions = require('./conventions')
|
|
|
2
2
|
const dotenvOptionPaths = require('./dotenvOptionPaths')
|
|
3
3
|
|
|
4
4
|
function buildEnvs (options) {
|
|
5
|
+
if (options.envs) {
|
|
6
|
+
return options.envs
|
|
7
|
+
}
|
|
8
|
+
|
|
5
9
|
// build envs using user set option.path
|
|
6
10
|
const optionPaths = dotenvOptionPaths(options) // [ '.env' ]
|
|
7
11
|
|
|
@@ -23,7 +23,7 @@ function executeExtension (ext, command, rawArgs) {
|
|
|
23
23
|
const result = childProcess.spawnSync(`dotenvx-ext-${command}`, forwardedArgs, { stdio: 'inherit', env })
|
|
24
24
|
if (result.error) {
|
|
25
25
|
// list known extension here for convenience to the user
|
|
26
|
-
if (['vault'
|
|
26
|
+
if (['vault'].includes(command)) {
|
|
27
27
|
logger.warn(`[INSTALLATION_NEEDED] install dotenvx-ext-${command} to use [dotenvx ext ${command}] commands`)
|
|
28
28
|
logger.help('? see installation instructions [https://github.com/dotenvx/dotenvx-ext-vault]')
|
|
29
29
|
} else {
|
package/src/lib/helpers/parse.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const decryptKeyValue = require('./cryptography/decryptKeyValue')
|
|
2
|
+
const isEncrypted = require('./cryptography/isEncrypted')
|
|
2
3
|
const evalKeyValue = require('./evalKeyValue')
|
|
3
4
|
const resolveEscapeSequences = require('./resolveEscapeSequences')
|
|
4
5
|
|
|
@@ -44,9 +45,11 @@ class Parse {
|
|
|
44
45
|
this.errors.push(e)
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
const encryptedPrefixed = isEncrypted(this.parsed[key]) // do not eval encrypted prefix
|
|
49
|
+
|
|
47
50
|
// eval empty, double, or backticks
|
|
48
51
|
let evaled = false
|
|
49
|
-
if (quote !== "'" && (!this.inProcessEnv(key) || this.processEnv[key] === this.parsed[key])) {
|
|
52
|
+
if (!encryptedPrefixed && quote !== "'" && (!this.inProcessEnv(key) || this.processEnv[key] === this.parsed[key])) {
|
|
50
53
|
const priorEvaled = this.parsed[key]
|
|
51
54
|
// eval
|
|
52
55
|
try {
|
|
@@ -60,7 +63,7 @@ class Parse {
|
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
// expand empty, double, or backticks
|
|
63
|
-
if (!evaled && quote !== "'" && (!this.processEnv[key] || this.overload)) {
|
|
66
|
+
if (!encryptedPrefixed && !evaled && quote !== "'" && (!this.processEnv[key] || this.overload)) {
|
|
64
67
|
this.parsed[key] = resolveEscapeSequences(this.expand(this.parsed[key]))
|
|
65
68
|
}
|
|
66
69
|
|
package/src/lib/main.d.ts
CHANGED
|
@@ -50,6 +50,15 @@ export function parse<T extends DotenvParseOutput = DotenvParseOutput>(
|
|
|
50
50
|
): T;
|
|
51
51
|
|
|
52
52
|
export interface DotenvConfigOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Specify explicit env sources. When set, `path` and `convention` are ignored.
|
|
55
|
+
*
|
|
56
|
+
* @default undefined
|
|
57
|
+
* @example require('@dotenvx/dotenvx').config({ envs: [{ type: 'envFile', value: '.env' }] })
|
|
58
|
+
* @example require('@dotenvx/dotenvx').config({ envs: [{ type: 'env', value: 'HELLO=World', privateKeyName: 'DOTENV_PRIVATE_KEY' }] })
|
|
59
|
+
*/
|
|
60
|
+
envs?: DotenvConfigEnv[];
|
|
61
|
+
|
|
53
62
|
/**
|
|
54
63
|
* Specify a custom path if your file containing environment variables is located elsewhere.
|
|
55
64
|
* Can also be an array of strings, specifying multiple paths.
|
|
@@ -161,6 +170,21 @@ export interface DotenvConfigOptions {
|
|
|
161
170
|
opsOff?: boolean;
|
|
162
171
|
}
|
|
163
172
|
|
|
173
|
+
export type DotenvConfigEnv =
|
|
174
|
+
| DotenvConfigEnvFile
|
|
175
|
+
| DotenvConfigEnvSrc;
|
|
176
|
+
|
|
177
|
+
export interface DotenvConfigEnvFile {
|
|
178
|
+
type: 'envFile';
|
|
179
|
+
value: string | URL;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface DotenvConfigEnvSrc {
|
|
183
|
+
type: 'env';
|
|
184
|
+
value: string | Buffer;
|
|
185
|
+
privateKeyName?: string;
|
|
186
|
+
}
|
|
187
|
+
|
|
164
188
|
export interface DotenvConfigOutput {
|
|
165
189
|
error?: Error;
|
|
166
190
|
parsed?: DotenvParseOutput;
|
package/src/lib/main.js
CHANGED
|
@@ -16,6 +16,7 @@ const Session = require('./../db/session')
|
|
|
16
16
|
|
|
17
17
|
// helpers
|
|
18
18
|
const buildEnvs = require('./helpers/buildEnvs')
|
|
19
|
+
const { determine } = require('./helpers/envResolution')
|
|
19
20
|
const Parse = require('./helpers/parse')
|
|
20
21
|
const fsx = require('./helpers/fsx')
|
|
21
22
|
const localDisplayPath = require('./helpers/localDisplayPath')
|
|
@@ -50,7 +51,10 @@ const config = function (options = {}) {
|
|
|
50
51
|
const noOps = resolveNoOps(options)
|
|
51
52
|
|
|
52
53
|
try {
|
|
53
|
-
|
|
54
|
+
let envs = buildEnvs(options)
|
|
55
|
+
if (!options.envs) {
|
|
56
|
+
envs = determine(envs, processEnv)
|
|
57
|
+
}
|
|
54
58
|
const {
|
|
55
59
|
processedEnvs,
|
|
56
60
|
readableFilepaths,
|
|
@@ -103,7 +107,7 @@ const config = function (options = {}) {
|
|
|
103
107
|
}
|
|
104
108
|
}
|
|
105
109
|
|
|
106
|
-
let msg = `
|
|
110
|
+
let msg = `injected env (${uniqueInjectedKeys.length})`
|
|
107
111
|
if (readableFilepaths.length > 0) {
|
|
108
112
|
msg += ` from ${readableFilepaths.join(', ')}`
|
|
109
113
|
}
|
package/src/lib/services/get.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const Run = require('./run')
|
|
2
2
|
const Errors = require('./../helpers/errors')
|
|
3
|
+
const { determine } = require('./../helpers/envResolution')
|
|
3
4
|
|
|
4
5
|
class Get {
|
|
5
6
|
constructor (key, envs = [], overload = false, all = false, envKeysFilepath = null, noOps = false) {
|
|
@@ -13,13 +14,15 @@ class Get {
|
|
|
13
14
|
|
|
14
15
|
runSync () {
|
|
15
16
|
const processEnv = { ...process.env }
|
|
16
|
-
const
|
|
17
|
+
const envs = determine(this.envs, processEnv)
|
|
18
|
+
const { processedEnvs } = new Run(envs, this.overload, processEnv, this.envKeysFilepath, this.noOps).runSync()
|
|
17
19
|
return this._result(processedEnvs, processEnv)
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
async run () {
|
|
21
23
|
const processEnv = { ...process.env }
|
|
22
|
-
const
|
|
24
|
+
const envs = determine(this.envs, processEnv)
|
|
25
|
+
const { processedEnvs } = await new Run(envs, this.overload, processEnv, this.envKeysFilepath, this.noOps).run()
|
|
23
26
|
return this._result(processedEnvs, processEnv)
|
|
24
27
|
}
|
|
25
28
|
|
package/src/lib/services/run.js
CHANGED
|
@@ -15,13 +15,9 @@ const {
|
|
|
15
15
|
keyValuesSync
|
|
16
16
|
} = require('./../helpers/keyResolution')
|
|
17
17
|
|
|
18
|
-
const {
|
|
19
|
-
determine
|
|
20
|
-
} = require('./../helpers/envResolution')
|
|
21
|
-
|
|
22
18
|
class Run {
|
|
23
19
|
constructor (envs = [], overload = false, processEnv = process.env, envKeysFilepath = null, noOps = false) {
|
|
24
|
-
this.envs =
|
|
20
|
+
this.envs = envs
|
|
25
21
|
this.overload = overload
|
|
26
22
|
this.processEnv = processEnv
|
|
27
23
|
this.envKeysFilepath = envKeysFilepath
|
|
@@ -46,7 +42,7 @@ class Run {
|
|
|
46
42
|
if (env.type === TYPE_ENV_FILE) {
|
|
47
43
|
this._injectEnvFileSync(env.value)
|
|
48
44
|
} else if (env.type === TYPE_ENV) {
|
|
49
|
-
this._injectEnv(env.value)
|
|
45
|
+
this._injectEnv(env.value, env.privateKeyName)
|
|
50
46
|
}
|
|
51
47
|
}
|
|
52
48
|
|
|
@@ -72,7 +68,7 @@ class Run {
|
|
|
72
68
|
if (env.type === TYPE_ENV_FILE) {
|
|
73
69
|
await this._injectEnvFile(env.value)
|
|
74
70
|
} else if (env.type === TYPE_ENV) {
|
|
75
|
-
this._injectEnv(env.value)
|
|
71
|
+
this._injectEnv(env.value, env.privateKeyName)
|
|
76
72
|
}
|
|
77
73
|
}
|
|
78
74
|
|
|
@@ -86,19 +82,23 @@ class Run {
|
|
|
86
82
|
}
|
|
87
83
|
}
|
|
88
84
|
|
|
89
|
-
_injectEnv (env) {
|
|
85
|
+
_injectEnv (env, privateKeyName = null) {
|
|
90
86
|
const row = {}
|
|
91
87
|
row.type = TYPE_ENV
|
|
92
88
|
row.string = env
|
|
93
89
|
|
|
94
90
|
try {
|
|
91
|
+
const privateKey = privateKeyName ? this.processEnv[privateKeyName] || null : null
|
|
92
|
+
|
|
95
93
|
const {
|
|
96
94
|
parsed,
|
|
97
95
|
errors,
|
|
98
96
|
injected,
|
|
99
97
|
preExisted
|
|
100
|
-
} = new Parse(env,
|
|
98
|
+
} = new Parse(env, privateKey, this.processEnv, this.overload, privateKeyName).run()
|
|
101
99
|
|
|
100
|
+
row.privateKeyName = privateKeyName
|
|
101
|
+
row.privateKey = privateKey
|
|
102
102
|
row.parsed = parsed
|
|
103
103
|
row.errors = errors
|
|
104
104
|
row.injected = injected
|