@dotenvx/dotenvx 2.17.0 → 2.17.2

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,19 @@
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/v2.17.0...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx/compare/v2.17.2...main)
6
+
7
+ ## [2.17.2](https://github.com/dotenvx/dotenvx/compare/v2.17.1...v2.17.2) (2026-07-22)
8
+
9
+ ### Added
10
+
11
+ * Add support for `DOTENV_CONFIG_IGNORE` global convenience ([#919](https://github.com/dotenvx/dotenvx/pull/919))
12
+
13
+ ## [2.17.1](https://github.com/dotenvx/dotenvx/compare/v2.17.0...v2.17.1) (2026-07-21)
14
+
15
+ ### Changed
16
+
17
+ * Handle `ctrl + c` better ([#916](https://github.com/dotenvx/dotenvx/pull/916))
6
18
 
7
19
  ## [2.17.0](https://github.com/dotenvx/dotenvx/compare/v2.16.1...v2.17.0) (2026-07-21)
8
20
 
package/README.md CHANGED
@@ -167,7 +167,7 @@ Hello World
167
167
  see [1Password guide](https://dotenvx.com/docs/secrets-in-1password)
168
168
 
169
169
  </details>
170
- <details><summary>Bitwarden 🔑</summary><br>
170
+ <details><summary>Bitwarden 🛡️</summary><br>
171
171
 
172
172
  Run with secrets resolved directly from Bitwarden Password Manager.
173
173
 
@@ -1586,6 +1586,11 @@ $ dotenvx run -f .env.missing --ignore=MISSING_ENV_FILE -- node index.js
1586
1586
  ...
1587
1587
  ```
1588
1588
 
1589
+ You can also set `DOTENV_CONFIG_IGNORE="MISSING_ENV_FILE"`. It is parsed as a comma-separated list.
1590
+
1591
+ ```sh
1592
+ $ DOTENV_CONFIG_IGNORE="MISSING_ENV_FILE,OTHER_ERROR_CODE" dotenvx run -f .env.missing -- node index.js
1593
+ ```
1589
1594
  </details>
1590
1595
  <details><summary>`run --convention=nextjs`</summary><br>
1591
1596
 
@@ -3039,6 +3044,8 @@ X.X.X
3039
3044
 
3040
3045
  </details>
3041
3046
 
3047
+ &nbsp;
3048
+
3042
3049
  ### Library 📦
3043
3050
 
3044
3051
  Use dotenvx directly in code.
@@ -3491,6 +3498,29 @@ Set `mask: 0` to fully mask values.
3491
3498
 
3492
3499
  &nbsp;
3493
3500
 
3501
+ ### Settings ⚙️
3502
+
3503
+ There are global settings available that can be configured as environment variables.
3504
+
3505
+ <details><summary>Environment variables</summary><br>
3506
+
3507
+ ```ini
3508
+ # dotenvx native settings
3509
+ DOTENV_CONFIG_CONVENTION= # set to a default convention like 'nextjs' or 'flow'
3510
+ DOTENV_CONFIG_IGNORE= # MISSING_ENV_FILE,OTHER
3511
+ DOTENV_CONFIG_QUIET= # set to "true" to default to --quiet
3512
+ DOTENVX_NO_ARMOR= # set to "true" to turn off Armor support
3513
+ DOTENVX_NO_1PASSWORD= # set to "true" to turn off 1Password support
3514
+ DOTENVX_NO_BITWARDEN= # set to "true" to turn off Bitwarden support
3515
+
3516
+ # other machine settings respected by dotenvx
3517
+ BW_SESSION= # set to bitwarden session token to bypass password prompt
3518
+ ```
3519
+
3520
+ </details>
3521
+
3522
+ &nbsp;
3523
+
3494
3524
  ## Armor ⛨
3495
3525
 
3496
3526
  [![dotenvx-armor](https://dotenvx.com/dotenvx-armor-banner.png?v2)](https://dotenvx.com/armor)
@@ -3513,6 +3543,7 @@ Set `mask: 0` to fully mask values.
3513
3543
  * [Claude](https://dotenvx.com/docs/secrets-in-claude)
3514
3544
  * [Codex](https://dotenvx.com/docs/secrets-in-codex)
3515
3545
  * [1Password](https://dotenvx.com/docs/secrets-in-1password)
3546
+ * [Bitwarden](https://dotenvx.com/docs/secrets-in-bitwarden)
3516
3547
  * [Node.js](https://dotenvx.com/docs/secrets-in-nodejs)
3517
3548
  * [Next.js](https://dotenvx.com/docs/secrets-in-nextjs)
3518
3549
  * [Express](https://dotenvx.com/docs/secrets-in-express)
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.17.0",
2
+ "version": "2.17.2",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a secure dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -53,7 +53,7 @@
53
53
  "funding": "https://dotenvx.com",
54
54
  "dependencies": {
55
55
  "@dotenvx/primitives": "^2.1.0",
56
- "@dotenvx/tooling": "^1.0.2",
56
+ "@dotenvx/tooling": "^1.0.3",
57
57
  "yocto-spinner": "^1.2.1"
58
58
  },
59
59
  "devDependencies": {
@@ -6,13 +6,14 @@ const createSpinner = require('../../lib/helpers/createSpinner')
6
6
  const Session = require('../../db/session')
7
7
  const getResolver = require('./../../lib/resolvers/get')
8
8
  const normalizeDotenvConfigConvention = require('../../lib/helpers/normalizeDotenvConfigConvention')
9
+ const normalizeDotenvConfigIgnore = require('../../lib/helpers/normalizeDotenvConfigIgnore')
9
10
  const buildCommandEnvs = require('../../lib/helpers/buildCommandEnvs')
10
11
  const resolveEnvKeysFile = require('../../lib/helpers/resolveEnvKeysFile')
11
12
  const mask = require('../../lib/helpers/mask')
12
13
  const filterKeys = require('../../lib/helpers/filterKeys')
13
14
 
14
15
  async function get (key) {
15
- const options = normalizeDotenvConfigConvention(this.opts())
16
+ const options = normalizeDotenvConfigIgnore(normalizeDotenvConfigConvention(this.opts()))
16
17
  const spinnerOptions = typeof this.optsWithGlobals === 'function' ? this.optsWithGlobals() : options
17
18
  const spinner = await createSpinner({ ...spinnerOptions, ...options, text: 'decrypting' })
18
19
 
@@ -120,6 +121,10 @@ async function get (key) {
120
121
  }
121
122
  } catch (error) {
122
123
  if (spinner) spinner.stop()
124
+ if (error.code === 'PROMPT_CANCELLED') {
125
+ process.exit(130)
126
+ return
127
+ }
123
128
  catchAndLog(error)
124
129
  process.exit(1)
125
130
  }
@@ -8,6 +8,7 @@ const createSpinner = require('../../lib/helpers/createSpinner')
8
8
  const Session = require('../../db/session')
9
9
  const normalizeDotenvConfigQuiet = require('../../lib/helpers/normalizeDotenvConfigQuiet')
10
10
  const normalizeDotenvConfigConvention = require('../../lib/helpers/normalizeDotenvConfigConvention')
11
+ const normalizeDotenvConfigIgnore = require('../../lib/helpers/normalizeDotenvConfigIgnore')
11
12
  const buildCommandEnvs = require('../../lib/helpers/buildCommandEnvs')
12
13
  const resolveEnvKeysFile = require('../../lib/helpers/resolveEnvKeysFile')
13
14
  const mask = require('../../lib/helpers/mask')
@@ -53,7 +54,7 @@ function uniqueInjectedKeys (processedEnvs) {
53
54
  }
54
55
 
55
56
  async function run () {
56
- const options = normalizeDotenvConfigConvention(normalizeDotenvConfigQuiet(this.opts()))
57
+ const options = normalizeDotenvConfigIgnore(normalizeDotenvConfigConvention(normalizeDotenvConfigQuiet(this.opts())))
57
58
  const spinnerOptions = typeof this.optsWithGlobals === 'function' ? this.optsWithGlobals() : options
58
59
  const maskEnabled = options.mask !== undefined
59
60
  const redactEnabled = options.redact === true
@@ -210,6 +211,10 @@ async function run () {
210
211
  logger.success(`⟐ ${msg}`)
211
212
  } catch (error) {
212
213
  if (spinner) spinner.stop()
214
+ if (error.code === 'PROMPT_CANCELLED') {
215
+ process.exit(130)
216
+ return
217
+ }
213
218
  catchAndLog(error)
214
219
  process.exit(1)
215
220
  }
@@ -6,6 +6,7 @@ const createSpinner = require('../../lib/helpers/createSpinner')
6
6
  const Session = require('../../db/session')
7
7
  const normalizeDotenvConfigQuiet = require('../../lib/helpers/normalizeDotenvConfigQuiet')
8
8
  const normalizeDotenvConfigConvention = require('../../lib/helpers/normalizeDotenvConfigConvention')
9
+ const normalizeDotenvConfigIgnore = require('../../lib/helpers/normalizeDotenvConfigIgnore')
9
10
  const buildCommandEnvs = require('../../lib/helpers/buildCommandEnvs')
10
11
  const resolveEnvKeysFile = require('../../lib/helpers/resolveEnvKeysFile')
11
12
  const validateEnvExample = require('../../lib/helpers/validateEnvExample')
@@ -13,7 +14,7 @@ const validateEnvExample = require('../../lib/helpers/validateEnvExample')
13
14
  const { determine } = require('./../../lib/helpers/envResolution')
14
15
 
15
16
  async function validate () {
16
- const options = normalizeDotenvConfigConvention(normalizeDotenvConfigQuiet(this.opts()))
17
+ const options = normalizeDotenvConfigIgnore(normalizeDotenvConfigConvention(normalizeDotenvConfigQuiet(this.opts())))
17
18
  const spinnerOptions = typeof this.optsWithGlobals === 'function' ? this.optsWithGlobals() : options
18
19
  const spinner = await createSpinner({ ...spinnerOptions, ...options, text: 'validating' })
19
20
  const ignore = options.ignore || []
@@ -1,4 +1,6 @@
1
- function normalizeDotenvConfigConvention (options) {
1
+ function normalizeDotenvConfigConvention (
2
+ /** @type {import('../main').DotenvConfigOptions} */ options
3
+ ) {
2
4
  if (!options.convention && process.env.DOTENV_CONFIG_CONVENTION) {
3
5
  options.convention = process.env.DOTENV_CONFIG_CONVENTION
4
6
  }
@@ -0,0 +1,17 @@
1
+ function normalizeDotenvConfigIgnore (
2
+ /** @type {import('../main').DotenvConfigOptions} */ options
3
+ ) {
4
+ const configIgnore = (process.env.DOTENV_CONFIG_IGNORE || '')
5
+ .split(',')
6
+ .map(code => code.trim())
7
+ .filter(Boolean)
8
+
9
+ if (configIgnore.length < 1) return options
10
+
11
+ return {
12
+ ...options,
13
+ ignore: [...(options.ignore || []), ...configIgnore]
14
+ }
15
+ }
16
+
17
+ module.exports = normalizeDotenvConfigIgnore
@@ -1,4 +1,6 @@
1
- function normalizeDotenvConfigQuiet (options) {
1
+ function normalizeDotenvConfigQuiet (
2
+ /** @type {import('../main').DotenvConfigOptions} */ options
3
+ ) {
2
4
  if (process.env.DOTENV_CONFIG_QUIET === 'true') {
3
5
  options.quiet = true
4
6
  }
@@ -117,6 +117,7 @@ async function resolveBitwardenPassword (parsed, options = {}) {
117
117
  })
118
118
  parsed[key] = secretValue(stdout)
119
119
  } catch (error) {
120
+ if (error && error.code === 'PROMPT_CANCELLED') throw error
120
121
  errors.push(resolutionError(key, error))
121
122
  unresolved.push(key)
122
123
  }
package/src/lib/main.js CHANGED
@@ -26,6 +26,7 @@ const decryptKeyValue = require('./helpers/cryptography/decryptKeyValue')
26
26
  const Errors = require('./helpers/errors')
27
27
  const normalizeDotenvConfigQuiet = require('./helpers/normalizeDotenvConfigQuiet')
28
28
  const normalizeDotenvConfigConvention = require('./helpers/normalizeDotenvConfigConvention')
29
+ const normalizeDotenvConfigIgnore = require('./helpers/normalizeDotenvConfigIgnore')
29
30
  const mask = require('./helpers/mask')
30
31
  const maskProcessedEnvs = require('./helpers/maskProcessedEnvs')
31
32
 
@@ -43,6 +44,7 @@ function uniqueInjectedKeys (processedEnvs) {
43
44
  const config = function (options = {}) {
44
45
  options = normalizeDotenvConfigQuiet(options)
45
46
  options = normalizeDotenvConfigConvention(options)
47
+ options = normalizeDotenvConfigIgnore(options)
46
48
 
47
49
  // allow user to set processEnv to write to
48
50
  let processEnv = process.env
@@ -318,6 +320,7 @@ const set = async function (key, value, options = {}) {
318
320
  /* @type {import('./main').get} */
319
321
  const get = async function (key, options = {}) {
320
322
  options = normalizeDotenvConfigConvention(options)
323
+ options = normalizeDotenvConfigIgnore(options)
321
324
 
322
325
  const envs = buildEnvs(options)
323
326
  const noArmor = resolveNoArmor(options)
@@ -118,6 +118,7 @@ async function injectEnv ({ env, overload, processEnv, envKeysFilepath, provider
118
118
 
119
119
  inject(processEnv, row.parsed)
120
120
  } catch (e) {
121
+ if (e.code === 'PROMPT_CANCELLED') throw e
121
122
  row.errors = [e]
122
123
  }
123
124
 
@@ -225,6 +226,7 @@ async function injectEnvFile ({ env, overload, processEnv, envKeysFilepath, prov
225
226
 
226
227
  inject(processEnv, parsed)
227
228
  } catch (e) {
229
+ if (e.code === 'PROMPT_CANCELLED') throw e
228
230
  if (e.code === 'ENOENT' || e.code === 'EISDIR') {
229
231
  row.errors = [new Errors({ envFilepath: env.value, filepath }).missingEnvFile()]
230
232
  } else {
@@ -299,6 +301,8 @@ async function envs (options = {}) {
299
301
  const readableFilepaths = new Set()
300
302
  const processEnv = options.processEnv || process.env
301
303
  const envKeysFilepath = options.envKeysFilepath || options.envKeysFile || null
304
+ const no1Password = options.no1Password === true || process.env.DOTENVX_NO_1PASSWORD === 'true'
305
+ const noBitwarden = options.noBitwarden === true || process.env.DOTENVX_NO_BITWARDEN === 'true'
302
306
  const provider = await providers(options)
303
307
  const decryptor = await decryptors(options)
304
308
  for (const env of options.envs || []) {
@@ -311,8 +315,8 @@ async function envs (options = {}) {
311
315
  provider,
312
316
  decryptor,
313
317
  readableFilepaths,
314
- no1Password: options.no1Password,
315
- noBitwarden: options.noBitwarden,
318
+ no1Password,
319
+ noBitwarden,
316
320
  onStatus: options.onStatus
317
321
  }))
318
322
  } else if (env.type === TYPE_ENV) {
@@ -323,8 +327,8 @@ async function envs (options = {}) {
323
327
  envKeysFilepath,
324
328
  provider,
325
329
  decryptor,
326
- no1Password: options.no1Password,
327
- noBitwarden: options.noBitwarden,
330
+ no1Password,
331
+ noBitwarden,
328
332
  onStatus: options.onStatus
329
333
  }))
330
334
  }
@@ -341,6 +345,8 @@ function envsSync (options = {}) {
341
345
  const readableFilepaths = new Set()
342
346
  const processEnv = options.processEnv || process.env
343
347
  const envKeysFilepath = options.envKeysFilepath || options.envKeysFile || null
348
+ const no1Password = options.no1Password === true || process.env.DOTENVX_NO_1PASSWORD === 'true'
349
+ const noBitwarden = options.noBitwarden === true || process.env.DOTENVX_NO_BITWARDEN === 'true'
344
350
  const provider = providers.sync(options)
345
351
  const decryptor = decryptors.sync(options)
346
352
 
@@ -354,8 +360,8 @@ function envsSync (options = {}) {
354
360
  provider,
355
361
  decryptor,
356
362
  readableFilepaths,
357
- no1Password: options.no1Password,
358
- noBitwarden: options.noBitwarden
363
+ no1Password,
364
+ noBitwarden
359
365
  }))
360
366
  } else if (env.type === TYPE_ENV) {
361
367
  processedEnvs.push(injectEnvSync({
@@ -365,8 +371,8 @@ function envsSync (options = {}) {
365
371
  envKeysFilepath,
366
372
  provider,
367
373
  decryptor,
368
- no1Password: options.no1Password,
369
- noBitwarden: options.noBitwarden
374
+ no1Password,
375
+ noBitwarden
370
376
  }))
371
377
  }
372
378
  }