diff --git a/.changeset/olive-walls-wonder.md b/.changeset/olive-walls-wonder.md new file mode 100644 index 0000000000..ef8d37272e --- /dev/null +++ b/.changeset/olive-walls-wonder.md @@ -0,0 +1,7 @@ +--- +'@backstage/frontend-app-api': minor +'@backstage/frontend-plugin-api': minor +'@backstage/frontend-test-utils': patch +--- + +Rename the `app/router` extension to `app/root`. diff --git a/packages/frontend-app-api/src/extensions/Core.tsx b/packages/frontend-app-api/src/extensions/App.tsx similarity index 97% rename from packages/frontend-app-api/src/extensions/Core.tsx rename to packages/frontend-app-api/src/extensions/App.tsx index ea722ce862..751a255fa7 100644 --- a/packages/frontend-app-api/src/extensions/Core.tsx +++ b/packages/frontend-app-api/src/extensions/App.tsx @@ -24,7 +24,7 @@ import { createTranslationExtension, } from '@backstage/frontend-plugin-api'; -export const Core = createExtension({ +export const App = createExtension({ namespace: 'app', attachTo: { id: 'root', input: 'default' }, // ignored inputs: { diff --git a/packages/frontend-app-api/src/extensions/CoreLayout.tsx b/packages/frontend-app-api/src/extensions/AppLayout.tsx similarity index 93% rename from packages/frontend-app-api/src/extensions/CoreLayout.tsx rename to packages/frontend-app-api/src/extensions/AppLayout.tsx index 2d65dff73a..7be0029c25 100644 --- a/packages/frontend-app-api/src/extensions/CoreLayout.tsx +++ b/packages/frontend-app-api/src/extensions/AppLayout.tsx @@ -22,10 +22,10 @@ import { } from '@backstage/frontend-plugin-api'; import { SidebarPage } from '@backstage/core-components'; -export const CoreLayout = createExtension({ +export const AppLayout = createExtension({ namespace: 'app', name: 'layout', - attachTo: { id: 'app/router', input: 'children' }, + attachTo: { id: 'app/root', input: 'children' }, inputs: { nav: createExtensionInput( { diff --git a/packages/frontend-app-api/src/extensions/CoreNav.tsx b/packages/frontend-app-api/src/extensions/AppNav.tsx similarity index 98% rename from packages/frontend-app-api/src/extensions/CoreNav.tsx rename to packages/frontend-app-api/src/extensions/AppNav.tsx index 9c0ac5e85a..c5bf028ef8 100644 --- a/packages/frontend-app-api/src/extensions/CoreNav.tsx +++ b/packages/frontend-app-api/src/extensions/AppNav.tsx @@ -78,7 +78,7 @@ const SidebarNavItem = ( return ; }; -export const CoreNav = createExtension({ +export const AppNav = createExtension({ namespace: 'app', name: 'nav', attachTo: { id: 'app/layout', input: 'nav' }, diff --git a/packages/frontend-app-api/src/extensions/CoreRouter.tsx b/packages/frontend-app-api/src/extensions/AppRoot.tsx similarity index 98% rename from packages/frontend-app-api/src/extensions/CoreRouter.tsx rename to packages/frontend-app-api/src/extensions/AppRoot.tsx index 5c823c2e60..0894287541 100644 --- a/packages/frontend-app-api/src/extensions/CoreRouter.tsx +++ b/packages/frontend-app-api/src/extensions/AppRoot.tsx @@ -34,9 +34,9 @@ import { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations import { BrowserRouter } from 'react-router-dom'; import { RouteTracker } from '../routing/RouteTracker'; -export const CoreRouter = createExtension({ +export const AppRoot = createExtension({ namespace: 'app', - name: 'router', + name: 'root', attachTo: { id: 'app', input: 'root' }, inputs: { signInPage: createExtensionInput( diff --git a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx b/packages/frontend-app-api/src/extensions/AppRoutes.tsx similarity index 97% rename from packages/frontend-app-api/src/extensions/CoreRoutes.tsx rename to packages/frontend-app-api/src/extensions/AppRoutes.tsx index d66c857f3b..38a9291755 100644 --- a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx +++ b/packages/frontend-app-api/src/extensions/AppRoutes.tsx @@ -24,7 +24,7 @@ import { } from '@backstage/frontend-plugin-api'; import { useRoutes } from 'react-router-dom'; -export const CoreRoutes = createExtension({ +export const AppRoutes = createExtension({ namespace: 'app', name: 'routes', attachTo: { id: 'app/layout', input: 'content' }, @@ -57,6 +57,7 @@ export const CoreRoutes = createExtension({ return element; }; + return { element: , }; diff --git a/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts b/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts index 4531947f9a..440407549e 100644 --- a/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts +++ b/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts @@ -25,18 +25,18 @@ describe('readAppExtensionsConfig', () => { it('should disable extension with shorthand notation', () => { expect( readAppExtensionsConfig( - new ConfigReader({ app: { extensions: [{ 'app/router': false }] } }), + new ConfigReader({ app: { extensions: [{ 'app/root': false }] } }), ), ).toEqual([ { - id: 'app/router', + id: 'app/root', disabled: true, }, ]); expect( readAppExtensionsConfig( new ConfigReader({ - app: { extensions: [{ 'app/router': { disabled: true } }] }, + app: { extensions: [{ 'app/root': { disabled: true } }] }, }), ), ).toEqual([ @@ -44,7 +44,7 @@ describe('readAppExtensionsConfig', () => { at: undefined, config: undefined, disabled: true, - id: 'app/router', + id: 'app/root', }, ]); }); @@ -52,33 +52,33 @@ describe('readAppExtensionsConfig', () => { it('should enable extension with shorthand notation', () => { expect( readAppExtensionsConfig( - new ConfigReader({ app: { extensions: ['app/router'] } }), + new ConfigReader({ app: { extensions: ['app/root'] } }), ), ).toEqual([ { - id: 'app/router', + id: 'app/root', disabled: false, }, ]); expect( readAppExtensionsConfig( - new ConfigReader({ app: { extensions: [{ 'app/router': true }] } }), + new ConfigReader({ app: { extensions: [{ 'app/root': true }] } }), ), ).toEqual([ { - id: 'app/router', + id: 'app/root', disabled: false, }, ]); expect( readAppExtensionsConfig( new ConfigReader({ - app: { extensions: [{ 'app/router': { disabled: false } }] }, + app: { extensions: [{ 'app/root': { disabled: false } }] }, }), ), ).toEqual([ { - id: 'app/router', + id: 'app/root', disabled: false, }, ]); @@ -89,12 +89,12 @@ describe('readAppExtensionsConfig', () => { readAppExtensionsConfig( new ConfigReader({ app: { - extensions: [{ 'app/router': 'some-string' }], + extensions: [{ 'app/root': 'some-string' }], }, }), ), ).toThrow( - 'Invalid extension configuration at app.extensions[0][app/router], value must be a boolean or object', + 'Invalid extension configuration at app.extensions[0][app/root], value must be a boolean or object', ); }); @@ -156,8 +156,8 @@ describe('expandShorthandExtensionParameters', () => { }); it('supports string key', () => { - expect(run('app/router')).toEqual({ - id: 'app/router', + expect(run('app/root')).toEqual({ + id: 'app/root', disabled: false, }); expect(() => run('')).toThrowErrorMatchingInlineSnapshot( @@ -170,96 +170,96 @@ describe('expandShorthandExtensionParameters', () => { it('supports null value', () => { // this is the result of typing: - // - app/router: + // - app/root: // The missing value is interpreted as null by the yaml parser so we deal with that - expect(run({ 'app/router': null })).toEqual({ - id: 'app/router', + expect(run({ 'app/root': null })).toEqual({ + id: 'app/root', disabled: false, }); }); it('supports boolean value', () => { - expect(run({ 'app/router': true })).toEqual({ - id: 'app/router', + expect(run({ 'app/root': true })).toEqual({ + id: 'app/root', disabled: false, }); - expect(run({ 'app/router': false })).toEqual({ - id: 'app/router', + expect(run({ 'app/root': false })).toEqual({ + id: 'app/root', disabled: true, }); }); it('should not support string values', () => { expect(() => - run({ 'app/router': 'example-package#MyRouter' }), + run({ 'app/root': 'example-package#MyRouter' }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][app/router], value must be a boolean or object"`, + `"Invalid extension configuration at app.extensions[1][app/root], value must be a boolean or object"`, ); }); it('supports object id only in the key', () => { expect(() => - run({ 'app/router': { id: 'some.id' } }), + run({ 'app/root': { id: 'some.id' } }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][app/router].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, + `"Invalid extension configuration at app.extensions[1][app/root].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, ); }); it('supports object attachTo', () => { expect( run({ - 'app/router': { attachTo: { id: 'other.root', input: 'inputs' } }, + 'app/root': { attachTo: { id: 'other.root', input: 'inputs' } }, }), ).toEqual({ - id: 'app/router', + id: 'app/root', attachTo: { id: 'other.root', input: 'inputs' }, }); expect(() => run({ - 'app/router': { + 'app/root': { id: 'other-id', }, }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][app/router].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, + `"Invalid extension configuration at app.extensions[1][app/root].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, ); }); it('supports object disabled', () => { - expect(run({ 'app/router': { disabled: true } })).toEqual({ - id: 'app/router', + expect(run({ 'app/root': { disabled: true } })).toEqual({ + id: 'app/root', disabled: true, }); - expect(run({ 'app/router': { disabled: false } })).toEqual({ - id: 'app/router', + expect(run({ 'app/root': { disabled: false } })).toEqual({ + id: 'app/root', disabled: false, }); expect(() => - run({ 'app/router': { disabled: 0 } }), + run({ 'app/root': { disabled: 0 } }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][app/router].disabled, must be a boolean"`, + `"Invalid extension configuration at app.extensions[1][app/root].disabled, must be a boolean"`, ); }); it('supports object config', () => { - expect( - run({ 'app/router': { config: { disableRedirects: true } } }), - ).toEqual({ - id: 'app/router', - config: { disableRedirects: true }, - }); + expect(run({ 'app/root': { config: { disableRedirects: true } } })).toEqual( + { + id: 'app/root', + config: { disableRedirects: true }, + }, + ); expect(() => - run({ 'app/router': { config: 0 } }), + run({ 'app/root': { config: 0 } }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][app/router].config, must be an object"`, + `"Invalid extension configuration at app.extensions[1][app/root].config, must be an object"`, ); }); it('rejects unknown object keys', () => { expect(() => - run({ 'app/router': { foo: { settings: true } } }), + run({ 'app/root': { foo: { settings: true } } }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][app/router].foo, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, + `"Invalid extension configuration at app.extensions[1][app/root].foo, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, ); }); }); diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index d5a206e7fb..e6ddc03e38 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -194,7 +194,7 @@ describe('createApp', () => { extensions: [ createExtension({ namespace: 'app', - name: 'router', + name: 'root', attachTo: { id: 'app', input: 'root' }, disabled: true, output: {}, @@ -244,7 +244,7 @@ describe('createApp', () => { expect(String(tree.root)).toMatchInlineSnapshot(` " root [ - + children [ content [ @@ -259,7 +259,7 @@ describe('createApp', () => { ] ] - + ] components [ diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 09a7034ffb..b25bad03bc 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -32,10 +32,10 @@ import { RouteRef, useRouteRef, } from '@backstage/frontend-plugin-api'; -import { Core } from '../extensions/Core'; -import { CoreRoutes } from '../extensions/CoreRoutes'; -import { CoreLayout } from '../extensions/CoreLayout'; -import { CoreNav } from '../extensions/CoreNav'; +import { App } from '../extensions/App'; +import { AppRoutes } from '../extensions/AppRoutes'; +import { AppLayout } from '../extensions/AppLayout'; +import { AppNav } from '../extensions/AppNav'; import { AnyApiFactory, ApiHolder, @@ -95,7 +95,7 @@ import { } from '../extensions/components'; import { AppNode } from '@backstage/frontend-plugin-api'; import { InternalAppContext } from './InternalAppContext'; -import { CoreRouter } from '../extensions/CoreRouter'; +import { AppRoot } from '../extensions/AppRoot'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalBackstagePlugin } from '../../../frontend-plugin-api/src/wiring/createPlugin'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports @@ -106,11 +106,11 @@ import { stringifyError } from '@backstage/errors'; const DefaultApis = defaultApis.map(factory => createApiExtension({ factory })); export const builtinExtensions = [ - Core, - CoreRouter, - CoreRoutes, - CoreNav, - CoreLayout, + App, + AppRoot, + AppRoutes, + AppNav, + AppLayout, DefaultProgressComponent, DefaultErrorBoundaryComponent, DefaultNotFoundErrorPageComponent, @@ -371,7 +371,7 @@ export function createSpecializedApp(options?: { ); const rootEl = tree.root.instance!.getData(coreExtensionData.reactElement); - const App = () => ( + const AppComponent = () => ( @@ -387,7 +387,7 @@ export function createSpecializedApp(options?: { return { createRoot() { - return ; + return ; }, }; } diff --git a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx index 543a5447ad..b525cc3a7b 100644 --- a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx @@ -50,7 +50,7 @@ export function createSignInPageExtension< kind: 'sign-in-page', namespace: options?.namespace, name: options?.name, - attachTo: options.attachTo ?? { id: 'app/router', input: 'signInPage' }, + attachTo: options.attachTo ?? { id: 'app/root', input: 'signInPage' }, configSchema: options.configSchema, inputs: options.inputs, disabled: options.disabled, diff --git a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts index cb02048bdc..d2f78122d3 100644 --- a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts @@ -150,7 +150,7 @@ describe('createPlugin', () => { await renderWithEffects( createTestAppRoot({ features: [plugin], - config: { app: { extensions: [{ 'app/router': false }] } }, + config: { app: { extensions: [{ 'app/root': false }] } }, }), ); @@ -172,7 +172,7 @@ describe('createPlugin', () => { config: { app: { extensions: [ - { 'app/router': false }, + { 'app/root': false }, { 'test/2': { config: { name: 'extension-2-renamed' }, @@ -210,7 +210,7 @@ describe('createPlugin', () => { features: [plugin], config: { app: { - extensions: [{ 'app/router': false }], + extensions: [{ 'app/root': false }], }, }, }), diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index aae2e5ed32..1a4ebbac48 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -151,7 +151,7 @@ const AuthenticationProvider = (props: { const TestCoreRouterExtension = createExtension({ namespace: 'app', - name: 'router', + name: 'root', attachTo: { id: 'app', input: 'root' }, inputs: { signInPage: createExtensionInput(