Merge pull request #15522 from backstage/rugvip/clean

backend-plugin-api: doc cleanup for create methods
This commit is contained in:
Patrik Oldsberg
2023-01-09 11:16:18 +01:00
committed by GitHub
7 changed files with 180 additions and 106 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-plugin-api': patch
---
Updates all `create*` methods to simplify their type definitions and ensure they all have configuration interfaces.
+61 -46
View File
@@ -111,28 +111,19 @@ export namespace coreServices {
}
// @public
export function createBackendModule<
TOptions extends object | undefined = undefined,
>(
export function createBackendModule<TOptions extends MaybeOptions = undefined>(
config: BackendModuleConfig<TOptions>,
): undefined extends TOptions
? (options?: TOptions) => BackendFeature
: (options: TOptions) => BackendFeature;
): FactoryFunctionWithOptions<BackendFeature, TOptions>;
// @public (undocumented)
export function createBackendPlugin<
TOptions extends object | undefined = undefined,
>(config: {
id: string;
register(reg: BackendRegistrationPoints, options: TOptions): void;
}): undefined extends TOptions
? (options?: TOptions) => BackendFeature
: (options: TOptions) => BackendFeature;
export function createBackendPlugin<TOptions extends MaybeOptions = undefined>(
config: BackendPluginConfig<TOptions>,
): FactoryFunctionWithOptions<BackendFeature, TOptions>;
// @public (undocumented)
export function createExtensionPoint<T>(options: {
id: string;
}): ExtensionPoint<T>;
export function createExtensionPoint<T>(
config: ExtensionPointConfig,
): ExtensionPoint<T>;
// @public (undocumented)
export function createServiceFactory<
@@ -142,37 +133,20 @@ export function createServiceFactory<
TDeps extends {
[name in string]: ServiceRef<unknown>;
},
TOpts extends object | undefined = undefined,
>(config: {
service: ServiceRef<TService, TScope>;
deps: TDeps;
factory(
deps: ServiceRefsToInstances<TDeps, 'root'>,
options: TOpts,
): TScope extends 'root'
? Promise<TImpl>
: Promise<(deps: ServiceRefsToInstances<TDeps>) => Promise<TImpl>>;
}): undefined extends TOpts
? (options?: TOpts) => ServiceFactory<TService>
: (options: TOpts) => ServiceFactory<TService>;
TOpts extends MaybeOptions = undefined,
>(
config: ServiceFactoryConfig<TService, TScope, TImpl, TDeps, TOpts>,
): FactoryFunctionWithOptions<ServiceFactory<TService>, TOpts>;
// @public (undocumented)
export function createServiceRef<T>(options: {
id: string;
scope?: 'plugin';
defaultFactory?: (
service: ServiceRef<T, 'plugin'>,
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>;
}): ServiceRef<T, 'plugin'>;
// @public
export function createServiceRef<TService>(
config: ServiceRefConfig<TService, 'plugin'>,
): ServiceRef<TService, 'plugin'>;
// @public (undocumented)
export function createServiceRef<T>(options: {
id: string;
scope: 'root';
defaultFactory?: (
service: ServiceRef<T, 'root'>,
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>;
}): ServiceRef<T, 'root'>;
// @public
export function createServiceRef<TService>(
config: ServiceRefConfig<TService, 'root'>,
): ServiceRef<TService, 'root'>;
// @public
export interface DatabaseService {
@@ -196,6 +170,12 @@ export type ExtensionPoint<T> = {
$$ref: 'extension-point';
};
// @public (undocumented)
export interface ExtensionPointConfig {
// (undocumented)
id: string;
}
// @public (undocumented)
export interface HttpRouterService {
// (undocumented)
@@ -344,6 +324,29 @@ export type ServiceFactory<TService = unknown> =
>;
};
// @public (undocumented)
export interface ServiceFactoryConfig<
TService,
TScope extends 'root' | 'plugin',
TImpl extends TService,
TDeps extends {
[name in string]: ServiceRef<unknown>;
},
TOpts extends MaybeOptions = undefined,
> {
// (undocumented)
deps: TDeps;
// (undocumented)
factory(
deps: ServiceRefsToInstances<TDeps, 'root'>,
options: TOpts,
): TScope extends 'root'
? Promise<TImpl>
: Promise<(deps: ServiceRefsToInstances<TDeps>) => Promise<TImpl>>;
// (undocumented)
service: ServiceRef<TService, TScope>;
}
// @public
export type ServiceRef<
TService,
@@ -356,6 +359,18 @@ export type ServiceRef<
$$ref: 'service';
};
// @public (undocumented)
export interface ServiceRefConfig<TService, TScope extends 'root' | 'plugin'> {
// (undocumented)
defaultFactory?: (
service: ServiceRef<TService, TScope>,
) => Promise<ServiceFactory<TService> | (() => ServiceFactory<TService>)>;
// (undocumented)
id: string;
// (undocumented)
scope?: TScope;
}
// @public
export interface TokenManagerService {
authenticate(token: string): Promise<void>;
@@ -14,5 +14,11 @@
* limitations under the License.
*/
export type { ServiceRef, TypesToServiceRef, ServiceFactory } from './types';
export type {
ServiceRef,
ServiceRefConfig,
TypesToServiceRef,
ServiceFactory,
ServiceFactoryConfig,
} from './types';
export { createServiceRef, createServiceFactory } from './types';
@@ -14,6 +14,8 @@
* limitations under the License.
*/
import { FactoryFunctionWithOptions, MaybeOptions } from '../../types';
/**
* TODO
*
@@ -70,48 +72,50 @@ export type ServiceFactory<TService = unknown> =
};
/** @public */
export function createServiceRef<T>(options: {
export interface ServiceRefConfig<TService, TScope extends 'root' | 'plugin'> {
id: string;
scope?: 'plugin';
scope?: TScope;
defaultFactory?: (
service: ServiceRef<T, 'plugin'>,
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>;
}): ServiceRef<T, 'plugin'>;
/** @public */
export function createServiceRef<T>(options: {
id: string;
scope: 'root';
defaultFactory?: (
service: ServiceRef<T, 'root'>,
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>;
}): ServiceRef<T, 'root'>;
export function createServiceRef<T>(options: {
id: string;
scope?: 'plugin' | 'root';
defaultFactory?:
| ((
service: ServiceRef<T, 'plugin'>,
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>)
| ((
service: ServiceRef<T, 'root'>,
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>);
}): ServiceRef<T> {
const { id, scope = 'plugin', defaultFactory } = options;
service: ServiceRef<TService, TScope>,
) => Promise<ServiceFactory<TService> | (() => ServiceFactory<TService>)>;
}
/**
* Creates a new service definition. This overload is used to create plugin scoped services.
*
* @public
*/
export function createServiceRef<TService>(
config: ServiceRefConfig<TService, 'plugin'>,
): ServiceRef<TService, 'plugin'>;
/**
* Creates a new service definition. This overload is used to create root scoped services.
*
* @public
*/
export function createServiceRef<TService>(
config: ServiceRefConfig<TService, 'root'>,
): ServiceRef<TService, 'root'>;
export function createServiceRef<TService>(
config: ServiceRefConfig<TService, any>,
): ServiceRef<TService, any> {
const { id, scope = 'plugin', defaultFactory } = config;
return {
id,
scope,
get T(): T {
get T(): TService {
throw new Error(`tried to read ServiceRef.T of ${this}`);
},
toString() {
return `serviceRef{${options.id}}`;
return `serviceRef{${config.id}}`;
},
$$ref: 'service', // TODO: declare
__defaultFactory: defaultFactory,
} as ServiceRef<T, typeof scope> & {
} as ServiceRef<TService, typeof scope> & {
__defaultFactory?: (
service: ServiceRef<T>,
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>;
service: ServiceRef<TService>,
) => Promise<ServiceFactory<TService> | (() => ServiceFactory<TService>)>;
};
}
@@ -125,16 +129,14 @@ type ServiceRefsToInstances<
}[keyof T]]: T[name] extends ServiceRef<infer TImpl> ? TImpl : never;
};
/**
* @public
*/
export function createServiceFactory<
/** @public */
export interface ServiceFactoryConfig<
TService,
TScope extends 'root' | 'plugin',
TImpl extends TService,
TDeps extends { [name in string]: ServiceRef<unknown> },
TOpts extends object | undefined = undefined,
>(config: {
TOpts extends MaybeOptions = undefined,
> {
service: ServiceRef<TService, TScope>;
deps: TDeps;
factory(
@@ -143,9 +145,20 @@ export function createServiceFactory<
): TScope extends 'root'
? Promise<TImpl>
: Promise<(deps: ServiceRefsToInstances<TDeps>) => Promise<TImpl>>;
}): undefined extends TOpts
? (options?: TOpts) => ServiceFactory<TService>
: (options: TOpts) => ServiceFactory<TService> {
}
/**
* @public
*/
export function createServiceFactory<
TService,
TScope extends 'root' | 'plugin',
TImpl extends TService,
TDeps extends { [name in string]: ServiceRef<unknown> },
TOpts extends MaybeOptions = undefined,
>(
config: ServiceFactoryConfig<TService, TScope, TImpl, TDeps, TOpts>,
): FactoryFunctionWithOptions<ServiceFactory<TService>, TOpts> {
return (options?: TOpts) =>
({
scope: config.service.scope,
+32
View File
@@ -0,0 +1,32 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Base type for options objects that aren't required.
*
* @ignore
*/
export type MaybeOptions = object | undefined;
/**
* Helper type that makes the options argument optional if options are not required.
*
* @ignore
*/
export type FactoryFunctionWithOptions<TResult, TOptions> =
undefined extends TOptions
? (options?: TOptions) => TResult
: (options: TOptions) => TResult;
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { FactoryFunctionWithOptions, MaybeOptions } from '../types';
import {
BackendRegistrationPoints,
BackendFeature,
@@ -21,16 +22,21 @@ import {
} from './types';
/** @public */
export function createExtensionPoint<T>(options: {
export interface ExtensionPointConfig {
id: string;
}): ExtensionPoint<T> {
}
/** @public */
export function createExtensionPoint<T>(
config: ExtensionPointConfig,
): ExtensionPoint<T> {
return {
id: options.id,
id: config.id,
get T(): T {
throw new Error(`tried to read ExtensionPoint.T of ${this}`);
},
toString() {
return `extensionPoint{${options.id}}`;
return `extensionPoint{${config.id}}`;
},
$$ref: 'extension-point', // TODO: declare
};
@@ -43,14 +49,9 @@ export interface BackendPluginConfig<TOptions> {
}
/** @public */
export function createBackendPlugin<
TOptions extends object | undefined = undefined,
>(config: {
id: string;
register(reg: BackendRegistrationPoints, options: TOptions): void;
}): undefined extends TOptions
? (options?: TOptions) => BackendFeature
: (options: TOptions) => BackendFeature {
export function createBackendPlugin<TOptions extends MaybeOptions = undefined>(
config: BackendPluginConfig<TOptions>,
): FactoryFunctionWithOptions<BackendFeature, TOptions> {
return (options?: TOptions) => ({
id: config.id,
register(register: BackendRegistrationPoints) {
@@ -70,9 +71,11 @@ export interface BackendModuleConfig<TOptions> {
}
/**
* Creates a new backend module for a given plugin.
*
* @public
*
* Creates a new backend module for a given plugin.
* @remarks
*
* The `moduleId` should be equal to the module-specific prefix of the exported name, such
* that the full name is `moduleId + PluginId + "Module"`. For example, a GitHub entity
@@ -81,13 +84,9 @@ export interface BackendModuleConfig<TOptions> {
*
* The `pluginId` should exactly match the `id` of the plugin that the module extends.
*/
export function createBackendModule<
TOptions extends object | undefined = undefined,
>(
export function createBackendModule<TOptions extends MaybeOptions = undefined>(
config: BackendModuleConfig<TOptions>,
): undefined extends TOptions
? (options?: TOptions) => BackendFeature
: (options: TOptions) => BackendFeature {
): FactoryFunctionWithOptions<BackendFeature, TOptions> {
return (options?: TOptions) => ({
id: `${config.pluginId}.${config.moduleId}`,
register(register: BackendRegistrationPoints) {
@@ -14,7 +14,11 @@
* limitations under the License.
*/
export type { BackendModuleConfig, BackendPluginConfig } from './factories';
export type {
BackendModuleConfig,
BackendPluginConfig,
ExtensionPointConfig,
} from './factories';
export {
createBackendModule,
createBackendPlugin,