feat(frontend-app-api): prevent plugins overring root extensions

Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2023-09-20 11:46:15 +02:00
parent f86bd410e6
commit cc94fbd3b3
2 changed files with 28 additions and 16 deletions
@@ -20,7 +20,7 @@ import { createInstances } from './createApp';
import { MockConfigApi } from '@backstage/test-utils';
describe('createInstances', () => {
it('throws an error when a root extension is overridden', () => {
it('throws an error when a root extension is parametrized', () => {
const config = new MockConfigApi({
app: {
extensions: [
@@ -39,11 +39,11 @@ describe('createInstances', () => {
}),
];
expect(() => createInstances({ config, plugins })).toThrow(
'There is a root extension in the app config file and root extensions are not configurable',
'A "root" extension was detected on the config file and root extensions are not configurable',
);
});
it('throws an error when cyclical dependencies are found', () => {
it('throws an error when a root extension is overridden', () => {
const config = new MockConfigApi({});
const plugins = [
createPlugin({
@@ -60,7 +60,7 @@ describe('createInstances', () => {
}),
];
expect(() => createInstances({ config, plugins })).toThrow(
'There is a cyclical dependency with the extension "core.layout": core.layout → core.routes → root → core.layout',
'The following plugins are overriding root extensions and root extensions cannot be overridden: plugin',
);
});
});
@@ -196,18 +196,30 @@ export function mergeExtensionParameters(options: {
}): ExtensionInstanceParameters[] {
const { sources, builtinExtensions, parameters } = options;
const pluginExtensions = sources.flatMap(source =>
source.extensions.map(extension => ({ ...extension, source })),
);
// Prevent root override
if (pluginExtensions.some(({ id }) => id === 'root')) {
const rootPluginIds = pluginExtensions
.filter(({ id }) => id === 'root')
.map(({ source }) => source.id);
throw new Error(
`The following plugins are overriding root extensions and root extensions cannot be overridden: ${rootPluginIds}`,
);
}
const overrides = [
...sources.flatMap(plugin =>
plugin.extensions.map(extension => ({
extension,
params: {
source: plugin,
at: extension.at,
disabled: extension.disabled,
config: undefined as unknown,
},
})),
),
...pluginExtensions.map(({ source, ...extension }) => ({
extension,
params: {
source,
at: extension.at,
disabled: extension.disabled,
config: undefined as unknown,
},
})),
...builtinExtensions.map(extension => ({
extension,
params: {
@@ -225,7 +237,7 @@ export function mergeExtensionParameters(options: {
// Prevent root parametrization
if (extensionId === 'root') {
throw new Error(
'There is a root extension in the app config file and root extensions are not configurable',
'A "root" extension was detected on the config file and root extensions are not configurable',
);
}