backend-app-api: disallow required service factory options

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-08-11 17:22:16 +02:00
parent 16b2f13bc6
commit c49785f00c
5 changed files with 16 additions and 154 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-plugin-api': minor
---
**BREAKING**: It is no longer possible to declare options as being required with `createServiceFactory`.
@@ -49,10 +49,10 @@ function toInternalServiceFactory<TService, TScope extends 'plugin' | 'root'>(
}
const pluginMetadataServiceFactory = createServiceFactory(
(options: { pluginId: string }) => ({
(options?: { pluginId: string }) => ({
service: coreServices.pluginMetadata,
deps: {},
factory: async () => ({ getId: () => options.pluginId }),
factory: async () => ({ getId: () => options?.pluginId! }),
}),
);
-29
View File
@@ -152,18 +152,6 @@ export function createServiceFactory<
config: (options?: TOpts) => RootServiceFactoryConfig<TService, TImpl, TDeps>,
): (options?: TOpts) => ServiceFactory<TService, 'root'>;
// @public
export function createServiceFactory<
TService,
TImpl extends TService,
TDeps extends {
[name in string]: ServiceRef<unknown>;
},
TOpts extends object | undefined = undefined,
>(
config: (options: TOpts) => RootServiceFactoryConfig<TService, TImpl, TDeps>,
): (options: TOpts) => ServiceFactory<TService, 'root'>;
// @public
export function createServiceFactory<
TService,
@@ -192,23 +180,6 @@ export function createServiceFactory<
) => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>,
): (options?: TOpts) => ServiceFactory<TService, 'plugin'>;
// @public
export function createServiceFactory<
TService,
TImpl extends TService,
TDeps extends {
[name in string]: ServiceRef<unknown>;
},
TContext = undefined,
TOpts extends object | undefined = undefined,
>(
config:
| PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>
| ((
options: TOpts,
) => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>),
): (options: TOpts) => ServiceFactory<TService, 'plugin'>;
// @public
export function createServiceRef<TService>(
config: ServiceRefConfig<TService, 'plugin'>,
@@ -26,7 +26,7 @@ interface TestOptions {
function unused(..._any: any[]) {}
describe('createServiceFactory', () => {
it('should create a sync factory with no options', () => {
it('should create a sync factory', () => {
const metaFactory = createServiceFactory({
service: ref,
deps: {},
@@ -51,7 +51,7 @@ describe('createServiceFactory', () => {
metaFactory();
});
it('should create a sync root factory with no options', () => {
it('should create a sync root factory', () => {
const metaFactory = createServiceFactory({
service: rootDep,
deps: {},
@@ -75,7 +75,7 @@ describe('createServiceFactory', () => {
metaFactory();
});
it('should create a factory with no options', () => {
it('should create a factory', () => {
const metaFactory = createServiceFactory({
service: ref,
deps: {},
@@ -100,7 +100,7 @@ describe('createServiceFactory', () => {
metaFactory();
});
it('should create a factory with optional options', () => {
it('should create a factory with options', () => {
const metaFactory = createServiceFactory((_opts?: { x: number }) => ({
service: ref,
deps: {},
@@ -124,7 +124,8 @@ describe('createServiceFactory', () => {
metaFactory();
});
it('should create a factory with required options', () => {
it('should not be allowed to require options', () => {
// @ts-expect-error
const metaFactory = createServiceFactory((_opts: { x: number }) => ({
service: ref,
deps: {},
@@ -134,23 +135,9 @@ describe('createServiceFactory', () => {
},
}));
expect(metaFactory).toEqual(expect.any(Function));
// @ts-expect-error
metaFactory('string');
// @ts-expect-error
metaFactory({});
metaFactory({ x: 1 });
// @ts-expect-error
metaFactory({ x: 1, y: 2 });
// @ts-expect-error
metaFactory(null);
// @ts-expect-error
metaFactory(undefined);
// @ts-expect-error
metaFactory();
});
it('should create a factory with optional options as interface', () => {
it('should create a factory with options as interface', () => {
const metaFactory = createServiceFactory((_opts?: TestOptions) => ({
service: ref,
deps: {},
@@ -174,32 +161,6 @@ describe('createServiceFactory', () => {
metaFactory();
});
it('should create a factory with required options as interface', () => {
const metaFactory = createServiceFactory((_opts: TestOptions) => ({
service: ref,
deps: {},
async createRootContext() {},
async factory() {
return 'x';
},
}));
expect(metaFactory).toEqual(expect.any(Function));
// @ts-expect-error
metaFactory('string');
// @ts-expect-error
metaFactory({});
metaFactory({ x: 1 });
// @ts-expect-error
metaFactory({ x: 1, y: 2 });
// @ts-expect-error
metaFactory(null);
// @ts-expect-error
metaFactory(undefined);
// @ts-expect-error
metaFactory();
});
it('should create root scoped factory with dependencies', () => {
const metaFactory = createServiceFactory({
service: createServiceRef({ id: 'foo', scope: 'root' }),
@@ -226,7 +187,7 @@ describe('createServiceFactory', () => {
metaFactory();
});
it('should create root scoped factory with dependencies and optional options', () => {
it('should create root scoped factory with dependencies and options', () => {
const metaFactory = createServiceFactory((_options?: TestOptions) => ({
service: createServiceRef({ id: 'foo', scope: 'root' }),
deps: {
@@ -325,49 +286,7 @@ describe('createServiceFactory', () => {
metaFactory();
});
it('should create factory with required options and dependencies', () => {
const metaFactory = createServiceFactory((_opts: TestOptions) => ({
service: ref,
deps: {
root: rootDep,
plugin: pluginDep,
},
async createRootContext({ root }) {
const root1: number = root;
// @ts-expect-error
const root2: string = root;
unused(root1, root2);
return { root };
},
async factory({ plugin }, { root }) {
const root1: number = root;
// @ts-expect-error
const root2: string = root;
const plugin3: boolean = plugin;
// @ts-expect-error
const plugin4: number = plugin;
unused(root1, root2, plugin3, plugin4);
return 'x';
},
}));
expect(metaFactory).toEqual(expect.any(Function));
// @ts-expect-error
metaFactory('string');
// @ts-expect-error
metaFactory({});
metaFactory({ x: 1 });
// @ts-expect-error
metaFactory({ x: 1, y: 2 });
// @ts-expect-error
metaFactory(null);
// @ts-expect-error
metaFactory(undefined);
// @ts-expect-error
metaFactory();
});
it('should create factory with optional options and dependencies', () => {
it('should create factory with options and dependencies', () => {
const metaFactory = createServiceFactory((_opts?: TestOptions) => ({
service: ref,
deps: {
@@ -191,20 +191,6 @@ export function createServiceFactory<
>(
config: (options?: TOpts) => RootServiceFactoryConfig<TService, TImpl, TDeps>,
): (options?: TOpts) => ServiceFactory<TService, 'root'>;
/**
* Creates a root scoped service factory with required options.
*
* @public
* @param config - The service factory configuration.
*/
export function createServiceFactory<
TService,
TImpl extends TService,
TDeps extends { [name in string]: ServiceRef<unknown> },
TOpts extends object | undefined = undefined,
>(
config: (options: TOpts) => RootServiceFactoryConfig<TService, TImpl, TDeps>,
): (options: TOpts) => ServiceFactory<TService, 'root'>;
/**
* Creates a plugin scoped service factory without options.
*
@@ -237,25 +223,6 @@ export function createServiceFactory<
options?: TOpts,
) => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>,
): (options?: TOpts) => ServiceFactory<TService, 'plugin'>;
/**
* Creates a plugin scoped service factory with required options.
*
* @public
* @param config - The service factory configuration.
*/
export function createServiceFactory<
TService,
TImpl extends TService,
TDeps extends { [name in string]: ServiceRef<unknown> },
TContext = undefined,
TOpts extends object | undefined = undefined,
>(
config:
| PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>
| ((
options: TOpts,
) => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>),
): (options: TOpts) => ServiceFactory<TService, 'plugin'>;
export function createServiceFactory<
TService,
TImpl extends TService,