From 283259ee394d245a1b72f2f176c4ec375a60b861 Mon Sep 17 00:00:00 2001 From: Rafael Thayto Tani Date: Mon, 22 Jun 2026 16:23:57 -0300 Subject: [PATCH] refactor(api): move bapiRequest into lib/bapi.ts Mirror the fapiRequest relocation: the BAPI passthrough wrapper now lives in lib/bapi.ts as a sibling to lib/fapi.ts, so both API clients sit in the leaf layer instead of one being a command module. Updates all importers and the relocated bapi test; no behavior change. Claude-Session: https://claude.ai/code/session_01QnfBw9qY7u19BvUWyfQGC6 --- .changeset/free-breads-pick.md | 2 ++ .claude/rules/errors.md | 2 +- packages/cli-core/src/commands/api/index.ts | 2 +- packages/cli-core/src/commands/users/create.test.ts | 2 +- packages/cli-core/src/commands/users/create.ts | 2 +- .../src/commands/users/interactive/pick-user.test.ts | 2 +- .../src/commands/users/interactive/pick-user.ts | 2 +- .../cli-core/src/commands/users/lifecycle-runner.ts | 2 +- packages/cli-core/src/commands/users/list.test.ts | 2 +- packages/cli-core/src/commands/users/list.ts | 2 +- .../cli-core/src/{commands/api => lib}/bapi.test.ts | 4 ++-- packages/cli-core/src/{commands/api => lib}/bapi.ts | 10 +++++----- packages/cli-core/src/lib/errors.ts | 2 +- 13 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 .changeset/free-breads-pick.md rename packages/cli-core/src/{commands/api => lib}/bapi.test.ts (98%) rename packages/cli-core/src/{commands/api => lib}/bapi.ts (77%) diff --git a/.changeset/free-breads-pick.md b/.changeset/free-breads-pick.md new file mode 100644 index 00000000..a845151c --- /dev/null +++ b/.changeset/free-breads-pick.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.claude/rules/errors.md b/.claude/rules/errors.md index 336acdb7..bfcc06b1 100644 --- a/.claude/rules/errors.md +++ b/.claude/rules/errors.md @@ -61,4 +61,4 @@ const config = await withApiContext( ## API error classes -`BapiError` and `PlapiError` (both extend `ApiError`) are thrown by the API helpers in `src/commands/api/bapi.ts` and `src/lib/plapi.ts` respectively. Don't construct these in commands — they're thrown automatically by the fetch wrappers. Use `withApiContext` to add context when calling those helpers. +`BapiError` and `PlapiError` (both extend `ApiError`) are thrown by the API helpers in `src/lib/bapi.ts` and `src/lib/plapi.ts` respectively. Don't construct these in commands — they're thrown automatically by the fetch wrappers. Use `withApiContext` to add context when calling those helpers. diff --git a/packages/cli-core/src/commands/api/index.ts b/packages/cli-core/src/commands/api/index.ts index 37395273..6a8331bc 100644 --- a/packages/cli-core/src/commands/api/index.ts +++ b/packages/cli-core/src/commands/api/index.ts @@ -3,7 +3,7 @@ import { getAuthToken } from "../../lib/plapi.ts"; import { getBapiBaseUrl, getPlapiBaseUrl } from "../../lib/environment.ts"; import { normalizeBapiPath, resolveBapiSecretKey } from "../../lib/bapi-command.ts"; import { type ApiResponse } from "../../lib/fetch.ts"; -import { bapiRequest } from "./bapi.ts"; +import { bapiRequest } from "../../lib/bapi.ts"; import { fapiRequest } from "../../lib/fapi.ts"; import { resolveFapiHost } from "./fapi.ts"; import { diff --git a/packages/cli-core/src/commands/users/create.test.ts b/packages/cli-core/src/commands/users/create.test.ts index bcfcf857..7e670706 100644 --- a/packages/cli-core/src/commands/users/create.test.ts +++ b/packages/cli-core/src/commands/users/create.test.ts @@ -10,7 +10,7 @@ mock.module("../../lib/bapi-command.ts", () => ({ })); const mockBapiRequest = mock(); -mock.module("../../commands/api/bapi.ts", () => ({ +mock.module("../../lib/bapi.ts", () => ({ bapiRequest: (...args: unknown[]) => mockBapiRequest(...args), })); diff --git a/packages/cli-core/src/commands/users/create.ts b/packages/cli-core/src/commands/users/create.ts index ddbcefa1..e8540c88 100644 --- a/packages/cli-core/src/commands/users/create.ts +++ b/packages/cli-core/src/commands/users/create.ts @@ -9,7 +9,7 @@ import { redactUsersDisplayPayload, } from "../../lib/users.ts"; import { isAgent, isHuman } from "../../mode.ts"; -import { bapiRequest } from "../api/bapi.ts"; +import { bapiRequest } from "../../lib/bapi.ts"; import { withSpinner, intro, outro, pausedOutro } from "../../lib/spinner.ts"; import { handleUsersBapiError, printUsersMutationResult } from "./output.ts"; import { registerUsersAction } from "./registry.ts"; diff --git a/packages/cli-core/src/commands/users/interactive/pick-user.test.ts b/packages/cli-core/src/commands/users/interactive/pick-user.test.ts index 9d9ebfa5..634cccd2 100644 --- a/packages/cli-core/src/commands/users/interactive/pick-user.test.ts +++ b/packages/cli-core/src/commands/users/interactive/pick-user.test.ts @@ -3,7 +3,7 @@ import { test, expect, describe, beforeEach, mock } from "bun:test"; const mockBapiRequest = mock(); const mockSearch = mock(); -mock.module("../../api/bapi.ts", () => ({ +mock.module("../../../lib/bapi.ts", () => ({ bapiRequest: (...args: unknown[]) => mockBapiRequest(...args), })); mock.module("../../../lib/listage.ts", () => ({ diff --git a/packages/cli-core/src/commands/users/interactive/pick-user.ts b/packages/cli-core/src/commands/users/interactive/pick-user.ts index 1e4329ec..6aeedfe1 100644 --- a/packages/cli-core/src/commands/users/interactive/pick-user.ts +++ b/packages/cli-core/src/commands/users/interactive/pick-user.ts @@ -1,5 +1,5 @@ import { search, Separator } from "../../../lib/listage.ts"; -import { bapiRequest } from "../../api/bapi.ts"; +import { bapiRequest } from "../../../lib/bapi.ts"; export type PickUserOptions = { secretKey: string; diff --git a/packages/cli-core/src/commands/users/lifecycle-runner.ts b/packages/cli-core/src/commands/users/lifecycle-runner.ts index 8894def2..10cd3e4f 100644 --- a/packages/cli-core/src/commands/users/lifecycle-runner.ts +++ b/packages/cli-core/src/commands/users/lifecycle-runner.ts @@ -9,7 +9,7 @@ import { log } from "../../lib/log.ts"; import { confirm } from "../../lib/prompts.ts"; import { withSpinner } from "../../lib/spinner.ts"; import { isHuman } from "../../mode.ts"; -import { bapiRequest } from "../api/bapi.ts"; +import { bapiRequest } from "../../lib/bapi.ts"; import { handleUsersBapiError, printUsersMutationSuccess } from "./output.ts"; export type UserLifecycleOptions = { diff --git a/packages/cli-core/src/commands/users/list.test.ts b/packages/cli-core/src/commands/users/list.test.ts index 0f8a9699..36ef337f 100644 --- a/packages/cli-core/src/commands/users/list.test.ts +++ b/packages/cli-core/src/commands/users/list.test.ts @@ -4,7 +4,7 @@ import { popPrefix, pushPrefix } from "../../lib/log.ts"; import { useCaptureLog } from "../../test/lib/stubs.ts"; const mockBapiRequest = mock(); -mock.module("../../commands/api/bapi.ts", () => ({ +mock.module("../../lib/bapi.ts", () => ({ bapiRequest: (...args: unknown[]) => mockBapiRequest(...args), })); diff --git a/packages/cli-core/src/commands/users/list.ts b/packages/cli-core/src/commands/users/list.ts index c52eadc8..8f3b56a0 100644 --- a/packages/cli-core/src/commands/users/list.ts +++ b/packages/cli-core/src/commands/users/list.ts @@ -4,7 +4,7 @@ import { CliError, ERROR_CODE, UserAbortError, isPromptExitError } from "../../l import { isInsideGutter, log } from "../../lib/log.ts"; import { isAgent, isHuman } from "../../mode.ts"; import { withSpinner, intro, outro, pausedOutro } from "../../lib/spinner.ts"; -import { bapiRequest } from "../api/bapi.ts"; +import { bapiRequest } from "../../lib/bapi.ts"; import { resolveUsersInstanceContext } from "./interactive/instance-context.ts"; import { registerUsersAction } from "./registry.ts"; diff --git a/packages/cli-core/src/commands/api/bapi.test.ts b/packages/cli-core/src/lib/bapi.test.ts similarity index 98% rename from packages/cli-core/src/commands/api/bapi.test.ts rename to packages/cli-core/src/lib/bapi.test.ts index 0500d702..5cd0c65c 100644 --- a/packages/cli-core/src/commands/api/bapi.test.ts +++ b/packages/cli-core/src/lib/bapi.test.ts @@ -1,7 +1,7 @@ import { test, expect, describe, beforeEach, afterEach } from "bun:test"; -import { stubFetch } from "../../test/lib/stubs.ts"; +import { stubFetch } from "../test/lib/stubs.ts"; import { bapiRequest } from "./bapi.ts"; -import { BapiError } from "../../lib/errors.ts"; +import { BapiError } from "./errors.ts"; describe("bapi", () => { const originalFetch = globalThis.fetch; diff --git a/packages/cli-core/src/commands/api/bapi.ts b/packages/cli-core/src/lib/bapi.ts similarity index 77% rename from packages/cli-core/src/commands/api/bapi.ts rename to packages/cli-core/src/lib/bapi.ts index d3d79495..e19fc2f3 100644 --- a/packages/cli-core/src/commands/api/bapi.ts +++ b/packages/cli-core/src/lib/bapi.ts @@ -1,12 +1,12 @@ /** * Backend API (BAPI) client. - * Thin HTTP wrapper for Clerk's Backend API endpoints. + * Thin HTTP wrapper for Clerk's Backend API endpoints. Sibling to lib/fapi.ts. */ -import { getBapiBaseUrl } from "../../lib/environment.ts"; -import { normalizeBapiPath } from "../../lib/bapi-command.ts"; -import { BapiError } from "../../lib/errors.ts"; -import { loggedFetch, type ApiResponse } from "../../lib/fetch.ts"; +import { getBapiBaseUrl } from "./environment.ts"; +import { normalizeBapiPath } from "./bapi-command.ts"; +import { BapiError } from "./errors.ts"; +import { loggedFetch, type ApiResponse } from "./fetch.ts"; export async function bapiRequest(options: { method: string; diff --git a/packages/cli-core/src/lib/errors.ts b/packages/cli-core/src/lib/errors.ts index f2f1d8aa..bff5a8cf 100644 --- a/packages/cli-core/src/lib/errors.ts +++ b/packages/cli-core/src/lib/errors.ts @@ -333,7 +333,7 @@ export class FapiError extends ApiError { /** * Error from the Clerk Backend API (BAPI). * - * Thrown by `src/commands/api/bapi.ts` when a Backend API request fails. + * Thrown by `src/lib/bapi.ts` when a Backend API request fails. * Displayed as "Backend API request failed" in the global error handler. * Unlike {@link PlapiError}, `headers` is always present (required). *