frontend-app-api: Add Extension utilities
Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Co-authored-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: Camila Belo <camilaibs@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
@@ -5,7 +5,11 @@
|
||||
```ts
|
||||
import { BackstagePlugin } from '@backstage/frontend-plugin-api';
|
||||
import { ConfigApi } from '@backstage/core-plugin-api';
|
||||
<<<<<<< HEAD
|
||||
import { JSX as JSX_2 } from 'react';
|
||||
=======
|
||||
import { ExtensionDataRef } from '@backstage/frontend-plugin-api';
|
||||
>>>>>>> ed3fd70bda19 (frontend-app-api: Add Extension utilities)
|
||||
|
||||
// @public (undocumented)
|
||||
export function createApp(options: {
|
||||
@@ -14,4 +18,33 @@ export function createApp(options: {
|
||||
}): {
|
||||
createRoot(): JSX_2.Element;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export function createExtensionTree(): ExtensionTree;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ExtensionInstance {
|
||||
// (undocumented)
|
||||
readonly $$type: '@backstage/ExtensionInstance';
|
||||
readonly attachments: Map<string, ExtensionInstance[]>;
|
||||
getData<T>(ref: ExtensionDataRef<T>): T | undefined;
|
||||
// (undocumented)
|
||||
readonly id: string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ExtensionTree {
|
||||
// (undocumented)
|
||||
getExtension(id: string): ExtensionInstance | undefined;
|
||||
// (undocumented)
|
||||
getExtensionAttachments(id: string, inputName: string): ExtensionInstance[];
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ExtensionTreeNode {
|
||||
// (undocumented)
|
||||
getData<T>(ref: ExtensionDataRef<T>): T | undefined;
|
||||
// (undocumented)
|
||||
id: string;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ConfigReader } from '@backstage/config';
|
||||
import {
|
||||
BackstagePlugin,
|
||||
coreExtensionData,
|
||||
ExtensionDataRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { Core } from '../extensions/Core';
|
||||
import { CoreRoutes } from '../extensions/CoreRoutes';
|
||||
@@ -76,26 +77,55 @@ import {
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
|
||||
/** @public */
|
||||
export function createApp(options: {
|
||||
plugins: BackstagePlugin[];
|
||||
config?: ConfigApi;
|
||||
}): {
|
||||
createRoot(): JSX.Element;
|
||||
} {
|
||||
const appConfig =
|
||||
options?.config ??
|
||||
ConfigReader.fromConfigs(overrideBaseUrlConfigs(defaultConfigLoaderSync()));
|
||||
export interface ExtensionTreeNode {
|
||||
id: string;
|
||||
getData<T>(ref: ExtensionDataRef<T>): T | undefined;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface ExtensionTree {
|
||||
getExtension(id: string): ExtensionInstance | undefined;
|
||||
getExtensionAttachments(id: string, inputName: string): ExtensionInstance[];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function createExtensionTree(): ExtensionTree {
|
||||
const plugins = getAvailablePlugins();
|
||||
const { instances } = createInstances({
|
||||
plugins,
|
||||
config: ConfigReader.fromConfigs(
|
||||
overrideBaseUrlConfigs(defaultConfigLoaderSync()),
|
||||
),
|
||||
});
|
||||
|
||||
return {
|
||||
getExtension(id: string): ExtensionInstance | undefined {
|
||||
return instances.get(id);
|
||||
},
|
||||
getExtensionAttachments(
|
||||
id: string,
|
||||
inputName: string,
|
||||
): ExtensionInstance[] {
|
||||
return this.getExtension(id)?.attachments.get(inputName) ?? [];
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function createInstances(options: {
|
||||
plugins: BackstagePlugin[];
|
||||
config: ConfigApi;
|
||||
}) {
|
||||
const builtinExtensions = [Core, CoreRoutes, CoreNav, CoreLayout];
|
||||
const discoveredPlugins = getAvailablePlugins();
|
||||
const allPlugins = [...discoveredPlugins, ...options.plugins];
|
||||
|
||||
// pull in default extension instance from discovered packages
|
||||
// apply config to adjust default extension instances and add more
|
||||
const extensionParams = mergeExtensionParameters({
|
||||
sources: allPlugins,
|
||||
sources: options.plugins,
|
||||
builtinExtensions,
|
||||
parameters: readAppExtensionParameters(appConfig),
|
||||
parameters: readAppExtensionParameters(options.config),
|
||||
});
|
||||
|
||||
// TODO: validate the config of all extension instances
|
||||
@@ -156,10 +186,32 @@ export function createApp(options: {
|
||||
}
|
||||
|
||||
const rootConfigs = attachmentMap.get('root')?.get('default') ?? [];
|
||||
|
||||
const rootInstances = rootConfigs.map(instanceParams =>
|
||||
createInstance(instanceParams),
|
||||
);
|
||||
|
||||
return { instances, rootInstances };
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function createApp(options: {
|
||||
plugins: BackstagePlugin[];
|
||||
config?: ConfigApi;
|
||||
}): {
|
||||
createRoot(): JSX.Element;
|
||||
} {
|
||||
const discoveredPlugins = getAvailablePlugins();
|
||||
const allPlugins = [...discoveredPlugins, ...options.plugins];
|
||||
const appConfig =
|
||||
options?.config ??
|
||||
ConfigReader.fromConfigs(overrideBaseUrlConfigs(defaultConfigLoaderSync()));
|
||||
|
||||
const { rootInstances } = createInstances({
|
||||
plugins: allPlugins,
|
||||
config: appConfig,
|
||||
});
|
||||
|
||||
const routePaths = extractRouteInfoFromInstanceTree(rootInstances);
|
||||
|
||||
const coreInstance = rootInstances.find(({ id }) => id === 'core');
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
|
||||
/** @internal */
|
||||
/** @public */
|
||||
export interface ExtensionInstance {
|
||||
readonly $$type: '@backstage/ExtensionInstance';
|
||||
|
||||
|
||||
@@ -14,4 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { createApp } from './createApp';
|
||||
export type { ExtensionInstance } from './createExtensionInstance';
|
||||
export {
|
||||
createApp,
|
||||
createExtensionTree,
|
||||
type ExtensionTreeNode,
|
||||
type ExtensionTree,
|
||||
} from './createApp';
|
||||
|
||||
Reference in New Issue
Block a user