Add support for filtering the extensions config by what is discovered in the provided features

Signed-off-by: Musaab Elfaqih <musaabe@spotify.com>
This commit is contained in:
Musaab Elfaqih
2025-04-24 14:03:09 +02:00
parent b4a2a7c6cf
commit 19f2aa04a8
2 changed files with 29 additions and 3 deletions
@@ -16,6 +16,7 @@
import { Config } from '@backstage/config';
import { JsonValue } from '@backstage/types';
import { FrontendFeature } from '../wiring';
export interface ExtensionParameters {
id: string;
@@ -26,12 +27,34 @@ export interface ExtensionParameters {
const knownExtensionParameters = ['attachTo', 'disabled', 'config'];
/**
* Returns a filtered list of extensions based on what is discovered in the
* provided features.
*/
export const filterExtensionsByFeatures = (
extensions: ExtensionParameters[],
features: FrontendFeature[],
): ExtensionParameters[] => {
// Get a list of all extension IDs discovered in the provided features.
const discoveredExtensionIds = features.flatMap(feature =>
('extensions' in feature && Array.isArray(feature.extensions)
? feature.extensions
: []
).map((extension: { id: string }) => extension.id),
);
return extensions.filter(extension =>
discoveredExtensionIds.includes(extension.id),
);
};
// Since we'll never merge arrays in config the config reader context
// isn't too much of a help. Fall back to manual config reading logic
// as the Config interface makes it quite hard for us otherwise.
/** @internal */
export function readAppExtensionsConfig(
rootConfig: Config,
features: FrontendFeature[] = [],
): ExtensionParameters[] {
const arr = rootConfig.getOptional('app.extensions');
if (!Array.isArray(arr)) {
@@ -43,8 +66,11 @@ export function readAppExtensionsConfig(
return [];
}
return arr.map((arrayEntry, arrayIndex) =>
expandShorthandExtensionParameters(arrayEntry, arrayIndex),
return filterExtensionsByFeatures(
arr.map((arrayEntry, arrayIndex) =>
expandShorthandExtensionParameters(arrayEntry, arrayIndex),
),
features,
);
}
@@ -219,7 +219,7 @@ export function createSpecializedApp(options?: {
builtinExtensions: [
resolveExtensionDefinition(Root, { namespace: 'root' }),
],
parameters: readAppExtensionsConfig(config),
parameters: readAppExtensionsConfig(config, features),
forbidden: new Set(['root']),
}),
);