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 <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-03-17 16:26:49 +01:00
parent 3c6de38345
commit da8e6603a4
19 changed files with 81 additions and 102 deletions
@@ -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`.
@@ -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`.
+1 -1
View File
@@ -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.
+1
View File
@@ -35,6 +35,7 @@
"dependencies": {
"@backstage/cli-module-auth": "workspace:^",
"@backstage/cli-node": "workspace:^",
"@backstage/errors": "workspace:^",
"cleye": "^2.3.0"
},
"devDependencies": {
@@ -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<typeof httpJson>;
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { httpJson } from '@backstage/cli-node';
import { httpJson } from './httpJson';
export type ActionDef = {
id: string;
@@ -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<string, string>;
method?: string;
body?: any;
signal?: AbortSignal;
};
export async function httpJson<T>(url: string, init?: HttpInit): Promise<T> {
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;
}
-34
View File
@@ -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<T = unknown>(
instanceName: string,
key: string,
): Promise<T | undefined>;
// @public (undocumented)
export function getSecretStore(): Promise<SecretStore>;
// @public @deprecated (undocumented)
export function getSelectedInstance(
instanceName?: string,
): Promise<StoredInstance>;
export { HttpInit };
export { httpJson };
// @public @deprecated (undocumented)
export function refreshAccessToken(
instanceName: string,
): Promise<StoredInstance>;
export { SecretStore };
export { StoredInstance };
// @public (undocumented)
export function updateInstanceConfig(
instanceName: string,
@@ -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 {
+1 -13
View File
@@ -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';
-2
View File
@@ -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<StoredInstance> {
+23 -1
View File
@@ -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<string, string>;
method?: string;
body?: any;
signal?: AbortSignal;
};
export async function httpJson<T>(url: string, init?: HttpInit): Promise<T> {
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;
}
@@ -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<string | undefined>;
set(service: string, account: string, secret: string): Promise<void>;
delete(service: string, account: string): Promise<void>;
};
async function loadKeytar(): Promise<typeof import('keytar') | undefined> {
try {
@@ -86,7 +89,6 @@ class FileSecretStore implements SecretStore {
let singleton: SecretStore | undefined;
/** @public */
export async function getSecretStore(): Promise<SecretStore> {
if (!singleton) {
const keytar = await loadKeytar();
@@ -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<StoredInstance> {
@@ -162,7 +161,6 @@ export async function setSelectedInstance(name: string): Promise<void> {
});
}
/** @public @deprecated Use {@link @backstage/cli-node#CliAuth.getConfig} instead. */
export async function getInstanceConfig<T = unknown>(
instanceName: string,
key: string,
-21
View File
@@ -148,9 +148,6 @@ export function createCliModule(options: {
}) => Promise<void>;
}): CliModule;
// @public (undocumented)
export function getSecretStore(): Promise<SecretStore>;
// @public
export class GitUtils {
static listChangedFiles(ref: string): Promise<string[]>;
@@ -160,17 +157,6 @@ export class GitUtils {
// @public
export function hasBackstageYarnPlugin(workspaceDir?: string): Promise<boolean>;
// @public (undocumented)
export type HttpInit = {
headers?: Record<string, string>;
method?: string;
body?: any;
signal?: AbortSignal;
};
// @public (undocumented)
export function httpJson<T>(url: string, init?: HttpInit): Promise<T>;
// @public
export function isMonoRepo(): Promise<boolean>;
@@ -301,13 +287,6 @@ export function runWorkerQueueThreads<TItem, TResult, TContext>(
results: TResult[];
}>;
// @public (undocumented)
export type SecretStore = {
get(service: string, account: string): Promise<string | undefined>;
set(service: string, account: string, secret: string): Promise<void>;
delete(service: string, account: string): Promise<void>;
};
// @public (undocumented)
export type StoredInstance = {
name: string;
-2
View File
@@ -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';
+2 -2
View File
@@ -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',
{}
+1 -1
View File
@@ -478,7 +478,7 @@ const appPlugin: OverridableFrontendPlugin<
icons: ExtensionInput<
ConfigurableExtensionDataRef<
{
[x: string]: IconComponent | IconElement;
[x: string]: IconElement | IconComponent;
},
'core.icons',
{}
+1
View File
@@ -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