frontend-plugin-api: add ExtensionDefinition IR

Co-authored-by: Philipp Hugenroth <philipph@spotify.com>
Co-authored-by: Camila Belo <camilaibs@gmail.com>
Co-authored-by: Vincenzo Scamporlino <vincenzos@spotify.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-11-21 16:49:25 +01:00
parent f808e625cf
commit 7e1907047f
2 changed files with 44 additions and 6 deletions
@@ -73,7 +73,9 @@ export interface CreateExtensionOptions<
TInputs extends AnyExtensionInputMap,
TConfig,
> {
id: string;
namespace?: string;
name?: string;
kind?: string;
attachTo: { id: string; input: string };
disabled?: boolean;
inputs?: TInputs;
@@ -86,6 +88,27 @@ export interface CreateExtensionOptions<
}): Expand<ExtensionDataValues<TOutput>>;
}
/** @public */
export interface ExtensionDefinition<TConfig> {
$$type: '@backstage/ExtensionDefinition';
namespace?: string;
name?: string;
kind?: string;
attachTo: { id: string; input: string };
disabled: boolean;
inputs: AnyExtensionInputMap;
output: AnyExtensionDataMap;
configSchema?: PortableSchema<TConfig>;
factory(options: {
node: AppNode;
config: TConfig;
inputs: Record<
string,
undefined | Record<string, unknown> | Array<Record<string, unknown>>
>;
}): ExtensionDataValues<any>;
}
/** @public */
export interface Extension<TConfig> {
$$type: '@backstage/Extension';
@@ -112,11 +135,11 @@ export function createExtension<
TConfig = never,
>(
options: CreateExtensionOptions<TOutput, TInputs, TConfig>,
): Extension<TConfig> {
): ExtensionDefinition<TConfig> {
return {
...options,
disabled: options.disabled ?? false,
$$type: '@backstage/Extension',
$$type: '@backstage/ExtensionDefinition',
inputs: options.inputs ?? {},
factory({ inputs, ...rest }) {
// TODO: Simplify this, but TS wouldn't infer the input type for some reason
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { Extension } from './createExtension';
import { Extension, ExtensionDefinition } from './createExtension';
import { ExternalRouteRef, RouteRef } from '../routing';
import { FeatureFlagConfig } from './types';
@@ -32,7 +32,7 @@ export interface PluginOptions<
id: string;
routes?: Routes;
externalRoutes?: ExternalRoutes;
extensions?: Extension<unknown>[];
extensions?: ExtensionDefinition<unknown>[];
featureFlags?: FeatureFlagConfig[];
}
@@ -70,8 +70,23 @@ export function createPlugin<
id: options.id,
routes: options.routes ?? ({} as Routes),
externalRoutes: options.externalRoutes ?? ({} as ExternalRoutes),
extensions: options.extensions ?? [],
featureFlags: options.featureFlags ?? [],
extensions: (options.extensions ?? []).map(definition => {
const { name, namespace: _, kind, ...rest } = definition;
let id;
if (kind && name) {
id = `${kind}:${options.id}/${name}`;
} else if (kind) {
id = `${kind}:${options.id}`;
} else if (name) {
id = `${options.id}/${name}`;
} else {
id = options.id;
}
return { id, ...rest, $$type: '@backstage/Extension' };
}),
} as InternalBackstagePlugin<Routes, ExternalRoutes>;
}