@dotenvx/dotenvx 2.15.1 → 2.16.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,13 @@
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.15.1...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx/compare/v2.16.0...main)
6
+
7
+ ## [2.16.0](https://github.com/dotenvx/dotenvx/compare/v2.15.1...v2.16.0) (2026-07-21)
8
+
9
+ ### Added
10
+
11
+ * Add support for `-ek` and `-ik` to `dotenvx get` ([#913](https://github.com/dotenvx/dotenvx/pull/913))
6
12
 
7
13
  ## [2.15.1](https://github.com/dotenvx/dotenvx/compare/v2.15.0...v2.15.1) (2026-07-20)
8
14
 
package/README.md CHANGED
@@ -1848,6 +1848,30 @@ $ dotenvx get
1848
1848
  {"HELLO":"World"}
1849
1849
  ```
1850
1850
 
1851
+ </details>
1852
+ <details><summary>`get -ik`</summary><br>
1853
+
1854
+ Include only matching keys by passing `--include-key`. Glob patterns are supported.
1855
+
1856
+ ```sh
1857
+ $ echo "HELLO=World\nHOLA=Mundo\nGOODBYE=World" > .env
1858
+
1859
+ $ dotenvx get -ik "H*"
1860
+ {"HELLO":"World","HOLA":"Mundo"}
1861
+ ```
1862
+
1863
+ </details>
1864
+ <details><summary>`get -ek`</summary><br>
1865
+
1866
+ Exclude matching keys by passing `--exclude-key`. Glob patterns are supported.
1867
+
1868
+ ```sh
1869
+ $ echo "DOTENV_PUBLIC_KEY=public\nHELLO=World" > .env
1870
+
1871
+ $ dotenvx get --format=eval-export -ek "DOTENV_PUBLIC_KEY*"
1872
+ export HELLO='World'
1873
+ ```
1874
+
1851
1875
  </details>
1852
1876
  <details><summary>`get --format shell`</summary><br>
1853
1877
 
@@ -3412,53 +3436,26 @@ Set `mask: 0` to fully mask values.
3412
3436
 
3413
3437
  &nbsp;
3414
3438
 
3415
- ## Guides
3439
+ ## Quickstarts
3416
3440
 
3417
- > Go deeper with `dotenvx` detailed framework and platform guides.
3441
+ > Encrypt and run secrets in your language, framework, or tool.
3418
3442
  >
3419
3443
 
3420
- * [Languages](https://dotenvx.com/docs#languages)
3421
- * [Node.js](https://dotenvx.com/docs/languages/nodejs)
3422
- * [Python](https://dotenvx.com/docs/languages/python)
3423
- * [Ruby](https://dotenvx.com/docs/languages/ruby)
3424
- * [Go](https://dotenvx.com/docs/languages/go)
3425
- * [PHP](https://dotenvx.com/docs/languages/php)
3426
- * [Rust](https://dotenvx.com/docs/languages/rust)
3427
- * [Frameworks](https://dotenvx.com/docs#frameworks)
3428
- * [Astro](https://dotenvx.com/docs/secrets-in-astro)
3429
- * [Expo](https://dotenvx.com/docs/secrets-in-expo)
3430
- * [Express](https://dotenvx.com/docs/frameworks/express)
3431
- * [Next](https://dotenvx.com/docs/frameworks/next)
3432
- * [Remix](https://dotenvx.com/docs/frameworks/remix)
3433
- * [Flask](https://dotenvx.com/docs/frameworks/flask)
3434
- * [Sinatra](https://dotenvx.com/docs/frameworks/sinatra)
3435
- * [Rocket](https://dotenvx.com/docs/frameworks/rocket)
3436
- * [Platforms](https://dotenvx.com/docs#platforms)
3437
- * [Digital Ocean](https://dotenvx.com/docs/platforms/digital-ocean)
3438
- * [Docker](https://dotenvx.com/docs/platforms/docker)
3439
- * [Fly](https://dotenvx.com/docs/platforms/fly)
3440
- * [Heroku](https://dotenvx.com/docs/platforms/heroku)
3441
- * [Netlify](https://dotenvx.com/docs/platforms/netlify)
3442
- * [Vercel](https://dotenvx.com/docs/platforms/vercel)
3443
- * [Railway](https://dotenvx.com/docs/platforms/railway)
3444
- * [Render](https://dotenvx.com/docs/platforms/render)
3445
- * [CI/CDs](https://dotenvx.com/docs#cis)
3446
- * [GitHub Actions](https://dotenvx.com/docs/cis/github-actions)
3447
- * [Password Managers](https://dotenvx.com/docs#password-managers)
3448
- * [1Password](https://dotenvx.com/docs/guides/1password)
3449
- * [Background Jobs](https://dotenvx.com/docs#background-jobs)
3450
- * [Trigger.dev](https://dotenvx.com/docs/background-jobs/triggerdotdev)
3451
- * [Package Managers](https://dotenvx.com/docs#package-managers)
3452
- * [NPM](https://dotenvx.com/docs/package-managers/npm)
3453
- * [PNPM](https://dotenvx.com/docs/package-managers/pnpm)
3454
- * [Process Managers](https://dotenvx.com/docs#process-managers)
3455
- * [PM2](https://dotenvx.com/docs/process-managers/pm2)
3456
- * [Monorepos](https://dotenvx.com/docs#monorepos)
3457
- * [Nx](https://dotenvx.com/docs/monorepos/nx)
3458
- * [Turborepo](https://dotenvx.com/docs/monorepos/turborepo)
3459
- * [Concepts](https://dotenvx.com/docs#concepts)
3460
- * [.env](https://dotenvx.com/docs/env-file)
3461
- * [.env.keys](https://dotenvx.com/docs/env-keys-file)
3444
+ * [Claude](https://dotenvx.com/docs/secrets-in-claude)
3445
+ * [Codex](https://dotenvx.com/docs/secrets-in-codex)
3446
+ * [1Password](https://dotenvx.com/docs/secrets-in-1password)
3447
+ * [Node.js](https://dotenvx.com/docs/secrets-in-nodejs)
3448
+ * [Next.js](https://dotenvx.com/docs/secrets-in-nextjs)
3449
+ * [Express](https://dotenvx.com/docs/secrets-in-express)
3450
+ * [Astro](https://dotenvx.com/docs/secrets-in-astro)
3451
+ * [Expo](https://dotenvx.com/docs/secrets-in-expo)
3452
+ * [Python](https://dotenvx.com/docs/secrets-in-python)
3453
+ * [Ruby](https://dotenvx.com/docs/secrets-in-ruby)
3454
+ * [Go](https://dotenvx.com/docs/secrets-in-go)
3455
+ * [PHP](https://dotenvx.com/docs/secrets-in-php)
3456
+ * [Rust](https://dotenvx.com/docs/secrets-in-rust)
3457
+
3458
+ [Browse all quickstarts](https://dotenvx.com/docs)
3462
3459
 
3463
3460
  &nbsp;
3464
3461
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.15.1",
2
+ "version": "2.16.0",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a secure dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -0,0 +1,70 @@
1
+ const { logger } = require('../../shared/logger')
2
+ const Session = require('../../db/session')
3
+ const { http } = require('../../lib/helpers/http')
4
+ const catchAndLog = require('../../lib/helpers/catchAndLog')
5
+
6
+ function requestUrl (value, hostname) {
7
+ const url = new URL(value)
8
+ const trusted = new URL(hostname)
9
+
10
+ if (url.origin !== trusted.origin) {
11
+ throw new Error(`refusing to send Armor token to [${url.origin}]. expected [${trusted.origin}]`)
12
+ }
13
+
14
+ if (url.username || url.password) {
15
+ throw new Error('refusing URL containing credentials')
16
+ }
17
+
18
+ return url.toString()
19
+ }
20
+
21
+ function requestBody (value) {
22
+ if (value === undefined) return undefined
23
+
24
+ try {
25
+ return JSON.stringify(JSON.parse(value))
26
+ } catch {
27
+ throw new Error('invalid JSON passed to [--data]')
28
+ }
29
+ }
30
+
31
+ function outputBody (value) {
32
+ try {
33
+ return JSON.stringify(JSON.parse(value), null, 2)
34
+ } catch {
35
+ return value
36
+ }
37
+ }
38
+
39
+ async function curl () {
40
+ try {
41
+ const options = this.opts()
42
+ const session = new Session()
43
+ const token = options.token || session.token()
44
+ if (!token) throw new Error('missing token. Try [dotenvx login].')
45
+
46
+ const body = requestBody(options.data)
47
+ const method = (options.request || (body === undefined ? 'GET' : 'POST')).toUpperCase()
48
+ const url = requestUrl(this.args[0], session.hostname())
49
+ const headers = {
50
+ Authorization: `Bearer ${token}`,
51
+ Accept: 'application/json'
52
+ }
53
+ if (body !== undefined) headers['Content-Type'] = 'application/json'
54
+
55
+ logger.debug(`request [${method} ${url}]`)
56
+ const response = await http(url, { method, headers, body })
57
+ const text = await response.body.text()
58
+ console.log(outputBody(text))
59
+
60
+ if (response.statusCode >= 400) process.exitCode = 1
61
+ } catch (error) {
62
+ catchAndLog(error)
63
+ process.exit(1)
64
+ }
65
+ }
66
+
67
+ module.exports = curl
68
+ module.exports.requestUrl = requestUrl
69
+ module.exports.requestBody = requestBody
70
+ module.exports.outputBody = outputBody
@@ -9,6 +9,7 @@ const normalizeDotenvConfigConvention = require('../../lib/helpers/normalizeDote
9
9
  const buildCommandEnvs = require('../../lib/helpers/buildCommandEnvs')
10
10
  const resolveEnvKeysFile = require('../../lib/helpers/resolveEnvKeysFile')
11
11
  const mask = require('../../lib/helpers/mask')
12
+ const filterKeys = require('../../lib/helpers/filterKeys')
12
13
 
13
14
  async function get (key) {
14
15
  const options = normalizeDotenvConfigConvention(this.opts())
@@ -30,7 +31,7 @@ async function get (key) {
30
31
  const sesh = new Session()
31
32
  const noArmor = options.armor === false || (await sesh.noArmor())
32
33
  const noKeychain = options.native === false || options.noNative === true
33
- const { parsed, errors } = await getResolver({
34
+ const { parsed: resolved, errors } = await getResolver({
34
35
  key,
35
36
  envs,
36
37
  overload: options.overload,
@@ -46,6 +47,7 @@ async function get (key) {
46
47
  }
47
48
  }
48
49
  })
50
+ const parsed = filterKeys(resolved, options.includeKey, options.excludeKey)
49
51
 
50
52
  for (const error of errors || []) {
51
53
  if (options.strict) throw error // throw immediately if strict
@@ -94,6 +94,8 @@ program.command('get')
94
94
  .option('--convention <name>', 'load a .env convention (available conventions: [\'nextjs\', \'flow\'])')
95
95
  .option('--ignore <errorCodes...>', 'error code(s) to ignore (example: --ignore=MISSING_ENV_FILE)')
96
96
  .option('-a, --all', 'include all machine envs as well')
97
+ .option('-ik, --include-key <includeKeys...>', 'keys(s) to include in output (default: all)')
98
+ .option('-ek, --exclude-key <excludeKeys...>', 'keys(s) to exclude from output (default: none)')
97
99
  .option('--mask [characters]', 'mask values, optionally setting visible characters')
98
100
  .option('-pp, --pretty-print', 'pretty print output')
99
101
  .option('--pp', 'pretty print output (alias)')
@@ -258,6 +260,17 @@ program.command('update')
258
260
  return require('./actions/update').apply(this, args)
259
261
  })
260
262
 
263
+ // dotenvx curl
264
+ program.command('curl', { hidden: true })
265
+ .description('make an authenticated dotenvx API request')
266
+ .argument('<url>', 'dotenvx API URL')
267
+ .option('-X, --request <method>', 'HTTP request method')
268
+ .option('--data <json>', 'JSON request body')
269
+ .option('--token <token>', 'set Armor ⛨ token')
270
+ .action(function (...args) {
271
+ return require('./actions/curl').apply(this, args)
272
+ })
273
+
261
274
  // dotenvx login (compatibility alias for dotenvx armor login)
262
275
  program.command('login', { hidden: true })
263
276
  .description('log in to move keys off-device, share with your team, and audit access')
@@ -0,0 +1,15 @@
1
+ const { match } = require('@dotenvx/primitives')
2
+
3
+ function filterKeys (parsed, includeKeys, excludeKeys) {
4
+ const include = includeKeys && match(includeKeys)
5
+ const exclude = excludeKeys && match(excludeKeys)
6
+
7
+ return Object.fromEntries(Object.entries(parsed).filter(([key]) => {
8
+ if (include && !include(key)) return false
9
+ if (exclude && exclude(key)) return false
10
+
11
+ return true
12
+ }))
13
+ }
14
+
15
+ module.exports = filterKeys