Address second round of PR review feedback
- Replace getConfig<T> with getMetadata/setMetadata on CliAuth, removing the unsafe type parameter in favor of returning unknown - Move updateInstanceConfig from cli-module-auth public API to CliAuth.setMetadata, removing the cross-package dependency - Rename 'config' to 'metadata' in StoredInstance and storage schemas - Add zod validation at consumer sites (cli-module-actions) for type-safe metadata access - Fix zod imports to use zod/v3 for compatibility with zod v4 - Add proper-lockfile to cli-node for metadata write locking - Refactor cli-node storage from fs-extra to node:fs - Remove @backstage/cli-module-auth dependency from cli-module-actions Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -33,10 +33,10 @@
|
||||
"test": "backstage-cli package test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/cli-module-auth": "workspace:^",
|
||||
"@backstage/cli-node": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"cleye": "^2.3.0"
|
||||
"cleye": "^2.3.0",
|
||||
"zod": "^3.25.76 || ^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
import { cli } from 'cleye';
|
||||
import { CliAuth, type CliCommandContext } from '@backstage/cli-node';
|
||||
import { updateInstanceConfig } from '@backstage/cli-module-auth';
|
||||
import { z } from 'zod/v3';
|
||||
|
||||
const pluginSourcesSchema = z.array(z.string()).default([]);
|
||||
|
||||
export default async ({ args, info }: CliCommandContext) => {
|
||||
const parsed = cli(
|
||||
@@ -31,7 +33,9 @@ export default async ({ args, info }: CliCommandContext) => {
|
||||
const pluginId = parsed._[0];
|
||||
|
||||
const auth = await CliAuth.create();
|
||||
const existing = (await auth.getConfig<string[]>('pluginSources')) ?? [];
|
||||
const existing = pluginSourcesSchema.parse(
|
||||
await auth.getMetadata('pluginSources'),
|
||||
);
|
||||
|
||||
if (existing.includes(pluginId)) {
|
||||
process.stderr.write(
|
||||
@@ -40,10 +44,7 @@ export default async ({ args, info }: CliCommandContext) => {
|
||||
return;
|
||||
}
|
||||
|
||||
await updateInstanceConfig(auth.getInstanceName(), 'pluginSources', [
|
||||
...existing,
|
||||
pluginId,
|
||||
]);
|
||||
await auth.setMetadata('pluginSources', [...existing, pluginId]);
|
||||
|
||||
process.stdout.write(`Added plugin source "${pluginId}".\n`);
|
||||
};
|
||||
|
||||
@@ -16,12 +16,17 @@
|
||||
|
||||
import { cli } from 'cleye';
|
||||
import { CliAuth, type CliCommandContext } from '@backstage/cli-node';
|
||||
import { z } from 'zod/v3';
|
||||
|
||||
const pluginSourcesSchema = z.array(z.string()).default([]);
|
||||
|
||||
export default async ({ args, info }: CliCommandContext) => {
|
||||
cli({ help: info }, undefined, args);
|
||||
|
||||
const auth = await CliAuth.create();
|
||||
const sources = (await auth.getConfig<string[]>('pluginSources')) ?? [];
|
||||
const sources = pluginSourcesSchema.parse(
|
||||
await auth.getMetadata('pluginSources'),
|
||||
);
|
||||
|
||||
if (!sources.length) {
|
||||
process.stderr.write('No plugin sources configured.\n');
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
import { cli } from 'cleye';
|
||||
import { CliAuth, type CliCommandContext } from '@backstage/cli-node';
|
||||
import { updateInstanceConfig } from '@backstage/cli-module-auth';
|
||||
import { z } from 'zod/v3';
|
||||
|
||||
const pluginSourcesSchema = z.array(z.string()).default([]);
|
||||
|
||||
export default async ({ args, info }: CliCommandContext) => {
|
||||
const parsed = cli(
|
||||
@@ -31,15 +33,16 @@ export default async ({ args, info }: CliCommandContext) => {
|
||||
const pluginId = parsed._[0];
|
||||
|
||||
const auth = await CliAuth.create();
|
||||
const existing = (await auth.getConfig<string[]>('pluginSources')) ?? [];
|
||||
const existing = pluginSourcesSchema.parse(
|
||||
await auth.getMetadata('pluginSources'),
|
||||
);
|
||||
|
||||
if (!existing.includes(pluginId)) {
|
||||
process.stderr.write(`Plugin source "${pluginId}" is not configured.\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
await updateInstanceConfig(
|
||||
auth.getInstanceName(),
|
||||
await auth.setMetadata(
|
||||
'pluginSources',
|
||||
existing.filter(s => s !== pluginId),
|
||||
);
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('resolveAuth', () => {
|
||||
getInstanceName: jest.fn().mockReturnValue('production'),
|
||||
getBaseUrl: jest.fn().mockReturnValue('https://backstage.example.com'),
|
||||
getAccessToken: jest.fn().mockResolvedValue('test-access-token'),
|
||||
getConfig: jest.fn().mockResolvedValue(['catalog', 'scaffolder']),
|
||||
getMetadata: jest.fn().mockResolvedValue(['catalog', 'scaffolder']),
|
||||
} as unknown as CliAuth);
|
||||
|
||||
const result = await resolveAuth();
|
||||
@@ -56,7 +56,7 @@ describe('resolveAuth', () => {
|
||||
getInstanceName: jest.fn().mockReturnValue('staging'),
|
||||
getBaseUrl: jest.fn().mockReturnValue('https://staging.example.com'),
|
||||
getAccessToken: jest.fn().mockResolvedValue('test-access-token'),
|
||||
getConfig: jest.fn().mockResolvedValue([]),
|
||||
getMetadata: jest.fn().mockResolvedValue([]),
|
||||
} as unknown as CliAuth);
|
||||
|
||||
await resolveAuth('staging');
|
||||
@@ -73,7 +73,7 @@ describe('resolveAuth', () => {
|
||||
.mockRejectedValue(
|
||||
new Error('No access token found. Run "auth login" to authenticate.'),
|
||||
),
|
||||
getConfig: jest.fn().mockResolvedValue([]),
|
||||
getMetadata: jest.fn().mockResolvedValue([]),
|
||||
} as unknown as CliAuth);
|
||||
|
||||
await expect(resolveAuth()).rejects.toThrow(
|
||||
@@ -86,7 +86,7 @@ describe('resolveAuth', () => {
|
||||
getInstanceName: jest.fn().mockReturnValue('production'),
|
||||
getBaseUrl: jest.fn().mockReturnValue('https://backstage.example.com'),
|
||||
getAccessToken: jest.fn().mockResolvedValue('test-access-token'),
|
||||
getConfig: jest.fn().mockResolvedValue(undefined),
|
||||
getMetadata: jest.fn().mockResolvedValue(undefined),
|
||||
} as unknown as CliAuth);
|
||||
|
||||
const result = await resolveAuth();
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
|
||||
import { CliAuth } from '@backstage/cli-node';
|
||||
import { z } from 'zod/v3';
|
||||
|
||||
const pluginSourcesSchema = z.array(z.string()).default([]);
|
||||
|
||||
export async function resolveAuth(instanceFlag?: string): Promise<{
|
||||
baseUrl: string;
|
||||
@@ -24,7 +27,9 @@ export async function resolveAuth(instanceFlag?: string): Promise<{
|
||||
}> {
|
||||
const auth = await CliAuth.create({ instanceName: instanceFlag });
|
||||
const accessToken = await auth.getAccessToken();
|
||||
const pluginSources = (await auth.getConfig<string[]>('pluginSources')) ?? [];
|
||||
const pluginSources = pluginSourcesSchema.parse(
|
||||
await auth.getMetadata('pluginSources'),
|
||||
);
|
||||
|
||||
return {
|
||||
baseUrl: auth.getBaseUrl(),
|
||||
|
||||
Reference in New Issue
Block a user