@get-dx/cli 0.5.0 → 0.5.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.
@@ -2,7 +2,7 @@ import { password, select } from "@inquirer/prompts";
2
2
  import { Command } from "commander";
3
3
  import { deleteToken, setToken } from "../secrets.js";
4
4
  import { renderJson } from "../renderers.js";
5
- import { renderAuthInfo, renderLoggedOut } from "./authRendering.js";
5
+ import { renderAuthInfo, renderAuthWhoami, renderLoggedOut, } from "./authRendering.js";
6
6
  import { createExampleText, getContext, wrapAction, } from "../commandHelpers.js";
7
7
  import { persistBaseUrls, resolveApiBaseUrl, deriveBaseUrlsFromEnv, } from "../config.js";
8
8
  import { CliError } from "../errors.js";
@@ -51,12 +51,12 @@ export function authCommand() {
51
51
  }
52
52
  else {
53
53
  token = await password({
54
- message: "Paste your account web API token here:",
54
+ message: "Paste your personal access token or organization token here:",
55
55
  mask: true,
56
56
  });
57
57
  }
58
58
  if (!token) {
59
- throw new CliError("Account web API token or personal access token is required");
59
+ throw new CliError("Personal access token or organization token is required");
60
60
  }
61
61
  }
62
62
  const runtime = await buildRuntime(context, {
@@ -128,6 +128,29 @@ export function authCommand() {
128
128
  renderAuthInfo(response, runtime.token, runtime.apiBaseUrl);
129
129
  }
130
130
  }));
131
+ auth
132
+ .command("whoami")
133
+ .description("Show user and team details for the authenticated token")
134
+ .addHelpText("afterAll", createExampleText([
135
+ {
136
+ label: "Fetch user and team details",
137
+ command: "dx auth whoami",
138
+ },
139
+ {
140
+ label: "Fetch user and team details as JSON",
141
+ command: "dx auth whoami --json",
142
+ },
143
+ ]))
144
+ .action(wrapAction(async (_options, command) => {
145
+ const runtime = await buildRuntime(getContext(command));
146
+ const response = await getAuthWhoami(runtime);
147
+ if (runtime.context.json) {
148
+ renderJson(response);
149
+ }
150
+ else {
151
+ renderAuthWhoami(response);
152
+ }
153
+ }));
131
154
  return auth;
132
155
  }
133
156
  // TODO: should we move this somewhere more central, since `init` needs it?
@@ -137,3 +160,9 @@ export async function getAuthInfo(runtime) {
137
160
  });
138
161
  return response.body;
139
162
  }
163
+ export async function getAuthWhoami(runtime) {
164
+ const response = await request(runtime, "/auth.whoami", {
165
+ method: "GET",
166
+ });
167
+ return response.body;
168
+ }
@@ -37,10 +37,51 @@ function scopesContent(scopes) {
37
37
  ];
38
38
  }
39
39
  }
40
+ export function renderAuthWhoami(response) {
41
+ const blocks = [];
42
+ // Auth section
43
+ blocks.push(ui.h3("Auth"));
44
+ blocks.push(ui.dl([
45
+ ui.dli("Account", response.account.name),
46
+ ui.dli("Token type", tokenTypeName(response.auth_token_type)),
47
+ ], { termWidth: 12 }));
48
+ // User section
49
+ blocks.push(ui.h3("Current user"));
50
+ if (response.user) {
51
+ blocks.push(ui.dl([
52
+ ui.dli("ID", ui.code(response.user.id)),
53
+ ui.dli("Name", response.user.name),
54
+ ui.dli("Email", response.user.email),
55
+ ], { termWidth: 7 }));
56
+ }
57
+ else {
58
+ blocks.push(ui.p(ui.dim("Not available for organization tokens")));
59
+ }
60
+ // Team section
61
+ blocks.push(ui.h3("Team"));
62
+ if (response.team) {
63
+ blocks.push(ui.dl([
64
+ ui.dli("ID", ui.code(response.team.id)),
65
+ ui.dli("Name", response.team.name),
66
+ ui.dli("Lead", formatUser(response.team.lead)),
67
+ ], { termWidth: 6 }));
68
+ if (response.team.contributors.length > 0) {
69
+ blocks.push(ui.p(ui.bold("Contributors:"), false));
70
+ blocks.push(ui.ul(response.team.contributors.map((c) => ui.li(formatUser(c)))));
71
+ }
72
+ }
73
+ else {
74
+ blocks.push(ui.p(ui.dim("Not available for organization tokens")));
75
+ }
76
+ renderRichText(blocks);
77
+ }
78
+ function formatUser(user) {
79
+ return `${user.name} ${ui.dim(`(${user.id}, ${user.email})`)}`;
80
+ }
40
81
  function tokenTypeName(tokenType) {
41
82
  switch (tokenType) {
42
83
  case "account_web_api_token":
43
- return "Account-level web API token";
84
+ return "Organization token";
44
85
  case "personal_access_token":
45
86
  return "Personal access token";
46
87
  default:
@@ -83,12 +83,12 @@ async function attemptLogin(apiBaseUrl, webBaseUrl, context) {
83
83
  }
84
84
  else {
85
85
  token = await password({
86
- message: "Paste your account web API token here:",
86
+ message: "Paste your personal access token or organization token here:",
87
87
  mask: true,
88
88
  });
89
89
  }
90
90
  if (!token) {
91
- throw new CliError("Account web API token is required");
91
+ throw new CliError("Personal access token or organization token is required");
92
92
  }
93
93
  const runtime = await buildRuntime(context, {
94
94
  apiBaseUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@get-dx/cli",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "DX CLI",
5
5
  "author": "DX <developers@getdx.com>",
6
6
  "bugs": {