Merge pull request #30840 from backstage/blam/only-allow-installations-in-app-plugin

nfs: warning when  extensions to be installed outside of the app plugin
This commit is contained in:
Ben Lambert
2025-08-11 11:47:44 +02:00
committed by GitHub
3 changed files with 49 additions and 7 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-app': patch
---
Log a warning when `SwappableComponent` extensions are installed outside of using the `app` plugin
@@ -17,6 +17,7 @@
import {
ApiBlueprint,
createExtensionInput,
createFrontendModule,
createSwappableComponent,
SwappableComponentBlueprint,
swappableComponentsApiRef,
@@ -202,7 +203,13 @@ describe('DefaultSwappableComponentsApi', () => {
});
renderInTestApp(<MockComponent />, {
extensions: [api, override],
extensions: [api],
features: [
createFrontendModule({
pluginId: 'app',
extensions: [override],
}),
],
});
await expect(
@@ -225,7 +232,13 @@ describe('DefaultSwappableComponentsApi', () => {
});
renderInTestApp(<MockComponent />, {
extensions: [api, override],
extensions: [api],
features: [
createFrontendModule({
pluginId: 'app',
extensions: [override],
}),
],
});
await expect(
@@ -252,7 +265,13 @@ describe('DefaultSwappableComponentsApi', () => {
});
renderInTestApp(<MockComponent external="test" />, {
extensions: [api, override],
extensions: [api],
features: [
createFrontendModule({
pluginId: 'app',
extensions: [override],
}),
],
});
await expect(
@@ -37,12 +37,30 @@ export const SwappableComponentsApi = ApiBlueprint.makeWithOverrides({
defineParams({
api: swappableComponentsApiRef,
deps: {},
factory: () =>
DefaultSwappableComponentsApi.fromComponents(
inputs.components.map(i =>
factory: () => {
const nonAppExtensions = inputs.components.filter(
i => i.node.spec.plugin?.id !== 'app',
);
if (nonAppExtensions.length > 0) {
// eslint-disable-next-line no-console
console.warn(
`SwappableComponents should only be installed as an extension in the app plugin. You can either use appPlugin.override(), or provide a module for the app-plugin with the extension there instead. Invalid extensions: ${nonAppExtensions
.map(i => i.node.spec.id)
.join(', ')}`,
);
}
const appExtensions = inputs.components.filter(
i => i.node.spec.plugin?.id === 'app',
);
return DefaultSwappableComponentsApi.fromComponents(
appExtensions.map(i =>
i.get(SwappableComponentBlueprint.dataRefs.component),
),
),
);
},
}),
);
},