refactor(frontend-app-api): remove duplicated plugin extensions
Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
@@ -2,4 +2,4 @@
|
||||
'@backstage/frontend-app-api': patch
|
||||
---
|
||||
|
||||
Prevents root extension configuration and cyclic dependency between extensions when creating extension instances.
|
||||
Prevents root extension override and duplicated plugin extensions.
|
||||
|
||||
@@ -72,8 +72,8 @@ describe('createInstances', () => {
|
||||
);
|
||||
});
|
||||
|
||||
describe('throws an error when immediate cyclical dependencies are found', () => {
|
||||
it('in an immediate level (e.g., A -> A)', () => {
|
||||
describe('should deduplicated plugins', () => {
|
||||
it('in an immediate dependency level (e.g., A -> A)', () => {
|
||||
const config = new MockConfigApi({});
|
||||
|
||||
const addonExtensionData =
|
||||
@@ -114,8 +114,9 @@ describe('createInstances', () => {
|
||||
}),
|
||||
];
|
||||
|
||||
expect(() => createInstances({ config, plugins })).toThrow(
|
||||
/There is a cyclical dependency with the extension "A": (.*) → A → A/,
|
||||
// It should not create an infinite loop
|
||||
expect(() => createInstances({ config, plugins })).not.toThrow(
|
||||
'Maximum call stack size exceeded',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -182,8 +183,9 @@ describe('createInstances', () => {
|
||||
}),
|
||||
];
|
||||
|
||||
expect(() => createInstances({ config, plugins })).toThrow(
|
||||
/There is a cyclical dependency with the extension "A": (.*) → A → B → A/,
|
||||
// It should not create an infinite loop
|
||||
expect(() => createInstances({ config, plugins })).not.toThrow(
|
||||
'Maximum call stack size exceeded',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -288,8 +290,9 @@ describe('createInstances', () => {
|
||||
}),
|
||||
];
|
||||
|
||||
expect(() => createInstances({ config, plugins })).toThrow(
|
||||
/There is a cyclical dependency with the extension "B": (.*) → A → B → C → D → B/,
|
||||
// It should not create an infinite loop
|
||||
expect(() => createInstances({ config, plugins })).not.toThrow(
|
||||
'Maximum call stack size exceeded',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -208,7 +208,6 @@ export function createInstances(options: {
|
||||
|
||||
function createInstance(
|
||||
instanceParams: ExtensionInstanceParameters,
|
||||
extensionAncestorIds: string[] = [],
|
||||
): ExtensionInstance {
|
||||
const extensionId = instanceParams.extension.id;
|
||||
const existingInstance = instances.get(extensionId);
|
||||
@@ -216,28 +215,10 @@ export function createInstances(options: {
|
||||
return existingInstance;
|
||||
}
|
||||
|
||||
// Prevent cyclical dependencies
|
||||
if (extensionAncestorIds.includes(extensionId)) {
|
||||
const extensionDependencyGraph = extensionAncestorIds
|
||||
.concat(extensionId)
|
||||
.join(' → ');
|
||||
throw new Error(
|
||||
`There is a cyclical dependency with the extension "${extensionId}": ${extensionDependencyGraph}`,
|
||||
);
|
||||
}
|
||||
|
||||
const attachments = new Map(
|
||||
Array.from(attachmentMap.get(extensionId)?.entries() ?? []).map(
|
||||
([inputName, attachmentConfigs]) => {
|
||||
return [
|
||||
inputName,
|
||||
attachmentConfigs.map(attachmentConfig =>
|
||||
createInstance(
|
||||
attachmentConfig,
|
||||
extensionAncestorIds.concat(extensionId),
|
||||
),
|
||||
),
|
||||
];
|
||||
return [inputName, attachmentConfigs.map(createInstance)];
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -196,9 +196,20 @@ export function mergeExtensionParameters(options: {
|
||||
}): ExtensionInstanceParameters[] {
|
||||
const { sources, builtinExtensions, parameters } = options;
|
||||
|
||||
const pluginExtensions = sources.flatMap(source =>
|
||||
source.extensions.map(extension => ({ ...extension, source })),
|
||||
);
|
||||
const pluginExtensionIds = new Set<string>();
|
||||
const pluginExtensions = sources.flatMap(source => {
|
||||
return source.extensions
|
||||
.filter(extension => {
|
||||
// Filter out duplicated extensions
|
||||
const id = extension.id;
|
||||
if (!pluginExtensionIds.has(id)) {
|
||||
pluginExtensionIds.add(id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.map(extension => ({ ...extension, source }));
|
||||
});
|
||||
|
||||
// Prevent root override
|
||||
if (pluginExtensions.some(({ id }) => id === 'root')) {
|
||||
|
||||
Reference in New Issue
Block a user