@secretstash/cli 0.1.4 → 0.1.8
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/README.md +68 -17
- package/dist/index.js +97 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,13 +32,38 @@ brew install secretstash/tap/sstash
|
|
|
32
32
|
|
|
33
33
|
### Authentication
|
|
34
34
|
|
|
35
|
+
The CLI uses browser-based authentication by default, supporting passkeys, OAuth (GitHub/Google), and 2FA:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Login via browser (opens browser window)
|
|
39
|
+
sstash login
|
|
40
|
+
|
|
41
|
+
# This will:
|
|
42
|
+
# 1. Generate a session code
|
|
43
|
+
# 2. Open your default browser to complete authentication
|
|
44
|
+
# 3. Wait for you to sign in (passkey, OAuth, or email/password)
|
|
45
|
+
# 4. Automatically complete CLI authentication
|
|
46
|
+
|
|
47
|
+
# Check who you're logged in as
|
|
48
|
+
sstash whoami
|
|
49
|
+
|
|
50
|
+
# Logout
|
|
51
|
+
sstash logout
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Service Token Authentication (CI/CD)
|
|
55
|
+
|
|
56
|
+
For automated workflows, use service tokens instead of browser authentication:
|
|
57
|
+
|
|
35
58
|
```bash
|
|
36
|
-
#
|
|
37
|
-
|
|
59
|
+
# Set service token as environment variable
|
|
60
|
+
export SECRETSTASH_TOKEN=stk_your-service-token
|
|
61
|
+
|
|
62
|
+
# Or login with token directly
|
|
63
|
+
sstash login --token stk_your-service-token
|
|
38
64
|
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
sstash auth status
|
|
65
|
+
# Verify token works
|
|
66
|
+
sstash teams
|
|
42
67
|
```
|
|
43
68
|
|
|
44
69
|
### Working with Secrets
|
|
@@ -285,25 +310,51 @@ For CI/CD and automated workflows, use service tokens instead of user credential
|
|
|
285
310
|
|
|
286
311
|
## Commands Reference
|
|
287
312
|
|
|
313
|
+
### Authentication
|
|
314
|
+
| Command | Description |
|
|
315
|
+
|---------|-------------|
|
|
316
|
+
| `sstash login` | Authenticate via browser (passkeys, OAuth, 2FA) |
|
|
317
|
+
| `sstash login --token <token>` | Authenticate with service token |
|
|
318
|
+
| `sstash logout` | Clear authentication |
|
|
319
|
+
| `sstash whoami` | Show current user/token info |
|
|
320
|
+
| `sstash 2fa setup` | Set up two-factor authentication |
|
|
321
|
+
| `sstash register` | Create a new SecretStash account |
|
|
322
|
+
|
|
323
|
+
### Secrets
|
|
288
324
|
| Command | Description |
|
|
289
325
|
|---------|-------------|
|
|
290
|
-
| `sstash auth login` | Authenticate with SecretStash |
|
|
291
|
-
| `sstash auth logout` | Clear authentication |
|
|
292
|
-
| `sstash auth status` | Show authentication status |
|
|
293
326
|
| `sstash pull` | Pull secrets from SecretStash |
|
|
294
327
|
| `sstash push` | Push secrets to SecretStash |
|
|
295
|
-
| `sstash list` | List secrets in an environment |
|
|
296
|
-
| `sstash get <key>` | Get a specific secret |
|
|
297
|
-
| `sstash set <key>=<value>` | Set a specific secret |
|
|
298
|
-
| `sstash delete <key>` | Delete a specific secret |
|
|
328
|
+
| `sstash secrets list` | List secrets in an environment |
|
|
329
|
+
| `sstash secrets get <key>` | Get a specific secret |
|
|
330
|
+
| `sstash secrets set <key>=<value>` | Set a specific secret |
|
|
331
|
+
| `sstash secrets delete <key>` | Delete a specific secret |
|
|
332
|
+
| `sstash secrets history <key>` | View version history for a secret |
|
|
333
|
+
| `sstash secrets rollback <key>` | Rollback to a previous version |
|
|
334
|
+
| `sstash secrets tag <key> <tag>` | Add a tag to a secret |
|
|
335
|
+
| `sstash secrets untag <key> <tag>` | Remove a tag from a secret |
|
|
336
|
+
| `sstash secrets expiring` | List secrets expiring soon |
|
|
299
337
|
| `sstash run` | Run a command with secrets injected |
|
|
300
338
|
| `sstash diff` | Compare local and remote secrets |
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
|
339
|
+
|
|
340
|
+
### Organization
|
|
341
|
+
| Command | Description |
|
|
342
|
+
|---------|-------------|
|
|
343
|
+
| `sstash teams` | List teams |
|
|
344
|
+
| `sstash teams use <slug>` | Switch team context |
|
|
345
|
+
| `sstash projects` | List projects in current team |
|
|
346
|
+
| `sstash projects use <slug>` | Switch project context |
|
|
347
|
+
| `sstash environments` | List environments in current project |
|
|
304
348
|
| `sstash environments create <name>` | Create a new environment |
|
|
305
|
-
|
|
306
|
-
|
|
349
|
+
|
|
350
|
+
### Tags & Shares
|
|
351
|
+
| Command | Description |
|
|
352
|
+
|---------|-------------|
|
|
353
|
+
| `sstash tags` | List tags in current team |
|
|
354
|
+
| `sstash tags create <name>` | Create a new tag |
|
|
355
|
+
| `sstash share create <key>` | Create a share link for a secret |
|
|
356
|
+
| `sstash share list` | List active share links |
|
|
357
|
+
| `sstash share revoke <id>` | Revoke a share link |
|
|
307
358
|
|
|
308
359
|
Use `sstash --help` or `sstash <command> --help` for detailed usage information.
|
|
309
360
|
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Command } from "commander";
|
|
|
5
5
|
import chalk3 from "chalk";
|
|
6
6
|
import { readFileSync as readFileSync4 } from "fs";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
|
-
import { dirname
|
|
8
|
+
import { dirname, join as join2 } from "path";
|
|
9
9
|
|
|
10
10
|
// src/commands/auth.ts
|
|
11
11
|
import enquirer from "enquirer";
|
|
@@ -306,7 +306,7 @@ var ApiClient = class {
|
|
|
306
306
|
const refreshToken = configManager.getRefreshToken();
|
|
307
307
|
if (!refreshToken) return false;
|
|
308
308
|
try {
|
|
309
|
-
const response = await fetch(`${configManager.getApiUrl()}/api/auth/refresh`, {
|
|
309
|
+
const response = await fetch(`${configManager.getApiUrl()}/api/v1/auth/refresh`, {
|
|
310
310
|
method: "POST",
|
|
311
311
|
headers: {
|
|
312
312
|
"Content-Type": "application/json"
|
|
@@ -317,11 +317,12 @@ var ApiClient = class {
|
|
|
317
317
|
configManager.logout();
|
|
318
318
|
return false;
|
|
319
319
|
}
|
|
320
|
-
const
|
|
320
|
+
const json = await response.json();
|
|
321
|
+
const tokens = json.data?.tokens || json.data || json;
|
|
321
322
|
configManager.setTokens(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
tokens.accessToken,
|
|
324
|
+
tokens.refreshToken,
|
|
325
|
+
tokens.expiresIn || 900
|
|
325
326
|
);
|
|
326
327
|
return true;
|
|
327
328
|
} catch {
|
|
@@ -358,17 +359,17 @@ var ApiClient = class {
|
|
|
358
359
|
headers: requestHeaders,
|
|
359
360
|
body: body ? JSON.stringify(body) : void 0
|
|
360
361
|
});
|
|
361
|
-
const
|
|
362
|
+
const json = await response.json();
|
|
362
363
|
if (!response.ok) {
|
|
363
364
|
return {
|
|
364
365
|
error: {
|
|
365
|
-
code:
|
|
366
|
-
message:
|
|
367
|
-
details:
|
|
366
|
+
code: json.code || json.error?.code || "API_ERROR",
|
|
367
|
+
message: json.message || json.error?.message || `Request failed with status ${response.status}`,
|
|
368
|
+
details: json.details || json.error?.details
|
|
368
369
|
}
|
|
369
370
|
};
|
|
370
371
|
}
|
|
371
|
-
return { data };
|
|
372
|
+
return { data: json.data };
|
|
372
373
|
} catch (error) {
|
|
373
374
|
return {
|
|
374
375
|
error: {
|
|
@@ -380,7 +381,7 @@ var ApiClient = class {
|
|
|
380
381
|
}
|
|
381
382
|
// Auth endpoints
|
|
382
383
|
async login(email, password) {
|
|
383
|
-
return this.request("/api/auth/login", {
|
|
384
|
+
return this.request("/api/v1/auth/login", {
|
|
384
385
|
method: "POST",
|
|
385
386
|
body: { email, password, client: "cli" },
|
|
386
387
|
requireAuth: false
|
|
@@ -399,14 +400,14 @@ var ApiClient = class {
|
|
|
399
400
|
});
|
|
400
401
|
}
|
|
401
402
|
async verify2FA(tempToken, code) {
|
|
402
|
-
return this.request("/api/auth/2fa
|
|
403
|
+
return this.request("/api/v1/auth/verify-2fa", {
|
|
403
404
|
method: "POST",
|
|
404
|
-
body: { tempToken, code },
|
|
405
|
+
body: { tempToken, token: code },
|
|
405
406
|
requireAuth: false
|
|
406
407
|
});
|
|
407
408
|
}
|
|
408
409
|
async register(email, password) {
|
|
409
|
-
return this.request("/api/auth/register", {
|
|
410
|
+
return this.request("/api/v1/auth/register", {
|
|
410
411
|
method: "POST",
|
|
411
412
|
body: { email, password },
|
|
412
413
|
requireAuth: false
|
|
@@ -415,7 +416,7 @@ var ApiClient = class {
|
|
|
415
416
|
async logout() {
|
|
416
417
|
const refreshToken = configManager.getRefreshToken();
|
|
417
418
|
if (refreshToken) {
|
|
418
|
-
await this.request("/api/auth/logout", {
|
|
419
|
+
await this.request("/api/v1/auth/logout", {
|
|
419
420
|
method: "POST",
|
|
420
421
|
body: { refreshToken }
|
|
421
422
|
});
|
|
@@ -423,39 +424,39 @@ var ApiClient = class {
|
|
|
423
424
|
configManager.logout();
|
|
424
425
|
}
|
|
425
426
|
async getMe() {
|
|
426
|
-
return this.request("/api/users/me");
|
|
427
|
+
return this.request("/api/v1/users/me");
|
|
427
428
|
}
|
|
428
429
|
// Team endpoints
|
|
429
430
|
async getTeams() {
|
|
430
|
-
return this.request("/api/teams");
|
|
431
|
+
return this.request("/api/v1/teams");
|
|
431
432
|
}
|
|
432
433
|
async createTeam(name) {
|
|
433
|
-
return this.request("/api/teams", {
|
|
434
|
+
return this.request("/api/v1/teams", {
|
|
434
435
|
method: "POST",
|
|
435
436
|
body: { name }
|
|
436
437
|
});
|
|
437
438
|
}
|
|
438
439
|
// Project endpoints
|
|
439
440
|
async getProjects(teamId) {
|
|
440
|
-
return this.request(`/api/teams/${teamId}/projects`);
|
|
441
|
+
return this.request(`/api/v1/teams/${teamId}/projects`);
|
|
441
442
|
}
|
|
442
443
|
async createProject(teamId, name, description) {
|
|
443
|
-
return this.request(`/api/teams/${teamId}/projects`, {
|
|
444
|
+
return this.request(`/api/v1/teams/${teamId}/projects`, {
|
|
444
445
|
method: "POST",
|
|
445
446
|
body: { name, description }
|
|
446
447
|
});
|
|
447
448
|
}
|
|
448
449
|
async deleteProject(projectId) {
|
|
449
|
-
return this.request(`/api/projects/${projectId}`, {
|
|
450
|
+
return this.request(`/api/v1/projects/${projectId}`, {
|
|
450
451
|
method: "DELETE"
|
|
451
452
|
});
|
|
452
453
|
}
|
|
453
454
|
// Environment endpoints
|
|
454
455
|
async getEnvironments(projectId) {
|
|
455
|
-
return this.request(`/api/projects/${projectId}/environments`);
|
|
456
|
+
return this.request(`/api/v1/projects/${projectId}/environments`);
|
|
456
457
|
}
|
|
457
458
|
async createEnvironment(projectId, name, parentId) {
|
|
458
|
-
return this.request(`/api/projects/${projectId}/environments`, {
|
|
459
|
+
return this.request(`/api/v1/projects/${projectId}/environments`, {
|
|
459
460
|
method: "POST",
|
|
460
461
|
body: { name, parentId }
|
|
461
462
|
});
|
|
@@ -467,29 +468,29 @@ var ApiClient = class {
|
|
|
467
468
|
}
|
|
468
469
|
// Secret endpoints (keys only, no decryption)
|
|
469
470
|
async getSecrets(environmentId) {
|
|
470
|
-
return this.request(`/api/environments/${environmentId}/secrets`);
|
|
471
|
+
return this.request(`/api/v1/environments/${environmentId}/secrets`);
|
|
471
472
|
}
|
|
472
473
|
// Decrypted secrets (requires password)
|
|
473
474
|
async getDecryptedSecrets(environmentId, password) {
|
|
474
|
-
return this.request(`/api/environments/${environmentId}/secrets/decrypt`, {
|
|
475
|
+
return this.request(`/api/v1/environments/${environmentId}/secrets/decrypt`, {
|
|
475
476
|
method: "POST",
|
|
476
477
|
body: { password }
|
|
477
478
|
});
|
|
478
479
|
}
|
|
479
480
|
async createSecret(environmentId, key, value, password, description) {
|
|
480
|
-
return this.request(`/api/environments/${environmentId}/secrets`, {
|
|
481
|
+
return this.request(`/api/v1/environments/${environmentId}/secrets`, {
|
|
481
482
|
method: "POST",
|
|
482
483
|
body: { key, value, password, description }
|
|
483
484
|
});
|
|
484
485
|
}
|
|
485
486
|
async updateSecret(secretId, value, password, description) {
|
|
486
|
-
return this.request(`/api/secrets/${secretId}`, {
|
|
487
|
+
return this.request(`/api/v1/secrets/${secretId}`, {
|
|
487
488
|
method: "PATCH",
|
|
488
489
|
body: { value, password, description }
|
|
489
490
|
});
|
|
490
491
|
}
|
|
491
492
|
async deleteSecret(secretId) {
|
|
492
|
-
return this.request(`/api/secrets/${secretId}`, {
|
|
493
|
+
return this.request(`/api/v1/secrets/${secretId}`, {
|
|
493
494
|
method: "DELETE"
|
|
494
495
|
});
|
|
495
496
|
}
|
|
@@ -497,58 +498,58 @@ var ApiClient = class {
|
|
|
497
498
|
async pullSecrets(teamSlug, projectSlug, environment, password, options) {
|
|
498
499
|
const includeInherited = options?.includeInherited ?? true;
|
|
499
500
|
const query = includeInherited ? "" : "?includeInherited=false";
|
|
500
|
-
return this.request(`/api/teams/${teamSlug}/projects/${projectSlug}/environments/${environment}/secrets/decrypt${query}`, {
|
|
501
|
+
return this.request(`/api/v1/teams/${teamSlug}/projects/${projectSlug}/environments/${environment}/secrets/decrypt${query}`, {
|
|
501
502
|
method: "POST",
|
|
502
503
|
body: { password }
|
|
503
504
|
});
|
|
504
505
|
}
|
|
505
506
|
async pushSecrets(teamSlug, projectSlug, environment, secrets, password) {
|
|
506
|
-
return this.request(`/api/teams/${teamSlug}/projects/${projectSlug}/environments/${environment}/secrets/bulk`, {
|
|
507
|
+
return this.request(`/api/v1/teams/${teamSlug}/projects/${projectSlug}/environments/${environment}/secrets/bulk`, {
|
|
507
508
|
method: "PUT",
|
|
508
509
|
body: { secrets, password }
|
|
509
510
|
});
|
|
510
511
|
}
|
|
511
512
|
// 2FA endpoints
|
|
512
513
|
async setup2FA() {
|
|
513
|
-
return this.request("/api/users/me/2fa/setup", {
|
|
514
|
+
return this.request("/api/v1/users/me/2fa/setup", {
|
|
514
515
|
method: "POST"
|
|
515
516
|
});
|
|
516
517
|
}
|
|
517
518
|
async enable2FA(code) {
|
|
518
|
-
return this.request("/api/users/me/2fa/
|
|
519
|
+
return this.request("/api/v1/users/me/2fa/verify", {
|
|
519
520
|
method: "POST",
|
|
520
521
|
body: { code }
|
|
521
522
|
});
|
|
522
523
|
}
|
|
523
524
|
async disable2FA(code) {
|
|
524
|
-
return this.request("/api/users/me/2fa
|
|
525
|
-
method: "
|
|
525
|
+
return this.request("/api/v1/users/me/2fa", {
|
|
526
|
+
method: "DELETE",
|
|
526
527
|
body: { code }
|
|
527
528
|
});
|
|
528
529
|
}
|
|
529
530
|
// Team member endpoints
|
|
530
531
|
async getTeamMembers(teamId) {
|
|
531
|
-
return this.request(`/api/teams/${teamId}/members`);
|
|
532
|
+
return this.request(`/api/v1/teams/${teamId}/members`);
|
|
532
533
|
}
|
|
533
534
|
async inviteTeamMember(teamId, email, role) {
|
|
534
|
-
return this.request(`/api/teams/${teamId}/invitations`, {
|
|
535
|
+
return this.request(`/api/v1/teams/${teamId}/invitations`, {
|
|
535
536
|
method: "POST",
|
|
536
537
|
body: { email, role }
|
|
537
538
|
});
|
|
538
539
|
}
|
|
539
540
|
async removeTeamMember(teamId, memberId) {
|
|
540
|
-
return this.request(`/api/teams/${teamId}/members/${memberId}`, {
|
|
541
|
+
return this.request(`/api/v1/teams/${teamId}/members/${memberId}`, {
|
|
541
542
|
method: "DELETE"
|
|
542
543
|
});
|
|
543
544
|
}
|
|
544
545
|
async updateTeamMemberRole(teamId, memberId, role) {
|
|
545
|
-
return this.request(`/api/teams/${teamId}/members/${memberId}`, {
|
|
546
|
+
return this.request(`/api/v1/teams/${teamId}/members/${memberId}`, {
|
|
546
547
|
method: "PATCH",
|
|
547
548
|
body: { role }
|
|
548
549
|
});
|
|
549
550
|
}
|
|
550
551
|
async getPendingInvitations(teamId) {
|
|
551
|
-
return this.request(`/api/teams/${teamId}/invitations`);
|
|
552
|
+
return this.request(`/api/v1/teams/${teamId}/invitations`);
|
|
552
553
|
}
|
|
553
554
|
// Share link endpoints
|
|
554
555
|
async createShare(teamSlug, projectSlug, environment, secretKey, options) {
|
|
@@ -574,7 +575,7 @@ var ApiClient = class {
|
|
|
574
575
|
}
|
|
575
576
|
// Service token verification - make a request to validate the token works
|
|
576
577
|
async verifyServiceToken(token) {
|
|
577
|
-
return this.request("/api/teams", {
|
|
578
|
+
return this.request("/api/v1/teams", {
|
|
578
579
|
headers: {
|
|
579
580
|
"Authorization": `Bearer ${token}`
|
|
580
581
|
},
|
|
@@ -1045,7 +1046,7 @@ function registerAuthCommands(program2) {
|
|
|
1045
1046
|
ui.heading("Two-Factor Authentication Setup");
|
|
1046
1047
|
ui.info("Scan this QR code with your authenticator app:");
|
|
1047
1048
|
ui.br();
|
|
1048
|
-
qrcode.generate(result.data.
|
|
1049
|
+
qrcode.generate(result.data.otpauthUrl, { small: true });
|
|
1049
1050
|
ui.br();
|
|
1050
1051
|
ui.subheading("Or enter this secret manually:");
|
|
1051
1052
|
console.log(colors.primary.bold(` ${result.data.secret}`));
|
|
@@ -1106,7 +1107,7 @@ function registerAuthCommands(program2) {
|
|
|
1106
1107
|
return true;
|
|
1107
1108
|
}
|
|
1108
1109
|
});
|
|
1109
|
-
|
|
1110
|
+
await prompt({
|
|
1110
1111
|
type: "password",
|
|
1111
1112
|
name: "confirmPassword",
|
|
1112
1113
|
message: "Confirm Password:",
|
|
@@ -2834,12 +2835,37 @@ function registerSecretCommands(program2) {
|
|
|
2834
2835
|
}
|
|
2835
2836
|
const ctx = requireContext();
|
|
2836
2837
|
const environment = options.env || ctx.environment;
|
|
2838
|
+
const projectSlug = options.project || ctx.projectSlug;
|
|
2837
2839
|
const currentTeam = configManager.getCurrentTeam();
|
|
2838
2840
|
if (!currentTeam) {
|
|
2839
2841
|
ui.error("No team selected. Run `sstash teams use <slug>` first.");
|
|
2840
2842
|
process.exit(1);
|
|
2841
2843
|
}
|
|
2842
2844
|
const spinner = ui.spinner("Looking up secret and tag...");
|
|
2845
|
+
const projectsResult = await apiClient.getProjects(currentTeam.id);
|
|
2846
|
+
if (projectsResult.error) {
|
|
2847
|
+
spinner.fail();
|
|
2848
|
+
ui.error(projectsResult.error.message);
|
|
2849
|
+
process.exit(1);
|
|
2850
|
+
}
|
|
2851
|
+
const project = projectsResult.data?.projects.find((p) => p.slug === projectSlug);
|
|
2852
|
+
if (!project) {
|
|
2853
|
+
spinner.fail();
|
|
2854
|
+
ui.error(`Project "${projectSlug}" not found`);
|
|
2855
|
+
process.exit(1);
|
|
2856
|
+
}
|
|
2857
|
+
const envsResult = await apiClient.getEnvironments(project.id);
|
|
2858
|
+
if (envsResult.error) {
|
|
2859
|
+
spinner.fail();
|
|
2860
|
+
ui.error(envsResult.error.message);
|
|
2861
|
+
process.exit(1);
|
|
2862
|
+
}
|
|
2863
|
+
const env = envsResult.data?.environments.find((e) => e.slug === environment || e.name.toLowerCase() === environment.toLowerCase());
|
|
2864
|
+
if (!env) {
|
|
2865
|
+
spinner.fail();
|
|
2866
|
+
ui.error(`Environment "${environment}" not found`);
|
|
2867
|
+
process.exit(1);
|
|
2868
|
+
}
|
|
2843
2869
|
const tagsResult = await apiClient.getTags(currentTeam.id);
|
|
2844
2870
|
if (tagsResult.error) {
|
|
2845
2871
|
spinner.fail();
|
|
@@ -2855,7 +2881,7 @@ function registerSecretCommands(program2) {
|
|
|
2855
2881
|
ui.info(`Create it with ${ui.code(`sstash tags create ${tagname}`)}`);
|
|
2856
2882
|
process.exit(1);
|
|
2857
2883
|
}
|
|
2858
|
-
const secretsResult = await apiClient.getSecrets(
|
|
2884
|
+
const secretsResult = await apiClient.getSecrets(env.id);
|
|
2859
2885
|
if (secretsResult.error) {
|
|
2860
2886
|
spinner.fail();
|
|
2861
2887
|
ui.error(secretsResult.error.message);
|
|
@@ -2889,12 +2915,37 @@ function registerSecretCommands(program2) {
|
|
|
2889
2915
|
}
|
|
2890
2916
|
const ctx = requireContext();
|
|
2891
2917
|
const environment = options.env || ctx.environment;
|
|
2918
|
+
const projectSlug = options.project || ctx.projectSlug;
|
|
2892
2919
|
const currentTeam = configManager.getCurrentTeam();
|
|
2893
2920
|
if (!currentTeam) {
|
|
2894
2921
|
ui.error("No team selected. Run `sstash teams use <slug>` first.");
|
|
2895
2922
|
process.exit(1);
|
|
2896
2923
|
}
|
|
2897
2924
|
const spinner = ui.spinner("Looking up secret and tag...");
|
|
2925
|
+
const projectsResult = await apiClient.getProjects(currentTeam.id);
|
|
2926
|
+
if (projectsResult.error) {
|
|
2927
|
+
spinner.fail();
|
|
2928
|
+
ui.error(projectsResult.error.message);
|
|
2929
|
+
process.exit(1);
|
|
2930
|
+
}
|
|
2931
|
+
const project = projectsResult.data?.projects.find((p) => p.slug === projectSlug);
|
|
2932
|
+
if (!project) {
|
|
2933
|
+
spinner.fail();
|
|
2934
|
+
ui.error(`Project "${projectSlug}" not found`);
|
|
2935
|
+
process.exit(1);
|
|
2936
|
+
}
|
|
2937
|
+
const envsResult = await apiClient.getEnvironments(project.id);
|
|
2938
|
+
if (envsResult.error) {
|
|
2939
|
+
spinner.fail();
|
|
2940
|
+
ui.error(envsResult.error.message);
|
|
2941
|
+
process.exit(1);
|
|
2942
|
+
}
|
|
2943
|
+
const env = envsResult.data?.environments.find((e) => e.slug === environment || e.name.toLowerCase() === environment.toLowerCase());
|
|
2944
|
+
if (!env) {
|
|
2945
|
+
spinner.fail();
|
|
2946
|
+
ui.error(`Environment "${environment}" not found`);
|
|
2947
|
+
process.exit(1);
|
|
2948
|
+
}
|
|
2898
2949
|
const tagsResult = await apiClient.getTags(currentTeam.id);
|
|
2899
2950
|
if (tagsResult.error) {
|
|
2900
2951
|
spinner.fail();
|
|
@@ -2909,7 +2960,7 @@ function registerSecretCommands(program2) {
|
|
|
2909
2960
|
ui.error(`Tag "${tagname}" not found`);
|
|
2910
2961
|
process.exit(1);
|
|
2911
2962
|
}
|
|
2912
|
-
const secretsResult = await apiClient.getSecrets(
|
|
2963
|
+
const secretsResult = await apiClient.getSecrets(env.id);
|
|
2913
2964
|
if (secretsResult.error) {
|
|
2914
2965
|
spinner.fail();
|
|
2915
2966
|
ui.error(secretsResult.error.message);
|
|
@@ -4076,7 +4127,7 @@ function registerExecCommand(program2) {
|
|
|
4076
4127
|
}
|
|
4077
4128
|
|
|
4078
4129
|
// src/index.ts
|
|
4079
|
-
var __dirname =
|
|
4130
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
4080
4131
|
var version = "0.1.0";
|
|
4081
4132
|
try {
|
|
4082
4133
|
const pkg = JSON.parse(readFileSync4(join2(__dirname, "..", "package.json"), "utf-8"));
|