From da8e6603a4319bb5229421dacbb10e2bae55ba4c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 17 Mar 2026 16:26:49 +0100 Subject: [PATCH] Clean up unreleased API surface Since cli-module-auth and cli-module-actions are not yet released, remove deprecated exports instead of keeping them. Also make httpJson and getSecretStore internal to cli-node, duplicating the small httpJson wrapper locally in each consuming package. Signed-off-by: Patrik Oldsberg Made-with: Cursor --- .changeset/cli-module-actions-use-cli-auth.md | 5 --- .../cli-module-auth-deprecate-exports.md | 5 --- .changeset/cli-node-auth-api.md | 2 +- packages/cli-module-actions/package.json | 1 + .../src/lib/ActionsClient.test.ts | 12 ++---- .../src/lib/ActionsClient.ts | 2 +- .../cli-module-actions/src/lib/httpJson.ts | 39 +++++++++++++++++++ packages/cli-module-auth/report.api.md | 34 ---------------- packages/cli-module-auth/src/commands/show.ts | 3 +- packages/cli-module-auth/src/index.ts | 14 +------ packages/cli-module-auth/src/lib/auth.ts | 2 - packages/cli-module-auth/src/lib/http.ts | 24 +++++++++++- .../cli-module-auth/src/lib/secretStore.ts | 8 ++-- packages/cli-module-auth/src/lib/storage.ts | 2 - packages/cli-node/report.api.md | 21 ---------- packages/cli-node/src/auth/index.ts | 2 - plugins/app-react/report.api.md | 4 +- plugins/app/report.api.md | 2 +- yarn.lock | 1 + 19 files changed, 81 insertions(+), 102 deletions(-) delete mode 100644 .changeset/cli-module-actions-use-cli-auth.md delete mode 100644 .changeset/cli-module-auth-deprecate-exports.md create mode 100644 packages/cli-module-actions/src/lib/httpJson.ts diff --git a/.changeset/cli-module-actions-use-cli-auth.md b/.changeset/cli-module-actions-use-cli-auth.md deleted file mode 100644 index 705ebac220..0000000000 --- a/.changeset/cli-module-actions-use-cli-auth.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli-module-actions': patch ---- - -Migrated to use `CliAuth` from `@backstage/cli-node` for authentication instead of importing individual functions from `@backstage/cli-module-auth`. diff --git a/.changeset/cli-module-auth-deprecate-exports.md b/.changeset/cli-module-auth-deprecate-exports.md deleted file mode 100644 index 5a8c79feef..0000000000 --- a/.changeset/cli-module-auth-deprecate-exports.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli-module-auth': patch ---- - -Deprecated `getSelectedInstance`, `getInstanceConfig`, `accessTokenNeedsRefresh`, `refreshAccessToken`, `getSecretStore`, and `httpJson` exports in favor of the new `CliAuth` class and shared utilities from `@backstage/cli-node`. diff --git a/.changeset/cli-node-auth-api.md b/.changeset/cli-node-auth-api.md index bed9681178..c28a2e29c8 100644 --- a/.changeset/cli-node-auth-api.md +++ b/.changeset/cli-node-auth-api.md @@ -2,4 +2,4 @@ '@backstage/cli-node': minor --- -Added `CliAuth` class for managing CLI authentication state. This provides a class-based API with a static `create` method that resolves the currently selected (or explicitly named) auth instance, transparently refreshes expired access tokens, and exposes helpers for other CLI modules to authenticate with a Backstage backend. Also added `httpJson`, `getSecretStore`, `SecretStore`, `StoredInstance`, and `HttpInit` exports. +Added `CliAuth` class for managing CLI authentication state. This provides a class-based API with a static `create` method that resolves the currently selected (or explicitly named) auth instance, transparently refreshes expired access tokens, and exposes helpers for other CLI modules to authenticate with a Backstage backend. diff --git a/packages/cli-module-actions/package.json b/packages/cli-module-actions/package.json index fe19a8a90d..c177e91fc4 100644 --- a/packages/cli-module-actions/package.json +++ b/packages/cli-module-actions/package.json @@ -35,6 +35,7 @@ "dependencies": { "@backstage/cli-module-auth": "workspace:^", "@backstage/cli-node": "workspace:^", + "@backstage/errors": "workspace:^", "cleye": "^2.3.0" }, "devDependencies": { diff --git a/packages/cli-module-actions/src/lib/ActionsClient.test.ts b/packages/cli-module-actions/src/lib/ActionsClient.test.ts index ecf7861f26..3aa2e06dc7 100644 --- a/packages/cli-module-actions/src/lib/ActionsClient.test.ts +++ b/packages/cli-module-actions/src/lib/ActionsClient.test.ts @@ -15,15 +15,11 @@ */ import { ActionsClient } from './ActionsClient'; -import { httpJson } from '@backstage/cli-node'; +import { httpJson } from './httpJson'; -jest.mock('@backstage/cli-node', () => { - const actual = jest.requireActual('@backstage/cli-node'); - return { - ...actual, - httpJson: jest.fn(), - }; -}); +jest.mock('./httpJson', () => ({ + httpJson: jest.fn(), +})); const mockHttpJson = httpJson as jest.MockedFunction; diff --git a/packages/cli-module-actions/src/lib/ActionsClient.ts b/packages/cli-module-actions/src/lib/ActionsClient.ts index f7d284ad1a..736a3b7f37 100644 --- a/packages/cli-module-actions/src/lib/ActionsClient.ts +++ b/packages/cli-module-actions/src/lib/ActionsClient.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { httpJson } from '@backstage/cli-node'; +import { httpJson } from './httpJson'; export type ActionDef = { id: string; diff --git a/packages/cli-module-actions/src/lib/httpJson.ts b/packages/cli-module-actions/src/lib/httpJson.ts new file mode 100644 index 0000000000..0bea9dab94 --- /dev/null +++ b/packages/cli-module-actions/src/lib/httpJson.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ResponseError } from '@backstage/errors'; + +type HttpInit = { + headers?: Record; + method?: string; + body?: any; + signal?: AbortSignal; +}; + +export async function httpJson(url: string, init?: HttpInit): Promise { + const res = await fetch(url, { + ...init, + body: init?.body ? JSON.stringify(init.body) : undefined, + headers: { + ...(init?.body ? { 'Content-Type': 'application/json' } : {}), + ...init?.headers, + }, + }); + if (!res.ok) { + throw await ResponseError.fromResponse(res); + } + return (await res.json()) as T; +} diff --git a/packages/cli-module-auth/report.api.md b/packages/cli-module-auth/report.api.md index 91191153c8..67fb636baa 100644 --- a/packages/cli-module-auth/report.api.md +++ b/packages/cli-module-auth/report.api.md @@ -4,45 +4,11 @@ ```ts import { CliModule } from '@backstage/cli-node'; -import { HttpInit } from '@backstage/cli-node'; -import { httpJson } from '@backstage/cli-node'; -import { SecretStore } from '@backstage/cli-node'; -import { StoredInstance } from '@backstage/cli-node'; - -// @public @deprecated (undocumented) -export function accessTokenNeedsRefresh(instance: StoredInstance): boolean; // @public (undocumented) const _default: CliModule; export default _default; -// @public @deprecated (undocumented) -export function getInstanceConfig( - instanceName: string, - key: string, -): Promise; - -// @public (undocumented) -export function getSecretStore(): Promise; - -// @public @deprecated (undocumented) -export function getSelectedInstance( - instanceName?: string, -): Promise; - -export { HttpInit }; - -export { httpJson }; - -// @public @deprecated (undocumented) -export function refreshAccessToken( - instanceName: string, -): Promise; - -export { SecretStore }; - -export { StoredInstance }; - // @public (undocumented) export function updateInstanceConfig( instanceName: string, diff --git a/packages/cli-module-auth/src/commands/show.ts b/packages/cli-module-auth/src/commands/show.ts index f9a3f4eb90..6a5db7f299 100644 --- a/packages/cli-module-auth/src/commands/show.ts +++ b/packages/cli-module-auth/src/commands/show.ts @@ -15,7 +15,8 @@ */ import { cli } from 'cleye'; -import { CliAuth, httpJson, type CliCommandContext } from '@backstage/cli-node'; +import { CliAuth, type CliCommandContext } from '@backstage/cli-node'; +import { httpJson } from '../lib/http'; export default async ({ args, info }: CliCommandContext) => { const { diff --git a/packages/cli-module-auth/src/index.ts b/packages/cli-module-auth/src/index.ts index a8079932d4..6fef1aea2b 100644 --- a/packages/cli-module-auth/src/index.ts +++ b/packages/cli-module-auth/src/index.ts @@ -53,16 +53,4 @@ export default createCliModule({ }, }); -/** @public @deprecated Use {@link @backstage/cli-node#CliAuth} instead. */ -export { - getSelectedInstance, - getInstanceConfig, - updateInstanceConfig, - type StoredInstance, -} from './lib/storage'; -/** @public @deprecated Use {@link @backstage/cli-node#CliAuth} instead. */ -export { accessTokenNeedsRefresh, refreshAccessToken } from './lib/auth'; -/** @public @deprecated Import from {@link @backstage/cli-node} instead. */ -export { getSecretStore, type SecretStore } from './lib/secretStore'; -/** @public @deprecated Import from {@link @backstage/cli-node} instead. */ -export { httpJson, type HttpInit } from './lib/http'; +export { updateInstanceConfig } from './lib/storage'; diff --git a/packages/cli-module-auth/src/lib/auth.ts b/packages/cli-module-auth/src/lib/auth.ts index d53aad6cb2..4b330cf982 100644 --- a/packages/cli-module-auth/src/lib/auth.ts +++ b/packages/cli-module-auth/src/lib/auth.ts @@ -27,13 +27,11 @@ const TokenResponseSchema = z.object({ refresh_token: z.string().min(1).optional(), }); -/** @public @deprecated Use {@link @backstage/cli-node#CliAuth} instead. */ export function accessTokenNeedsRefresh(instance: StoredInstance): boolean { // 2 minutes before expiration return instance.accessTokenExpiresAt <= Date.now() + 2 * 60_000; } -/** @public @deprecated Use {@link @backstage/cli-node#CliAuth} instead. */ export async function refreshAccessToken( instanceName: string, ): Promise { diff --git a/packages/cli-module-auth/src/lib/http.ts b/packages/cli-module-auth/src/lib/http.ts index df0704fcf4..4daaf823fb 100644 --- a/packages/cli-module-auth/src/lib/http.ts +++ b/packages/cli-module-auth/src/lib/http.ts @@ -14,4 +14,26 @@ * limitations under the License. */ -export { httpJson, type HttpInit } from '@backstage/cli-node'; +import { ResponseError } from '@backstage/errors'; + +export type HttpInit = { + headers?: Record; + method?: string; + body?: any; + signal?: AbortSignal; +}; + +export async function httpJson(url: string, init?: HttpInit): Promise { + const res = await fetch(url, { + ...init, + body: init?.body ? JSON.stringify(init.body) : undefined, + headers: { + ...(init?.body ? { 'Content-Type': 'application/json' } : {}), + ...init?.headers, + }, + }); + if (!res.ok) { + throw await ResponseError.fromResponse(res); + } + return (await res.json()) as T; +} diff --git a/packages/cli-module-auth/src/lib/secretStore.ts b/packages/cli-module-auth/src/lib/secretStore.ts index f7aa5256ae..55fac878b7 100644 --- a/packages/cli-module-auth/src/lib/secretStore.ts +++ b/packages/cli-module-auth/src/lib/secretStore.ts @@ -18,8 +18,11 @@ import fs from 'fs-extra'; import os from 'node:os'; import path from 'node:path'; -export type { SecretStore } from '@backstage/cli-node'; -import type { SecretStore } from '@backstage/cli-node'; +type SecretStore = { + get(service: string, account: string): Promise; + set(service: string, account: string, secret: string): Promise; + delete(service: string, account: string): Promise; +}; async function loadKeytar(): Promise { try { @@ -86,7 +89,6 @@ class FileSecretStore implements SecretStore { let singleton: SecretStore | undefined; -/** @public */ export async function getSecretStore(): Promise { if (!singleton) { const keytar = await loadKeytar(); diff --git a/packages/cli-module-auth/src/lib/storage.ts b/packages/cli-module-auth/src/lib/storage.ts index b50b472157..d66d4fb04a 100644 --- a/packages/cli-module-auth/src/lib/storage.ts +++ b/packages/cli-module-auth/src/lib/storage.ts @@ -99,7 +99,6 @@ export async function getAllInstances(): Promise<{ }; } -/** @public @deprecated Use {@link @backstage/cli-node#CliAuth} instead. */ export async function getSelectedInstance( instanceName?: string, ): Promise { @@ -162,7 +161,6 @@ export async function setSelectedInstance(name: string): Promise { }); } -/** @public @deprecated Use {@link @backstage/cli-node#CliAuth.getConfig} instead. */ export async function getInstanceConfig( instanceName: string, key: string, diff --git a/packages/cli-node/report.api.md b/packages/cli-node/report.api.md index 5af6665789..eeeb92f5b3 100644 --- a/packages/cli-node/report.api.md +++ b/packages/cli-node/report.api.md @@ -148,9 +148,6 @@ export function createCliModule(options: { }) => Promise; }): CliModule; -// @public (undocumented) -export function getSecretStore(): Promise; - // @public export class GitUtils { static listChangedFiles(ref: string): Promise; @@ -160,17 +157,6 @@ export class GitUtils { // @public export function hasBackstageYarnPlugin(workspaceDir?: string): Promise; -// @public (undocumented) -export type HttpInit = { - headers?: Record; - method?: string; - body?: any; - signal?: AbortSignal; -}; - -// @public (undocumented) -export function httpJson(url: string, init?: HttpInit): Promise; - // @public export function isMonoRepo(): Promise; @@ -301,13 +287,6 @@ export function runWorkerQueueThreads( results: TResult[]; }>; -// @public (undocumented) -export type SecretStore = { - get(service: string, account: string): Promise; - set(service: string, account: string, secret: string): Promise; - delete(service: string, account: string): Promise; -}; - // @public (undocumented) export type StoredInstance = { name: string; diff --git a/packages/cli-node/src/auth/index.ts b/packages/cli-node/src/auth/index.ts index 8037f25714..c84c1742d7 100644 --- a/packages/cli-node/src/auth/index.ts +++ b/packages/cli-node/src/auth/index.ts @@ -16,5 +16,3 @@ export { CliAuth, type CliAuthCreateOptions } from './CliAuth'; export { type StoredInstance } from './storage'; -export { httpJson, type HttpInit } from './httpJson'; -export { getSecretStore, type SecretStore } from './secretStore'; diff --git a/plugins/app-react/report.api.md b/plugins/app-react/report.api.md index a4e63e254b..4e3fff6e42 100644 --- a/plugins/app-react/report.api.md +++ b/plugins/app-react/report.api.md @@ -86,7 +86,7 @@ export const IconBundleBlueprint: ExtensionBlueprint<{ }; output: ExtensionDataRef< { - [x: string]: IconComponent | IconElement; + [x: string]: IconElement | IconComponent; }, 'core.icons', {} @@ -97,7 +97,7 @@ export const IconBundleBlueprint: ExtensionBlueprint<{ dataRefs: { icons: ConfigurableExtensionDataRef< { - [x: string]: IconComponent | IconElement; + [x: string]: IconElement | IconComponent; }, 'core.icons', {} diff --git a/plugins/app/report.api.md b/plugins/app/report.api.md index 4c9b2a8ce4..baa3b714b0 100644 --- a/plugins/app/report.api.md +++ b/plugins/app/report.api.md @@ -478,7 +478,7 @@ const appPlugin: OverridableFrontendPlugin< icons: ExtensionInput< ConfigurableExtensionDataRef< { - [x: string]: IconComponent | IconElement; + [x: string]: IconElement | IconComponent; }, 'core.icons', {} diff --git a/yarn.lock b/yarn.lock index 2a8c8e7f02..3996199a39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2830,6 +2830,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/cli-module-auth": "workspace:^" "@backstage/cli-node": "workspace:^" + "@backstage/errors": "workspace:^" cleye: "npm:^2.3.0" bin: cli-module-actions: bin/backstage-cli-module-actions