frontend-plugin-api: use api ref ID as namespace + allow namespace override for plugins
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -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 },
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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 }),
|
||||
),
|
||||
],
|
||||
}),
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -376,18 +376,23 @@ export type CoreProgressComponent = ComponentType<PropsWithChildren<{}>>;
|
||||
export function createApiExtension<
|
||||
TConfig extends {},
|
||||
TInputs extends AnyExtensionInputMap,
|
||||
>(options: {
|
||||
factory:
|
||||
| AnyApiFactory
|
||||
| ((options: {
|
||||
config: TConfig;
|
||||
inputs: Expand<ExtensionInputValues<TInputs>>;
|
||||
}) => AnyApiFactory);
|
||||
namespace?: string;
|
||||
name?: string;
|
||||
configSchema?: PortableSchema<TConfig>;
|
||||
inputs?: TInputs;
|
||||
}): ExtensionDefinition<TConfig>;
|
||||
>(
|
||||
options: (
|
||||
| {
|
||||
api: AnyApiRef;
|
||||
factory: (options: {
|
||||
config: TConfig;
|
||||
inputs: Expand<ExtensionInputValues<TInputs>>;
|
||||
}) => AnyApiFactory;
|
||||
}
|
||||
| {
|
||||
factory: AnyApiFactory;
|
||||
}
|
||||
) & {
|
||||
configSchema?: PortableSchema<TConfig>;
|
||||
inputs?: TInputs;
|
||||
},
|
||||
): ExtensionDefinition<TConfig>;
|
||||
|
||||
export { createApiFactory };
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<ExtensionInputValues<TInputs>>;
|
||||
}) => AnyApiFactory);
|
||||
namespace?: string;
|
||||
name?: string;
|
||||
configSchema?: PortableSchema<TConfig>;
|
||||
inputs?: TInputs;
|
||||
}) {
|
||||
>(
|
||||
options: (
|
||||
| {
|
||||
api: AnyApiRef;
|
||||
factory: (options: {
|
||||
config: TConfig;
|
||||
inputs: Expand<ExtensionInputValues<TInputs>>;
|
||||
}) => AnyApiFactory;
|
||||
}
|
||||
| {
|
||||
factory: AnyApiFactory;
|
||||
}
|
||||
) & {
|
||||
configSchema?: PortableSchema<TConfig>;
|
||||
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:<api-ref-id>`
|
||||
namespace: apiRef.id,
|
||||
attachTo: { id: 'core', input: 'apis' },
|
||||
inputs: extensionInputs,
|
||||
configSchema,
|
||||
|
||||
@@ -22,7 +22,7 @@ export function resolveExtensionDefinition<TConfig>(
|
||||
context?: { namespace?: string },
|
||||
): Extension<TConfig> {
|
||||
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;
|
||||
|
||||
@@ -41,7 +41,6 @@ export const CatalogApi = createApiExtension({
|
||||
});
|
||||
|
||||
export const StarredEntitiesApi = createApiExtension({
|
||||
name: 'starred-entities',
|
||||
factory: createApiFactory({
|
||||
api: starredEntitiesApiRef,
|
||||
deps: { storageApi: storageApiRef },
|
||||
|
||||
@@ -57,7 +57,7 @@ const endpointDataRef = createExtensionDataRef<GraphQLEndpoint>(
|
||||
|
||||
/** @alpha */
|
||||
export const graphiqlBrowseApi = createApiExtension({
|
||||
name: 'browse',
|
||||
api: graphQlBrowseApiRef,
|
||||
inputs: {
|
||||
endpoints: createExtensionInput({
|
||||
endpoint: endpointDataRef,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user