From 1d527ae2b68befd8413ab43c8d46d1d9e7106d27 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Tue, 18 Jul 2023 16:35:17 +0200 Subject: [PATCH] Add components to available plugins Co-authored-by: Vincenzo Scamporlino Signed-off-by: Philipp Hugenroth --- packages/autodetect/package.json | 5 +- packages/autodetect/src/index.ts | 59 ++++++++++++++++--- .../Content/InfoContent/InfoContent.tsx | 17 +++--- yarn.lock | 1 + 4 files changed, 65 insertions(+), 17 deletions(-) diff --git a/packages/autodetect/package.json b/packages/autodetect/package.json index dc3684a6bf..4cd00c6f8a 100644 --- a/packages/autodetect/package.json +++ b/packages/autodetect/package.json @@ -27,5 +27,8 @@ }, "files": [ "dist" - ] + ], + "dependencies": { + "@backstage/core-plugin-api": "workspace:^" + } } diff --git a/packages/autodetect/src/index.ts b/packages/autodetect/src/index.ts index 11b77fb780..b347a351da 100644 --- a/packages/autodetect/src/index.ts +++ b/packages/autodetect/src/index.ts @@ -14,16 +14,61 @@ * limitations under the License. */ -type Modules = Array<{ - name: string; - module: object; // Loaded Webpack Module of Backstage Plugin -}>; +import { BackstagePlugin } from '@backstage/core-plugin-api'; -function getAvailablePlugins() { - const { modules }: { modules: Modules } = __webpack_require__( +/** + * @public + */ +type DetectedPlugin = { + name: string; + plugin: BackstagePlugin; + components: Record; +}; + +type DetectedModule = { + name: string; + module: Record; +}; + +/** + * @public + */ +function getAvailablePlugins(): DetectedPlugin[] { + const { modules } = __webpack_require__( './node_modules/backstage-autodetected-plugins.js', + ) as { modules: DetectedModule[] }; + + return modules + .map(splitPluginFromComponents) + .filter((m): m is DetectedPlugin => !!m.plugin); +} + +function splitPluginFromComponents({ module, name }: DetectedModule) { + return Object.entries(module).reduce( + (acc, [k, v]) => { + if (!isBackstagePlugin(v)) { + acc.components[k] = v; + } else { + acc.plugin = v; + } + return acc; + }, + { name, components: {} } as { + name: string; + plugin?: BackstagePlugin; + components: Record; + }, + ); +} + +function isBackstagePlugin(obj: Record): obj is BackstagePlugin { + return ( + typeof obj.getId !== 'undefined' && + typeof obj.getApis !== 'undefined' && + typeof obj.getFeatureFlags !== 'undefined' && + typeof obj.provide !== 'undefined' ); - return modules; } export { getAvailablePlugins }; +export type { DetectedPlugin }; diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx index c55b57b4b8..6ed0140b96 100644 --- a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx +++ b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx @@ -78,16 +78,15 @@ export const InfoContent = () => { const classes = useStyles(); const { about, loading, error } = useInfo(); const plugins = autodetect.getAvailablePlugins(); - const availablePlugins: PackageDependency[] = ( - plugins as Array> - ).map(({ name, module }) => { - const pluginImpl: any = Object.values(module).find((v: any) => !!v?.getId); - return { - name, - versions: (pluginImpl?.getId() as string) || '', - }; - }); + const availablePlugins: PackageDependency[] = plugins.map( + ({ name, components }) => { + return { + name, + versions: Object.keys(components).toString(), + }; + }, + ); if (loading) { return ; } else if (error) { diff --git a/yarn.lock b/yarn.lock index a6459092b8..d914859dd7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3382,6 +3382,7 @@ __metadata: resolution: "@backstage/autodetect@workspace:packages/autodetect" dependencies: "@backstage/cli": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" "@testing-library/jest-dom": ^5.10.1 languageName: unknown linkType: soft