From 36a40b4903059537a8e0ef174819c44ef2b886a7 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 1 Aug 2023 20:43:28 +0200 Subject: [PATCH] define BackendFeatureFactory Signed-off-by: Vincenzo Scamporlino --- packages/backend-app-api/src/alpha.ts | 48 ++++++++++++------- .../src/wiring/factories.ts | 17 ++++--- .../backend-plugin-api/src/wiring/index.ts | 1 + .../backend-plugin-api/src/wiring/types.ts | 8 ++++ 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/packages/backend-app-api/src/alpha.ts b/packages/backend-app-api/src/alpha.ts index da77c7cfc5..31b61950b9 100644 --- a/packages/backend-app-api/src/alpha.ts +++ b/packages/backend-app-api/src/alpha.ts @@ -16,6 +16,7 @@ import { BackendFeature, + BackendFeatureFactory, RootConfigService, coreServices, createServiceFactory, @@ -71,8 +72,11 @@ export class PackageDiscoveryService implements FeatureDiscoveryService { throw new Error('NOOOOOOOOOOOOOOOOOOOOOOOOOO'); } console.log(`DEBUG: packageDir=`, packageDir); - const { dependencies } = require(resolvePath(packageDir, 'package.json')); - const dependencyNames = Object.keys(dependencies); + const { dependencies } = require(resolvePath( + packageDir, + 'package.json', + )) as BackstagePackageJson; + const dependencyNames = Object.keys(dependencies || {}); console.log(`DEBUG: dependencyNames=`, dependencyNames); const features: BackendFeature[] = []; @@ -82,23 +86,16 @@ export class PackageDiscoveryService implements FeatureDiscoveryService { if (!LOADED_PACKAGE_ROLES.includes(depPkg?.backstage?.role ?? '')) { continue; } - const depModule = require(name); // @backstage/plugin-catalog-backend + const depModule = require(name); console.log(`DEBUG: loaded ${name} depModule=`, depModule); - Object.values(depModule).filter(exportValue => { - if ( - exportValue && - typeof exportValue === 'object' && - (exportValue as any).$$type === '@backstage/BackendFeature' - ) { - features.push(exportValue as BackendFeature); + for (const exportValue of Object.values(depModule)) { + if (isBackendFeature(exportValue)) { + features.push(exportValue); } - if ( - typeof exportValue === 'function' && - (exportValue as any).$$type === '@backstage/BackendFeatureFactory' - ) { - features.push(exportValue() as BackendFeature); + if (isBackendFeatureFactory(exportValue)) { + features.push(exportValue()); } - }); + } } console.log(`DEBUG: features=`, features); @@ -116,3 +113,22 @@ export const packageFeatureDiscoveryServiceFactory = createServiceFactory({ return new PackageDiscoveryService(config); }, }); + +function isBackendFeature(value: unknown): value is BackendFeature { + return ( + !!value && + typeof value === 'object' && + (value as BackendFeature).$$type === '@backstage/BackendFeature' + ); +} + +function isBackendFeatureFactory( + value: unknown, +): value is BackendFeatureFactory { + return ( + !!value && + typeof value === 'object' && + (value as BackendFeatureFactory).$$type === + '@backstage/BackendFeatureFactory' + ); +} diff --git a/packages/backend-plugin-api/src/wiring/factories.ts b/packages/backend-plugin-api/src/wiring/factories.ts index 41584e9a29..ba9238e0e0 100644 --- a/packages/backend-plugin-api/src/wiring/factories.ts +++ b/packages/backend-plugin-api/src/wiring/factories.ts @@ -17,11 +17,10 @@ import { BackendModuleRegistrationPoints, BackendPluginRegistrationPoints, - BackendFeature, ExtensionPoint, - InternalBackendFeature, InternalBackendModuleRegistration, InternalBackendPluginRegistration, + BackendFeatureFactory, } from './types'; /** @@ -92,9 +91,10 @@ export const catalogPlugin = createBackendPlugin({ */ export function createBackendPlugin( config: BackendPluginConfig | ((...params: TOptions) => BackendPluginConfig), -): (...params: TOptions) => BackendFeature { +): BackendFeatureFactory { const configCallback = typeof config === 'function' ? config : () => config; - const factory = (...options: TOptions): InternalBackendFeature => { + + const factory: BackendFeatureFactory = (...options) => { const c = configCallback(...options); let registrations: InternalBackendPluginRegistration[]; @@ -149,8 +149,8 @@ export function createBackendPlugin( }, }; }; - factory.$$type = '@backstage/BackendFeatureFactory'; + return factory; } @@ -184,9 +184,9 @@ export interface BackendModuleConfig { */ export function createBackendModule( config: BackendModuleConfig | ((...params: TOptions) => BackendModuleConfig), -): (...params: TOptions) => BackendFeature { +): BackendFeatureFactory { const configCallback = typeof config === 'function' ? config : () => config; - return (...options: TOptions): InternalBackendFeature => { + const factory: BackendFeatureFactory = (...options: TOptions) => { const c = configCallback(...options); let registrations: InternalBackendModuleRegistration[]; @@ -231,4 +231,7 @@ export function createBackendModule( }, }; }; + factory.$$type = '@backstage/BackendFeatureFactory'; + + return factory; } diff --git a/packages/backend-plugin-api/src/wiring/index.ts b/packages/backend-plugin-api/src/wiring/index.ts index 9cb767b8ac..0b7104374a 100644 --- a/packages/backend-plugin-api/src/wiring/index.ts +++ b/packages/backend-plugin-api/src/wiring/index.ts @@ -28,5 +28,6 @@ export type { BackendModuleRegistrationPoints, BackendPluginRegistrationPoints, BackendFeature, + BackendFeatureFactory, ExtensionPoint, } from './types'; diff --git a/packages/backend-plugin-api/src/wiring/types.ts b/packages/backend-plugin-api/src/wiring/types.ts index c81ee3ceb7..b9b4f3ff10 100644 --- a/packages/backend-plugin-api/src/wiring/types.ts +++ b/packages/backend-plugin-api/src/wiring/types.ts @@ -67,6 +67,14 @@ export interface BackendModuleRegistrationPoints { }): void; } +/** @public */ +export interface BackendFeatureFactory< + TOptions extends [options?: object] = [], +> { + (...options: TOptions): BackendFeature; + $$type: '@backstage/BackendFeatureFactory'; +} + /** @public */ export interface BackendFeature { // NOTE: This type is opaque in order to simplify future API evolution.