catalog-backend: attribute provider connection failures to modules
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -35,7 +35,7 @@ describe('createBackendModule', () => {
|
||||
expect(module.getRegistrations).toEqual(expect.any(Function));
|
||||
expect(module.getRegistrations()).toEqual([
|
||||
{
|
||||
type: 'module',
|
||||
type: 'module-v1.1',
|
||||
pluginId: 'x',
|
||||
moduleId: 'y',
|
||||
extensionPoints: [],
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
import { BackendFeature } from '../types';
|
||||
import {
|
||||
BackendModuleRegistrationPoints,
|
||||
InternalBackendModuleRegistration,
|
||||
InternalBackendPluginRegistration,
|
||||
ExtensionPoint,
|
||||
ExtensionPointFactoryContext,
|
||||
InternalBackendModuleRegistrationV1_1,
|
||||
InternalBackendRegistrations,
|
||||
} from './types';
|
||||
|
||||
@@ -55,16 +56,43 @@ export function createBackendModule(
|
||||
options: CreateBackendModuleOptions,
|
||||
): BackendFeature {
|
||||
function getRegistrations() {
|
||||
const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =
|
||||
const extensionPoints: InternalBackendModuleRegistrationV1_1['extensionPoints'] =
|
||||
[];
|
||||
let init: InternalBackendModuleRegistration['init'] | undefined = undefined;
|
||||
let init: InternalBackendModuleRegistrationV1_1['init'] | undefined =
|
||||
undefined;
|
||||
|
||||
options.register({
|
||||
registerExtensionPoint(ext, impl) {
|
||||
registerExtensionPoint<TExtensionPoint>(
|
||||
extOrOpts:
|
||||
| ExtensionPoint<TExtensionPoint>
|
||||
| {
|
||||
extensionPoint: ExtensionPoint<TExtensionPoint>;
|
||||
factory: (
|
||||
context: ExtensionPointFactoryContext,
|
||||
) => TExtensionPoint;
|
||||
},
|
||||
impl?: TExtensionPoint,
|
||||
) {
|
||||
if (init) {
|
||||
throw new Error('registerExtensionPoint called after registerInit');
|
||||
}
|
||||
extensionPoints.push([ext, impl]);
|
||||
if (
|
||||
typeof extOrOpts === 'object' &&
|
||||
extOrOpts !== null &&
|
||||
'extensionPoint' in extOrOpts
|
||||
) {
|
||||
extensionPoints.push({
|
||||
extensionPoint: extOrOpts.extensionPoint,
|
||||
factory: extOrOpts.factory as (
|
||||
context: ExtensionPointFactoryContext,
|
||||
) => unknown,
|
||||
});
|
||||
} else {
|
||||
extensionPoints.push({
|
||||
extensionPoint: extOrOpts,
|
||||
factory: () => impl,
|
||||
});
|
||||
}
|
||||
},
|
||||
registerInit(regInit) {
|
||||
if (init) {
|
||||
@@ -85,7 +113,7 @@ export function createBackendModule(
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'module',
|
||||
type: 'module-v1.1',
|
||||
pluginId: options.pluginId,
|
||||
moduleId: options.moduleId,
|
||||
extensionPoints,
|
||||
|
||||
@@ -34,7 +34,7 @@ describe('createBackendPlugin', () => {
|
||||
expect(plugin.getRegistrations).toEqual(expect.any(Function));
|
||||
expect(plugin.getRegistrations()).toEqual([
|
||||
{
|
||||
type: 'plugin',
|
||||
type: 'plugin-v1.1',
|
||||
pluginId: 'x',
|
||||
extensionPoints: [],
|
||||
init: {
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
import { BackendFeature } from '../types';
|
||||
import {
|
||||
BackendPluginRegistrationPoints,
|
||||
InternalBackendPluginRegistration,
|
||||
ExtensionPoint,
|
||||
ExtensionPointFactoryContext,
|
||||
InternalBackendPluginRegistrationV1_1,
|
||||
InternalBackendRegistrations,
|
||||
} from './types';
|
||||
|
||||
@@ -49,16 +51,43 @@ export function createBackendPlugin(
|
||||
options: CreateBackendPluginOptions,
|
||||
): BackendFeature {
|
||||
function getRegistrations() {
|
||||
const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =
|
||||
const extensionPoints: InternalBackendPluginRegistrationV1_1['extensionPoints'] =
|
||||
[];
|
||||
let init: InternalBackendPluginRegistration['init'] | undefined = undefined;
|
||||
let init: InternalBackendPluginRegistrationV1_1['init'] | undefined =
|
||||
undefined;
|
||||
|
||||
options.register({
|
||||
registerExtensionPoint(ext, impl) {
|
||||
registerExtensionPoint<TExtensionPoint>(
|
||||
extOrOpts:
|
||||
| ExtensionPoint<TExtensionPoint>
|
||||
| {
|
||||
extensionPoint: ExtensionPoint<TExtensionPoint>;
|
||||
factory: (
|
||||
context: ExtensionPointFactoryContext,
|
||||
) => TExtensionPoint;
|
||||
},
|
||||
impl?: TExtensionPoint,
|
||||
) {
|
||||
if (init) {
|
||||
throw new Error('registerExtensionPoint called after registerInit');
|
||||
}
|
||||
extensionPoints.push([ext, impl]);
|
||||
if (
|
||||
typeof extOrOpts === 'object' &&
|
||||
extOrOpts !== null &&
|
||||
'extensionPoint' in extOrOpts
|
||||
) {
|
||||
extensionPoints.push({
|
||||
extensionPoint: extOrOpts.extensionPoint,
|
||||
factory: extOrOpts.factory as (
|
||||
context: ExtensionPointFactoryContext,
|
||||
) => unknown,
|
||||
});
|
||||
} else {
|
||||
extensionPoints.push({
|
||||
extensionPoint: extOrOpts,
|
||||
factory: () => impl,
|
||||
});
|
||||
}
|
||||
},
|
||||
registerInit(regInit) {
|
||||
if (init) {
|
||||
@@ -79,7 +108,7 @@ export function createBackendPlugin(
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'plugin',
|
||||
type: 'plugin-v1.1',
|
||||
pluginId: options.pluginId,
|
||||
extensionPoints,
|
||||
init,
|
||||
|
||||
@@ -30,6 +30,7 @@ export type {
|
||||
BackendModuleRegistrationPoints,
|
||||
BackendPluginRegistrationPoints,
|
||||
ExtensionPoint,
|
||||
ExtensionPointFactoryContext,
|
||||
} from './types';
|
||||
|
||||
export type {
|
||||
|
||||
@@ -36,6 +36,20 @@ export type ExtensionPoint<T> = {
|
||||
$$type: '@backstage/ExtensionPoint';
|
||||
};
|
||||
|
||||
/**
|
||||
* Context provided to extension point factories.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface ExtensionPointFactoryContext {
|
||||
/**
|
||||
* Report a startup failure that happened as part of using an extension that
|
||||
* the module provided. This should be called before the plugin's `init`
|
||||
* function returns.
|
||||
*/
|
||||
reportModuleStartupFailure(options: { error: Error }): void;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
type DepsToInstances<
|
||||
TDeps extends {
|
||||
@@ -53,10 +67,20 @@ type DepsToInstances<
|
||||
* @public
|
||||
*/
|
||||
export interface BackendPluginRegistrationPoints {
|
||||
/**
|
||||
* Registers an implementation for an extension point.
|
||||
*/
|
||||
registerExtensionPoint<TExtensionPoint>(
|
||||
ref: ExtensionPoint<TExtensionPoint>,
|
||||
impl: TExtensionPoint,
|
||||
): void;
|
||||
/**
|
||||
* Registers a factory that produces a separate implementation for an extension point for each module.
|
||||
*/
|
||||
registerExtensionPoint<TExtensionPoint>(options: {
|
||||
extensionPoint: ExtensionPoint<TExtensionPoint>;
|
||||
factory: (context: ExtensionPointFactoryContext) => TExtensionPoint;
|
||||
}): void;
|
||||
registerInit<
|
||||
TDeps extends {
|
||||
[name in string]: ServiceRef<unknown>;
|
||||
@@ -77,6 +101,10 @@ export interface BackendModuleRegistrationPoints {
|
||||
ref: ExtensionPoint<TExtensionPoint>,
|
||||
impl: TExtensionPoint,
|
||||
): void;
|
||||
registerExtensionPoint<TExtensionPoint>(options: {
|
||||
extensionPoint: ExtensionPoint<TExtensionPoint>;
|
||||
factory: (context: ExtensionPointFactoryContext) => TExtensionPoint;
|
||||
}): void;
|
||||
registerInit<
|
||||
TDeps extends {
|
||||
[name in string]: ServiceRef<unknown> | ExtensionPoint<unknown>;
|
||||
@@ -92,7 +120,10 @@ export interface InternalBackendRegistrations extends BackendFeature {
|
||||
version: 'v1';
|
||||
featureType: 'registrations';
|
||||
getRegistrations(): Array<
|
||||
InternalBackendPluginRegistration | InternalBackendModuleRegistration
|
||||
| InternalBackendPluginRegistration
|
||||
| InternalBackendModuleRegistration
|
||||
| InternalBackendPluginRegistrationV1_1
|
||||
| InternalBackendModuleRegistrationV1_1
|
||||
>;
|
||||
}
|
||||
|
||||
@@ -119,6 +150,35 @@ export interface InternalBackendModuleRegistration {
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export type ExtensionPointRegistration = {
|
||||
extensionPoint: ExtensionPoint<unknown>;
|
||||
factory: (context: ExtensionPointFactoryContext) => unknown;
|
||||
};
|
||||
|
||||
/** @internal */
|
||||
export interface InternalBackendPluginRegistrationV1_1 {
|
||||
pluginId: string;
|
||||
type: 'plugin-v1.1';
|
||||
extensionPoints: Array<ExtensionPointRegistration>;
|
||||
init: {
|
||||
deps: Record<string, ServiceRef<unknown>>;
|
||||
func(deps: Record<string, unknown>): Promise<void>;
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface InternalBackendModuleRegistrationV1_1 {
|
||||
pluginId: string;
|
||||
moduleId: string;
|
||||
type: 'module-v1.1';
|
||||
extensionPoints: Array<ExtensionPointRegistration>;
|
||||
init: {
|
||||
deps: Record<string, ServiceRef<unknown> | ExtensionPoint<unknown>>;
|
||||
func(deps: Record<string, unknown>): Promise<void>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user