@dotenvx/dotenvx 1.60.2 → 1.61.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 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/v1.60.2...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.61.1...main)
6
+
7
+ ## [1.61.1](https://github.com/dotenvx/dotenvx/compare/v1.61.0...v1.61.1) (2026-04-17)
8
+
9
+ * Faster coldstarts! ([#781](https://github.com/dotenvx/dotenvx/pull/781))
10
+ * Patch `dotenvx precommit|prebuild` shorthand ([#793](https://github.com/dotenvx/dotenvx/pull/793))
11
+
12
+ ## [1.61.0](https://github.com/dotenvx/dotenvx/compare/v1.60.2...v1.61.0) (2026-04-08)
13
+
14
+ ### Added
15
+
16
+ * Add `login` and `logout` method that proxy to `dotenvx-ops login/logout` ([#780](https://github.com/dotenvx/dotenvx/pull/780))
17
+ * Note: dotenvx continues to make zero outgoing HTTP requests and includes no telemetry. Outgoing requests occur only if you explicitly install the [dotenvx-ops](https://dotenvx.com/ops) SDK or CLI.
6
18
 
7
19
  ## [1.60.2](https://github.com/dotenvx/dotenvx/compare/v1.60.1...v1.60.2) (2026-04-07)
8
20
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.60.2",
2
+ "version": "1.61.1",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "secrets for agents–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -50,7 +50,7 @@
50
50
  "fdir": "^6.2.0",
51
51
  "ignore": "^5.3.0",
52
52
  "object-treeify": "1.1.33",
53
- "picomatch": "^4.0.2",
53
+ "picomatch": "^4.0.4",
54
54
  "which": "^4.0.0",
55
55
  "yocto-spinner": "^1.1.0"
56
56
  },
@@ -24,28 +24,36 @@ ext.command('ls')
24
24
  .argument('[directory]', 'directory to list .env files from', '.')
25
25
  .option('-f, --env-file <filenames...>', 'path(s) to your env file(s)', '.env*')
26
26
  .option('-ef, --exclude-env-file <excludeFilenames...>', 'path(s) to exclude from your env file(s) (default: none)')
27
- .action(require('./../actions/ls'))
27
+ .action(function (...args) {
28
+ return require('./../actions/ls').apply(this, args)
29
+ })
28
30
 
29
31
  // dotenvx ext genexample
30
32
  ext.command('genexample')
31
33
  .description('generate .env.example')
32
34
  .argument('[directory]', 'directory to generate from', '.')
33
35
  .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', '.env')
34
- .action(require('./../actions/ext/genexample'))
36
+ .action(function (...args) {
37
+ return require('./../actions/ext/genexample').apply(this, args)
38
+ })
35
39
 
36
40
  // dotenvx ext gitignore
37
41
  ext.command('gitignore')
38
42
  .description('append to .gitignore file (and if existing, .dockerignore, .npmignore, and .vercelignore)')
39
43
  .addHelpText('after', examples.gitignore)
40
44
  .option('--pattern <patterns...>', 'pattern(s) to gitignore', ['.env*'])
41
- .action(require('./../actions/ext/gitignore'))
45
+ .action(function (...args) {
46
+ return require('./../actions/ext/gitignore').apply(this, args)
47
+ })
42
48
 
43
49
  // dotenvx ext prebuild
44
50
  ext.command('prebuild')
45
51
  .description('prevent including .env files in docker builds')
46
52
  .addHelpText('after', examples.prebuild)
47
53
  .argument('[directory]', 'directory to prevent including .env files from', '.')
48
- .action(require('./../actions/ext/prebuild'))
54
+ .action(function (...args) {
55
+ return require('./../actions/ext/prebuild').apply(this, args)
56
+ })
49
57
 
50
58
  // dotenvx ext precommit
51
59
  ext.command('precommit')
@@ -53,12 +61,16 @@ ext.command('precommit')
53
61
  .addHelpText('after', examples.precommit)
54
62
  .argument('[directory]', 'directory to prevent committing .env files from', '.')
55
63
  .option('-i, --install', 'install to .git/hooks/pre-commit')
56
- .action(require('./../actions/ext/precommit'))
64
+ .action(function (...args) {
65
+ return require('./../actions/ext/precommit').apply(this, args)
66
+ })
57
67
 
58
68
  // dotenvx scan
59
69
  ext.command('scan')
60
70
  .description('scan for leaked secrets')
61
- .action(require('./../actions/ext/scan'))
71
+ .action(function (...args) {
72
+ return require('./../actions/ext/scan').apply(this, args)
73
+ })
62
74
 
63
75
  // override helpInformation to hide dynamic commands
64
76
  ext.helpInformation = function () {
@@ -60,7 +60,6 @@ program
60
60
  .allowUnknownOption()
61
61
 
62
62
  // dotenvx run -- node index.js
63
- const runAction = require('./actions/run')
64
63
  program.command('run')
65
64
  .description('inject env at runtime [dotenvx run -- yourcommand]')
66
65
  .addHelpText('after', examples.run)
@@ -75,11 +74,10 @@ program.command('run')
75
74
  .addOption(new Option('--ops-off', 'DEPRECATED: use --no-ops').hideHelp())
76
75
  .action(function (...args) {
77
76
  this.envs = envs
78
- return runAction.apply(this, args)
77
+ return require('./actions/run').apply(this, args)
79
78
  })
80
79
 
81
80
  // dotenvx get
82
- const getAction = require('./actions/get')
83
81
  program.command('get')
84
82
  .usage('[KEY] [options]')
85
83
  .description('return a single environment variable')
@@ -98,11 +96,10 @@ program.command('get')
98
96
  .option('--no-ops', 'disable dotenvx-ops features')
99
97
  .action(function (...args) {
100
98
  this.envs = envs
101
- return getAction.apply(this, args)
99
+ return require('./actions/get').apply(this, args)
102
100
  })
103
101
 
104
102
  // dotenvx set
105
- const setAction = require('./actions/set')
106
103
  program.command('set')
107
104
  .usage('<KEY> <value> [options]')
108
105
  .description('encrypt a single environment variable')
@@ -118,11 +115,10 @@ program.command('set')
118
115
  .option('--no-ops', 'disable dotenvx-ops features')
119
116
  .action(function (...args) {
120
117
  this.envs = envs
121
- return setAction.apply(this, args)
118
+ return require('./actions/set').apply(this, args)
122
119
  })
123
120
 
124
121
  // dotenvx encrypt
125
- const encryptAction = require('./actions/encrypt')
126
122
  program.command('encrypt')
127
123
  .description('convert .env file(s) to encrypted .env file(s)')
128
124
  .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', collectEnvs('envFile'), [])
@@ -134,11 +130,10 @@ program.command('encrypt')
134
130
  .option('--no-ops', 'disable dotenvx-ops features')
135
131
  .action(function (...args) {
136
132
  this.envs = envs
137
- return encryptAction.apply(this, args)
133
+ return require('./actions/encrypt').apply(this, args)
138
134
  })
139
135
 
140
136
  // dotenvx decrypt
141
- const decryptAction = require('./actions/decrypt')
142
137
  program.command('decrypt')
143
138
  .description('convert encrypted .env file(s) to plain .env file(s)')
144
139
  .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', collectEnvs('envFile'), [])
@@ -149,11 +144,10 @@ program.command('decrypt')
149
144
  .option('--stdout', 'send to stdout')
150
145
  .action(function (...args) {
151
146
  this.envs = envs
152
- return decryptAction.apply(this, args)
147
+ return require('./actions/decrypt').apply(this, args)
153
148
  })
154
149
 
155
150
  // dotenvx rotate
156
- const rotateAction = require('./actions/rotate')
157
151
  program.command('rotate')
158
152
  .description('rotate keypair(s) and re-encrypt .env file(s)')
159
153
  .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', collectEnvs('envFile'), [])
@@ -164,11 +158,10 @@ program.command('rotate')
164
158
  .option('--stdout', 'send to stdout')
165
159
  .action(function (...args) {
166
160
  this.envs = envs
167
- return rotateAction.apply(this, args)
161
+ return require('./actions/rotate').apply(this, args)
168
162
  })
169
163
 
170
164
  // dotenvx keypair
171
- const keypairAction = require('./actions/keypair')
172
165
  program.command('keypair')
173
166
  .usage('[KEY] [options]')
174
167
  .description('print public/private keys for .env file(s)')
@@ -179,16 +172,36 @@ program.command('keypair')
179
172
  .option('-pp, --pretty-print', 'pretty print output')
180
173
  .option('--pp', 'pretty print output (alias)')
181
174
  .option('--format <type>', 'format of the output (json, shell)', 'json')
182
- .action(keypairAction)
175
+ .action(function (...args) {
176
+ return require('./actions/keypair').apply(this, args)
177
+ })
183
178
 
184
179
  // dotenvx ls
185
- const lsAction = require('./actions/ls')
186
180
  program.command('ls')
187
181
  .description('print all .env files in a tree structure')
188
182
  .argument('[directory]', 'directory to list .env files from', '.')
189
183
  .option('-f, --env-file <filenames...>', 'path(s) to your env file(s)', '.env*')
190
184
  .option('-ef, --exclude-env-file <excludeFilenames...>', 'path(s) to exclude from your env file(s) (default: none)')
191
- .action(lsAction)
185
+ .action(function (...args) {
186
+ return require('./actions/ls').apply(this, args)
187
+ })
188
+
189
+ // dotenvx login
190
+ program.command('login')
191
+ .description('log in to unlock ⛨ ARMORED KEYS ✦ BETA')
192
+ .action(() => {
193
+ const rawArgs = ['ops', 'login', ...process.argv.slice(3)]
194
+ executeDynamic(program, 'ops', rawArgs)
195
+ })
196
+
197
+ // dotenvx logout
198
+ program.command('logout', { hidden: true })
199
+ .description('optional: log out of your dotenvx account')
200
+ .allowUnknownOption()
201
+ .action(() => {
202
+ const rawArgs = ['ops', 'logout', ...process.argv.slice(3)]
203
+ executeDynamic(program, 'ops', rawArgs)
204
+ })
192
205
 
193
206
  // dotenvx help
194
207
  program.command('help [command]')
@@ -218,25 +231,25 @@ program.addCommand(require('./commands/ext'))
218
231
  //
219
232
  // MOVED
220
233
  //
221
- const prebuildAction = require('./actions/ext/prebuild')
222
234
  program.command('prebuild')
223
235
  .description('DEPRECATED: moved to [dotenvx ext prebuild]')
224
236
  .addHelpText('after', examples.prebuild)
237
+ .argument('[directory]', 'directory to prevent including .env files from', '.')
225
238
  .action(function (...args) {
226
239
  logger.warn('DEPRECATION NOTICE: [prebuild] has moved to [dotenvx ext prebuild]')
227
240
 
228
- prebuildAction.apply(this, args)
241
+ require('./actions/ext/prebuild').apply(this, args)
229
242
  })
230
243
 
231
- const precommitAction = require('./actions/ext/precommit')
232
244
  program.command('precommit')
233
245
  .description('DEPRECATED: moved to [dotenvx ext precommit]')
234
246
  .addHelpText('after', examples.precommit)
247
+ .argument('[directory]', 'directory to prevent committing .env files from', '.')
235
248
  .option('-i, --install', 'install to .git/hooks/pre-commit')
236
249
  .action(function (...args) {
237
250
  logger.warn('DEPRECATION NOTICE: [precommit] has moved to [dotenvx ext precommit]')
238
251
 
239
- precommitAction.apply(this, args)
252
+ require('./actions/ext/precommit').apply(this, args)
240
253
  })
241
254
 
242
255
  // override helpInformation to hide DEPRECATED and 'ext' commands
@@ -18,7 +18,7 @@ function opsBanner (installCommand) {
18
18
  '',
19
19
  ' ⛨ ARMORED KEYS: Harden your private keys.',
20
20
  ` ⮕ install [${installCommand}]`,
21
- ' ⮕ and then run [dotenvx-ops login]'
21
+ ' ⮕ then run [dotenvx-ops login]'
22
22
  ]
23
23
 
24
24
  const innerWidth = Math.max(67, ...lines.map((line) => line.length))
@@ -5,6 +5,37 @@ function removeOptionsHelpParts (lines) {
5
5
  lines[i] = lines[i].replace(' [options]', '')
6
6
  }
7
7
 
8
+ let commandsStart = -1
9
+ for (let i = 0; i < lines.length; i++) {
10
+ if (lines[i] === 'Commands:') {
11
+ commandsStart = i + 1
12
+ break
13
+ }
14
+ }
15
+
16
+ if (commandsStart !== -1) {
17
+ const commands = []
18
+
19
+ for (let i = commandsStart; i < lines.length; i++) {
20
+ const line = lines[i]
21
+ if (line === '' || line.endsWith(':')) {
22
+ break
23
+ }
24
+
25
+ const match = line.match(/^(\s{2})(\S(?:.*\S)?)\s{2,}(\S.*)$/)
26
+ if (match) {
27
+ commands.push({ index: i, indent: match[1], command: match[2], description: match[3] })
28
+ }
29
+ }
30
+
31
+ if (commands.length > 0) {
32
+ const maxCommandLength = commands.reduce((max, item) => Math.max(max, item.command.length), 0)
33
+ for (const item of commands) {
34
+ lines[item.index] = `${item.indent}${item.command.padEnd(maxCommandLength + 2)}${item.description}`
35
+ }
36
+ }
37
+ }
38
+
8
39
  return lines
9
40
  }
10
41