From 1b241c3901c692bc9d2afd785340e78a64332050 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 24 Nov 2023 14:26:01 +0100 Subject: [PATCH] frontend-plugin-api: use api ref ID as namespace + allow namespace override for plugins Signed-off-by: Patrik Oldsberg --- packages/app-next/src/App.tsx | 2 - .../src/collectLegacyRoutes.test.tsx | 6 +- .../src/collectLegacyRoutes.tsx | 7 +- .../src/convertLegacyApp.test.tsx | 6 +- packages/frontend-plugin-api/api-report.md | 29 +++++---- .../src/extensions/createApiExtension.test.ts | 28 +------- .../src/extensions/createApiExtension.ts | 39 ++++++----- .../src/wiring/resolveExtensionDefinition.ts | 2 +- plugins/catalog/src/alpha/apis.tsx | 1 - plugins/graphiql/src/alpha.tsx | 2 +- plugins/tech-radar/src/alpha.tsx | 4 +- plugins/techdocs/src/alpha.tsx | 65 +++++++++---------- 12 files changed, 85 insertions(+), 106 deletions(-) diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index b0a73c8358..ccfeb61b58 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -101,12 +101,10 @@ const signInPage = createSignInPageExtension({ }); const scmAuthExtension = createApiExtension({ - name: 'scm-auth', factory: ScmAuth.createDefaultApiFactory(), }); const scmIntegrationApi = createApiExtension({ - name: 'scm-integration', factory: createApiFactory({ api: scmIntegrationsApiRef, deps: { configApi: configApiRef }, diff --git a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx index 1238fbbcb4..3dd9f330cc 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx @@ -57,7 +57,7 @@ describe('collectLegacyRoutes', () => { defaultConfig: { path: 'score-board' }, }, { - id: 'api:score-card', + id: 'api:plugin.scoringdata.service', attachTo: { id: 'core', input: 'apis' }, disabled: false, }, @@ -73,7 +73,7 @@ describe('collectLegacyRoutes', () => { defaultConfig: { path: 'stackstorm' }, }, { - id: 'api:stackstorm', + id: 'api:plugin.stackstorm.service', attachTo: { id: 'core', input: 'apis' }, disabled: false, }, @@ -95,7 +95,7 @@ describe('collectLegacyRoutes', () => { defaultConfig: { path: 'puppetdb' }, }, { - id: 'api:puppetDb', + id: 'api:plugin.puppetdb.service', attachTo: { id: 'core', input: 'apis' }, disabled: false, }, diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index 764149948d..92bced29a2 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -130,11 +130,8 @@ export function collectLegacyRoutes( id: plugin.getId(), extensions: [ ...extensions, - ...Array.from(plugin.getApis()).map((factory, index) => - createApiExtension({ - factory, - name: index > 0 ? String(index + 1) : undefined, - }), + ...Array.from(plugin.getApis()).map(factory => + createApiExtension({ factory }), ), ], }), diff --git a/packages/core-compat-api/src/convertLegacyApp.test.tsx b/packages/core-compat-api/src/convertLegacyApp.test.tsx index eeb53ad998..4a5be57bc8 100644 --- a/packages/core-compat-api/src/convertLegacyApp.test.tsx +++ b/packages/core-compat-api/src/convertLegacyApp.test.tsx @@ -65,7 +65,7 @@ describe('convertLegacyApp', () => { defaultConfig: { path: 'score-board' }, }, { - id: 'api:score-card', + id: 'api:plugin.scoringdata.service', attachTo: { id: 'core', input: 'apis' }, disabled: false, }, @@ -81,7 +81,7 @@ describe('convertLegacyApp', () => { defaultConfig: { path: 'stackstorm' }, }, { - id: 'api:stackstorm', + id: 'api:plugin.stackstorm.service', attachTo: { id: 'core', input: 'apis' }, disabled: false, }, @@ -103,7 +103,7 @@ describe('convertLegacyApp', () => { defaultConfig: { path: 'puppetdb' }, }, { - id: 'api:puppetDb', + id: 'api:plugin.puppetdb.service', attachTo: { id: 'core', input: 'apis' }, disabled: false, }, diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index d3c02bfc1e..65c865b352 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -376,18 +376,23 @@ export type CoreProgressComponent = ComponentType>; export function createApiExtension< TConfig extends {}, TInputs extends AnyExtensionInputMap, ->(options: { - factory: - | AnyApiFactory - | ((options: { - config: TConfig; - inputs: Expand>; - }) => AnyApiFactory); - namespace?: string; - name?: string; - configSchema?: PortableSchema; - inputs?: TInputs; -}): ExtensionDefinition; +>( + options: ( + | { + api: AnyApiRef; + factory: (options: { + config: TConfig; + inputs: Expand>; + }) => AnyApiFactory; + } + | { + factory: AnyApiFactory; + } + ) & { + configSchema?: PortableSchema; + inputs?: TInputs; + }, +): ExtensionDefinition; export { createApiFactory }; diff --git a/packages/frontend-plugin-api/src/extensions/createApiExtension.test.ts b/packages/frontend-plugin-api/src/extensions/createApiExtension.test.ts index b2f84f05aa..2585b0d694 100644 --- a/packages/frontend-plugin-api/src/extensions/createApiExtension.test.ts +++ b/packages/frontend-plugin-api/src/extensions/createApiExtension.test.ts @@ -33,31 +33,7 @@ describe('createApiExtension', () => { ).toEqual({ $$type: '@backstage/ExtensionDefinition', kind: 'api', - attachTo: { id: 'core', input: 'apis' }, - disabled: false, - configSchema: undefined, - inputs: {}, - output: { - api: expect.objectContaining({ - $$type: '@backstage/ExtensionDataRef', - id: 'core.api.factory', - config: {}, - }), - }, - factory: expect.any(Function), - }); - - expect( - createApiExtension({ - factory, - namespace: 'ns', - name: 'n', - }), - ).toEqual({ - $$type: '@backstage/ExtensionDefinition', - kind: 'api', - namespace: 'ns', - name: 'n', + namespace: 'test', attachTo: { id: 'core', input: 'apis' }, disabled: false, configSchema: undefined, @@ -78,6 +54,7 @@ describe('createApiExtension', () => { const factory = jest.fn(() => ({ foo: 'bar' })); const extension = createApiExtension({ + api, inputs: {}, factory({ config: _config, inputs: _inputs }) { return createApiFactory({ @@ -91,6 +68,7 @@ describe('createApiExtension', () => { expect(extension).toEqual({ $$type: '@backstage/ExtensionDefinition', kind: 'api', + namespace: 'test', attachTo: { id: 'core', input: 'apis' }, disabled: false, configSchema: undefined, diff --git a/packages/frontend-plugin-api/src/extensions/createApiExtension.ts b/packages/frontend-plugin-api/src/extensions/createApiExtension.ts index fb9acf0076..0f4f721530 100644 --- a/packages/frontend-plugin-api/src/extensions/createApiExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createApiExtension.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { AnyApiFactory } from '@backstage/core-plugin-api'; +import { AnyApiFactory, AnyApiRef } from '@backstage/core-plugin-api'; import { PortableSchema } from '../schema'; import { ExtensionInputValues, @@ -28,24 +28,33 @@ import { Expand } from '../types'; export function createApiExtension< TConfig extends {}, TInputs extends AnyExtensionInputMap, ->(options: { - factory: - | AnyApiFactory - | ((options: { - config: TConfig; - inputs: Expand>; - }) => AnyApiFactory); - namespace?: string; - name?: string; - configSchema?: PortableSchema; - inputs?: TInputs; -}) { +>( + options: ( + | { + api: AnyApiRef; + factory: (options: { + config: TConfig; + inputs: Expand>; + }) => AnyApiFactory; + } + | { + factory: AnyApiFactory; + } + ) & { + configSchema?: PortableSchema; + inputs?: TInputs; + }, +) { const { factory, configSchema, inputs: extensionInputs } = options; + const apiRef = + 'api' in options ? options.api : (factory as { api: AnyApiRef }).api; + return createExtension({ kind: 'api', - namespace: options.namespace, - name: options.name, + // Since ApiRef IDs use a global namespace we use the namespace here in order to override + // potential plugin IDs and always end up with the format `api:` + namespace: apiRef.id, attachTo: { id: 'core', input: 'apis' }, inputs: extensionInputs, configSchema, diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts index 3d7acb33bd..42f3a75246 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts @@ -22,7 +22,7 @@ export function resolveExtensionDefinition( context?: { namespace?: string }, ): Extension { const { name, kind, namespace: _, ...rest } = definition; - const namespace = context?.namespace ?? definition.namespace; + const namespace = definition.namespace ?? context?.namespace; const namePart = name && namespace ? `${namespace}/${name}` : namespace || name; diff --git a/plugins/catalog/src/alpha/apis.tsx b/plugins/catalog/src/alpha/apis.tsx index 21036d8c67..a887a33a04 100644 --- a/plugins/catalog/src/alpha/apis.tsx +++ b/plugins/catalog/src/alpha/apis.tsx @@ -41,7 +41,6 @@ export const CatalogApi = createApiExtension({ }); export const StarredEntitiesApi = createApiExtension({ - name: 'starred-entities', factory: createApiFactory({ api: starredEntitiesApiRef, deps: { storageApi: storageApiRef }, diff --git a/plugins/graphiql/src/alpha.tsx b/plugins/graphiql/src/alpha.tsx index 29d6877a0a..d9470b7d46 100644 --- a/plugins/graphiql/src/alpha.tsx +++ b/plugins/graphiql/src/alpha.tsx @@ -57,7 +57,7 @@ const endpointDataRef = createExtensionDataRef( /** @alpha */ export const graphiqlBrowseApi = createApiExtension({ - name: 'browse', + api: graphQlBrowseApiRef, inputs: { endpoints: createExtensionInput({ endpoint: endpointDataRef, diff --git a/plugins/tech-radar/src/alpha.tsx b/plugins/tech-radar/src/alpha.tsx index 9920c767cd..2d15e92537 100644 --- a/plugins/tech-radar/src/alpha.tsx +++ b/plugins/tech-radar/src/alpha.tsx @@ -49,9 +49,7 @@ export const TechRadarPage = createPageExtension({ /** @alpha */ export const sampleTechRadarApi = createApiExtension({ - factory() { - return createApiFactory(techRadarApiRef, new SampleTechRadarApi()); - }, + factory: createApiFactory(techRadarApiRef, new SampleTechRadarApi()), }); /** @alpha */ diff --git a/plugins/techdocs/src/alpha.tsx b/plugins/techdocs/src/alpha.tsx index cad983df3c..82bda828e2 100644 --- a/plugins/techdocs/src/alpha.tsx +++ b/plugins/techdocs/src/alpha.tsx @@ -46,45 +46,40 @@ import { createEntityContentExtension } from '@backstage/plugin-catalog-react/al /** @alpha */ const techDocsStorage = createApiExtension({ - name: 'storage', - factory() { - return createApiFactory({ - api: techdocsStorageApiRef, - deps: { - configApi: configApiRef, - discoveryApi: discoveryApiRef, - identityApi: identityApiRef, - fetchApi: fetchApiRef, - }, - factory: ({ configApi, discoveryApi, identityApi, fetchApi }) => - new TechDocsStorageClient({ - configApi, - discoveryApi, - identityApi, - fetchApi, - }), - }); - }, + factory: createApiFactory({ + api: techdocsStorageApiRef, + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + identityApi: identityApiRef, + fetchApi: fetchApiRef, + }, + factory: ({ configApi, discoveryApi, identityApi, fetchApi }) => + new TechDocsStorageClient({ + configApi, + discoveryApi, + identityApi, + fetchApi, + }), + }), }); /** @alpha */ const techDocsClient = createApiExtension({ - factory() { - return createApiFactory({ - api: techdocsApiRef, - deps: { - configApi: configApiRef, - discoveryApi: discoveryApiRef, - fetchApi: fetchApiRef, - }, - factory: ({ configApi, discoveryApi, fetchApi }) => - new TechDocsClient({ - configApi, - discoveryApi, - fetchApi, - }), - }); - }, + factory: createApiFactory({ + api: techdocsApiRef, + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + fetchApi: fetchApiRef, + }, + factory: ({ configApi, discoveryApi, fetchApi }) => + new TechDocsClient({ + configApi, + discoveryApi, + fetchApi, + }), + }), }); /** @alpha */