frontend-app-api: Add getData method to ExtensionInstance

Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Philipp Hugenroth <philipph@spotify.com>
Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
Johan Haals
2023-09-11 16:42:55 +02:00
parent 2949a8154f
commit 34ffe5654c
2 changed files with 18 additions and 23 deletions
@@ -174,13 +174,8 @@ export function createApp(options: {
return {
createRoot() {
const rootComponents = rootInstances
.map(
e =>
e.data.get(
coreExtensionData.reactComponent.id,
) as typeof coreExtensionData.reactComponent.T,
)
.filter(Boolean);
.map(e => e.getData(coreExtensionData.reactComponent))
.filter((x): x is React.ComponentType => !!x);
return (
<ApiProvider apis={apiHolder}>
<AppContextProvider appContext={appContext}>
@@ -254,13 +249,8 @@ function createApiHolder(
const apiFactories =
coreExtension.attachments
.get('apis')
?.map(
e =>
e.data.get(
coreExtensionData.apiFactory.id,
) as typeof coreExtensionData.apiFactory.T,
)
.filter(Boolean) ?? [];
?.map(e => e.getData(coreExtensionData.apiFactory))
.filter((x): x is AnyApiFactory => !!x) ?? [];
for (const factory of apiFactories) {
factoryRegistry.register('default', factory);
@@ -307,10 +297,8 @@ export function extractRouteInfoFromInstanceTree(
const results = new Map<RouteRef, string>();
function visit(current: ExtensionInstance, basePath: string) {
const routePath = current.data.get(coreExtensionData.routePath.id) ?? '';
const routeRef = current.data.get(
coreExtensionData.routeRef.id,
) as RouteRef;
const routePath = current.getData(coreExtensionData.routePath) ?? '';
const routeRef = current.getData(coreExtensionData.routeRef);
// TODO: join paths in a more robust way
const fullPath = basePath + routePath;
@@ -14,16 +14,20 @@
* limitations under the License.
*/
import { BackstagePlugin, Extension } from '@backstage/frontend-plugin-api';
import {
BackstagePlugin,
Extension,
ExtensionDataRef,
} from '@backstage/frontend-plugin-api';
import mapValues from 'lodash/mapValues';
/** @internal */
export interface ExtensionInstance {
readonly id: string;
/**
* Maps extension data ref IDs to extensions produced.
* Get concrete value for the given extension data reference. Returns undefined if no value is available.
*/
readonly data: Map<string, unknown>;
getData<T>(ref: ExtensionDataRef<T>): T | undefined;
/**
* Maps input names to the actual instances given to them.
*/
@@ -70,7 +74,7 @@ export function createExtensionInstance(options: {
({ extensionData: pointData }, inputName) => {
// TODO: validation
return (attachments.get(inputName) ?? []).map(attachment =>
mapValues(pointData, ref => attachment.data.get(ref.id)),
mapValues(pointData, ref => attachment.getData(ref)),
);
},
),
@@ -83,7 +87,10 @@ export function createExtensionInstance(options: {
return {
id: options.extension.id,
data: extensionData,
getData<T>(ref: ExtensionDataRef<T>): T | undefined {
return extensionData.get(ref.id) as T | undefined;
},
attachments,
$$type: 'extension-instance',
};