env-secrets 0.5.2 → 0.5.4
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/.claude/rules/cicd.md +189 -0
- package/.claude/rules/docs.md +96 -0
- package/.claude/rules/git-hooks.md +43 -0
- package/.claude/rules/local-dev-badges.md +91 -0
- package/.claude/rules/local-dev-env.md +382 -0
- package/.claude/rules/local-dev-license.md +104 -0
- package/.claude/rules/local-dev-mcp.md +70 -0
- package/.claude/rules/observability.md +23 -0
- package/.claude/rules/publishing-api.md +158 -0
- package/.claude/rules/publishing-apps.md +204 -0
- package/.claude/rules/publishing-apt.md +146 -0
- package/.claude/rules/publishing-brew.md +110 -0
- package/.claude/rules/publishing-cli.md +238 -0
- package/.claude/rules/publishing-libraries.md +115 -0
- package/.claude/rules/publishing-sdks.md +109 -0
- package/.claude/rules/publishing-web.md +185 -0
- package/.claude/rules/typescript-linting.md +141 -0
- package/.claude/rules/typescript-logging.md +356 -0
- package/.claude/rules/typescript-testing.md +185 -0
- package/.claude/settings.json +18 -0
- package/.claude/skills/github-health-check.skill +0 -0
- package/.codex/rules/cicd.md +21 -0
- package/.codex/rules/docs.md +98 -0
- package/.codex/rules/git-hooks.md +43 -0
- package/.codex/rules/github-health-check.md +440 -0
- package/.codex/rules/local-dev-env.md +47 -0
- package/.codex/rules/local-dev-license.md +3 -1
- package/.codex/rules/publishing-api.md +160 -0
- package/.codex/rules/publishing-apps.md +206 -0
- package/.codex/rules/publishing-apt.md +148 -0
- package/.codex/rules/publishing-brew.md +112 -0
- package/.codex/rules/publishing-cli.md +240 -0
- package/.codex/rules/publishing-libraries.md +117 -0
- package/.codex/rules/publishing-sdks.md +111 -0
- package/.codex/rules/publishing-web.md +187 -0
- package/.codex/rules/typescript-linting.md +143 -0
- package/.codex/rules/typescript-logging.md +358 -0
- package/.codex/rules/typescript-testing.md +187 -0
- package/.github/workflows/deploy-docs.yml +2 -2
- package/.github/workflows/unittests.yaml +1 -1
- package/.rulesrc.json +20 -0
- package/AGENTS.md +34 -0
- package/CLAUDE.md +58 -0
- package/README.md +17 -3
- package/__e2e__/aws-exec-args.test.ts +97 -1
- package/__e2e__/aws-secret-value-args.test.ts +142 -0
- package/__e2e__/utils/test-utils.ts +78 -0
- package/__tests__/cli/helpers.test.ts +35 -0
- package/__tests__/index.test.ts +208 -58
- package/dist/cli/helpers.js +13 -1
- package/dist/index.js +94 -44
- package/docker-compose.yaml +1 -1
- package/docs/AWS.md +42 -13
- package/package.json +6 -6
- package/src/cli/helpers.ts +16 -0
- package/src/index.ts +117 -52
package/docs/AWS.md
CHANGED
|
@@ -153,11 +153,12 @@ In addition to injecting variables into a process, `env-secrets` can manage AWS
|
|
|
153
153
|
|
|
154
154
|
- `env-secrets aws secret create`
|
|
155
155
|
- `env-secrets aws secret update`
|
|
156
|
+
- `env-secrets aws secret upsert` (alias: `import`)
|
|
156
157
|
- `env-secrets aws secret append`
|
|
157
158
|
- `env-secrets aws secret remove`
|
|
158
|
-
- `env-secrets aws secret upsert` (alias: `import`)
|
|
159
159
|
- `env-secrets aws secret list`
|
|
160
160
|
- `env-secrets aws secret get`
|
|
161
|
+
- `env-secrets aws secret value`
|
|
161
162
|
- `env-secrets aws secret delete`
|
|
162
163
|
|
|
163
164
|
`aws secret` subcommands consistently honor `--region`, `--profile`, and `--output`.
|
|
@@ -165,8 +166,8 @@ Use these options directly with each subcommand.
|
|
|
165
166
|
|
|
166
167
|
### `aws -s` vs `aws secret ...`
|
|
167
168
|
|
|
168
|
-
- `env-secrets aws -s <secret-name> -- <command>`: retrieves a secret value and injects it into the environment for the spawned process (or use `-o <file>` to write exports to a file).
|
|
169
|
-
- `env-secrets aws secret ...`: management commands only (`create`, `update`, `
|
|
169
|
+
- `env-secrets aws -s <secret-name> -- <command>`: retrieves a secret value and injects it into the environment for the spawned process (or use `-o <file>` to write exports to a file). Use `--no-shell` to run the program directly without a shell wrapper (disables shell expansion).
|
|
170
|
+
- `env-secrets aws secret ...`: management commands only (`create`, `update`, `upsert/import`, `append`, `remove`, `list`, `get`, `value`, `delete`).
|
|
170
171
|
|
|
171
172
|
Example:
|
|
172
173
|
|
|
@@ -206,18 +207,24 @@ source secrets.env
|
|
|
206
207
|
- dotenv-style input is converted (`KEY=value` -> `{"KEY":"value"}`)
|
|
207
208
|
- non-object/scalar input is wrapped (`super-secret-value` -> `{"value":"super-secret-value"}`)
|
|
208
209
|
|
|
210
|
+
Optional flags: `-d/--description`, `-k/--kms-key-id`, `-t/--tag key=value` (repeatable).
|
|
211
|
+
|
|
209
212
|
2. **Create from stdin (recommended for sensitive values):**
|
|
210
213
|
|
|
211
214
|
```bash
|
|
212
215
|
echo -n 'super-secret-value' | env-secrets aws secret create -n my-app/dev/raw --value-stdin -r us-east-1
|
|
213
216
|
```
|
|
214
217
|
|
|
218
|
+
`create` and `update` accept `--value`, `--value-stdin`, or `--file` — use only one.
|
|
219
|
+
|
|
215
220
|
3. **Update an existing secret value:**
|
|
216
221
|
|
|
217
222
|
```bash
|
|
218
223
|
env-secrets aws secret update -n my-app/dev/api -v '{"API_KEY":"rotated"}' -r us-east-1
|
|
219
224
|
```
|
|
220
225
|
|
|
226
|
+
Optional flags: `-d/--description`, `-k/--kms-key-id`. Accepts `--value-stdin` or `--file` instead of `-v`.
|
|
227
|
+
|
|
221
228
|
4. **Upsert from an env file into one JSON secret (`export KEY=value` or `KEY=value`):**
|
|
222
229
|
|
|
223
230
|
```bash
|
|
@@ -232,47 +239,69 @@ source secrets.env
|
|
|
232
239
|
{ "API_KEY": "abc123", "DATABASE_URL": "postgres://..." }
|
|
233
240
|
```
|
|
234
241
|
|
|
242
|
+
Optional flags: `-d/--description`, `-k/--kms-key-id`, `-t/--tag key=value` (repeatable, applies on create only).
|
|
243
|
+
|
|
235
244
|
5. **Append/remove keys in an existing JSON secret:**
|
|
236
245
|
|
|
237
246
|
```bash
|
|
247
|
+
# Append a key (accepts --value-stdin or --file instead of -v)
|
|
238
248
|
env-secrets aws secret append -n my-app/dev --key JIRA_EMAIL_TOKEN -v blah -r us-east-1
|
|
239
|
-
|
|
249
|
+
|
|
250
|
+
# Remove one or more keys
|
|
251
|
+
env-secrets aws secret remove -n my-app/dev --key OLD_TOKEN --key UNUSED_KEY -r us-east-1
|
|
240
252
|
```
|
|
241
253
|
|
|
242
|
-
6. **List secrets by prefix:**
|
|
254
|
+
6. **List secrets by prefix or tag:**
|
|
243
255
|
|
|
244
256
|
```bash
|
|
245
257
|
env-secrets aws secret list --prefix my-app/dev -r us-east-1 --output table
|
|
246
|
-
```
|
|
247
258
|
|
|
248
|
-
|
|
259
|
+
# Filter by tag
|
|
260
|
+
env-secrets aws secret list -t env=production -t team=platform -r us-east-1
|
|
249
261
|
|
|
250
|
-
|
|
262
|
+
# Multi-region comparison
|
|
251
263
|
env-secrets aws secret list --prefix my-app/dev -r us-west-2 --output json
|
|
252
264
|
env-secrets aws secret list --prefix my-app/dev -r us-east-1 --output json
|
|
253
265
|
```
|
|
254
266
|
|
|
255
|
-
7. **Get metadata and version info (without printing secret
|
|
267
|
+
7. **Get metadata and version info (without printing secret values):**
|
|
256
268
|
|
|
257
269
|
```bash
|
|
258
270
|
env-secrets aws secret get -n my-app/dev/api -r us-east-1 --output json
|
|
259
271
|
```
|
|
260
272
|
|
|
261
|
-
8. **
|
|
273
|
+
8. **Get the values of a secret:**
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Table output — values masked by default
|
|
277
|
+
env-secrets aws secret value -n my-app/dev/api -r us-east-1
|
|
278
|
+
|
|
279
|
+
# Reveal actual values (warning printed to stderr)
|
|
280
|
+
env-secrets aws secret value -n my-app/dev/api -r us-east-1 --reveal
|
|
281
|
+
|
|
282
|
+
# JSON output — always returns full values (warns on TTY)
|
|
283
|
+
env-secrets aws secret value -n my-app/dev/api -r us-east-1 --output json
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
9. **Delete with explicit confirmation:**
|
|
262
287
|
|
|
263
288
|
```bash
|
|
289
|
+
# With a recovery window (7–30 days)
|
|
264
290
|
env-secrets aws secret delete -n my-app/dev/raw --recovery-days 7 --yes -r us-east-1
|
|
291
|
+
|
|
292
|
+
# Permanent delete with no recovery window
|
|
293
|
+
env-secrets aws secret delete -n my-app/dev/raw --force-delete-without-recovery --yes -r us-east-1
|
|
265
294
|
```
|
|
266
295
|
|
|
267
296
|
### Secret Management Safety Notes
|
|
268
297
|
|
|
269
|
-
- `delete` requires `--yes`.
|
|
270
|
-
- `create
|
|
298
|
+
- `delete` requires `--yes`. Use either `--recovery-days <7-30>` or `--force-delete-without-recovery`, not both.
|
|
299
|
+
- `create`, `update`, and `append` accept `--value`, `--value-stdin`, or `--file` (use only one).
|
|
271
300
|
- `create` always stores `SecretString` as a JSON object.
|
|
272
301
|
- `append` and `remove` require the secret value to be a JSON object.
|
|
273
302
|
- `upsert/import --file --name` parses `export KEY=value` and `KEY=value`, stores them as one JSON secret object, ignores blank lines/comments, and reports `created`, `updated`, `skipped`, and `failed`.
|
|
274
303
|
- Use `--value-stdin` to avoid shell history leakage for sensitive values.
|
|
275
|
-
-
|
|
304
|
+
- `value` masks secret values as `****` in table output by default. Use `--reveal` to show them (prints a warning to stderr). JSON output always returns full values and warns when stdout is a terminal.
|
|
276
305
|
|
|
277
306
|
## Examples
|
|
278
307
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "env-secrets",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "get secrets from a secrets vault and inject them into the running environment",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Mark C Allen (@markcallen)",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@everydaydevopsio/ballast": "^3.2.1",
|
|
34
|
-
"@types/debug": "^4.1.
|
|
34
|
+
"@types/debug": "^4.1.13",
|
|
35
35
|
"@types/jest": "^29.5.14",
|
|
36
36
|
"@types/node": "^18.19.130",
|
|
37
37
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
@@ -48,14 +48,14 @@
|
|
|
48
48
|
"release-it": "^15.11.0",
|
|
49
49
|
"rimraf": "^3.0.2",
|
|
50
50
|
"tsc-files": "^1.1.4",
|
|
51
|
-
"ts-jest": "^29.4.
|
|
51
|
+
"ts-jest": "^29.4.9",
|
|
52
52
|
"ts-node": "^10.9.2",
|
|
53
53
|
"typescript": "^4.9.5"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@aws-sdk/client-secrets-manager": "^3.
|
|
57
|
-
"@aws-sdk/client-sts": "^3.
|
|
58
|
-
"@aws-sdk/credential-providers": "^3.
|
|
56
|
+
"@aws-sdk/client-secrets-manager": "^3.1038.0",
|
|
57
|
+
"@aws-sdk/client-sts": "^3.1038.0",
|
|
58
|
+
"@aws-sdk/credential-providers": "^3.1038.0",
|
|
59
59
|
"commander": "^9.5.0",
|
|
60
60
|
"debug": "^4.4.3"
|
|
61
61
|
},
|
package/src/cli/helpers.ts
CHANGED
|
@@ -218,6 +218,22 @@ export const parseEnvSecretsFile = async (
|
|
|
218
218
|
return parseEnvSecrets(content);
|
|
219
219
|
};
|
|
220
220
|
|
|
221
|
+
export const resolveOutputFormat = (
|
|
222
|
+
options: { output?: string },
|
|
223
|
+
command?: CommandLikeWithGlobalOpts
|
|
224
|
+
): OutputFormat => {
|
|
225
|
+
if (options.output) {
|
|
226
|
+
return asOutputFormat(options.output);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const globalOutput = command?.optsWithGlobals?.()?.output;
|
|
230
|
+
if (globalOutput === 'json' || globalOutput === 'table') {
|
|
231
|
+
return globalOutput;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return 'table';
|
|
235
|
+
};
|
|
236
|
+
|
|
221
237
|
export const resolveAwsScope = (
|
|
222
238
|
options: AwsScopeOptions,
|
|
223
239
|
command?: CommandLikeWithGlobalOpts
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
printData,
|
|
24
24
|
parseRecoveryDays,
|
|
25
25
|
resolveAwsScope,
|
|
26
|
+
resolveOutputFormat,
|
|
26
27
|
resolveSecretValue
|
|
27
28
|
} from './cli/helpers';
|
|
28
29
|
import { objectToExport } from './vaults/utils';
|
|
@@ -121,6 +122,10 @@ const awsCommand = program
|
|
|
121
122
|
'-o, --output <file>',
|
|
122
123
|
'output secrets to file instead of environment variables'
|
|
123
124
|
)
|
|
125
|
+
.option(
|
|
126
|
+
'--no-shell',
|
|
127
|
+
'run program directly without a shell (disables shell expansion)'
|
|
128
|
+
)
|
|
124
129
|
.action(async (program, options) => {
|
|
125
130
|
if (!options.secret) {
|
|
126
131
|
exitWithError(
|
|
@@ -163,10 +168,22 @@ const awsCommand = program
|
|
|
163
168
|
return;
|
|
164
169
|
}
|
|
165
170
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
171
|
+
const child = options.shell
|
|
172
|
+
? spawn(program.join(' '), [], {
|
|
173
|
+
stdio: 'inherit',
|
|
174
|
+
shell: true,
|
|
175
|
+
env
|
|
176
|
+
})
|
|
177
|
+
: spawn(program[0], program.slice(1), { stdio: 'inherit', env });
|
|
178
|
+
|
|
179
|
+
child.on('error', (err) => {
|
|
180
|
+
// eslint-disable-next-line no-console
|
|
181
|
+
console.error(`Failed to start process: ${err.message}`);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
child.on('exit', (code, signal) => {
|
|
186
|
+
process.exit(signal ? 1 : code ?? 0);
|
|
170
187
|
});
|
|
171
188
|
}
|
|
172
189
|
}
|
|
@@ -192,12 +209,7 @@ secretCommand
|
|
|
192
209
|
.action(async (options, command) => {
|
|
193
210
|
try {
|
|
194
211
|
const { profile, region } = resolveAwsScope(options, command);
|
|
195
|
-
const
|
|
196
|
-
const output =
|
|
197
|
-
options.output ??
|
|
198
|
-
(typeof globalOptions.output === 'string'
|
|
199
|
-
? globalOptions.output
|
|
200
|
-
: 'table');
|
|
212
|
+
const output = resolveOutputFormat(options, command);
|
|
201
213
|
const value = await resolveSecretValue(
|
|
202
214
|
options.value,
|
|
203
215
|
options.valueStdin,
|
|
@@ -249,12 +261,7 @@ secretCommand
|
|
|
249
261
|
.action(async (options, command) => {
|
|
250
262
|
try {
|
|
251
263
|
const { profile, region } = resolveAwsScope(options, command);
|
|
252
|
-
const
|
|
253
|
-
const output =
|
|
254
|
-
options.output ??
|
|
255
|
-
(typeof globalOptions.output === 'string'
|
|
256
|
-
? globalOptions.output
|
|
257
|
-
: 'table');
|
|
264
|
+
const output = resolveOutputFormat(options, command);
|
|
258
265
|
const value = await resolveSecretValue(
|
|
259
266
|
options.value,
|
|
260
267
|
options.valueStdin,
|
|
@@ -304,12 +311,7 @@ secretCommand
|
|
|
304
311
|
.action(async (options, command) => {
|
|
305
312
|
try {
|
|
306
313
|
const { profile, region } = resolveAwsScope(options, command);
|
|
307
|
-
const
|
|
308
|
-
const output =
|
|
309
|
-
options.output ??
|
|
310
|
-
(typeof globalOptions.output === 'string'
|
|
311
|
-
? globalOptions.output
|
|
312
|
-
: 'table');
|
|
314
|
+
const output = resolveOutputFormat(options, command);
|
|
313
315
|
const parsed = await parseEnvSecretsFile(options.file);
|
|
314
316
|
|
|
315
317
|
if (parsed.entries.length === 0) {
|
|
@@ -438,12 +440,7 @@ secretCommand
|
|
|
438
440
|
.action(async (options, command) => {
|
|
439
441
|
try {
|
|
440
442
|
const { profile, region } = resolveAwsScope(options, command);
|
|
441
|
-
const
|
|
442
|
-
const output =
|
|
443
|
-
options.output ??
|
|
444
|
-
(typeof globalOptions.output === 'string'
|
|
445
|
-
? globalOptions.output
|
|
446
|
-
: 'table');
|
|
443
|
+
const output = resolveOutputFormat(options, command);
|
|
447
444
|
const value = await resolveSecretValue(
|
|
448
445
|
options.value,
|
|
449
446
|
options.valueStdin,
|
|
@@ -503,12 +500,7 @@ secretCommand
|
|
|
503
500
|
.action(async (options, command) => {
|
|
504
501
|
try {
|
|
505
502
|
const { profile, region } = resolveAwsScope(options, command);
|
|
506
|
-
const
|
|
507
|
-
const output =
|
|
508
|
-
options.output ??
|
|
509
|
-
(typeof globalOptions.output === 'string'
|
|
510
|
-
? globalOptions.output
|
|
511
|
-
: 'table');
|
|
503
|
+
const output = resolveOutputFormat(options, command);
|
|
512
504
|
const keys = options.key as string[];
|
|
513
505
|
const current = await getSecretString({
|
|
514
506
|
name: options.name,
|
|
@@ -574,12 +566,7 @@ secretCommand
|
|
|
574
566
|
.action(async (options, command) => {
|
|
575
567
|
try {
|
|
576
568
|
const { profile, region } = resolveAwsScope(options, command);
|
|
577
|
-
const
|
|
578
|
-
const output =
|
|
579
|
-
options.output ??
|
|
580
|
-
(typeof globalOptions.output === 'string'
|
|
581
|
-
? globalOptions.output
|
|
582
|
-
: 'table');
|
|
569
|
+
const output = resolveOutputFormat(options, command);
|
|
583
570
|
const result = await listSecrets({
|
|
584
571
|
prefix: options.prefix,
|
|
585
572
|
tags: options.tag,
|
|
@@ -616,12 +603,7 @@ secretCommand
|
|
|
616
603
|
.action(async (options, command) => {
|
|
617
604
|
try {
|
|
618
605
|
const { profile, region } = resolveAwsScope(options, command);
|
|
619
|
-
const
|
|
620
|
-
const output =
|
|
621
|
-
options.output ??
|
|
622
|
-
(typeof globalOptions.output === 'string'
|
|
623
|
-
? globalOptions.output
|
|
624
|
-
: 'table');
|
|
606
|
+
const output = resolveOutputFormat(options, command);
|
|
625
607
|
const result = await getSecretMetadata({
|
|
626
608
|
name: options.name,
|
|
627
609
|
profile,
|
|
@@ -656,6 +638,94 @@ secretCommand
|
|
|
656
638
|
}
|
|
657
639
|
});
|
|
658
640
|
|
|
641
|
+
secretCommand
|
|
642
|
+
.command('value')
|
|
643
|
+
.description('get the values of a secret')
|
|
644
|
+
.requiredOption('-n, --name <name>', 'secret name')
|
|
645
|
+
.option(
|
|
646
|
+
'--reveal',
|
|
647
|
+
'reveal secret values in table output (values are masked by default)',
|
|
648
|
+
false
|
|
649
|
+
)
|
|
650
|
+
.option('-p, --profile <profile>', 'profile to use')
|
|
651
|
+
.option('-r, --region <region>', 'region to use')
|
|
652
|
+
.option('--output <format>', 'output format: json|table')
|
|
653
|
+
.action(async (options, command) => {
|
|
654
|
+
try {
|
|
655
|
+
const { profile, region } = resolveAwsScope(options, command);
|
|
656
|
+
const output = resolveOutputFormat(options, command);
|
|
657
|
+
|
|
658
|
+
let secretString: string;
|
|
659
|
+
try {
|
|
660
|
+
secretString = await getSecretString({
|
|
661
|
+
name: options.name,
|
|
662
|
+
profile,
|
|
663
|
+
region
|
|
664
|
+
});
|
|
665
|
+
} catch (error: unknown) {
|
|
666
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
667
|
+
if (msg.includes('cannot be edited with append/remove')) {
|
|
668
|
+
throw new Error(
|
|
669
|
+
`Secret "${options.name}" is stored as binary and cannot be displayed as text.`
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
throw error;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
let jsonEntries: Array<{ key: string; value: unknown }>;
|
|
676
|
+
try {
|
|
677
|
+
const parsed = JSON.parse(secretString) as unknown;
|
|
678
|
+
if (parsed && !Array.isArray(parsed) && typeof parsed === 'object') {
|
|
679
|
+
jsonEntries = Object.entries(parsed as Record<string, unknown>).map(
|
|
680
|
+
([key, value]) => ({ key, value })
|
|
681
|
+
);
|
|
682
|
+
} else {
|
|
683
|
+
jsonEntries = [{ key: options.name, value: secretString }];
|
|
684
|
+
}
|
|
685
|
+
} catch {
|
|
686
|
+
jsonEntries = [{ key: options.name, value: secretString }];
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
if (output === 'json') {
|
|
690
|
+
if (process.stdout.isTTY) {
|
|
691
|
+
// eslint-disable-next-line no-console
|
|
692
|
+
console.error('Warning: displaying sensitive secret values.');
|
|
693
|
+
}
|
|
694
|
+
const result = Object.fromEntries(
|
|
695
|
+
jsonEntries.map(({ key, value }) => [key, value])
|
|
696
|
+
);
|
|
697
|
+
// eslint-disable-next-line no-console
|
|
698
|
+
console.log(JSON.stringify(result, null, 2));
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (options.reveal) {
|
|
703
|
+
// eslint-disable-next-line no-console
|
|
704
|
+
console.error('Warning: displaying sensitive secret values.');
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
const rows = jsonEntries.map(({ key, value }) => ({
|
|
708
|
+
key,
|
|
709
|
+
value: options.reveal
|
|
710
|
+
? typeof value === 'string'
|
|
711
|
+
? value
|
|
712
|
+
: JSON.stringify(value)
|
|
713
|
+
: '****'
|
|
714
|
+
}));
|
|
715
|
+
|
|
716
|
+
printData(
|
|
717
|
+
asOutputFormat(output),
|
|
718
|
+
[
|
|
719
|
+
{ key: 'key', label: 'Key' },
|
|
720
|
+
{ key: 'value', label: 'Value' }
|
|
721
|
+
],
|
|
722
|
+
rows
|
|
723
|
+
);
|
|
724
|
+
} catch (error: unknown) {
|
|
725
|
+
exitWithError(error);
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
|
|
659
729
|
secretCommand
|
|
660
730
|
.command('delete')
|
|
661
731
|
.description('delete a secret in AWS Secrets Manager')
|
|
@@ -677,12 +747,7 @@ secretCommand
|
|
|
677
747
|
.action(async (options, command) => {
|
|
678
748
|
try {
|
|
679
749
|
const { profile, region } = resolveAwsScope(options, command);
|
|
680
|
-
const
|
|
681
|
-
const output =
|
|
682
|
-
options.output ??
|
|
683
|
-
(typeof globalOptions.output === 'string'
|
|
684
|
-
? globalOptions.output
|
|
685
|
-
: 'table');
|
|
750
|
+
const output = resolveOutputFormat(options, command);
|
|
686
751
|
if (!options.yes) {
|
|
687
752
|
throw new Error('Delete requires --yes confirmation.');
|
|
688
753
|
}
|