@getpara/cli 2.15.0 → 2.15.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.
Files changed (60) hide show
  1. package/dist/api/client.d.ts +2 -2
  2. package/dist/api/client.d.ts.map +1 -1
  3. package/dist/api/client.js +1 -1
  4. package/dist/auth/polling-flow.d.ts +2 -2
  5. package/dist/auth/polling-flow.d.ts.map +1 -1
  6. package/dist/auth/polling-flow.js +3 -3
  7. package/dist/auth/session-manager.d.ts +3 -3
  8. package/dist/auth/session-manager.d.ts.map +1 -1
  9. package/dist/auth/session-manager.js +8 -8
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +26 -7
  12. package/dist/commands/auth/login.d.ts.map +1 -1
  13. package/dist/commands/auth/login.js +8 -9
  14. package/dist/commands/auth/logout.d.ts.map +1 -1
  15. package/dist/commands/auth/logout.js +7 -8
  16. package/dist/commands/auth/status.d.ts.map +1 -1
  17. package/dist/commands/auth/status.js +4 -5
  18. package/dist/commands/config.js +5 -5
  19. package/dist/commands/create.js +5 -5
  20. package/dist/commands/init.d.ts.map +1 -1
  21. package/dist/commands/init.js +3 -5
  22. package/dist/commands/keys/archive.d.ts.map +1 -1
  23. package/dist/commands/keys/archive.js +20 -10
  24. package/dist/commands/keys/config/branding.js +5 -5
  25. package/dist/commands/keys/config/categories.d.ts.map +1 -1
  26. package/dist/commands/keys/config/categories.js +19 -1
  27. package/dist/commands/keys/config/index.d.ts.map +1 -1
  28. package/dist/commands/keys/config/index.js +12 -4
  29. package/dist/commands/keys/config/ramps.js +5 -5
  30. package/dist/commands/keys/config/security.js +5 -5
  31. package/dist/commands/keys/config/setup.js +5 -5
  32. package/dist/commands/keys/config/webhooks.d.ts +1 -1
  33. package/dist/commands/keys/config/webhooks.d.ts.map +1 -1
  34. package/dist/commands/keys/config/webhooks.js +15 -14
  35. package/dist/commands/keys/create.js +3 -3
  36. package/dist/commands/keys/get.d.ts.map +1 -1
  37. package/dist/commands/keys/get.js +62 -57
  38. package/dist/commands/keys/list.js +3 -3
  39. package/dist/commands/keys/rotate.d.ts.map +1 -1
  40. package/dist/commands/keys/rotate.js +22 -12
  41. package/dist/commands/orgs/list.js +2 -2
  42. package/dist/commands/orgs/switch.js +2 -2
  43. package/dist/commands/projects/archive.js +2 -2
  44. package/dist/commands/projects/create.js +2 -2
  45. package/dist/commands/projects/list.js +2 -2
  46. package/dist/commands/projects/restore.js +2 -2
  47. package/dist/commands/projects/switch.js +2 -2
  48. package/dist/commands/projects/update.js +2 -2
  49. package/dist/commands/whoami.js +5 -5
  50. package/dist/config/config-manager.d.ts.map +1 -1
  51. package/dist/config/config-manager.js +21 -9
  52. package/dist/config/credential-store.d.ts +4 -4
  53. package/dist/config/credential-store.d.ts.map +1 -1
  54. package/dist/config/credential-store.js +10 -10
  55. package/dist/core/constants.d.ts +11 -5
  56. package/dist/core/constants.d.ts.map +1 -1
  57. package/dist/core/constants.js +33 -18
  58. package/dist/core/types.d.ts +5 -3
  59. package/dist/core/types.d.ts.map +1 -1
  60. package/package.json +2 -3
@@ -26,24 +26,32 @@ Each category also accepts flags for non-interactive use:
26
26
  const opts = await getGlobalOptions(cmd);
27
27
  const formatter = createFormatter(opts);
28
28
  const config2 = await resolveConfig(opts);
29
- const session = await ensureAuthenticated(config2.environment);
29
+ const session = await ensureAuthenticated(config2.backend);
30
30
  if (!config2.organizationId || !config2.projectId) {
31
31
  throw new CliError(
32
32
  "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
33
33
  );
34
34
  }
35
35
  const client = new ParaApiClient({
36
- environment: config2.environment,
36
+ backend: config2.backend,
37
37
  sessionId: session.sessionId
38
38
  });
39
39
  const { keyId, key } = await resolveKeyId(
40
40
  client,
41
41
  config2.organizationId,
42
42
  config2.projectId,
43
- config2.environment,
43
+ config2.keyEnvironment,
44
44
  keyIdArg
45
45
  );
46
- await runInteractiveMenu(client, config2.organizationId, config2.projectId, config2.environment, keyId, key, formatter);
46
+ await runInteractiveMenu(
47
+ client,
48
+ config2.organizationId,
49
+ config2.projectId,
50
+ config2.keyEnvironment,
51
+ keyId,
52
+ key,
53
+ formatter
54
+ );
47
55
  });
48
56
  registerSecurityConfigCommand(config);
49
57
  registerBrandingConfigCommand(config);
@@ -42,28 +42,28 @@ function registerRampsConfigCommand(parent) {
42
42
  const opts = await getGlobalOptions(cmd);
43
43
  const formatter = createFormatter(opts);
44
44
  const config = await resolveConfig(opts);
45
- const session = await ensureAuthenticated(config.environment);
45
+ const session = await ensureAuthenticated(config.backend);
46
46
  if (!config.organizationId || !config.projectId) {
47
47
  throw new CliError(
48
48
  "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
49
49
  );
50
50
  }
51
51
  const client = new ParaApiClient({
52
- environment: config.environment,
52
+ backend: config.backend,
53
53
  sessionId: session.sessionId
54
54
  });
55
55
  const { keyId, key } = await resolveKeyId(
56
56
  client,
57
57
  config.organizationId,
58
58
  config.projectId,
59
- config.environment,
59
+ config.keyEnvironment,
60
60
  keyIdArg
61
61
  );
62
62
  await runRampsAction(
63
63
  client,
64
64
  config.organizationId,
65
65
  config.projectId,
66
- config.environment,
66
+ config.keyEnvironment,
67
67
  keyId,
68
68
  key,
69
69
  formatter,
@@ -176,7 +176,7 @@ async function runRampsAction(client, orgId, projectId, environment, keyId, curr
176
176
  }
177
177
  await client.updateApiKey(orgId, projectId, environment, keyId, updates);
178
178
  formatter.json({ keyId, updated: updates });
179
- formatter.success("Updated ramp settings.");
179
+ formatter.success(`Updated ramps on ${currentKey.displayName || currentKey.name} (${currentKey.environment})`);
180
180
  formatter.flush();
181
181
  }
182
182
  export {
@@ -32,28 +32,28 @@ function registerSecurityConfigCommand(parent) {
32
32
  const opts = await getGlobalOptions(cmd);
33
33
  const formatter = createFormatter(opts);
34
34
  const config = await resolveConfig(opts);
35
- const session = await ensureAuthenticated(config.environment);
35
+ const session = await ensureAuthenticated(config.backend);
36
36
  if (!config.organizationId || !config.projectId) {
37
37
  throw new CliError(
38
38
  "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
39
39
  );
40
40
  }
41
41
  const client = new ParaApiClient({
42
- environment: config.environment,
42
+ backend: config.backend,
43
43
  sessionId: session.sessionId
44
44
  });
45
45
  const { keyId, key } = await resolveKeyId(
46
46
  client,
47
47
  config.organizationId,
48
48
  config.projectId,
49
- config.environment,
49
+ config.keyEnvironment,
50
50
  keyIdArg
51
51
  );
52
52
  await runSecurityAction(
53
53
  client,
54
54
  config.organizationId,
55
55
  config.projectId,
56
- config.environment,
56
+ config.keyEnvironment,
57
57
  keyId,
58
58
  key,
59
59
  formatter,
@@ -203,7 +203,7 @@ async function runSecurityAction(client, orgId, projectId, environment, keyId, c
203
203
  await client.updateIpAllowlist(orgId, projectId, environment, keyId, ipUpdates);
204
204
  }
205
205
  formatter.json({ keyId, updated: { ...updates, ...hasIpUpdates ? { ipAllowlistCidrs: ipUpdates } : {} } });
206
- formatter.success("Updated security settings.");
206
+ formatter.success(`Updated security on ${currentKey.displayName || currentKey.name} (${currentKey.environment})`);
207
207
  formatter.flush();
208
208
  }
209
209
  export {
@@ -35,28 +35,28 @@ function registerSetupConfigCommand(parent) {
35
35
  const opts = await getGlobalOptions(cmd);
36
36
  const formatter = createFormatter(opts);
37
37
  const config = await resolveConfig(opts);
38
- const session = await ensureAuthenticated(config.environment);
38
+ const session = await ensureAuthenticated(config.backend);
39
39
  if (!config.organizationId || !config.projectId) {
40
40
  throw new CliError(
41
41
  "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
42
42
  );
43
43
  }
44
44
  const client = new ParaApiClient({
45
- environment: config.environment,
45
+ backend: config.backend,
46
46
  sessionId: session.sessionId
47
47
  });
48
48
  const { keyId, key } = await resolveKeyId(
49
49
  client,
50
50
  config.organizationId,
51
51
  config.projectId,
52
- config.environment,
52
+ config.keyEnvironment,
53
53
  keyIdArg
54
54
  );
55
55
  await runSetupAction(
56
56
  client,
57
57
  config.organizationId,
58
58
  config.projectId,
59
- config.environment,
59
+ config.keyEnvironment,
60
60
  keyId,
61
61
  key,
62
62
  formatter,
@@ -226,7 +226,7 @@ async function runSetupAction(client, orgId, projectId, environment, keyId, curr
226
226
  }
227
227
  await client.updateApiKey(orgId, projectId, environment, keyId, updates);
228
228
  formatter.json({ keyId, updated: updates });
229
- formatter.success("Updated setup settings.");
229
+ formatter.success(`Updated setup on ${currentKey.displayName || currentKey.name} (${currentKey.environment})`);
230
230
  formatter.flush();
231
231
  }
232
232
  export {
@@ -13,6 +13,6 @@ interface WebhooksFlags {
13
13
  yes?: boolean;
14
14
  }
15
15
  export declare function registerWebhooksConfigCommand(parent: Command): void;
16
- export declare function runWebhooksAction(client: ParaApiClient, orgId: string, projectId: string, environment: string, keyId: string, _currentKey: ApiKey, formatter: OutputFormatter, flags?: WebhooksFlags): Promise<void>;
16
+ export declare function runWebhooksAction(client: ParaApiClient, orgId: string, projectId: string, environment: string, keyId: string, key: ApiKey, formatter: OutputFormatter, flags?: WebhooksFlags): Promise<void>;
17
17
  export {};
18
18
  //# sourceMappingURL=webhooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../../../src/commands/keys/config/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,uBAAuB,CAAC;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAKpE,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAgEnE;AA0BD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,eAAe,EAC1B,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CA6Of"}
1
+ {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../../../src/commands/keys/config/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,uBAAuB,CAAC;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAKpE,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAgEnE;AA0BD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,eAAe,EAC1B,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CA8Of"}
@@ -25,28 +25,28 @@ Event types: user.created, wallet.created, transaction.signed, send.broadcasted,
25
25
  const opts = await getGlobalOptions(cmd);
26
26
  const formatter = createFormatter(opts);
27
27
  const config = await resolveConfig(opts);
28
- const session = await ensureAuthenticated(config.environment);
28
+ const session = await ensureAuthenticated(config.backend);
29
29
  if (!config.organizationId || !config.projectId) {
30
30
  throw new CliError(
31
31
  "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
32
32
  );
33
33
  }
34
34
  const client = new ParaApiClient({
35
- environment: config.environment,
35
+ backend: config.backend,
36
36
  sessionId: session.sessionId
37
37
  });
38
38
  const { keyId, key } = await resolveKeyId(
39
39
  client,
40
40
  config.organizationId,
41
41
  config.projectId,
42
- config.environment,
42
+ config.keyEnvironment,
43
43
  keyIdArg
44
44
  );
45
45
  await runWebhooksAction(
46
46
  client,
47
47
  config.organizationId,
48
48
  config.projectId,
49
- config.environment,
49
+ config.keyEnvironment,
50
50
  keyId,
51
51
  key,
52
52
  formatter,
@@ -74,7 +74,8 @@ function formatWebhookStatus(webhook) {
74
74
  p.log.info(`Enabled: ${webhook.enabled ? "yes" : "no"}`);
75
75
  p.log.info(`Events: ${webhook.events.length ? webhook.events.join(", ") : "(none)"}`);
76
76
  }
77
- async function runWebhooksAction(client, orgId, projectId, environment, keyId, _currentKey, formatter, flags) {
77
+ async function runWebhooksAction(client, orgId, projectId, environment, keyId, key, formatter, flags) {
78
+ const keyLabel = `${key.displayName || key.name} (${key.environment})`;
78
79
  const isInteractive = !hasAnyFlag(flags);
79
80
  if (hasOperationFlag(flags)) {
80
81
  const ops = [flags?.status, flags?.test, flags?.rotateSecret, flags?.delete].filter(Boolean);
@@ -95,7 +96,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
95
96
  const result = await client.testWebhook(orgId, projectId, environment, keyId);
96
97
  formatter.json({ success: result.success, timestamp: result.timestamp });
97
98
  if (result.success) {
98
- formatter.success("Test webhook sent successfully.");
99
+ formatter.success(`Test webhook sent on ${keyLabel}`);
99
100
  } else {
100
101
  formatter.error("Test webhook delivery failed.");
101
102
  }
@@ -112,7 +113,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
112
113
  }
113
114
  const result = await client.rotateWebhookSecret(orgId, projectId, environment, keyId);
114
115
  formatter.json({ secret: result.secret });
115
- formatter.success("Rotated webhook signing secret.");
116
+ formatter.success(`Rotated webhook secret on ${keyLabel}`);
116
117
  p.log.warn(`New secret: ${result.secret}`);
117
118
  p.log.warn("Save this now \u2014 it will not be shown again.");
118
119
  formatter.flush();
@@ -128,7 +129,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
128
129
  }
129
130
  await client.deleteWebhookConfig(orgId, projectId, environment, keyId);
130
131
  formatter.json({ deleted: true });
131
- formatter.success("Deleted webhook configuration.");
132
+ formatter.success(`Deleted webhook on ${keyLabel}`);
132
133
  formatter.flush();
133
134
  return;
134
135
  }
@@ -160,7 +161,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
160
161
  }
161
162
  const result = await client.updateWebhookConfig(orgId, projectId, environment, keyId, { url, events, enabled });
162
163
  formatter.json({ webhook: result.webhook, ...result.secret ? { secret: result.secret } : {} });
163
- formatter.success("Updated webhook settings.");
164
+ formatter.success(`Updated webhook on ${keyLabel}`);
164
165
  if (result.secret) {
165
166
  p.log.warn(`Webhook signing secret: ${result.secret}`);
166
167
  p.log.warn("Save this now \u2014 it will not be shown again.");
@@ -192,7 +193,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
192
193
  enabled
193
194
  });
194
195
  formatter.json({ webhook: result.webhook, ...result.secret ? { secret: result.secret } : {} });
195
- formatter.success("Created webhook configuration.");
196
+ formatter.success(`Created webhook on ${keyLabel}`);
196
197
  if (result.secret) {
197
198
  p.log.warn(`Webhook signing secret: ${result.secret}`);
198
199
  p.log.warn("Save this now \u2014 it will not be shown again.");
@@ -237,7 +238,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
237
238
  events,
238
239
  enabled
239
240
  });
240
- formatter.success("Updated webhook settings.");
241
+ formatter.success(`Updated webhook on ${keyLabel}`);
241
242
  if (result.secret) {
242
243
  p.log.warn(`Webhook signing secret: ${result.secret}`);
243
244
  p.log.warn("Save this now \u2014 it will not be shown again.");
@@ -246,7 +247,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
246
247
  if (action === "test") {
247
248
  const result = await client.testWebhook(orgId, projectId, environment, keyId);
248
249
  if (result.success) {
249
- formatter.success("Test webhook sent successfully.");
250
+ formatter.success(`Test webhook sent on ${keyLabel}`);
250
251
  } else {
251
252
  formatter.error("Test webhook delivery failed.");
252
253
  }
@@ -256,7 +257,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
256
257
  const confirmed = await confirm("Rotate webhook signing secret?");
257
258
  if (confirmed) {
258
259
  const result = await client.rotateWebhookSecret(orgId, projectId, environment, keyId);
259
- formatter.success("Rotated webhook signing secret.");
260
+ formatter.success(`Rotated webhook secret on ${keyLabel}`);
260
261
  p.log.warn(`New secret: ${result.secret}`);
261
262
  p.log.warn("Save this now \u2014 it will not be shown again.");
262
263
  }
@@ -266,7 +267,7 @@ async function runWebhooksAction(client, orgId, projectId, environment, keyId, _
266
267
  const confirmed = await confirm("Delete webhook?");
267
268
  if (confirmed) {
268
269
  await client.deleteWebhookConfig(orgId, projectId, environment, keyId);
269
- formatter.success("Deleted webhook configuration.");
270
+ formatter.success(`Deleted webhook on ${keyLabel}`);
270
271
  break;
271
272
  }
272
273
  }
@@ -16,7 +16,7 @@ The secret key is only shown once on creation \u2014 save it immediately.`)
16
16
  const opts = await getGlobalOptions(cmd);
17
17
  const formatter = createFormatter(opts);
18
18
  const config = await resolveConfig(opts);
19
- const session = await ensureAuthenticated(config.environment);
19
+ const session = await ensureAuthenticated(config.backend);
20
20
  if (!config.organizationId || !config.projectId) {
21
21
  throw new CliError(
22
22
  "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
@@ -28,10 +28,10 @@ The secret key is only shown once on creation \u2014 save it immediately.`)
28
28
  }
29
29
  });
30
30
  const client = new ParaApiClient({
31
- environment: config.environment,
31
+ backend: config.backend,
32
32
  sessionId: session.sessionId
33
33
  });
34
- const key = await client.createApiKey(config.organizationId, config.projectId, config.environment, {
34
+ const key = await client.createApiKey(config.organizationId, config.projectId, config.keyEnvironment, {
35
35
  name,
36
36
  displayName: cmdOpts.displayName
37
37
  });
@@ -1 +1 @@
1
- {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/get.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BzC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA+E5D"}
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/get.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BzC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA2F5D"}
@@ -4,6 +4,7 @@ import { resolveConfig } from "../../config/config-manager.js";
4
4
  import { ParaApiClient } from "../../api/client.js";
5
5
  import { CliError } from "../../core/error-handler.js";
6
6
  import { maskSecret } from "../../output/mask.js";
7
+ import { resolveKeyId } from "./config/categories.js";
7
8
  async function copyToClipboard(value) {
8
9
  try {
9
10
  const { execFileSync } = await import("node:child_process");
@@ -23,68 +24,72 @@ async function copyToClipboard(value) {
23
24
  }
24
25
  }
25
26
  function registerKeysGetCommand(parent) {
26
- parent.command("get").description("Get details of a specific API key").argument("<key-id>", "API key ID").option("--show-secret", "Show the full secret API key").option("--copy", "Copy the public API key to clipboard").option("--copy-secret", "Copy the secret API key to clipboard").addHelpText(
27
+ parent.command("get").description("Get details of an API key").argument("[key-id]", "API key ID (resolved from project + environment if omitted)").option("--show-secret", "Show the full secret API key").option("--copy", "Copy the public API key to clipboard").option("--copy-secret", "Copy the secret API key to clipboard").addHelpText(
27
28
  "after",
28
29
  helpText(`Examples:
29
- $ para keys get abc-123 Show name, public key, masked secret, env, origins
30
- $ para keys get abc-123 --copy Copy the public API key to your clipboard
31
- $ para keys get abc-123 --copy-secret Copy the secret key (for .env files)
32
- $ para keys get abc-123 --show-secret Print the full unmasked secret key`)
33
- ).action(async (keyId, cmdOpts, cmd) => {
34
- const opts = await getGlobalOptions(cmd);
35
- const formatter = createFormatter(opts);
36
- const config = await resolveConfig(opts);
37
- const session = await ensureAuthenticated(config.environment);
38
- if (!config.organizationId || !config.projectId) {
39
- throw new CliError(
40
- "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
41
- );
42
- }
43
- const client = new ParaApiClient({
44
- environment: config.environment,
45
- sessionId: session.sessionId
46
- });
47
- const key = await client.getApiKey(config.organizationId, config.projectId, config.environment, keyId);
48
- if (cmdOpts.copy || cmdOpts.copySecret) {
49
- const valueToCopy = cmdOpts.copySecret ? key.secretApiKey : key.apiKey;
50
- if (valueToCopy) {
51
- const copied = await copyToClipboard(valueToCopy);
52
- if (copied) {
53
- formatter.success(`${cmdOpts.copySecret ? "Secret API key" : "API key"} copied to clipboard.`);
54
- formatter.flush();
55
- return;
56
- }
57
- formatter.warn("Could not copy to clipboard. Displaying instead.");
30
+ $ para keys get Show the beta key for the active project
31
+ $ para keys get -e prod Show the prod key
32
+ $ para keys get abc-123 Show a specific key by ID
33
+ $ para keys get --copy Copy the beta API key to your clipboard
34
+ $ para keys get -e prod --copy-secret Copy the prod secret key (for .env files)
35
+ $ para keys get --show-secret Print the full unmasked secret key`)
36
+ ).action(
37
+ async (keyIdArg, cmdOpts, cmd) => {
38
+ const opts = await getGlobalOptions(cmd);
39
+ const formatter = createFormatter(opts);
40
+ const config = await resolveConfig(opts);
41
+ const session = await ensureAuthenticated(config.backend);
42
+ if (!config.organizationId || !config.projectId) {
43
+ throw new CliError(
44
+ "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
45
+ );
58
46
  }
59
- }
60
- if (opts.json) {
61
- formatter.json({
62
- id: key.id,
63
- name: key.name,
64
- displayName: key.displayName,
65
- apiKey: key.apiKey,
66
- secretApiKey: cmdOpts.showSecret ? key.secretApiKey : key.secretApiKey ? maskSecret(key.secretApiKey) : void 0,
67
- environment: key.environment,
68
- archived: key.archived,
69
- origins: key.origins
47
+ const client = new ParaApiClient({
48
+ backend: config.backend,
49
+ sessionId: session.sessionId
70
50
  });
71
- } else {
72
- formatter.detail([
73
- { label: "Name", value: key.displayName || key.name },
74
- { label: "ID", value: key.id },
75
- { label: "API Key", value: key.apiKey },
76
- {
77
- label: "Secret Key",
78
- value: key.secretApiKey || "N/A",
79
- mask: !cmdOpts.showSecret
80
- },
81
- { label: "Environment", value: key.environment },
82
- { label: "Status", value: key.archived ? "archived" : "active" },
83
- ...key.origins?.length ? [{ label: "Origins", value: key.origins.join(", ") }] : []
84
- ]);
51
+ const { key } = await resolveKeyId(client, config.organizationId, config.projectId, config.keyEnvironment, keyIdArg);
52
+ if (cmdOpts.copy || cmdOpts.copySecret) {
53
+ const valueToCopy = cmdOpts.copySecret ? key.secretApiKey : key.apiKey;
54
+ if (valueToCopy) {
55
+ const copied = await copyToClipboard(valueToCopy);
56
+ if (copied) {
57
+ formatter.success(`${cmdOpts.copySecret ? "Secret API key" : "API key"} copied to clipboard.`);
58
+ formatter.flush();
59
+ return;
60
+ }
61
+ formatter.warn("Could not copy to clipboard. Displaying instead.");
62
+ }
63
+ }
64
+ if (opts.json) {
65
+ formatter.json({
66
+ id: key.id,
67
+ name: key.name,
68
+ displayName: key.displayName,
69
+ apiKey: key.apiKey,
70
+ secretApiKey: cmdOpts.showSecret ? key.secretApiKey : key.secretApiKey ? maskSecret(key.secretApiKey) : void 0,
71
+ environment: key.environment,
72
+ archived: key.archived,
73
+ origins: key.origins
74
+ });
75
+ } else {
76
+ formatter.detail([
77
+ { label: "Name", value: key.displayName || key.name },
78
+ { label: "ID", value: key.id },
79
+ { label: "API Key", value: key.apiKey },
80
+ {
81
+ label: "Secret Key",
82
+ value: key.secretApiKey || "N/A",
83
+ mask: !cmdOpts.showSecret
84
+ },
85
+ { label: "Environment", value: key.environment },
86
+ { label: "Status", value: key.archived ? "archived" : "active" },
87
+ ...key.origins?.length ? [{ label: "Origins", value: key.origins.join(", ") }] : []
88
+ ]);
89
+ }
90
+ formatter.flush();
85
91
  }
86
- formatter.flush();
87
- });
92
+ );
88
93
  }
89
94
  export {
90
95
  registerKeysGetCommand
@@ -17,17 +17,17 @@ Requires an active org and project. Run "para orgs switch" and "para projects sw
17
17
  const opts = await getGlobalOptions(cmd);
18
18
  const formatter = createFormatter(opts);
19
19
  const config = await resolveConfig(opts);
20
- const session = await ensureAuthenticated(config.environment);
20
+ const session = await ensureAuthenticated(config.backend);
21
21
  if (!config.organizationId || !config.projectId) {
22
22
  throw new CliError(
23
23
  "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
24
24
  );
25
25
  }
26
26
  const client = new ParaApiClient({
27
- environment: config.environment,
27
+ backend: config.backend,
28
28
  sessionId: session.sessionId
29
29
  });
30
- const keys = await client.getApiKeys(config.organizationId, config.projectId, config.environment);
30
+ const keys = await client.getApiKeys(config.organizationId, config.projectId, config.keyEnvironment);
31
31
  const filtered = cmdOpts.includeArchived ? keys : keys.filter((k) => !k.archived);
32
32
  if (opts.json) {
33
33
  formatter.json(
@@ -1 +1 @@
1
- {"version":3,"file":"rotate.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/rotate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAiE/D"}
1
+ {"version":3,"file":"rotate.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/rotate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA0E/D"}
@@ -4,25 +4,39 @@ import { resolveConfig } from "../../config/config-manager.js";
4
4
  import { ParaApiClient } from "../../api/client.js";
5
5
  import { CliError } from "../../core/error-handler.js";
6
6
  import { confirm } from "../../output/prompts.js";
7
+ import { resolveKeyId } from "./config/categories.js";
7
8
  function registerKeysRotateCommand(parent) {
8
- parent.command("rotate").description("Rotate an API key").argument("<key-id>", "API key ID to rotate").option("--secret", "Rotate the secret key instead of the public key").option("-y, --yes", "Skip confirmation prompt").addHelpText(
9
+ parent.command("rotate").description("Rotate an API key").argument("[key-id]", "API key ID to rotate (resolved from project + environment if omitted)").option("--secret", "Rotate the secret key instead of the public key").option("-y, --yes", "Skip confirmation prompt").addHelpText(
9
10
  "after",
10
11
  helpText(`Examples:
11
- $ para keys rotate abc-123 Generates a new public key (asks for confirmation)
12
- $ para keys rotate abc-123 --secret Rotate the secret key instead of the public key
13
- $ para keys rotate abc-123 -y Skip the confirmation prompt (for scripts)
12
+ $ para keys rotate Rotate the beta key (asks for confirmation)
13
+ $ para keys rotate -e prod Rotate the prod key
14
+ $ para keys rotate abc-123 Rotate a specific key by ID
15
+ $ para keys rotate --secret Rotate the secret key instead of the public key
16
+ $ para keys rotate -y Skip the confirmation prompt (for scripts)
14
17
 
15
18
  This is irreversible \u2014 the old key stops working immediately.`)
16
- ).action(async (keyId, cmdOpts, cmd) => {
19
+ ).action(async (keyIdArg, cmdOpts, cmd) => {
17
20
  const opts = await getGlobalOptions(cmd);
18
21
  const formatter = createFormatter(opts);
19
22
  const config = await resolveConfig(opts);
20
- const session = await ensureAuthenticated(config.environment);
23
+ const session = await ensureAuthenticated(config.backend);
21
24
  if (!config.organizationId || !config.projectId) {
22
25
  throw new CliError(
23
26
  "Organization and project required. Run `para orgs switch` and `para projects switch`, or pass --org and --project."
24
27
  );
25
28
  }
29
+ const client = new ParaApiClient({
30
+ backend: config.backend,
31
+ sessionId: session.sessionId
32
+ });
33
+ const { keyId, key } = await resolveKeyId(
34
+ client,
35
+ config.organizationId,
36
+ config.projectId,
37
+ config.keyEnvironment,
38
+ keyIdArg
39
+ );
26
40
  const keyType = cmdOpts.secret ? "secret" : "public";
27
41
  if (!cmdOpts.yes) {
28
42
  const confirmed = await confirm(`Are you sure you want to rotate the ${keyType} API key? This cannot be undone.`);
@@ -31,11 +45,7 @@ This is irreversible \u2014 the old key stops working immediately.`)
31
45
  return;
32
46
  }
33
47
  }
34
- const client = new ParaApiClient({
35
- environment: config.environment,
36
- sessionId: session.sessionId
37
- });
38
- const result = cmdOpts.secret ? await client.rotateSecretApiKey(config.organizationId, config.projectId, config.environment, keyId) : await client.rotateApiKey(config.organizationId, config.projectId, config.environment, keyId);
48
+ const result = cmdOpts.secret ? await client.rotateSecretApiKey(config.organizationId, config.projectId, config.keyEnvironment, keyId) : await client.rotateApiKey(config.organizationId, config.projectId, config.keyEnvironment, keyId);
39
49
  if (opts.json) {
40
50
  formatter.json({
41
51
  id: keyId,
@@ -45,7 +55,7 @@ This is irreversible \u2014 the old key stops working immediately.`)
45
55
  } else if (opts.quiet) {
46
56
  console.log(result.newKey);
47
57
  } else {
48
- formatter.success(`Rotated ${keyType} API key`);
58
+ formatter.success(`Rotated ${keyType} key on ${key.displayName || key.name} (${key.environment})`);
49
59
  formatter.detail([
50
60
  { label: "Key ID", value: keyId },
51
61
  { label: `New ${keyType} key`, value: result.newKey }
@@ -13,9 +13,9 @@ function registerOrgsListCommand(parent) {
13
13
  const opts = await getGlobalOptions(cmd);
14
14
  const formatter = createFormatter(opts);
15
15
  const config = await resolveConfig(opts);
16
- const session = await ensureAuthenticated(config.environment);
16
+ const session = await ensureAuthenticated(config.backend);
17
17
  const client = new ParaApiClient({
18
- environment: config.environment,
18
+ backend: config.backend,
19
19
  sessionId: session.sessionId
20
20
  });
21
21
  let userId = session.userId;
@@ -17,9 +17,9 @@ Required before using projects or keys commands.`)
17
17
  const opts = await getGlobalOptions(cmd);
18
18
  const formatter = createFormatter(opts);
19
19
  const config = await resolveConfig(opts);
20
- const session = await ensureAuthenticated(config.environment);
20
+ const session = await ensureAuthenticated(config.backend);
21
21
  const client = new ParaApiClient({
22
- environment: config.environment,
22
+ backend: config.backend,
23
23
  sessionId: session.sessionId
24
24
  });
25
25
  let userId = session.userId;
@@ -17,7 +17,7 @@ Archived projects can be restored with "para projects restore".`)
17
17
  const opts = await getGlobalOptions(cmd);
18
18
  const formatter = createFormatter(opts);
19
19
  const config = await resolveConfig(opts);
20
- const session = await ensureAuthenticated(config.environment);
20
+ const session = await ensureAuthenticated(config.backend);
21
21
  if (!config.organizationId) {
22
22
  throw new CliError("No organization selected. Run `para orgs switch` or pass --org <id>.");
23
23
  }
@@ -34,7 +34,7 @@ Archived projects can be restored with "para projects restore".`)
34
34
  }
35
35
  }
36
36
  const client = new ParaApiClient({
37
- environment: config.environment,
37
+ backend: config.backend,
38
38
  sessionId: session.sessionId
39
39
  });
40
40
  await client.deleteProject(config.organizationId, projectId);
@@ -17,7 +17,7 @@ Requires an active organization. Run "para orgs switch" first.`)
17
17
  const opts = await getGlobalOptions(cmd);
18
18
  const formatter = createFormatter(opts);
19
19
  const config = await resolveConfig(opts);
20
- const session = await ensureAuthenticated(config.environment);
20
+ const session = await ensureAuthenticated(config.backend);
21
21
  if (!config.organizationId) {
22
22
  throw new CliError("No organization selected. Run `para orgs switch` or pass --org <id>.");
23
23
  }
@@ -27,7 +27,7 @@ Requires an active organization. Run "para orgs switch" first.`)
27
27
  }
28
28
  });
29
29
  const client = new ParaApiClient({
30
- environment: config.environment,
30
+ backend: config.backend,
31
31
  sessionId: session.sessionId
32
32
  });
33
33
  const project = await client.createProject(config.organizationId, {
@@ -16,12 +16,12 @@ Requires an active organization. Run "para orgs switch" first.`)
16
16
  const opts = await getGlobalOptions(cmd);
17
17
  const formatter = createFormatter(opts);
18
18
  const config = await resolveConfig(opts);
19
- const session = await ensureAuthenticated(config.environment);
19
+ const session = await ensureAuthenticated(config.backend);
20
20
  if (!config.organizationId) {
21
21
  throw new CliError("No organization selected. Run `para orgs switch` or pass --org <id>.");
22
22
  }
23
23
  const client = new ParaApiClient({
24
- environment: config.environment,
24
+ backend: config.backend,
25
25
  sessionId: session.sessionId
26
26
  });
27
27
  const projects = await client.getProjects(config.organizationId);