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:
@@ -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`.
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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',
|
||||
{}
|
||||
|
||||
@@ -478,7 +478,7 @@ const appPlugin: OverridableFrontendPlugin<
|
||||
icons: ExtensionInput<
|
||||
ConfigurableExtensionDataRef<
|
||||
{
|
||||
[x: string]: IconComponent | IconElement;
|
||||
[x: string]: IconElement | IconComponent;
|
||||
},
|
||||
'core.icons',
|
||||
{}
|
||||
|
||||
Reference in New Issue
Block a user