Merge pull request #25571 from backstage/rugvip/compat

backend-*: deprecate or remove support for installing backend features with callback form
This commit is contained in:
Patrik Oldsberg
2024-07-16 09:16:22 +02:00
committed by GitHub
10 changed files with 67 additions and 54 deletions
+5
View File
@@ -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.
+5
View File
@@ -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.
+5
View File
@@ -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.
+10 -3
View File
@@ -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)
@@ -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<string>();
const duplicates = new Set<string>();
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);
}
+11 -4
View File
@@ -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<void>;
stop(): Promise<void>;
@@ -39,7 +46,7 @@ export interface Backend {
* @public
*/
export interface CreateSpecializedBackendOptions {
defaultServiceFactories: ServiceFactoryOrFunction[];
defaultServiceFactories: ServiceFactory[];
}
/**
+20 -20
View File
@@ -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,
];
/**
+3 -6
View File
@@ -371,9 +371,7 @@ export namespace mockServices {
// @public
export class ServiceFactoryTester<TService, TScope extends 'root' | 'plugin'> {
static from<TService, TScope extends 'root' | 'plugin'>(
subject:
| ServiceFactory<TService, TScope>
| (() => ServiceFactory<TService, TScope>),
subject: ServiceFactory<TService, TScope>,
options?: ServiceFactoryTesterOptions,
): ServiceFactoryTester<TService, TScope>;
// @deprecated
@@ -391,7 +389,7 @@ export class ServiceFactoryTester<TService, TScope extends 'root' | 'plugin'> {
// @public
export interface ServiceFactoryTesterOptions {
dependencies?: Array<ServiceFactory | (() => ServiceFactory)>;
dependencies?: Array<ServiceFactory>;
}
// @public (undocumented)
@@ -436,9 +434,8 @@ export interface TestBackendOptions<TExtensionPoints extends any[]> {
// (undocumented)
features?: Array<
| BackendFeature
| (() => BackendFeature)
| Promise<{
default: BackendFeature | (() => BackendFeature);
default: BackendFeature;
}>
>;
}
@@ -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 | (() => ServiceFactory)>;
dependencies?: Array<ServiceFactory>;
}
/**
@@ -55,20 +55,15 @@ export class ServiceFactoryTester<TService, TScope extends 'root' | 'plugin'> {
* @returns A new tester instance for the provided subject.
*/
static from<TService, TScope extends 'root' | 'plugin'>(
subject:
| ServiceFactory<TService, TScope>
| (() => ServiceFactory<TService, TScope>),
subject: ServiceFactory<TService, TScope>,
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(
@@ -48,11 +48,7 @@ export interface TestBackendOptions<TExtensionPoints extends any[]> {
];
},
];
features?: Array<
| BackendFeature
| (() => BackendFeature)
| Promise<{ default: BackendFeature | (() => BackendFeature) }>
>;
features?: Array<BackendFeature | Promise<{ default: BackendFeature }>>;
}
/** @public */