diff --git a/.changeset/dry-wombats-type.md b/.changeset/dry-wombats-type.md new file mode 100644 index 0000000000..31fed70293 --- /dev/null +++ b/.changeset/dry-wombats-type.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': minor +--- + +**BREAKING**: Removed the ability to pass callback-form service factories through the `defaultServiceFactories` option of `createSpecializedBackend`. This is an immediate breaking change as usage of this function is expected to be very rare. diff --git a/.changeset/smooth-pianos-argue.md b/.changeset/smooth-pianos-argue.md new file mode 100644 index 0000000000..e7fc66dee4 --- /dev/null +++ b/.changeset/smooth-pianos-argue.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Updated `startTestBackend` and `ServiceFactoryTester` to only accept plain service factory or backend feature objects, no longer supporting the callback form. This lines up with the changes to `@backstage/backend-plugin-api` and should not require any code changes. diff --git a/.changeset/three-lizards-crash.md b/.changeset/three-lizards-crash.md new file mode 100644 index 0000000000..5dffed0f3b --- /dev/null +++ b/.changeset/three-lizards-crash.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +The ability to install backend features in callback form (`() => BackendFeature`) has been deprecated. This typically means that you need to update the installed features to use the latest version of `@backstage/backend-plugin-api`. If the feature is from a third-party package, please reach out to the package maintainer to update it. diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 51839b88be..54e2900cc2 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -38,8 +38,8 @@ import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; import type { Server } from 'node:http'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; -import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api'; import { TokenManagerService } from '@backstage/backend-plugin-api'; import { transport } from 'winston'; import { UrlReaderService } from '@backstage/backend-plugin-api'; @@ -58,9 +58,16 @@ export interface Backend { add( feature: | BackendFeature + | Promise<{ + default: BackendFeature; + }>, + ): void; + // @deprecated (undocumented) + add( + feature: | (() => BackendFeature) | Promise<{ - default: BackendFeature | (() => BackendFeature); + default: () => BackendFeature; }>, ): void; // (undocumented) @@ -99,7 +106,7 @@ export function createSpecializedBackend( // @public (undocumented) export interface CreateSpecializedBackendOptions { // (undocumented) - defaultServiceFactories: ServiceFactoryOrFunction[]; + defaultServiceFactories: ServiceFactory[]; } // @public @deprecated (undocumented) diff --git a/packages/backend-app-api/src/wiring/createSpecializedBackend.ts b/packages/backend-app-api/src/wiring/createSpecializedBackend.ts index f5c4d8b152..fd449be541 100644 --- a/packages/backend-app-api/src/wiring/createSpecializedBackend.ts +++ b/packages/backend-app-api/src/wiring/createSpecializedBackend.ts @@ -24,13 +24,9 @@ import { Backend, CreateSpecializedBackendOptions } from './types'; export function createSpecializedBackend( options: CreateSpecializedBackendOptions, ): Backend { - const services = options.defaultServiceFactories.map(sf => - typeof sf === 'function' ? sf() : sf, - ); - const exists = new Set(); const duplicates = new Set(); - for (const { service } of services) { + for (const { service } of options.defaultServiceFactories) { if (exists.has(service.id)) { duplicates.add(service.id); } else { @@ -47,5 +43,5 @@ export function createSpecializedBackend( ); } - return new BackstageBackend(services); + return new BackstageBackend(options.defaultServiceFactories); } diff --git a/packages/backend-app-api/src/wiring/types.ts b/packages/backend-app-api/src/wiring/types.ts index 027b2bf254..075eb58b3f 100644 --- a/packages/backend-app-api/src/wiring/types.ts +++ b/packages/backend-app-api/src/wiring/types.ts @@ -18,18 +18,25 @@ import { BackendFeature, ExtensionPoint, ServiceRef, - ServiceFactoryOrFunction, + ServiceFactory, } from '@backstage/backend-plugin-api'; /** * @public */ export interface Backend { + add(feature: BackendFeature | Promise<{ default: BackendFeature }>): void; + /** + * @deprecated The ability to add features defined as a callback is being + * removed. Please update the installed feature to no longer be defined as a + * callback, typically this means updating it to use the latest version of + * `@backstage/backend-plugin-api`. If the feature is from a third-party + * package, please reach out to the package maintainer to update it. + */ add( feature: - | BackendFeature | (() => BackendFeature) - | Promise<{ default: BackendFeature | (() => BackendFeature) }>, + | Promise<{ default: () => BackendFeature }>, ): void; start(): Promise; stop(): Promise; @@ -39,7 +46,7 @@ export interface Backend { * @public */ export interface CreateSpecializedBackendOptions { - defaultServiceFactories: ServiceFactoryOrFunction[]; + defaultServiceFactories: ServiceFactory[]; } /** diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index e3195748a6..47fa09da49 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -40,26 +40,26 @@ import { userInfoServiceFactory } from '@backstage/backend-defaults/userInfo'; import { eventsServiceFactory } from '@backstage/plugin-events-node'; export const defaultServiceFactories = [ - authServiceFactory(), - cacheServiceFactory(), - rootConfigServiceFactory(), - databaseServiceFactory(), - discoveryServiceFactory(), - httpAuthServiceFactory(), - httpRouterServiceFactory(), - identityServiceFactory(), - lifecycleServiceFactory(), - loggerServiceFactory(), - permissionsServiceFactory(), - rootHealthServiceFactory(), - rootHttpRouterServiceFactory(), - rootLifecycleServiceFactory(), - rootLoggerServiceFactory(), - schedulerServiceFactory(), - tokenManagerServiceFactory(), - userInfoServiceFactory(), - urlReaderServiceFactory(), - eventsServiceFactory(), + authServiceFactory, + cacheServiceFactory, + rootConfigServiceFactory, + databaseServiceFactory, + discoveryServiceFactory, + httpAuthServiceFactory, + httpRouterServiceFactory, + identityServiceFactory, + lifecycleServiceFactory, + loggerServiceFactory, + permissionsServiceFactory, + rootHealthServiceFactory, + rootHttpRouterServiceFactory, + rootLifecycleServiceFactory, + rootLoggerServiceFactory, + schedulerServiceFactory, + tokenManagerServiceFactory, + userInfoServiceFactory, + urlReaderServiceFactory, + eventsServiceFactory, ]; /** diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index c585c4cf68..af7edba061 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -371,9 +371,7 @@ export namespace mockServices { // @public export class ServiceFactoryTester { static from( - subject: - | ServiceFactory - | (() => ServiceFactory), + subject: ServiceFactory, options?: ServiceFactoryTesterOptions, ): ServiceFactoryTester; // @deprecated @@ -391,7 +389,7 @@ export class ServiceFactoryTester { // @public export interface ServiceFactoryTesterOptions { - dependencies?: Array ServiceFactory)>; + dependencies?: Array; } // @public (undocumented) @@ -436,9 +434,8 @@ export interface TestBackendOptions { // (undocumented) features?: Array< | BackendFeature - | (() => BackendFeature) | Promise<{ - default: BackendFeature | (() => BackendFeature); + default: BackendFeature; }> >; } diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts index 40b473663b..aea0d9d270 100644 --- a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts +++ b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts @@ -35,7 +35,7 @@ export interface ServiceFactoryTesterOptions { * If a service factory is provided for a service that already has a default * implementation, the provided factory will override the default. */ - dependencies?: Array ServiceFactory)>; + dependencies?: Array; } /** @@ -55,20 +55,15 @@ export class ServiceFactoryTester { * @returns A new tester instance for the provided subject. */ static from( - subject: - | ServiceFactory - | (() => ServiceFactory), + subject: ServiceFactory, options?: ServiceFactoryTesterOptions, ) { - const subjectFactory = typeof subject === 'function' ? subject() : subject; const registry = ServiceRegistry.create([ ...defaultServiceFactories, - ...(options?.dependencies?.map(f => - typeof f === 'function' ? f() : f, - ) ?? []), - subjectFactory, + ...(options?.dependencies ?? []), + subject, ]); - return new ServiceFactoryTester(subjectFactory.service, registry); + return new ServiceFactoryTester(subject.service, registry); } private constructor( diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts index f23883ba3e..16ee6b78d2 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -48,11 +48,7 @@ export interface TestBackendOptions { ]; }, ]; - features?: Array< - | BackendFeature - | (() => BackendFeature) - | Promise<{ default: BackendFeature | (() => BackendFeature) }> - >; + features?: Array>; } /** @public */