frontend-app-api: fix circular dependency

Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
Vincenzo Scamporlino
2023-11-13 14:20:45 +01:00
committed by Patrik Oldsberg
parent e3bd5ab726
commit 50a9e40122
4 changed files with 58 additions and 40 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ export type AppRouteBinder = <
) => void;
// @public (undocumented)
export function createApp(options?: {
export function createApp(options: {
features?: (BackstagePlugin | ExtensionOverrides)[];
configLoader?: () => Promise<ConfigApi>;
bindRoutes?(context: { bind: AppRouteBinder }): void;
@@ -15,10 +15,9 @@
*/
import { RouteRef, coreExtensionData } from '@backstage/frontend-plugin-api';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { toLegacyPlugin } from '../wiring/createApp';
import { BackstageRouteObject } from './types';
import { AppNode } from '@backstage/frontend-plugin-api';
import { toLegacyPlugin } from './toLegacyPlugin';
// We always add a child that matches all subroutes but without any route refs. This makes
// sure that we're always able to match each route no matter how deep the navigation goes.
@@ -0,0 +1,55 @@
/*
* 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.
*/
import { BackstagePlugin } from '@backstage/frontend-plugin-api';
import { BackstagePlugin as LegacyBackstagePlugin } from '@backstage/core-plugin-api';
import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
// Make sure that we only convert each new plugin instance to its legacy equivalent once
const legacyPluginStore = getOrCreateGlobalSingleton(
'legacy-plugin-compatibility-store',
() => new WeakMap<BackstagePlugin, LegacyBackstagePlugin>(),
);
export function toLegacyPlugin(plugin: BackstagePlugin): LegacyBackstagePlugin {
let legacy = legacyPluginStore.get(plugin);
if (legacy) {
return legacy;
}
const errorMsg = 'Not implemented in legacy plugin compatibility layer';
const notImplemented = () => {
throw new Error(errorMsg);
};
legacy = {
getId(): string {
return plugin.id;
},
get routes() {
return {};
},
get externalRoutes() {
return {};
},
getApis: notImplemented,
getFeatureFlags: notImplemented,
provide: notImplemented,
};
legacyPluginStore.set(plugin, legacy);
return legacy;
}
@@ -80,7 +80,6 @@ import { BrowserRouter, Route } from 'react-router-dom';
import { SidebarItem } from '@backstage/core-components';
import { DarkTheme, LightTheme } from '../extensions/themes';
import { extractRouteInfoFromAppNode } from '../routing/extractRouteInfoFromAppNode';
import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
import {
appLanguageApiRef,
translationApiRef,
@@ -91,6 +90,7 @@ import { resolveRouteBindings } from '../routing/resolveRouteBindings';
import { collectRouteIds } from '../routing/collectRouteIds';
import { createAppTree } from '../tree';
import { AppNode } from '@backstage/frontend-plugin-api';
import { toLegacyPlugin } from '../routing/toLegacyPlugin';
const builtinExtensions = [
Core,
@@ -328,42 +328,6 @@ export function createSpecializedApp(options?: {
};
}
// Make sure that we only convert each new plugin instance to its legacy equivalent once
const legacyPluginStore = getOrCreateGlobalSingleton(
'legacy-plugin-compatibility-store',
() => new WeakMap<BackstagePlugin, LegacyBackstagePlugin>(),
);
export function toLegacyPlugin(plugin: BackstagePlugin): LegacyBackstagePlugin {
let legacy = legacyPluginStore.get(plugin);
if (legacy) {
return legacy;
}
const errorMsg = 'Not implemented in legacy plugin compatibility layer';
const notImplemented = () => {
throw new Error(errorMsg);
};
legacy = {
getId(): string {
return plugin.id;
},
get routes() {
return {};
},
get externalRoutes() {
return {};
},
getApis: notImplemented,
getFeatureFlags: notImplemented,
provide: notImplemented,
};
legacyPluginStore.set(plugin, legacy);
return legacy;
}
function createLegacyAppContext(plugins: BackstagePlugin[]): AppContext {
return {
getPlugins(): LegacyBackstagePlugin[] {