diff --git a/.changeset/cool-knives-design.md b/.changeset/cool-knives-design.md new file mode 100644 index 0000000000..63197edd16 --- /dev/null +++ b/.changeset/cool-knives-design.md @@ -0,0 +1,7 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +The `id` option of `createFrontendPlugin` has been renamed to `pluginId` in order to better align with similar APIs in the frontend and backend systems. + +The old `id` option is deprecated and will be removed in a future release. diff --git a/.changeset/fruity-bags-flow.md b/.changeset/fruity-bags-flow.md new file mode 100644 index 0000000000..bc6034a489 --- /dev/null +++ b/.changeset/fruity-bags-flow.md @@ -0,0 +1,23 @@ +--- +'@backstage/plugin-catalog-unprocessed-entities': patch +'@backstage/frontend-test-utils': patch +'@backstage/core-compat-api': patch +'@backstage/plugin-app-visualizer': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-catalog-graph': patch +'@backstage/plugin-notifications': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-api-docs': patch +'@backstage/plugin-devtools': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-signals': patch +'@backstage/plugin-search': patch +'@backstage/plugin-home': patch +'@backstage/plugin-app': patch +'@backstage/plugin-org': patch +--- + +Internal update to use the new `pluginId` option of `createFrontendPlugin`. diff --git a/docs/frontend-system/architecture/15-plugins.md b/docs/frontend-system/architecture/15-plugins.md index a54573427d..825f2a3982 100644 --- a/docs/frontend-system/architecture/15-plugins.md +++ b/docs/frontend-system/architecture/15-plugins.md @@ -28,7 +28,7 @@ const myPage = PageBlueprint.make({ }); export default createFrontendPlugin({ - id: 'my-plugin', + pluginId: 'my-plugin', extensions: [myPage], }); ``` diff --git a/docs/frontend-system/architecture/36-routes.md b/docs/frontend-system/architecture/36-routes.md index e5d316e751..7b6376b2eb 100644 --- a/docs/frontend-system/architecture/36-routes.md +++ b/docs/frontend-system/architecture/36-routes.md @@ -55,7 +55,7 @@ const catalogIndexPage = createPageExtension({ }); export default createFrontendPlugin({ - id: 'catalog', + pluginId: 'catalog', // highlight-start routes: { index: indexRouteRef, @@ -204,7 +204,7 @@ const catalogIndexPage = createPageExtension({ }); export default createFrontendPlugin({ - id: 'catalog', + pluginId: 'catalog', routes: { index: indexRouteRef, }, @@ -411,7 +411,7 @@ const catalogIndexPage = createPageExtension({ }); export default createFrontendPlugin({ - id: 'catalog', + pluginId: 'catalog', routes: { index: indexRouteRef, // highlight-next-line diff --git a/docs/frontend-system/architecture/50-naming-patterns.md b/docs/frontend-system/architecture/50-naming-patterns.md index 11e0b8e733..55068d8ea1 100644 --- a/docs/frontend-system/architecture/50-naming-patterns.md +++ b/docs/frontend-system/architecture/50-naming-patterns.md @@ -24,7 +24,7 @@ Example: ```ts // This declaration is only for internal usage in tests. This could also be a direct default export. export const userSettingsPlugin = createFrontendPlugin({ - id: 'user-settings', + pluginId: 'user-settings', ... }) @@ -68,7 +68,7 @@ const catalogSearchResultListItem = SearchResultListItemBlueprint.make({ // Note that the extensions themselves are not exported, only the plugin instance export const catalogPlugin = createFrontendPlugin({ - id: 'catalog', + pluginId: 'catalog', extensions: [catalogEntityPage, catalogSearchResultListItem /* ... */], }); ``` diff --git a/docs/frontend-system/building-apps/08-migrating.md b/docs/frontend-system/building-apps/08-migrating.md index ecd036af61..861be2e39c 100644 --- a/docs/frontend-system/building-apps/08-migrating.md +++ b/docs/frontend-system/building-apps/08-migrating.md @@ -219,7 +219,7 @@ Can be converted to the following plugin configuration: ```tsx createFrontendPlugin({ - id: 'tech-radar', + pluginId: 'tech-radar', // ... featureFlags: [{ name: 'tech-radar' }], // ... diff --git a/docs/frontend-system/building-plugins/01-index.md b/docs/frontend-system/building-plugins/01-index.md index 633afd6ce8..33ec65d9d1 100644 --- a/docs/frontend-system/building-plugins/01-index.md +++ b/docs/frontend-system/building-plugins/01-index.md @@ -32,7 +32,7 @@ This is how to create a minimal plugin: import { createFrontendPlugin } from '@backstage/frontend-plugin-api'; export const examplePlugin = createFrontendPlugin({ - id: 'example', + pluginId: 'example', extensions: [], }); ``` @@ -98,7 +98,7 @@ const exampleNavItem = NavItemBlueprint.make({ // The same plugin as above, now with the extensions added export const examplePlugin = createFrontendPlugin({ - id: 'example', + pluginId: 'example', extensions: [examplePage, exampleNavItem], // We can also make routes available to other plugins. // highlight-start @@ -174,7 +174,7 @@ const exampleApi = ApiBlueprint.make({ /* Omitted definitions for examplePage, exampleNavItem, and rootRouteRef. */ export const examplePlugin = createFrontendPlugin({ - id: 'example', + pluginId: 'example', extensions: [ // highlight-add-next-line exampleApi, @@ -210,7 +210,7 @@ const exampleEntityContent = EntityContentBlueprint.make({ }); export const examplePlugin = createFrontendPlugin({ - id: 'example', + pluginId: 'example', extensions: [ // highlight-add-next-line exampleEntityContent, diff --git a/docs/frontend-system/building-plugins/05-migrating.md b/docs/frontend-system/building-plugins/05-migrating.md index 846e2c944b..ba292aa5d5 100644 --- a/docs/frontend-system/building-plugins/05-migrating.md +++ b/docs/frontend-system/building-plugins/05-migrating.md @@ -42,7 +42,9 @@ In order to migrate the actual definition of the plugin you need to recreate the import { convertLegacyRouteRefs } from '@backstage/core-compat-api'; export default createFrontendPlugin({ - id: 'my-plugin', + // The plugin ID is now provided as `pluginId` instead of `id` + /* highlight-next-line */ + pluginId: 'my-plugin', // bind all the extensions to the plugin /* highlight-next-line */ extensions: [/* APIs will go here, but don't worry about those yet */], @@ -138,7 +140,7 @@ Then add the `fooPage` extension to the plugin: import { createFrontendPlugin } from '@backstage/frontend-plugin-api'; export default createFrontendPlugin({ - id: 'my-plugin', + pluginId: 'my-plugin', // bind all the extensions to the plugin /* highlight-remove-next-line */ extensions: [], @@ -229,7 +231,7 @@ Finally, let's add the `exampleWorkApi` extension to the plugin: import { createFrontendPlugin } from '@backstage/frontend-plugin-api'; export default createFrontendPlugin({ - id: 'my-plugin', + pluginId: 'my-plugin', // bind all the extensions to the plugin /* highlight-remove-next-line */ extensions: [fooPage], diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index a2b3bf06f6..bf53911d24 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -80,7 +80,7 @@ const workApi = ApiBlueprint.make({ * @public */ export default createFrontendPlugin({ - id: 'example', + pluginId: 'example', extensions: [exampleWorkApi], }); ``` diff --git a/packages/app-next-example-plugin/src/plugin.tsx b/packages/app-next-example-plugin/src/plugin.tsx index 9d335f480c..7e1e7a1bd6 100644 --- a/packages/app-next-example-plugin/src/plugin.tsx +++ b/packages/app-next-example-plugin/src/plugin.tsx @@ -28,6 +28,6 @@ export const ExamplePage = PageBlueprint.make({ /** @public */ export const examplePlugin = createFrontendPlugin({ - id: 'example', + pluginId: 'example', extensions: [ExamplePage], }); diff --git a/packages/app-next/src/examples/pagesPlugin.tsx b/packages/app-next/src/examples/pagesPlugin.tsx index 1d0f9f3e0e..ddd080c28b 100644 --- a/packages/app-next/src/examples/pagesPlugin.tsx +++ b/packages/app-next/src/examples/pagesPlugin.tsx @@ -131,7 +131,7 @@ const ExternalPage = PageBlueprint.make({ }); export const pagesPlugin = createFrontendPlugin({ - id: 'pages', + pluginId: 'pages', // routes: { // index: indexRouteRef, // // reference in config: diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index f65856ec08..425f3684b6 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -304,7 +304,7 @@ export function collectLegacyRoutes( for (const [plugin, extensions] of pluginExtensions) { output.push( createFrontendPlugin({ - id: plugin.getId(), + pluginId: plugin.getId(), extensions: [ ...extensions, ...Array.from(plugin.getApis()).map(factory => diff --git a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx index 3faaf124fd..151fb21067 100644 --- a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx +++ b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx @@ -85,7 +85,7 @@ export function toLegacyPlugin( // TODO: Currently a very naive implementation, may need some more work function toNewPlugin(plugin: LegacyBackstagePlugin): NewFrontendPlugin { return createNewPlugin({ - id: plugin.getId(), + pluginId: plugin.getId(), }); } diff --git a/packages/core-compat-api/src/convertLegacyPlugin.ts b/packages/core-compat-api/src/convertLegacyPlugin.ts index 5fd5e585e6..bf315563ef 100644 --- a/packages/core-compat-api/src/convertLegacyPlugin.ts +++ b/packages/core-compat-api/src/convertLegacyPlugin.ts @@ -32,7 +32,7 @@ export function convertLegacyPlugin( ApiBlueprint.make({ name: factory.api.id, params: { factory } }), ); return createFrontendPlugin({ - id: legacyPlugin.getId(), + pluginId: legacyPlugin.getId(), featureFlags: [...legacyPlugin.getFeatureFlags()], routes: convertLegacyRouteRefs(legacyPlugin.routes ?? {}), externalRoutes: convertLegacyRouteRefs(legacyPlugin.externalRoutes ?? {}), diff --git a/packages/frontend-app-api/src/routing/collectRouteIds.test.ts b/packages/frontend-app-api/src/routing/collectRouteIds.test.ts index d74ab43e33..395886f982 100644 --- a/packages/frontend-app-api/src/routing/collectRouteIds.test.ts +++ b/packages/frontend-app-api/src/routing/collectRouteIds.test.ts @@ -35,7 +35,7 @@ describe('collectRouteIds', () => { const collected = collectRouteIds([ createFrontendPlugin({ - id: 'test', + pluginId: 'test', routes: { ref }, externalRoutes: { extRef }, }), diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts index 3f4f84c1ce..29e8767fb3 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts @@ -81,7 +81,7 @@ function createTestExtension(options: { function routeInfoFromExtensions(extensions: ExtensionDefinition[]) { const plugin = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions, }); diff --git a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts index a80c4cb35b..c486370563 100644 --- a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts +++ b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts @@ -100,7 +100,7 @@ describe('resolveAppNodeSpecs', () => { it('should override attachment points', () => { const b = makeExt('b'); const pluginA = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [makeExtDef('a')], }); expect( @@ -135,7 +135,7 @@ describe('resolveAppNodeSpecs', () => { const a = makeExt('test/a'); const b = makeExt('test/b'); const plugin = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [makeExtDef('a'), makeExtDef('b')], }); expect( @@ -182,7 +182,7 @@ describe('resolveAppNodeSpecs', () => { const b = makeExt('b', 'disabled'); expect( resolveAppNodeSpecs({ - features: [createFrontendPlugin({ id: 'empty', extensions: [] })], + features: [createFrontendPlugin({ pluginId: 'empty', extensions: [] })], builtinExtensions: [a, b], parameters: [ { @@ -221,7 +221,7 @@ describe('resolveAppNodeSpecs', () => { const g = makeExt('g', 'disabled'); expect( resolveAppNodeSpecs({ - features: [createFrontendPlugin({ id: 'empty', extensions: [] })], + features: [createFrontendPlugin({ pluginId: 'empty', extensions: [] })], builtinExtensions: [a, b, c, d, e, f, g], parameters: [ { id: 'e', disabled: false }, @@ -277,7 +277,7 @@ describe('resolveAppNodeSpecs', () => { it('should apply module overrides', () => { const plugin = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [makeExtDef('a'), makeExtDef('b')], }); const aOverride = makeExt('test/a', 'enabled', 'other'); @@ -329,7 +329,7 @@ describe('resolveAppNodeSpecs', () => { const result = resolveAppNodeSpecs({ features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ makeExtDef('a', 'disabled'), makeExtDef('b', 'disabled'), @@ -364,7 +364,7 @@ describe('resolveAppNodeSpecs', () => { resolveAppNodeSpecs({ features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [makeExtDef('forbidden')], }), ], @@ -382,7 +382,7 @@ describe('resolveAppNodeSpecs', () => { resolveAppNodeSpecs({ features: [ createFrontendPlugin({ - id: 'forbidden', + pluginId: 'forbidden', extensions: [], }), createFrontendModule({ diff --git a/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx b/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx index 96450f06fb..c363ce08bd 100644 --- a/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx @@ -45,7 +45,7 @@ describe('createSpecializedApp', () => { const app = createSpecializedApp({ features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ createExtension({ attachTo: { id: 'root', input: 'app' }, @@ -66,7 +66,7 @@ describe('createSpecializedApp', () => { const app = createSpecializedApp({ features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ createExtension({ attachTo: { id: 'root', input: 'app' }, @@ -78,7 +78,7 @@ describe('createSpecializedApp', () => { ], }), createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ createExtension({ attachTo: { id: 'root', input: 'app' }, @@ -102,7 +102,7 @@ describe('createSpecializedApp', () => { config: mockApis.config({ data: { test: 'foo' } }), features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ createExtension({ attachTo: { id: 'root', input: 'app' }, @@ -128,7 +128,7 @@ describe('createSpecializedApp', () => { const app = createSpecializedApp({ features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', featureFlags: [{ name: 'a' }, { name: 'b' }], extensions: [ createExtension({ @@ -250,7 +250,7 @@ describe('createSpecializedApp', () => { const app = createSpecializedApp({ features: [ createFrontendPlugin({ - id: 'first', + pluginId: 'first', extensions: [ ApiBlueprint.make({ params: { @@ -266,7 +266,7 @@ describe('createSpecializedApp', () => { ], }), createFrontendPlugin({ - id: 'test', + pluginId: 'test', featureFlags: [{ name: 'a' }, { name: 'b' }], extensions: [ createExtension({ @@ -321,7 +321,7 @@ describe('createSpecializedApp', () => { ]), features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ createExtension({ attachTo: { id: 'root', input: 'app' }, @@ -368,7 +368,7 @@ describe('createSpecializedApp', () => { const { tree } = createSpecializedApp({ features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ createExtension({ attachTo: { id: 'root', input: 'app' }, @@ -446,7 +446,7 @@ describe('createSpecializedApp', () => { const extRouteRef = createExternalRouteRef(); const pluginA = createFrontendPlugin({ - id: 'a', + pluginId: 'a', externalRoutes: { ext: extRouteRef, }, @@ -489,7 +489,7 @@ describe('createSpecializedApp', () => { ], }); const pluginB = createFrontendPlugin({ - id: 'b', + pluginId: 'b', routes: { root: routeRef, }, @@ -531,7 +531,7 @@ describe('createSpecializedApp', () => { createSpecializedApp({ features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ createExtension({ name: 'root', @@ -611,7 +611,7 @@ describe('createSpecializedApp', () => { const app = createSpecializedApp({ features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ createExtension({ attachTo: { id: 'root', input: 'app' }, diff --git a/packages/frontend-defaults/src/createApp.test.tsx b/packages/frontend-defaults/src/createApp.test.tsx index 569416fca7..4fd1ba4c5b 100644 --- a/packages/frontend-defaults/src/createApp.test.tsx +++ b/packages/frontend-defaults/src/createApp.test.tsx @@ -55,7 +55,7 @@ describe('createApp', () => { }), features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ ThemeBlueprint.make({ name: 'derp', @@ -84,7 +84,7 @@ describe('createApp', () => { configLoader: async () => ({ config: mockApis.config() }), features: [ createFrontendPlugin({ - id: duplicatedFeatureId, + pluginId: duplicatedFeatureId, extensions: [ PageBlueprint.make({ params: { @@ -95,7 +95,7 @@ describe('createApp', () => { ], }), createFrontendPlugin({ - id: duplicatedFeatureId, + pluginId: duplicatedFeatureId, extensions: [ PageBlueprint.make({ params: { @@ -128,7 +128,7 @@ describe('createApp', () => { return { features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ PageBlueprint.make({ params: { @@ -193,7 +193,7 @@ describe('createApp', () => { ], }), createFrontendPlugin({ - id: 'test', + pluginId: 'test', featureFlags: [{ name: 'test-1' }], extensions: [ createExtension({ @@ -219,7 +219,7 @@ describe('createApp', () => { ], }), createFrontendPlugin({ - id: 'other', + pluginId: 'other', featureFlags: [{ name: 'test-2' }], extensions: [], }), @@ -241,7 +241,7 @@ describe('createApp', () => { features: [ appPlugin, createFrontendPlugin({ - id: 'my-plugin', + pluginId: 'my-plugin', extensions: [ PageBlueprint.make({ params: { @@ -402,7 +402,7 @@ describe('createApp', () => { features: [ appPlugin, createFrontendPlugin({ - id: 'test-plugin', + pluginId: 'test-plugin', extensions: [ PageBlueprint.make({ name: 'test-page', diff --git a/packages/frontend-defaults/src/discovery.test.ts b/packages/frontend-defaults/src/discovery.test.ts index 52a2fcde11..d1738554a4 100644 --- a/packages/frontend-defaults/src/discovery.test.ts +++ b/packages/frontend-defaults/src/discovery.test.ts @@ -45,7 +45,7 @@ describe('discoverAvailableFeatures', () => { }); it('should discover a plugin', () => { - const testPlugin = createFrontendPlugin({ id: 'test' }); + const testPlugin = createFrontendPlugin({ pluginId: 'test' }); globalSpy.mockReturnValue({ modules: [{ default: testPlugin }], }); @@ -86,9 +86,9 @@ describe('discoverAvailableFeatures', () => { }); it('should discover multiple plugins', () => { - const test1Plugin = createFrontendPlugin({ id: 'test1' }); - const test2Plugin = createFrontendPlugin({ id: 'test2' }); - const test3Plugin = createFrontendPlugin({ id: 'test3' }); + const test1Plugin = createFrontendPlugin({ pluginId: 'test1' }); + const test2Plugin = createFrontendPlugin({ pluginId: 'test2' }); + const test3Plugin = createFrontendPlugin({ pluginId: 'test3' }); globalSpy.mockReturnValue({ modules: [ { default: test1Plugin }, diff --git a/packages/frontend-defaults/src/resolution.test.ts b/packages/frontend-defaults/src/resolution.test.ts index 609b975a33..b39e302b24 100644 --- a/packages/frontend-defaults/src/resolution.test.ts +++ b/packages/frontend-defaults/src/resolution.test.ts @@ -38,7 +38,7 @@ describe('resolveAsyncFeatures', () => { config: mockApis.config(), features: [ createFrontendPlugin({ - id: 'test-feature', + pluginId: 'test-feature', extensions: [ PageBlueprint.make({ params: { @@ -80,7 +80,7 @@ describe('resolveAsyncFeatures', () => { return { features: [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ PageBlueprint.make({ params: { @@ -145,7 +145,7 @@ describe('resolveAsyncFeatures', () => { async loader({ config: _ }) { return [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ PageBlueprint.make({ params: { diff --git a/packages/frontend-dynamic-feature-loader/src/loader.test.tsx b/packages/frontend-dynamic-feature-loader/src/loader.test.tsx index 87ddc7770f..4b872a5414 100644 --- a/packages/frontend-dynamic-feature-loader/src/loader.test.tsx +++ b/packages/frontend-dynamic-feature-loader/src/loader.test.tsx @@ -191,7 +191,7 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValue({ default: createFrontendPlugin({ - id: 'test-plugin', + pluginId: 'test-plugin', extensions: [], }), }); @@ -311,13 +311,13 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'plugin-1', + pluginId: 'plugin-1', extensions: [], }), }); mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'plugin-2', + pluginId: 'plugin-2', extensions: [], }), }); @@ -428,13 +428,13 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'test-plugin', + pluginId: 'test-plugin', extensions: [], }), }); mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'test-plugin-alpha', + pluginId: 'test-plugin-alpha', extensions: [], }), }); @@ -527,7 +527,7 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'test-plugin', + pluginId: 'test-plugin', extensions: [], }), }); @@ -591,7 +591,7 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValue({ default: createFrontendPlugin({ - id: 'test-plugin', + pluginId: 'test-plugin', extensions: [], }), }); @@ -640,7 +640,7 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValue({ default: createFrontendPlugin({ - id: 'test-plugin', + pluginId: 'test-plugin', extensions: [], }), }); @@ -746,7 +746,7 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValueOnce(undefined); mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'plugin-2', + pluginId: 'plugin-2', extensions: [], }), }); @@ -876,7 +876,7 @@ describe('dynamicFrontendFeaturesLoader', () => { }); mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'plugin-2', + pluginId: 'plugin-2', extensions: [], }), }); @@ -989,7 +989,7 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'plugin-2', + pluginId: 'plugin-2', extensions: [], }), }); @@ -1099,7 +1099,7 @@ describe('dynamicFrontendFeaturesLoader', () => { mocks.federation.get.mockReturnValueOnce({ default: createFrontendPlugin({ - id: 'plugin-2', + pluginId: 'plugin-2', extensions: [], }), }); diff --git a/packages/frontend-plugin-api/report.api.md b/packages/frontend-plugin-api/report.api.md index 0d29eec03f..cd5d89401d 100644 --- a/packages/frontend-plugin-api/report.api.md +++ b/packages/frontend-plugin-api/report.api.md @@ -774,6 +774,25 @@ export function createFrontendPlugin< MakeSortedExtensionsMap >; +// @public @deprecated (undocumented) +export function createFrontendPlugin< + TId extends string, + TRoutes extends AnyRoutes = {}, + TExternalRoutes extends AnyExternalRoutes = {}, + TExtensions extends readonly ExtensionDefinition[] = [], +>( + options: Omit< + PluginOptions, + 'pluginId' + > & { + id: string; + }, +): FrontendPlugin< + TRoutes, + TExternalRoutes, + MakeSortedExtensionsMap +>; + // @public export function createRouteRef< TParams extends @@ -1495,7 +1514,7 @@ export interface PluginOptions< // (undocumented) featureFlags?: FeatureFlagConfig[]; // (undocumented) - id: TId; + pluginId: TId; // (undocumented) routes?: TRoutes; } diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendFeatureLoader.test.ts b/packages/frontend-plugin-api/src/wiring/createFrontendFeatureLoader.test.ts index e8e2e90bf7..63ce4cb284 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendFeatureLoader.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendFeatureLoader.test.ts @@ -60,7 +60,7 @@ describe('createFrontendFeatureLoader', () => { ); return [ createFrontendPlugin({ - id: `${pluginIdPrefix}-1`, + pluginId: `${pluginIdPrefix}-1`, extensions: [ createExtension({ name: '1', @@ -76,7 +76,7 @@ describe('createFrontendFeatureLoader', () => { ], }) as FrontendFeature | FrontendFeatureLoader, createFrontendPlugin({ - id: `${pluginIdPrefix}-2`, + pluginId: `${pluginIdPrefix}-2`, extensions: [ createExtension({ name: '2', @@ -92,7 +92,7 @@ describe('createFrontendFeatureLoader', () => { ], }) as FrontendFeature | FrontendFeatureLoader, createFrontendPlugin({ - id: `${pluginIdPrefix}-output`, + pluginId: `${pluginIdPrefix}-output`, extensions: [ createExtension({ name: 'output', @@ -166,7 +166,7 @@ describe('createFrontendFeatureLoader', () => { async loader(_) { return [ createFrontendPlugin({ - id: 'plugin-0', + pluginId: 'plugin-0', extensions: [ createExtension({ name: '0', @@ -184,7 +184,7 @@ describe('createFrontendFeatureLoader', () => { createFrontendFeatureLoader({ async *loader(__) { yield createFrontendPlugin({ - id: 'plugin-1', + pluginId: 'plugin-1', extensions: [ createExtension({ name: '1', @@ -202,7 +202,7 @@ describe('createFrontendFeatureLoader', () => { yield createFrontendFeatureLoader({ loader: async ___ => [ createFrontendPlugin({ - id: 'plugin-2', + pluginId: 'plugin-2', extensions: [ createExtension({ name: '2', @@ -222,7 +222,7 @@ describe('createFrontendFeatureLoader', () => { }, }), createFrontendPlugin({ - id: 'plugin-output', + pluginId: 'plugin-output', extensions: [ createExtension({ name: 'output', @@ -278,7 +278,7 @@ describe('createFrontendFeatureLoader', () => { [ nestedFeatureLoaderHolder.loader, createFrontendPlugin({ - id: 'plugin', + pluginId: 'plugin', extensions: [ createExtension({ name: 'output', @@ -319,7 +319,7 @@ describe('createFrontendFeatureLoader', () => { it('should support multiple output formats', async () => { const feature = createFrontendPlugin({ - id: 'test', + pluginId: 'test', }); const dynamicFeature = Promise.resolve({ default: feature }); @@ -411,7 +411,7 @@ describe('createFrontendFeatureLoader', () => { it('should limit feature loading recursion', async () => { const plugin = createFrontendPlugin({ - id: 'plugin', + pluginId: 'plugin', extensions: [ createExtension({ name: 'output', diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts index 6553157885..359f9da417 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts @@ -134,6 +134,13 @@ function createTestAppRoot({ describe('createFrontendPlugin', () => { it('should create an empty plugin', () => { + const plugin = createFrontendPlugin({ pluginId: 'test' }); + + expect(plugin).toBeDefined(); + expect(String(plugin)).toBe('Plugin{id=test}'); + }); + + it('should create an empty plugin with deprecated id option', () => { const plugin = createFrontendPlugin({ id: 'test' }); expect(plugin).toBeDefined(); @@ -142,7 +149,7 @@ describe('createFrontendPlugin', () => { it('should create a plugin with extension instances', async () => { const plugin = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [Extension1, Extension2, outputExtension], }); expect(plugin).toBeDefined(); @@ -189,7 +196,7 @@ describe('createFrontendPlugin', () => { it('should create a plugin with nested extension instances', async () => { const plugin = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [Extension1, Extension2, Extension3, Child, outputExtension], }); expect(plugin).toBeDefined(); @@ -221,7 +228,7 @@ describe('createFrontendPlugin', () => { it('should create a plugin with nested extension instances and multiple children', async () => { const plugin = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ Extension1, Extension2, @@ -254,14 +261,14 @@ describe('createFrontendPlugin', () => { it('should throw on duplicate extensions', async () => { expect(() => createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [Extension1, Extension1], }), ).toThrow("Plugin 'test' provided duplicate extensions: test/1"); expect(() => createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [ Extension1, Extension2, @@ -277,7 +284,7 @@ describe('createFrontendPlugin', () => { describe('overrides', () => { it('should return a plugin instance with the correct namespace', () => { const plugin = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [Extension1, Extension2], }); @@ -308,7 +315,7 @@ describe('createFrontendPlugin', () => { it('should allow overriding extensions that have a matching ID, while keeping old extensions that do not have overlapping IDs', async () => { const plugin = createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions: [Extension1, Extension2, outputExtension], }); diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts index 09ff96a4e6..b7c530a0c0 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts @@ -51,7 +51,7 @@ export interface PluginOptions< TExternalRoutes extends AnyExternalRoutes, TExtensions extends readonly ExtensionDefinition[], > { - id: TId; + pluginId: TId; routes?: TRoutes; externalRoutes?: TExternalRoutes; extensions?: TExtensions; @@ -70,7 +70,49 @@ export function createFrontendPlugin< TRoutes, TExternalRoutes, MakeSortedExtensionsMap +>; +/** + * @public + * @deprecated The `id` option is deprecated, use `pluginId` instead. + */ +export function createFrontendPlugin< + TId extends string, + TRoutes extends AnyRoutes = {}, + TExternalRoutes extends AnyExternalRoutes = {}, + TExtensions extends readonly ExtensionDefinition[] = [], +>( + options: Omit< + PluginOptions, + 'pluginId' + > & { id: string }, +): FrontendPlugin< + TRoutes, + TExternalRoutes, + MakeSortedExtensionsMap +>; +export function createFrontendPlugin< + TId extends string, + TRoutes extends AnyRoutes = {}, + TExternalRoutes extends AnyExternalRoutes = {}, + TExtensions extends readonly ExtensionDefinition[] = [], +>( + options: + | PluginOptions + | (Omit< + PluginOptions, + 'pluginId' + > & { id: string }), +): FrontendPlugin< + TRoutes, + TExternalRoutes, + MakeSortedExtensionsMap > { + const pluginId = 'pluginId' in options ? options.pluginId : options.id; + if (!pluginId) { + throw new Error( + "Either 'id' or 'pluginId' must be provided to createFrontendPlugin", + ); + } const extensions = new Array>(); const extensionDefinitionsById = new Map< string, @@ -79,11 +121,11 @@ export function createFrontendPlugin< for (const def of options.extensions ?? []) { const internal = OpaqueExtensionDefinition.toInternal(def); - const ext = resolveExtensionDefinition(def, { namespace: options.id }); + const ext = resolveExtensionDefinition(def, { namespace: pluginId }); extensions.push(ext); extensionDefinitionsById.set(ext.id, { ...internal, - namespace: options.id, + namespace: pluginId, }); } @@ -96,14 +138,14 @@ export function createFrontendPlugin< ); // TODO(Rugvip): This could provide some more information about the kind + name of the extensions throw new Error( - `Plugin '${options.id}' provided duplicate extensions: ${duplicates.join( + `Plugin '${pluginId}' provided duplicate extensions: ${duplicates.join( ', ', )}`, ); } return OpaqueFrontendPlugin.createInstance('v1', { - id: options.id, + id: pluginId, routes: options.routes ?? ({} as TRoutes), externalRoutes: options.externalRoutes ?? ({} as TExternalRoutes), featureFlags: options.featureFlags ?? [], @@ -112,28 +154,29 @@ export function createFrontendPlugin< const ext = extensionDefinitionsById.get(id); if (!ext) { throw new Error( - `Attempted to get non-existent extension '${id}' from plugin '${options.id}'`, + `Attempted to get non-existent extension '${id}' from plugin '${pluginId}'`, ); } return ext; }, toString() { - return `Plugin{id=${options.id}}`; + return `Plugin{id=${pluginId}}`; }, withOverrides(overrides) { const overriddenExtensionIds = new Set( overrides.extensions.map( - e => resolveExtensionDefinition(e, { namespace: options.id }).id, + e => resolveExtensionDefinition(e, { namespace: pluginId }).id, ), ); const nonOverriddenExtensions = (options.extensions ?? []).filter( e => !overriddenExtensionIds.has( - resolveExtensionDefinition(e, { namespace: options.id }).id, + resolveExtensionDefinition(e, { namespace: pluginId }).id, ), ); return createFrontendPlugin({ ...options, + pluginId, extensions: [...nonOverriddenExtensions, ...overrides.extensions], }); }, diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.tsx index 84171646df..d4010a92ad 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.tsx @@ -198,7 +198,7 @@ export function renderInTestApp( const features: FrontendFeature[] = [ createFrontendPlugin({ - id: 'test', + pluginId: 'test', extensions, }), appPluginOverride, diff --git a/plugins/api-docs/src/alpha.tsx b/plugins/api-docs/src/alpha.tsx index f85df511ec..b575dcc014 100644 --- a/plugins/api-docs/src/alpha.tsx +++ b/plugins/api-docs/src/alpha.tsx @@ -227,7 +227,7 @@ const apiDocsApisEntityContent = EntityContentBlueprint.make({ }); export default createFrontendPlugin({ - id: 'api-docs', + pluginId: 'api-docs', routes: { root: convertLegacyRouteRef(rootRoute), }, diff --git a/plugins/app-visualizer/src/plugin.tsx b/plugins/app-visualizer/src/plugin.tsx index 465f5100ce..92ccd00159 100644 --- a/plugins/app-visualizer/src/plugin.tsx +++ b/plugins/app-visualizer/src/plugin.tsx @@ -45,6 +45,6 @@ export const appVisualizerNavItem = NavItemBlueprint.make({ /** @public */ export const visualizerPlugin = createFrontendPlugin({ - id: 'app-visualizer', + pluginId: 'app-visualizer', extensions: [appVisualizerPage, appVisualizerNavItem], }); diff --git a/plugins/app/src/plugin.ts b/plugins/app/src/plugin.ts index 809e101d0f..b166423fa1 100644 --- a/plugins/app/src/plugin.ts +++ b/plugins/app/src/plugin.ts @@ -41,7 +41,7 @@ import { apis } from './defaultApis'; /** @public */ export const appPlugin = createFrontendPlugin({ - id: 'app', + pluginId: 'app', extensions: [ ...apis, App, diff --git a/plugins/catalog-graph/src/alpha.tsx b/plugins/catalog-graph/src/alpha.tsx index 096dcca2b8..d70232e92a 100644 --- a/plugins/catalog-graph/src/alpha.tsx +++ b/plugins/catalog-graph/src/alpha.tsx @@ -86,7 +86,7 @@ const CatalogGraphPage = PageBlueprint.makeWithOverrides({ }); export default createFrontendPlugin({ - id: 'catalog-graph', + pluginId: 'catalog-graph', routes: { catalogGraph: convertLegacyRouteRef(catalogGraphRouteRef), }, diff --git a/plugins/catalog-import/src/alpha.tsx b/plugins/catalog-import/src/alpha.tsx index e70d964ce2..0d1599ee5c 100644 --- a/plugins/catalog-import/src/alpha.tsx +++ b/plugins/catalog-import/src/alpha.tsx @@ -86,7 +86,7 @@ const catalogImportApi = ApiBlueprint.make({ /** @alpha */ export default createFrontendPlugin({ - id: 'catalog-import', + pluginId: 'catalog-import', extensions: [catalogImportApi, catalogImportPage], routes: { importPage: convertLegacyRouteRef(rootRouteRef), diff --git a/plugins/catalog-unprocessed-entities/src/alpha/plugin.tsx b/plugins/catalog-unprocessed-entities/src/alpha/plugin.tsx index df1935f89a..8ff83605c7 100644 --- a/plugins/catalog-unprocessed-entities/src/alpha/plugin.tsx +++ b/plugins/catalog-unprocessed-entities/src/alpha/plugin.tsx @@ -73,7 +73,7 @@ export const catalogUnprocessedEntitiesNavItem = NavItemBlueprint.make({ /** @alpha */ export default createFrontendPlugin({ - id: 'catalog-unprocessed-entities', + pluginId: 'catalog-unprocessed-entities', routes: { root: convertLegacyRouteRef(rootRouteRef), }, diff --git a/plugins/catalog/src/alpha/plugin.tsx b/plugins/catalog/src/alpha/plugin.tsx index 04034e2156..6fd171ed54 100644 --- a/plugins/catalog/src/alpha/plugin.tsx +++ b/plugins/catalog/src/alpha/plugin.tsx @@ -38,7 +38,7 @@ import contextMenuItems from './contextMenuItems'; /** @alpha */ export default createFrontendPlugin({ - id: 'catalog', + pluginId: 'catalog', routes: convertLegacyRouteRefs({ catalogIndex: rootRouteRef, catalogEntity: entityRouteRef, diff --git a/plugins/devtools/src/alpha/plugin.tsx b/plugins/devtools/src/alpha/plugin.tsx index bb2142ab9b..959670f3a5 100644 --- a/plugins/devtools/src/alpha/plugin.tsx +++ b/plugins/devtools/src/alpha/plugin.tsx @@ -70,7 +70,7 @@ export const devToolsNavItem = NavItemBlueprint.make({ /** @alpha */ export default createFrontendPlugin({ - id: 'devtools', + pluginId: 'devtools', routes: { root: convertLegacyRouteRef(rootRouteRef), }, diff --git a/plugins/home/src/alpha.tsx b/plugins/home/src/alpha.tsx index 755cf55212..74f96a2195 100644 --- a/plugins/home/src/alpha.tsx +++ b/plugins/home/src/alpha.tsx @@ -67,6 +67,6 @@ const homePage = PageBlueprint.makeWithOverrides({ * @alpha */ export default createFrontendPlugin({ - id: 'home', + pluginId: 'home', extensions: [homePage], }); diff --git a/plugins/kubernetes/src/alpha/plugin.tsx b/plugins/kubernetes/src/alpha/plugin.tsx index 1369133a24..35cb9e037d 100644 --- a/plugins/kubernetes/src/alpha/plugin.tsx +++ b/plugins/kubernetes/src/alpha/plugin.tsx @@ -27,7 +27,7 @@ import { } from './apis'; export default createFrontendPlugin({ - id: 'kubernetes', + pluginId: 'kubernetes', extensions: [ kubernetesPage, entityKubernetesContent, diff --git a/plugins/notifications/src/alpha.tsx b/plugins/notifications/src/alpha.tsx index d61ecf16f2..d7c4ec27b6 100644 --- a/plugins/notifications/src/alpha.tsx +++ b/plugins/notifications/src/alpha.tsx @@ -53,7 +53,7 @@ const api = ApiBlueprint.make({ /** @alpha */ export default createFrontendPlugin({ - id: 'notifications', + pluginId: 'notifications', routes: convertLegacyRouteRefs({ root: rootRouteRef, }), diff --git a/plugins/org/src/alpha.tsx b/plugins/org/src/alpha.tsx index 30cfe4f271..beb4f573af 100644 --- a/plugins/org/src/alpha.tsx +++ b/plugins/org/src/alpha.tsx @@ -72,7 +72,7 @@ const EntityUserProfileCard = EntityCardBlueprint.make({ /** @alpha */ export default createFrontendPlugin({ - id: 'org', + pluginId: 'org', extensions: [ EntityGroupProfileCard, EntityMembersListCard, diff --git a/plugins/scaffolder/src/alpha/plugin.tsx b/plugins/scaffolder/src/alpha/plugin.tsx index 90fc22e980..aa37f80493 100644 --- a/plugins/scaffolder/src/alpha/plugin.tsx +++ b/plugins/scaffolder/src/alpha/plugin.tsx @@ -38,7 +38,7 @@ import { formDecoratorsApi } from './api'; /** @alpha */ export default createFrontendPlugin({ - id: 'scaffolder', + pluginId: 'scaffolder', routes: convertLegacyRouteRefs({ root: rootRouteRef, selectedTemplate: selectedTemplateRouteRef, diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index 651057e9a4..fed0124fa7 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -278,7 +278,7 @@ export const searchNavItem = NavItemBlueprint.make({ /** @alpha */ export default createFrontendPlugin({ - id: 'search', + pluginId: 'search', extensions: [searchApi, searchPage, searchNavItem], routes: convertLegacyRouteRefs({ root: rootRouteRef, diff --git a/plugins/signals/src/alpha.tsx b/plugins/signals/src/alpha.tsx index 6d4eb73af3..ba7f72f420 100644 --- a/plugins/signals/src/alpha.tsx +++ b/plugins/signals/src/alpha.tsx @@ -44,6 +44,6 @@ const api = ApiBlueprint.make({ /** @alpha */ export default createFrontendPlugin({ - id: 'signals', + pluginId: 'signals', extensions: [api], }); diff --git a/plugins/techdocs/src/alpha.tsx b/plugins/techdocs/src/alpha.tsx index 98021304c6..b2bf794e73 100644 --- a/plugins/techdocs/src/alpha.tsx +++ b/plugins/techdocs/src/alpha.tsx @@ -235,7 +235,7 @@ const techDocsNavItem = NavItemBlueprint.make({ /** @alpha */ export default createFrontendPlugin({ - id: 'techdocs', + pluginId: 'techdocs', extensions: [ techDocsClientApi, techDocsStorageApi, diff --git a/plugins/user-settings/src/alpha.tsx b/plugins/user-settings/src/alpha.tsx index a6b297d443..228c6a23d2 100644 --- a/plugins/user-settings/src/alpha.tsx +++ b/plugins/user-settings/src/alpha.tsx @@ -68,7 +68,7 @@ export const settingsNavItem = NavItemBlueprint.make({ * @alpha */ export default createFrontendPlugin({ - id: 'user-settings', + pluginId: 'user-settings', extensions: [userSettingsPage, settingsNavItem], routes: convertLegacyRouteRefs({ root: settingsRouteRef,