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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user