diff --git a/.changeset/angry-candies-draw.md b/.changeset/angry-candies-draw.md new file mode 100644 index 0000000000..fdf4d31994 --- /dev/null +++ b/.changeset/angry-candies-draw.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +The `source` property of `AppNodeSpec` has been renamed to `plugin`. The old property has been deprecated and will be removed in a future release. diff --git a/.changeset/evil-lies-punch.md b/.changeset/evil-lies-punch.md new file mode 100644 index 0000000000..e878c65731 --- /dev/null +++ b/.changeset/evil-lies-punch.md @@ -0,0 +1,6 @@ +--- +'@backstage/frontend-app-api': patch +'@backstage/core-compat-api': patch +--- + +Updates to use the new `plugin` property of `AppNodeSpec`. diff --git a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx index 151fb21067..0a5dd68aa3 100644 --- a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx +++ b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx @@ -119,7 +119,7 @@ function LegacyAppContextProvider(props: { children: ReactNode }) { const pluginSet = new Set(); for (const node of tree.nodes.values()) { - const plugin = node.spec.source; + const plugin = node.spec.plugin; if (plugin) { pluginSet.add(toLegacyPlugin(plugin)); } diff --git a/packages/frontend-app-api/src/routing/RouteTracker.test.tsx b/packages/frontend-app-api/src/routing/RouteTracker.test.tsx index 08a9673afc..5cee727075 100644 --- a/packages/frontend-app-api/src/routing/RouteTracker.test.tsx +++ b/packages/frontend-app-api/src/routing/RouteTracker.test.tsx @@ -49,7 +49,7 @@ describe('RouteTracker', () => { appNode: { spec: { extension: { id: 'home.page.index' }, - source: { id: 'home' }, + plugin: { id: 'home' }, }, } as AppNode, }, @@ -63,7 +63,7 @@ describe('RouteTracker', () => { appNode: { spec: { extension: { id: 'plugin1.page.index' }, - source: { id: 'plugin1' }, + plugin: { id: 'plugin1' }, }, } as AppNode, }, @@ -77,7 +77,7 @@ describe('RouteTracker', () => { appNode: { spec: { extension: { id: 'plugin2.page.index' }, - source: { id: 'plugin2' }, + plugin: { id: 'plugin2' }, }, } as AppNode, }, diff --git a/packages/frontend-app-api/src/routing/RouteTracker.tsx b/packages/frontend-app-api/src/routing/RouteTracker.tsx index 4a218a0900..0068f87d4d 100644 --- a/packages/frontend-app-api/src/routing/RouteTracker.tsx +++ b/packages/frontend-app-api/src/routing/RouteTracker.tsx @@ -63,7 +63,7 @@ const getExtensionContext = ( return acc; }, {}); - const plugin = routeObject.appNode?.spec.source; + const plugin = routeObject.appNode?.spec.plugin; const extension = routeObject.appNode?.spec.extension; return { diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.ts index 17afbeb4c9..a1abaf1599 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.ts @@ -124,8 +124,8 @@ export function extractRouteInfoFromAppNode(node: AppNode): { routeParents.set(routeRef, newParentRef); currentObj?.routeRefs.add(routeRef); - if (current.spec.source) { - currentObj?.plugins.add(toLegacyPlugin(current.spec.source)); + if (current.spec.plugin) { + currentObj?.plugins.add(toLegacyPlugin(current.spec.plugin)); } } diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index a000e016be..8801e2070e 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -57,6 +57,7 @@ function makeSpec( disabled: extension.disabled, extension: extension as Extension, source: undefined, + plugin: undefined, ...spec, }; } diff --git a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts index c486370563..979c851a47 100644 --- a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts +++ b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts @@ -126,6 +126,7 @@ describe('resolveAppNodeSpecs', () => { extension: makeExt('test/a'), attachTo: { id: 'root', input: 'default' }, source: pluginA, + plugin: pluginA, disabled: false, }, ]); @@ -162,6 +163,7 @@ describe('resolveAppNodeSpecs', () => { id: 'test/a', extension: a, attachTo: { id: 'root', input: 'default' }, + plugin, source: plugin, config: { foo: { bar: 1 } }, disabled: false, @@ -170,6 +172,7 @@ describe('resolveAppNodeSpecs', () => { id: 'test/b', extension: b, attachTo: { id: 'root', input: 'default' }, + plugin, source: plugin, config: { foo: { qux: 3 } }, disabled: false, @@ -305,6 +308,7 @@ describe('resolveAppNodeSpecs', () => { id: 'test/a', extension: expect.objectContaining(aOverride), attachTo: { id: 'other', input: 'default' }, + plugin, source: plugin, disabled: false, }, @@ -312,6 +316,7 @@ describe('resolveAppNodeSpecs', () => { id: 'test/b', extension: expect.objectContaining(bOverride), attachTo: { id: 'other', input: 'default' }, + plugin, source: plugin, disabled: true, }, @@ -319,6 +324,7 @@ describe('resolveAppNodeSpecs', () => { id: 'test/c', extension: expect.objectContaining(cOverride), attachTo: { id: 'root', input: 'default' }, + plugin, source: plugin, disabled: false, }, diff --git a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts index 3da68dcb50..399e6ccb7b 100644 --- a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts +++ b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts @@ -46,23 +46,23 @@ export function resolveAppNodeSpecs(options: { const plugins = features.filter(OpaqueFrontendPlugin.isType); const modules = features.filter(isInternalFrontendModule); - const pluginExtensions = plugins.flatMap(source => { - return OpaqueFrontendPlugin.toInternal(source).extensions.map( + const pluginExtensions = plugins.flatMap(plugin => { + return OpaqueFrontendPlugin.toInternal(plugin).extensions.map( extension => ({ ...extension, - source, + plugin, }), ); }); const moduleExtensions = modules.flatMap(mod => toInternalFrontendModule(mod).extensions.flatMap(extension => { // Modules for plugins that are not installed are ignored - const source = plugins.find(p => p.id === mod.pluginId); - if (!source) { + const plugin = plugins.find(p => p.id === mod.pluginId); + if (!plugin) { return []; } - return [{ ...extension, source }]; + return [{ ...extension, plugin }]; }), ); @@ -70,7 +70,7 @@ export function resolveAppNodeSpecs(options: { if (pluginExtensions.some(({ id }) => forbidden.has(id))) { const pluginsStr = pluginExtensions .filter(({ id }) => forbidden.has(id)) - .map(({ source }) => `'${source.id}'`) + .map(({ plugin }) => `'${plugin.id}'`) .join(', '); const forbiddenStr = [...forbidden].map(id => `'${id}'`).join(', '); throw new Error( @@ -80,7 +80,7 @@ export function resolveAppNodeSpecs(options: { if (moduleExtensions.some(({ id }) => forbidden.has(id))) { const pluginsStr = moduleExtensions .filter(({ id }) => forbidden.has(id)) - .map(({ source }) => `'${source.id}'`) + .map(({ plugin }) => `'${plugin.id}'`) .join(', '); const forbiddenStr = [...forbidden].map(id => `'${id}'`).join(', '); throw new Error( @@ -89,12 +89,13 @@ export function resolveAppNodeSpecs(options: { } const configuredExtensions = [ - ...pluginExtensions.map(({ source, ...extension }) => { + ...pluginExtensions.map(({ plugin, ...extension }) => { const internalExtension = toInternalExtension(extension); return { extension: internalExtension, params: { - source, + plugin, + source: plugin, attachTo: internalExtension.attachTo, disabled: internalExtension.disabled, config: undefined as unknown, @@ -107,6 +108,7 @@ export function resolveAppNodeSpecs(options: { extension: internalExtension, params: { source: undefined, + plugin: undefined, attachTo: internalExtension.attachTo, disabled: internalExtension.disabled, config: undefined as unknown, @@ -133,7 +135,8 @@ export function resolveAppNodeSpecs(options: { configuredExtensions.push({ extension: internalExtension, params: { - source: extension.source, + plugin: extension.plugin, + source: extension.plugin, attachTo: internalExtension.attachTo, disabled: internalExtension.disabled, config: undefined, @@ -219,6 +222,7 @@ export function resolveAppNodeSpecs(options: { attachTo: param.params.attachTo, extension: param.extension, disabled: param.params.disabled, + plugin: param.params.plugin, source: param.params.source, config: param.params.config, })); diff --git a/packages/frontend-plugin-api/report.api.md b/packages/frontend-plugin-api/report.api.md index cd5d89401d..1c01e0ac83 100644 --- a/packages/frontend-plugin-api/report.api.md +++ b/packages/frontend-plugin-api/report.api.md @@ -235,6 +235,8 @@ export interface AppNodeSpec { // (undocumented) readonly id: string; // (undocumented) + readonly plugin?: FrontendPlugin; + // @deprecated (undocumented) readonly source?: FrontendPlugin; } diff --git a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts index c9d9896600..0c6dde3cc8 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts @@ -37,6 +37,10 @@ export interface AppNodeSpec { readonly extension: Extension; readonly disabled: boolean; readonly config?: unknown; + readonly plugin?: FrontendPlugin; + /** + * @deprecated Use {@link AppNodeSpec.plugin} instead. + */ readonly source?: FrontendPlugin; } diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx index 46b3956e0e..a55afeeffd 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx @@ -69,14 +69,14 @@ export function ExtensionBoundary(props: ExtensionBoundaryProps) { node.instance?.getData(coreExtensionData.routePath), ); - const plugin = node.spec.source; + const plugin = node.spec.plugin; const Progress = useComponentRef(coreComponentRefs.progress); const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback); // Skipping "routeRef" attribute in the new system, the extension "id" should provide more insight const attributes = { extensionId: node.spec.id, - pluginId: node.spec.source?.id ?? 'app', + pluginId: node.spec.plugin?.id ?? 'app', }; return (