diff --git a/.changeset/sharp-lobsters-build.md b/.changeset/sharp-lobsters-build.md new file mode 100644 index 0000000000..f9d317a1f6 --- /dev/null +++ b/.changeset/sharp-lobsters-build.md @@ -0,0 +1,10 @@ +--- +'@backstage/backend-plugin-api': minor +--- + +The `register` methods passed to `createBackendPlugin` and `createBackendModule` +now have dedicated `BackendPluginRegistrationPoints` and +`BackendModuleRegistrationPoints` arguments, respectively. This lets us make it +clear on a type level that it's not possible to pass in extension points as +dependencies to plugins (should only ever be done for modules). This has no +practical effect on code that was already well behaved. diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 86917dae11..4543e5b580 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -29,9 +29,22 @@ export interface BackendModuleConfig { // (undocumented) pluginId: string; // (undocumented) - register( - reg: Omit, - ): void; + register(reg: BackendModuleRegistrationPoints): void; +} + +// @public +export interface BackendModuleRegistrationPoints { + // (undocumented) + registerInit< + Deps extends { + [name in string]: unknown; + }, + >(options: { + deps: { + [name in keyof Deps]: ServiceRef | ExtensionPoint; + }; + init(deps: Deps): Promise; + }): void; } // @public (undocumented) @@ -39,10 +52,30 @@ export interface BackendPluginConfig { // (undocumented) id: string; // (undocumented) - register(reg: BackendRegistrationPoints): void; + register(reg: BackendPluginRegistrationPoints): void; } -// @public (undocumented) +// @public +export interface BackendPluginRegistrationPoints { + // (undocumented) + registerExtensionPoint( + ref: ExtensionPoint, + impl: TExtensionPoint, + ): void; + // (undocumented) + registerInit< + Deps extends { + [name in string]: unknown; + }, + >(options: { + deps: { + [name in keyof Deps]: ServiceRef; + }; + init(deps: Deps): Promise; + }): void; +} + +// @public export interface BackendRegistrationPoints { // (undocumented) registerExtensionPoint( diff --git a/packages/backend-plugin-api/src/wiring/factories.ts b/packages/backend-plugin-api/src/wiring/factories.ts index ad2e8edd13..b7482a9f0b 100644 --- a/packages/backend-plugin-api/src/wiring/factories.ts +++ b/packages/backend-plugin-api/src/wiring/factories.ts @@ -15,6 +15,8 @@ */ import { + BackendModuleRegistrationPoints, + BackendPluginRegistrationPoints, BackendRegistrationPoints, BackendFeature, ExtensionPoint, @@ -44,7 +46,7 @@ export function createExtensionPoint( /** @public */ export interface BackendPluginConfig { id: string; - register(reg: BackendRegistrationPoints): void; + register(reg: BackendPluginRegistrationPoints): void; } /** @public */ @@ -62,9 +64,7 @@ export function createBackendPlugin( export interface BackendModuleConfig { pluginId: string; moduleId: string; - register( - reg: Omit, - ): void; + register(reg: BackendModuleRegistrationPoints): void; } /** @@ -96,8 +96,9 @@ export function createBackendModule( return () => ({ id: `${config.pluginId}.${config.moduleId}`, register(register: BackendRegistrationPoints) { - // TODO: Hide registerExtensionPoint - return config.register(register); + return config.register({ + registerInit: register.registerInit.bind(register), + }); }, }); } diff --git a/packages/backend-plugin-api/src/wiring/index.ts b/packages/backend-plugin-api/src/wiring/index.ts index 0d5999ad12..e0c25eeb4e 100644 --- a/packages/backend-plugin-api/src/wiring/index.ts +++ b/packages/backend-plugin-api/src/wiring/index.ts @@ -30,6 +30,8 @@ export { createExtensionPoint, } from './factories'; export type { + BackendModuleRegistrationPoints, + BackendPluginRegistrationPoints, BackendRegistrationPoints, BackendFeature, ExtensionPoint, diff --git a/packages/backend-plugin-api/src/wiring/types.ts b/packages/backend-plugin-api/src/wiring/types.ts index cdb56ea2e4..6e081f57e5 100644 --- a/packages/backend-plugin-api/src/wiring/types.ts +++ b/packages/backend-plugin-api/src/wiring/types.ts @@ -35,7 +35,13 @@ export type ExtensionPoint = { $$ref: 'extension-point'; }; -/** @public */ +/** + * The callbacks passed to the `register` method of a backend feature; this is + * essentially a superset of {@link BackendPluginRegistrationPoints} and + * {@link BackendModuleRegistrationPoints}. + * + * @public + */ export interface BackendRegistrationPoints { registerExtensionPoint( ref: ExtensionPoint, @@ -49,6 +55,38 @@ export interface BackendRegistrationPoints { }): void; } +/** + * The callbacks passed to the `register` method of a backend plugin. + * + * @public + */ +export interface BackendPluginRegistrationPoints { + registerExtensionPoint( + ref: ExtensionPoint, + impl: TExtensionPoint, + ): void; + registerInit(options: { + deps: { + [name in keyof Deps]: ServiceRef; + }; + init(deps: Deps): Promise; + }): void; +} + +/** + * The callbacks passed to the `register` method of a backend module. + * + * @public + */ +export interface BackendModuleRegistrationPoints { + registerInit(options: { + deps: { + [name in keyof Deps]: ServiceRef | ExtensionPoint; + }; + init(deps: Deps): Promise; + }): void; +} + /** @public */ export interface BackendFeature { // TODO(Rugvip): Try to get rid of the ID at this level, allowing for a feature to register multiple features as a bundle