backend-plugin-api: refactor feature factories with new option callback pattern

Co-authored-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: blam <ben@blam.sh>
Co-authored-by: Johan Haals <johan.haals@gmail.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-01-11 14:30:50 +01:00
parent 76110d7787
commit 53d8f4fb8c
3 changed files with 58 additions and 39 deletions
+8
View File
@@ -21,6 +21,14 @@
*/
export type MaybeOptions = object | undefined;
/**
* @ignore
*/
export type FactoryFunctionConfig<TConfig, TOptions> =
| TConfig
| ((options: TOptions) => TConfig)
| (() => TConfig);
/**
* Helper type that makes the options argument optional if options are not required.
*
@@ -32,10 +32,10 @@ describe('createExtensionPoint', () => {
describe('createBackendPlugin', () => {
it('should create a BackendPlugin', () => {
const plugin = createBackendPlugin({
const plugin = createBackendPlugin((_options: { a: string }) => ({
id: 'x',
register(_reg, _options: { a: string }) {},
});
register() {},
}));
expect(plugin).toBeDefined();
expect(plugin({ a: 'a' })).toBeDefined();
expect(plugin({ a: 'a' }).id).toBe('x');
@@ -46,10 +46,10 @@ describe('createBackendPlugin', () => {
});
it('should create plugins with optional options', () => {
const plugin = createBackendPlugin({
const plugin = createBackendPlugin((_options?: { a: string }) => ({
id: 'x',
register(_reg, _options?: { a: string }) {},
});
register() {},
}));
expect(plugin).toBeDefined();
expect(plugin({ a: 'a' })).toBeDefined();
expect(plugin()).toBeDefined();
@@ -73,10 +73,10 @@ describe('createBackendPlugin', () => {
interface TestOptions {
a: string;
}
const plugin = createBackendPlugin({
const plugin = createBackendPlugin((_options: TestOptions) => ({
id: 'x',
register(_reg, _options: TestOptions) {},
});
register() {},
}));
expect(plugin).toBeDefined();
expect(plugin({ a: 'a' })).toBeDefined();
expect(plugin({ a: 'a' }).id).toBe('x');
@@ -90,10 +90,10 @@ describe('createBackendPlugin', () => {
interface TestOptions {
a: string;
}
const plugin = createBackendPlugin({
const plugin = createBackendPlugin((_options?: TestOptions) => ({
id: 'x',
register(_reg, _options?: TestOptions) {},
});
register() {},
}));
expect(plugin).toBeDefined();
expect(plugin({ a: 'a' })).toBeDefined();
expect(plugin()).toBeDefined();
@@ -104,11 +104,11 @@ describe('createBackendPlugin', () => {
describe('createBackendModule', () => {
it('should create a BackendModule', () => {
const mod = createBackendModule({
const mod = createBackendModule((_options: { a: string }) => ({
pluginId: 'x',
moduleId: 'y',
register(_reg, _options: { a: string }) {},
});
register() {},
}));
expect(mod).toBeDefined();
expect(mod({ a: 'a' })).toBeDefined();
expect(mod({ a: 'a' }).id).toBe('x.y');
@@ -119,11 +119,11 @@ describe('createBackendModule', () => {
});
it('should create modules with optional options', () => {
const mod = createBackendModule({
const mod = createBackendModule((_options?: { a: string }) => ({
pluginId: 'x',
moduleId: 'y',
register(_reg, _options?: { a: string }) {},
});
register() {},
}));
expect(mod).toBeDefined();
expect(mod({ a: 'a' })).toBeDefined();
expect(mod()).toBeDefined();
@@ -148,11 +148,11 @@ describe('createBackendModule', () => {
interface TestOptions {
a: string;
}
const mod = createBackendModule({
const mod = createBackendModule((_options: TestOptions) => ({
pluginId: 'x',
moduleId: 'y',
register(_reg, _options: TestOptions) {},
});
register() {},
}));
expect(mod).toBeDefined();
expect(mod({ a: 'a' })).toBeDefined();
expect(mod({ a: 'a' }).id).toBe('x.y');
@@ -166,11 +166,11 @@ describe('createBackendModule', () => {
interface TestOptions {
a: string;
}
const mod = createBackendModule({
const mod = createBackendModule((_options?: TestOptions) => ({
pluginId: 'x',
moduleId: 'y',
register(_reg, _options?: TestOptions) {},
});
register() {},
}));
expect(mod).toBeDefined();
expect(mod({ a: 'a' })).toBeDefined();
expect(mod()).toBeDefined();
@@ -14,7 +14,11 @@
* limitations under the License.
*/
import { FactoryFunctionWithOptions, MaybeOptions } from '../types';
import {
FactoryFunctionWithOptions,
MaybeOptions,
FactoryFunctionConfig,
} from '../types';
import {
BackendRegistrationPoints,
BackendFeature,
@@ -43,30 +47,28 @@ export function createExtensionPoint<T>(
}
/** @public */
export interface BackendPluginConfig<TOptions> {
export interface BackendPluginConfig {
id: string;
register(reg: BackendRegistrationPoints, options: TOptions): void;
register(reg: BackendRegistrationPoints): void;
}
/** @public */
export function createBackendPlugin<TOptions extends MaybeOptions = undefined>(
config: BackendPluginConfig<TOptions>,
config: FactoryFunctionConfig<BackendPluginConfig, TOptions>,
): FactoryFunctionWithOptions<BackendFeature, TOptions> {
return (options?: TOptions) => ({
id: config.id,
register(register: BackendRegistrationPoints) {
return config.register(register, options!);
},
});
if (typeof config === 'function') {
return config as FactoryFunctionWithOptions<BackendFeature, TOptions>;
}
return () => config;
}
/** @public */
export interface BackendModuleConfig<TOptions> {
export interface BackendModuleConfig {
pluginId: string;
moduleId: string;
register(
reg: Omit<BackendRegistrationPoints, 'registerExtensionPoint'>,
options: TOptions,
): void;
}
@@ -85,13 +87,22 @@ export interface BackendModuleConfig<TOptions> {
* The `pluginId` should exactly match the `id` of the plugin that the module extends.
*/
export function createBackendModule<TOptions extends MaybeOptions = undefined>(
config: BackendModuleConfig<TOptions>,
config: FactoryFunctionConfig<BackendModuleConfig, TOptions>,
): FactoryFunctionWithOptions<BackendFeature, TOptions> {
return (options?: TOptions) => ({
if (typeof config === 'function') {
return (options?: TOptions) => {
const c = config(options!);
return {
id: `${c.pluginId}.${c.moduleId}`,
register: c.register,
};
};
}
return () => ({
id: `${config.pluginId}.${config.moduleId}`,
register(register: BackendRegistrationPoints) {
// TODO: Hide registerExtensionPoint
return config.register(register, options!);
return config.register(register);
},
});
}