Merge remote-tracking branch 'origin/master' into bui-toast
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor # Conflicts: # packages/frontend-defaults/src/createPublicSignInApp.test.tsx # yarn.lock
This commit is contained in:
@@ -1,5 +1,50 @@
|
||||
# @backstage/frontend-defaults
|
||||
|
||||
## 0.5.0-next.1
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 92af1ae: **BREAKING**: Removed the `allowUnknownExtensionConfig` option from `createApp`. This flag had no effect and was a no-op, so no behavioral changes are expected.
|
||||
- 33de79d: **BREAKING**: Removed the deprecated `createPublicSignInApp` function. Use `createApp` from `@backstage/frontend-defaults` with `appModulePublicSignIn` from `@backstage/plugin-app/alpha` instead.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/frontend-plugin-api@0.15.0-next.1
|
||||
- @backstage/frontend-app-api@0.16.0-next.1
|
||||
- @backstage/core-components@0.18.8-next.1
|
||||
- @backstage/plugin-app@0.4.1-next.2
|
||||
|
||||
## 0.4.1-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/frontend-plugin-api@0.14.2-next.0
|
||||
- @backstage/plugin-app@0.4.1-next.0
|
||||
- @backstage/config@1.3.6
|
||||
- @backstage/core-components@0.18.8-next.0
|
||||
- @backstage/errors@1.2.7
|
||||
- @backstage/frontend-app-api@0.15.1-next.0
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 55b2ef6: **BREAKING**: The `API_FACTORY_CONFLICT` warning is now treated as an error and will prevent the app from starting.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 122d39c: Completely removed support for the deprecated `app.experimental.packages` configuration. Replace existing usage directly with `app.packages`.
|
||||
- c38b74d: Dependency update for tests.
|
||||
- 53b6549: Plugins in the new frontend system now have a `pluginId` field rather than `id` to better align with naming conventions used throughout the frontend and backend systems. The old field is still present but marked as deprecated. All internal code has been updated to prefer `pluginId` while maintaining backward compatibility by falling back to `id` when needed.
|
||||
- a7e0d50: Updated `react-router-dom` peer dependency to `^6.30.2` and explicitly disabled v7 future flags to suppress deprecation warnings.
|
||||
- Updated dependencies
|
||||
- @backstage/frontend-app-api@0.15.0
|
||||
- @backstage/core-components@0.18.7
|
||||
- @backstage/frontend-plugin-api@0.14.0
|
||||
- @backstage/plugin-app@0.4.0
|
||||
|
||||
## 0.4.0-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/frontend-defaults",
|
||||
"version": "0.4.0-next.2",
|
||||
"version": "0.5.0-next.1",
|
||||
"backstage": {
|
||||
"role": "web-library"
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AppErrorTypes } from '@backstage/frontend-app-api';
|
||||
import { Config } from '@backstage/config';
|
||||
import { ConfigApi } from '@backstage/frontend-plugin-api';
|
||||
import { CreateAppRouteBinder } from '@backstage/frontend-app-api';
|
||||
import { ExtensionFactoryMiddleware } from '@backstage/frontend-plugin-api';
|
||||
import { ExtensionFactoryMiddleware } from '@backstage/frontend-app-api';
|
||||
import { FrontendFeature } from '@backstage/frontend-plugin-api';
|
||||
import { FrontendFeatureLoader } from '@backstage/frontend-plugin-api';
|
||||
import { FrontendPluginInfoResolver } from '@backstage/frontend-app-api';
|
||||
@@ -23,7 +23,6 @@ export function createApp(options?: CreateAppOptions): {
|
||||
// @public
|
||||
export interface CreateAppOptions {
|
||||
advanced?: {
|
||||
allowUnknownExtensionConfig?: boolean;
|
||||
configLoader?: () => Promise<{
|
||||
config: ConfigApi;
|
||||
}>;
|
||||
@@ -37,11 +36,6 @@ export interface CreateAppOptions {
|
||||
features?: (FrontendFeature | FrontendFeatureLoader)[];
|
||||
}
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export function createPublicSignInApp(options?: CreateAppOptions): {
|
||||
createRoot(): JSX_2;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export function discoverAvailableFeatures(config: Config): {
|
||||
features: (FrontendFeature | FrontendFeatureLoader)[];
|
||||
|
||||
@@ -283,7 +283,9 @@ describe('createApp', () => {
|
||||
).resolves.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should allow unknown extension config if the flag is set', async () => {
|
||||
it('should warn about unknown extension config', async () => {
|
||||
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
|
||||
const app = createApp({
|
||||
features: [
|
||||
appPlugin,
|
||||
@@ -300,7 +302,6 @@ describe('createApp', () => {
|
||||
}),
|
||||
],
|
||||
advanced: {
|
||||
allowUnknownExtensionConfig: true,
|
||||
configLoader: async () => ({
|
||||
config: mockApis.config({
|
||||
data: {
|
||||
@@ -316,6 +317,12 @@ describe('createApp', () => {
|
||||
await renderWithEffects(app.createRoot());
|
||||
|
||||
await expect(screen.findByText('Derp')).resolves.toBeInTheDocument();
|
||||
expect(warnSpy).toHaveBeenCalledWith('App startup encountered warnings:');
|
||||
expect(warnSpy).toHaveBeenCalledWith(
|
||||
'INVALID_EXTENSION_CONFIG_KEY: Extension unknown:lols/wut does not exist',
|
||||
);
|
||||
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
it('should make the app structure available through the AppTreeApi', async () => {
|
||||
let appTreeApi: AppTreeApi | undefined = undefined;
|
||||
@@ -390,11 +397,13 @@ describe('createApp', () => {
|
||||
<component:app/core-progress out=[core.swappableComponent] />
|
||||
<component:app/core-not-found-error-page out=[core.swappableComponent] />
|
||||
<component:app/core-error-display out=[core.swappableComponent] />
|
||||
<component:app/core-page-layout out=[core.swappableComponent] />
|
||||
]
|
||||
</api:app/swappable-components>
|
||||
<api:app/icons out=[core.api.factory] />
|
||||
<api:app/feature-flags out=[core.api.factory] />
|
||||
<api:app/plugin-wrapper out=[core.api.factory] />
|
||||
<api:app/plugin-header-actions out=[core.api.factory] />
|
||||
<api:app/translations out=[core.api.factory] />
|
||||
<api:app/components out=[core.api.factory] />
|
||||
]
|
||||
|
||||
@@ -18,7 +18,6 @@ import { JSX, lazy, ReactNode, Suspense } from 'react';
|
||||
import {
|
||||
ConfigApi,
|
||||
coreExtensionData,
|
||||
ExtensionFactoryMiddleware,
|
||||
FrontendFeature,
|
||||
FrontendFeatureLoader,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
@@ -31,6 +30,7 @@ import { ConfigReader } from '@backstage/config';
|
||||
import {
|
||||
CreateAppRouteBinder,
|
||||
createSpecializedApp,
|
||||
ExtensionFactoryMiddleware,
|
||||
FrontendPluginInfoResolver,
|
||||
} from '@backstage/frontend-app-api';
|
||||
import appPlugin from '@backstage/plugin-app';
|
||||
@@ -58,17 +58,6 @@ export interface CreateAppOptions {
|
||||
* Advanced, more rarely used options.
|
||||
*/
|
||||
advanced?: {
|
||||
/**
|
||||
* If set to true, the system will silently accept and move on if
|
||||
* encountering config for extensions that do not exist. The default is to
|
||||
* reject such config to help catch simple mistakes.
|
||||
*
|
||||
* This flag can be useful in some scenarios where you have a dynamic set of
|
||||
* extensions enabled at different times, but also increases the risk of
|
||||
* accidentally missing e.g. simple typos in your config.
|
||||
*/
|
||||
allowUnknownExtensionConfig?: boolean;
|
||||
|
||||
/**
|
||||
* Sets a custom config loader, replacing the builtin one.
|
||||
*
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createFrontendModule } from '@backstage/frontend-plugin-api';
|
||||
import { SignInPageBlueprint } from '@backstage/plugin-app-react';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import { useEffect } from 'react';
|
||||
import { createPublicSignInApp } from './createPublicSignInApp';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
describe('createPublicSignInApp', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should render a sign-in page', async () => {
|
||||
const app = createPublicSignInApp({
|
||||
advanced: {
|
||||
configLoader: async () => ({ config: mockApis.config() }),
|
||||
},
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
extensions: [
|
||||
SignInPageBlueprint.make({
|
||||
params: {
|
||||
loader: async () => () => <div>Sign in page</div>,
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
render(app.createRoot());
|
||||
|
||||
await expect(
|
||||
screen.findByText('Sign in page'),
|
||||
).resolves.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render the form redirect on sign-in', async () => {
|
||||
const submitSpy = jest
|
||||
.spyOn(HTMLFormElement.prototype, 'submit')
|
||||
.mockReturnValue();
|
||||
|
||||
const app = createPublicSignInApp({
|
||||
advanced: {
|
||||
configLoader: async () => ({ config: mockApis.config() }),
|
||||
},
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
extensions: [
|
||||
SignInPageBlueprint.make({
|
||||
params: {
|
||||
loader:
|
||||
async () =>
|
||||
({ onSignInSuccess }) => {
|
||||
useEffect(() => {
|
||||
onSignInSuccess(
|
||||
mockApis.identity({ token: 'mock-token' }),
|
||||
);
|
||||
}, [onSignInSuccess]);
|
||||
return <div />;
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const { baseElement } = render(app.createRoot());
|
||||
|
||||
await waitFor(() => {
|
||||
expect(submitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
expect(baseElement).toMatchInlineSnapshot(`
|
||||
<body
|
||||
data-theme-mode="light"
|
||||
data-theme-name="backstage"
|
||||
data-unified-theme-stack="[{"mode":"light","name":"backstage"}]"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
aria-label="0 notifications."
|
||||
class="container"
|
||||
data-react-aria-top-layer="true"
|
||||
data-theme-mode="dark"
|
||||
role="region"
|
||||
tabindex="-1"
|
||||
/>
|
||||
<form
|
||||
action="http://localhost/"
|
||||
method="POST"
|
||||
style="visibility: hidden;"
|
||||
>
|
||||
<input
|
||||
name="type"
|
||||
type="hidden"
|
||||
value="sign-in"
|
||||
/>
|
||||
<input
|
||||
name="token"
|
||||
type="hidden"
|
||||
value="mock-token"
|
||||
/>
|
||||
<input
|
||||
type="submit"
|
||||
value="Continue"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
`);
|
||||
});
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { appModulePublicSignIn } from '@backstage/plugin-app/alpha';
|
||||
import { CreateAppOptions, createApp } from './createApp';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use {@link @backstage/plugin-app/alpha#appModulePublicSignIn} instead.
|
||||
*/
|
||||
export function createPublicSignInApp(options?: CreateAppOptions) {
|
||||
return createApp({
|
||||
...options,
|
||||
features: [...(options?.features ?? []), appModulePublicSignIn],
|
||||
});
|
||||
}
|
||||
@@ -21,7 +21,6 @@
|
||||
*/
|
||||
|
||||
export { createApp, type CreateAppOptions } from './createApp';
|
||||
export { createPublicSignInApp } from './createPublicSignInApp';
|
||||
export { discoverAvailableFeatures } from './discovery';
|
||||
export { resolveAsyncFeatures } from './resolution';
|
||||
export { maybeCreateErrorPage } from './maybeCreateErrorPage';
|
||||
|
||||
Reference in New Issue
Block a user