Skip to content

Commit 1a69614

Browse files
lollipop-onlclaude
andcommitted
refactor: auth commands use shared space() option
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 42a474b commit 1a69614

7 files changed

Lines changed: 61 additions & 30 deletions

File tree

apps/cli/src/commands/auth/logout.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { UserError } from "@repo/cli-utils";
22
import { loadConfig, removeSpace } from "@repo/config";
33
import consola from "consola";
44
import { BeeCommand } from "../../lib/bee-command";
5+
import * as opt from "../../lib/common-options";
56

67
const logout = new BeeCommand("logout")
78
.summary("Remove authentication for a Backlog space")
89
.description(
910
`Removes stored credentials locally. Does not revoke API keys or OAuth tokens on the server.`,
1011
)
11-
.option("-s, --space <hostname>", "The hostname of the Backlog space")
12-
.envVars([["BACKLOG_SPACE", "Space hostname to log out from"]])
12+
.addOption(opt.space())
1313
.examples([
1414
{ description: "Select space via prompt", command: "bee auth logout" },
1515
{
@@ -20,7 +20,7 @@ const logout = new BeeCommand("logout")
2020
.action(async (opts) => {
2121
const config = loadConfig();
2222

23-
let hostname = opts.space || process.env.BACKLOG_SPACE;
23+
let hostname = opts.space;
2424
if (!hostname) {
2525
if (config.spaces.length === 0) {
2626
consola.info("No spaces are currently authenticated.");

apps/cli/src/commands/auth/refresh.test.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { refreshAccessToken } from "@repo/backlog-utils";
2-
import { resolveSpace, updateSpaceAuth } from "@repo/config";
2+
import { findSpace, loadConfig, updateSpaceAuth } from "@repo/config";
33
import { Backlog } from "backlog-js";
44
import consola from "consola";
55
import { describe, expect, it, vi } from "vitest";
@@ -19,15 +19,22 @@ vi.mock("@repo/backlog-utils", () => ({
1919
vi.mock("@repo/config", () => ({
2020
findSpace: vi.fn(),
2121
loadConfig: vi.fn(),
22-
resolveSpace: vi.fn(),
2322
updateSpaceAuth: vi.fn(),
2423
}));
2524

2625
vi.mock("consola", () => import("@repo/test-utils/mock-consola"));
2726

27+
const mockDefaultSpace = (space: ReturnType<typeof findSpace>) => {
28+
vi.mocked(loadConfig).mockReturnValue({
29+
spaces: space ? [space] : [],
30+
defaultSpace: space?.host,
31+
});
32+
vi.mocked(findSpace).mockReturnValue(space);
33+
};
34+
2835
describe("auth refresh", () => {
2936
it("throws error when no space is configured", async () => {
30-
vi.mocked(resolveSpace).mockReturnValue(null);
37+
mockDefaultSpace(null);
3138

3239
const { default: refresh } = await import("./refresh");
3340
await expect(refresh.parseAsync([], { from: "user" })).rejects.toThrow(
@@ -36,7 +43,7 @@ describe("auth refresh", () => {
3643
});
3744

3845
it("shows error for API key authentication", async () => {
39-
vi.mocked(resolveSpace).mockReturnValue({
46+
mockDefaultSpace({
4047
host: "example.backlog.com",
4148
auth: { method: "api-key" as const, apiKey: "key" },
4249
});
@@ -48,7 +55,7 @@ describe("auth refresh", () => {
4855
});
4956

5057
it("shows error when clientId/clientSecret are missing", async () => {
51-
vi.mocked(resolveSpace).mockReturnValue({
58+
mockDefaultSpace({
5259
host: "example.backlog.com",
5360
auth: {
5461
method: "oauth" as const,
@@ -64,7 +71,7 @@ describe("auth refresh", () => {
6471
});
6572

6673
it("successfully refreshes token", async () => {
67-
vi.mocked(resolveSpace).mockReturnValue({
74+
mockDefaultSpace({
6875
host: "example.backlog.com",
6976
auth: {
7077
method: "oauth" as const,
@@ -108,7 +115,7 @@ describe("auth refresh", () => {
108115
});
109116

110117
it("shows error on refresh failure", async () => {
111-
vi.mocked(resolveSpace).mockReturnValue({
118+
mockDefaultSpace({
112119
host: "example.backlog.com",
113120
auth: {
114121
method: "oauth" as const,
@@ -127,7 +134,7 @@ describe("auth refresh", () => {
127134
});
128135

129136
it("shows error when token verification fails after refresh", async () => {
130-
vi.mocked(resolveSpace).mockReturnValue({
137+
mockDefaultSpace({
131138
host: "example.backlog.com",
132139
auth: {
133140
method: "oauth" as const,

apps/cli/src/commands/auth/refresh.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { refreshAccessToken } from "@repo/backlog-utils";
22
import { UserError } from "@repo/cli-utils";
3-
import { findSpace, loadConfig, resolveSpace, updateSpaceAuth } from "@repo/config";
3+
import { findSpace, loadConfig, updateSpaceAuth } from "@repo/config";
44
import { Backlog } from "backlog-js";
55
import consola from "consola";
66
import { BeeCommand } from "../../lib/bee-command";
7+
import * as opt from "../../lib/common-options";
78

89
const refresh = new BeeCommand("refresh")
910
.summary("Refresh OAuth token")
1011
.description(
1112
`Only available for spaces authenticated with OAuth. If the refresh token is expired, re-authenticate with \`bee auth login -m oauth\`.`,
1213
)
13-
.option("-s, --space <hostname>", "The hostname of the Backlog space")
14-
.envVars([["BACKLOG_SPACE", "Default space hostname"]])
14+
.addOption(opt.space())
1515
.examples([
1616
{ description: "Refresh token for default space", command: "bee auth refresh" },
1717
{
@@ -20,7 +20,9 @@ const refresh = new BeeCommand("refresh")
2020
},
2121
])
2222
.action(async (opts) => {
23-
const space = opts.space ? findSpace(loadConfig().spaces, opts.space) : resolveSpace();
23+
const config = loadConfig();
24+
const host = opts.space ?? config.defaultSpace;
25+
const space = host ? findSpace(config.spaces, host) : null;
2426

2527
if (!space) {
2628
throw new UserError("No space configured. Run `bee auth login` to authenticate.");

apps/cli/src/commands/auth/status.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { type Entity, Backlog } from "backlog-js";
33
import consola from "consola";
44
import { printDefinitionList } from "@repo/cli-utils";
55
import { BeeCommand } from "../../lib/bee-command";
6+
import * as opt from "../../lib/common-options";
67

78
const getToken = (auth: RcAuth): string =>
89
auth.method === "api-key" ? auth.apiKey : auth.accessToken;
@@ -12,9 +13,8 @@ const status = new BeeCommand("status")
1213
.description(
1314
`Verifies credential validity for each configured space via the Backlog API. The active (default) space is indicated.`,
1415
)
15-
.option("-s, --space <hostname>", "The hostname of the Backlog space")
16+
.addOption(opt.space())
1617
.option("--show-token", "Display the auth token")
17-
.envVars([["BACKLOG_SPACE", "Filter by space hostname"]])
1818
.examples([
1919
{ description: "Display status for all spaces", command: "bee auth status" },
2020
{
@@ -26,7 +26,7 @@ const status = new BeeCommand("status")
2626
.action(async (opts) => {
2727
const config = loadConfig();
2828

29-
const filterSpace = opts.space || process.env.BACKLOG_SPACE;
29+
const filterSpace = opts.space;
3030
const spaces = filterSpace
3131
? config.spaces.filter((s) => s.host === filterSpace)
3232
: config.spaces;

apps/cli/src/commands/auth/switch.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { UserError } from "@repo/cli-utils";
22
import { loadConfig, writeConfig } from "@repo/config";
33
import consola from "consola";
44
import { BeeCommand } from "../../lib/bee-command";
5+
import * as opt from "../../lib/common-options";
56

67
const switchSpace = new BeeCommand("switch")
78
.summary("Switch active space")
89
.description(`Changes which space is used by default when \`--space\` is not provided.`)
9-
.option("-s, --space <hostname>", "The hostname of the Backlog space")
10-
.envVars([["BACKLOG_SPACE", "Space hostname to switch to"]])
10+
.addOption(opt.space())
1111
.examples([
1212
{ description: "Select space via prompt", command: "bee auth switch" },
1313
{
@@ -18,7 +18,7 @@ const switchSpace = new BeeCommand("switch")
1818
.action(async (opts) => {
1919
const config = loadConfig();
2020

21-
let hostname = opts.space || process.env.BACKLOG_SPACE;
21+
let hostname = opts.space;
2222

2323
if (!hostname) {
2424
if (config.spaces.length === 0) {

apps/cli/src/commands/auth/token.test.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
import { resolveSpace } from "@repo/config";
1+
import { findSpace, loadConfig } from "@repo/config";
22
import { describe, expect, it, vi } from "vitest";
33

44
vi.mock("@repo/config", () => ({
55
findSpace: vi.fn(),
66
loadConfig: vi.fn(),
7-
resolveSpace: vi.fn(),
87
}));
98

109
describe("auth token", () => {
1110
it("outputs API key to stdout", async () => {
12-
vi.mocked(resolveSpace).mockReturnValue({
11+
vi.mocked(loadConfig).mockReturnValue({
12+
spaces: [{ host: "example.backlog.com", auth: { method: "api-key", apiKey: "my-api-key" } }],
13+
defaultSpace: "example.backlog.com",
14+
});
15+
vi.mocked(findSpace).mockReturnValue({
1316
host: "example.backlog.com",
1417
auth: { method: "api-key", apiKey: "my-api-key" },
1518
});
@@ -26,7 +29,20 @@ describe("auth token", () => {
2629
});
2730

2831
it("outputs OAuth token to stdout", async () => {
29-
vi.mocked(resolveSpace).mockReturnValue({
32+
vi.mocked(loadConfig).mockReturnValue({
33+
spaces: [
34+
{
35+
host: "example.backlog.com",
36+
auth: {
37+
method: "oauth",
38+
accessToken: "my-access-token",
39+
refreshToken: "my-refresh-token",
40+
},
41+
},
42+
],
43+
defaultSpace: "example.backlog.com",
44+
});
45+
vi.mocked(findSpace).mockReturnValue({
3046
host: "example.backlog.com",
3147
auth: { method: "oauth", accessToken: "my-access-token", refreshToken: "my-refresh-token" },
3248
});
@@ -43,7 +59,11 @@ describe("auth token", () => {
4359
});
4460

4561
it("throws error when no space is configured", async () => {
46-
vi.mocked(resolveSpace).mockReturnValue(null);
62+
vi.mocked(loadConfig).mockReturnValue({
63+
spaces: [],
64+
defaultSpace: undefined,
65+
});
66+
vi.mocked(findSpace).mockReturnValue(null);
4767

4868
const { default: token } = await import("./token");
4969
await expect(token.parseAsync([], { from: "user" })).rejects.toThrow(

apps/cli/src/commands/auth/token.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { UserError } from "@repo/cli-utils";
2-
import { findSpace, loadConfig, resolveSpace } from "@repo/config";
2+
import { findSpace, loadConfig } from "@repo/config";
33
import { BeeCommand } from "../../lib/bee-command";
4+
import * as opt from "../../lib/common-options";
45

56
const tokenCommand = new BeeCommand("token")
67
.summary("Print the auth token to stdout")
78
.description(
89
`Prints the token for the default space, or the space given by \`--space\`. Useful for piping to other commands.`,
910
)
10-
.option("-s, --space <hostname>", "The hostname of the Backlog space")
11-
.envVars([["BACKLOG_SPACE", "Default space hostname"]])
11+
.addOption(opt.space())
1212
.examples([
1313
{ description: "Print token for default space", command: "bee auth token" },
1414
{
@@ -22,7 +22,9 @@ const tokenCommand = new BeeCommand("token")
2222
},
2323
])
2424
.action((opts) => {
25-
const space = opts.space ? findSpace(loadConfig().spaces, opts.space) : resolveSpace();
25+
const config = loadConfig();
26+
const host = opts.space ?? config.defaultSpace;
27+
const space = host ? findSpace(config.spaces, host) : null;
2628

2729
if (!space) {
2830
throw new UserError("No space configured. Run `bee auth login` to authenticate.");

0 commit comments

Comments
 (0)