app-defaults,core-app-api: refactor into createApp/createSpecializedApp split
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
+11
-12
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { apis, components, configLoader, icons, themes } from './defaults';
|
||||
import { apis, components, icons, themes } from './defaults';
|
||||
import {
|
||||
AppTheme,
|
||||
BackstagePlugin,
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
AppComponents,
|
||||
AppOptions,
|
||||
AppIcons,
|
||||
PrivateAppImpl,
|
||||
createSpecializedApp,
|
||||
} from '@backstage/core-app-api';
|
||||
|
||||
/**
|
||||
@@ -33,8 +33,10 @@ import {
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function createApp(options?: AppOptions) {
|
||||
return new PrivateAppImpl({
|
||||
export function createApp(
|
||||
options?: Omit<AppOptions, keyof OptionalAppOptions> & OptionalAppOptions,
|
||||
) {
|
||||
return createSpecializedApp({
|
||||
...options,
|
||||
apis: options?.apis ?? [],
|
||||
bindRoutes: options?.bindRoutes,
|
||||
@@ -42,7 +44,7 @@ export function createApp(options?: AppOptions) {
|
||||
...components,
|
||||
...options?.components,
|
||||
},
|
||||
configLoader: options?.configLoader ?? configLoader,
|
||||
configLoader: options?.configLoader,
|
||||
defaultApis: apis,
|
||||
icons: {
|
||||
...icons,
|
||||
@@ -53,16 +55,13 @@ export function createApp(options?: AppOptions) {
|
||||
});
|
||||
}
|
||||
|
||||
// NOTE: we don't re-export any of the types imported from core-app-api, as we
|
||||
// want them to be imported from there rather than core-components.
|
||||
|
||||
/**
|
||||
* The set of app options that will be populated by {@link withDefaults} if they
|
||||
* are not passed in explicitly.
|
||||
* The set of app options that {@link createApp} will provide defaults for
|
||||
* if they are not passed in explicitly.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface OptionalAppOptions {
|
||||
export type OptionalAppOptions = {
|
||||
/**
|
||||
* A set of icons to override the default icons with.
|
||||
*
|
||||
@@ -91,4 +90,4 @@ export interface OptionalAppOptions {
|
||||
* @public
|
||||
*/
|
||||
components?: Partial<AppComponents>;
|
||||
}
|
||||
};
|
||||
+2
-2
@@ -32,7 +32,7 @@ import MuiPeopleIcon from '@material-ui/icons/People';
|
||||
import MuiPersonIcon from '@material-ui/icons/Person';
|
||||
import MuiWarningIcon from '@material-ui/icons/Warning';
|
||||
|
||||
export const icons = () => ({
|
||||
export const icons = {
|
||||
brokenImage: MuiBrokenImageIcon as IconComponent,
|
||||
// To be confirmed: see https://github.com/backstage/backstage/issues/4970
|
||||
catalog: MuiMenuBookIcon as IconComponent,
|
||||
@@ -52,4 +52,4 @@ export const icons = () => ({
|
||||
'kind:user': MuiPersonIcon as IconComponent,
|
||||
user: MuiPersonIcon as IconComponent,
|
||||
warning: MuiWarningIcon as IconComponent,
|
||||
});
|
||||
};
|
||||
@@ -20,4 +20,5 @@
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
export * from './createApp';
|
||||
export { createApp } from './createApp';
|
||||
export type { OptionalAppOptions } from './createApp';
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/app-defaults": "^0.1.0",
|
||||
"@backstage/core-components": "^0.7.3",
|
||||
"@backstage/config": "^0.1.11",
|
||||
"@backstage/core-plugin-api": "^0.1.13",
|
||||
|
||||
@@ -78,6 +78,7 @@ import {
|
||||
SignInResult,
|
||||
} from './types';
|
||||
import { AppThemeProvider } from './AppThemeProvider';
|
||||
import { defaultConfigLoader } from './defaultConfigLoader';
|
||||
|
||||
export function generateBoundRoutes(bindRoutes: AppOptions['bindRoutes']) {
|
||||
const result = new Map<ExternalRouteRef, RouteRef | SubRouteRef>();
|
||||
@@ -122,17 +123,6 @@ function getBasePath(configApi: Config) {
|
||||
return pathname;
|
||||
}
|
||||
|
||||
type FullAppOptions = {
|
||||
apis: Iterable<AnyApiFactory>;
|
||||
icons: NonNullable<AppOptions['icons']>;
|
||||
plugins: BackstagePlugin<any, any>[];
|
||||
components: AppComponents;
|
||||
themes: (Partial<AppTheme> & Omit<AppTheme, 'theme'>)[];
|
||||
configLoader?: AppConfigLoader;
|
||||
defaultApis: Iterable<AnyApiFactory>;
|
||||
bindRoutes?: AppOptions['bindRoutes'];
|
||||
};
|
||||
|
||||
function useConfigLoader(
|
||||
configLoader: AppConfigLoader | undefined,
|
||||
components: AppComponents,
|
||||
@@ -202,14 +192,16 @@ export class AppManager implements BackstageApp {
|
||||
private readonly identityApi = new AppIdentity();
|
||||
private readonly apiFactoryRegistry: ApiFactoryRegistry;
|
||||
|
||||
constructor(options: FullAppOptions) {
|
||||
this.apis = options.apis;
|
||||
constructor(options: AppOptions) {
|
||||
this.apis = options.apis ?? [];
|
||||
this.icons = options.icons;
|
||||
this.plugins = new Set(options.plugins);
|
||||
this.plugins = new Set(
|
||||
(options.plugins as BackstagePlugin<any, any>[]) ?? [],
|
||||
);
|
||||
this.components = options.components;
|
||||
this.themes = options.themes as AppTheme[];
|
||||
this.configLoader = options.configLoader;
|
||||
this.defaultApis = options.defaultApis;
|
||||
this.configLoader = options.configLoader ?? defaultConfigLoader;
|
||||
this.defaultApis = options.defaultApis ?? [];
|
||||
this.bindRoutes = options.bindRoutes;
|
||||
this.apiFactoryRegistry = new ApiFactoryRegistry();
|
||||
}
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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 { screen } from '@testing-library/react';
|
||||
import { renderWithEffects } from '@backstage/test-utils';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { defaultConfigLoader, createApp } from './createApp';
|
||||
|
||||
(process as any).env = { NODE_ENV: 'test' };
|
||||
const anyEnv = process.env as any;
|
||||
const anyWindow = window as any;
|
||||
|
||||
describe('defaultConfigLoader', () => {
|
||||
afterEach(() => {
|
||||
delete anyEnv.APP_CONFIG;
|
||||
delete anyWindow.__APP_CONFIG__;
|
||||
});
|
||||
|
||||
it('loads static config', async () => {
|
||||
anyEnv.APP_CONFIG = [
|
||||
{ data: { my: 'config' }, context: 'a' },
|
||||
{ data: { my: 'override-config' }, context: 'b' },
|
||||
];
|
||||
|
||||
const configs = await defaultConfigLoader();
|
||||
expect(configs).toEqual([
|
||||
{ data: { my: 'config' }, context: 'a' },
|
||||
{ data: { my: 'override-config' }, context: 'b' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('loads runtime config', async () => {
|
||||
anyEnv.APP_CONFIG = [
|
||||
{ data: { my: 'override-config' }, context: 'a' },
|
||||
{ data: { my: 'config' }, context: 'b' },
|
||||
];
|
||||
|
||||
const configs = await (defaultConfigLoader as any)(
|
||||
'{"my":"runtime-config"}',
|
||||
);
|
||||
expect(configs).toEqual([
|
||||
{ data: { my: 'override-config' }, context: 'a' },
|
||||
{ data: { my: 'config' }, context: 'b' },
|
||||
{ data: { my: 'runtime-config' }, context: 'env' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('fails to load invalid missing config', async () => {
|
||||
await expect(defaultConfigLoader()).rejects.toThrow(
|
||||
'No static configuration provided',
|
||||
);
|
||||
});
|
||||
|
||||
it('fails to load invalid static config', async () => {
|
||||
anyEnv.APP_CONFIG = { my: 'invalid-config' };
|
||||
await expect(defaultConfigLoader()).rejects.toThrow(
|
||||
'Static configuration has invalid format',
|
||||
);
|
||||
});
|
||||
|
||||
it('fails to load bad runtime config', async () => {
|
||||
anyEnv.APP_CONFIG = [{ data: { my: 'config' }, context: 'a' }];
|
||||
|
||||
await expect((defaultConfigLoader as any)('}')).rejects.toThrow(
|
||||
'Failed to load runtime configuration, SyntaxError: Unexpected token } in JSON at position 0',
|
||||
);
|
||||
});
|
||||
|
||||
it('loads config from window.__APP_CONFIG__', async () => {
|
||||
anyEnv.APP_CONFIG = [
|
||||
{ data: { my: 'config' }, context: 'a' },
|
||||
{ data: { my: 'override-config' }, context: 'b' },
|
||||
];
|
||||
const windowConfig = { app: { configKey: 'config-value' } };
|
||||
anyWindow.__APP_CONFIG__ = windowConfig;
|
||||
|
||||
const configs = await defaultConfigLoader();
|
||||
|
||||
expect(configs).toEqual([
|
||||
...anyEnv.APP_CONFIG,
|
||||
{ context: 'window', data: windowConfig },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Optional ThemeProvider', () => {
|
||||
it('should render app with user-provided ThemeProvider', async () => {
|
||||
const components = {
|
||||
NotFoundErrorPage: () => null,
|
||||
BootErrorPage: () => null,
|
||||
Progress: () => null,
|
||||
Router: MemoryRouter,
|
||||
ErrorBoundaryFallback: () => null,
|
||||
ThemeProvider: ({ children }: PropsWithChildren<{}>) => (
|
||||
<main role="main">{children}</main>
|
||||
),
|
||||
};
|
||||
|
||||
const App = createApp({ components }).getProvider();
|
||||
|
||||
await renderWithEffects(<App />);
|
||||
|
||||
expect(screen.getByRole('main')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -14,132 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AppConfig } from '@backstage/config';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { withDefaults } from '@backstage/core-components';
|
||||
import { AppManager } from './AppManager';
|
||||
import { AppComponents, AppConfigLoader, AppOptions } from './types';
|
||||
import { defaultApis } from './defaultApis';
|
||||
import { BackstagePlugin } from '@backstage/core-plugin-api';
|
||||
|
||||
const REQUIRED_APP_COMPONENTS: Array<keyof AppComponents> = [
|
||||
'Progress',
|
||||
'Router',
|
||||
'NotFoundErrorPage',
|
||||
'BootErrorPage',
|
||||
'ErrorBoundaryFallback',
|
||||
];
|
||||
|
||||
/**
|
||||
* The default config loader, which expects that config is available at compile-time
|
||||
* in `process.env.APP_CONFIG`. APP_CONFIG should be an array of config objects as
|
||||
* returned by the config loader.
|
||||
*
|
||||
* It will also load runtime config from the __APP_INJECTED_RUNTIME_CONFIG__ string,
|
||||
* which can be rewritten at runtime to contain an additional JSON config object.
|
||||
* If runtime config is present, it will be placed first in the config array, overriding
|
||||
* other config values.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const defaultConfigLoader: AppConfigLoader = async (
|
||||
// This string may be replaced at runtime to provide additional config.
|
||||
// It should be replaced by a JSON-serialized config object.
|
||||
// It's a param so we can test it, but at runtime this will always fall back to default.
|
||||
runtimeConfigJson: string = '__APP_INJECTED_RUNTIME_CONFIG__',
|
||||
) => {
|
||||
const appConfig = process.env.APP_CONFIG;
|
||||
if (!appConfig) {
|
||||
throw new Error('No static configuration provided');
|
||||
}
|
||||
if (!Array.isArray(appConfig)) {
|
||||
throw new Error('Static configuration has invalid format');
|
||||
}
|
||||
const configs = appConfig.slice() as unknown as AppConfig[];
|
||||
|
||||
// Avoiding this string also being replaced at runtime
|
||||
if (
|
||||
runtimeConfigJson !==
|
||||
'__app_injected_runtime_config__'.toLocaleUpperCase('en-US')
|
||||
) {
|
||||
try {
|
||||
const data = JSON.parse(runtimeConfigJson) as JsonObject;
|
||||
if (Array.isArray(data)) {
|
||||
configs.push(...data);
|
||||
} else {
|
||||
configs.push({ data, context: 'env' });
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to load runtime configuration, ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
const windowAppConfig = (window as any).__APP_CONFIG__;
|
||||
if (windowAppConfig) {
|
||||
configs.push({
|
||||
context: 'window',
|
||||
data: windowAppConfig,
|
||||
});
|
||||
}
|
||||
return configs;
|
||||
};
|
||||
import {
|
||||
createApp as createDefaultApp,
|
||||
OptionalAppOptions,
|
||||
} from '@backstage/app-defaults';
|
||||
|
||||
/**
|
||||
* Creates a new Backstage App.
|
||||
*
|
||||
* @deprecated Use createApp from @backstage/app-defaults instead
|
||||
* @param options - A set of options for creating the app
|
||||
* @public
|
||||
*/
|
||||
export function createApp(options?: AppOptions) {
|
||||
const optionsWithDefaults = withDefaults(options);
|
||||
|
||||
const missingRequiredComponents = REQUIRED_APP_COMPONENTS.filter(
|
||||
name => !options?.components?.[name],
|
||||
export function createApp(options?: OptionalAppOptions) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'DEPRECATION WARNING: The createApp function from @backstage/core-app-api will soon be removed, ' +
|
||||
'migrate to importing createApp from the @backstage/app-defaults package instead. ' +
|
||||
'If you do not wish to use a standard app configuration but instead supply all options yourself ' +
|
||||
' you can use createSpecializedApp from @backstage/core-app-api instead.',
|
||||
);
|
||||
if (missingRequiredComponents.length > 0) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'DEPRECATION WARNING: The createApp options will soon require a minimal set of components to ' +
|
||||
'be provided. You can use the default components by using withDefaults from @backstage/core-components ' +
|
||||
'like this: createApp(withDefaults({ ... })), or you can provide the components yourself. ' +
|
||||
`The following components are missing: ${missingRequiredComponents.join(
|
||||
', ',
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const providedIconKeys = Object.keys(options?.icons ?? {});
|
||||
const missingIconKeys = Object.keys(optionsWithDefaults.icons!).filter(
|
||||
key => !providedIconKeys.includes(key),
|
||||
);
|
||||
if (missingIconKeys.length > 0) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'DEPRECATION WARNING: The createApp options will soon require a minimal set of icons to ' +
|
||||
'be provided. You can use the default icons by using withDefaults from @backstage/core-components ' +
|
||||
'like this: createApp(withDefaults({ ... })), or you can provide the icons yourself. ' +
|
||||
`The following icons are missing: ${missingIconKeys.join(', ')}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!options?.themes) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'DEPRECATION WARNING: The createApp options will soon require the themes to be provided. ' +
|
||||
'You can use the default themes by using withDefaults from @backstage/core-components ' +
|
||||
'like this: createApp(withDefaults({ ... })), or you can provide the themes yourself. ',
|
||||
);
|
||||
}
|
||||
|
||||
const { icons, themes, components } = optionsWithDefaults;
|
||||
|
||||
return new AppManager({
|
||||
icons: icons!,
|
||||
themes: themes!,
|
||||
components: components! as AppComponents,
|
||||
defaultApis,
|
||||
apis: options?.apis ?? [],
|
||||
bindRoutes: options?.bindRoutes,
|
||||
plugins: (options?.plugins as BackstagePlugin<any, any>[]) ?? [],
|
||||
configLoader: options?.configLoader ?? defaultConfigLoader,
|
||||
});
|
||||
return createDefaultApp(options);
|
||||
}
|
||||
|
||||
+12
-1
@@ -14,4 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { createApp } from './createApp';
|
||||
import { AppManager } from './AppManager';
|
||||
import { AppOptions } from './types';
|
||||
|
||||
/**
|
||||
* Creates a new Backstage App where the full set of options are required.
|
||||
*
|
||||
* @param options - A set of options for creating the app
|
||||
* @returns
|
||||
*/
|
||||
export function createSpecializedApp(options: AppOptions) {
|
||||
return new AppManager(options);
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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 {
|
||||
AlertApiForwarder,
|
||||
NoOpAnalyticsApi,
|
||||
ErrorApiForwarder,
|
||||
ErrorAlerter,
|
||||
GoogleAuth,
|
||||
GithubAuth,
|
||||
OAuth2,
|
||||
OktaAuth,
|
||||
GitlabAuth,
|
||||
Auth0Auth,
|
||||
MicrosoftAuth,
|
||||
BitbucketAuth,
|
||||
OAuthRequestManager,
|
||||
WebStorage,
|
||||
UrlPatternDiscovery,
|
||||
SamlAuth,
|
||||
OneLoginAuth,
|
||||
UnhandledErrorForwarder,
|
||||
AtlassianAuth,
|
||||
} from '../apis';
|
||||
|
||||
import {
|
||||
createApiFactory,
|
||||
alertApiRef,
|
||||
analyticsApiRef,
|
||||
errorApiRef,
|
||||
discoveryApiRef,
|
||||
oauthRequestApiRef,
|
||||
googleAuthApiRef,
|
||||
githubAuthApiRef,
|
||||
oauth2ApiRef,
|
||||
oktaAuthApiRef,
|
||||
gitlabAuthApiRef,
|
||||
auth0AuthApiRef,
|
||||
microsoftAuthApiRef,
|
||||
storageApiRef,
|
||||
configApiRef,
|
||||
samlAuthApiRef,
|
||||
oneloginAuthApiRef,
|
||||
oidcAuthApiRef,
|
||||
bitbucketAuthApiRef,
|
||||
atlassianAuthApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
import OAuth2Icon from '@material-ui/icons/AcUnit';
|
||||
|
||||
export const defaultApis = [
|
||||
createApiFactory({
|
||||
api: discoveryApiRef,
|
||||
deps: { configApi: configApiRef },
|
||||
factory: ({ configApi }) =>
|
||||
UrlPatternDiscovery.compile(
|
||||
`${configApi.getString('backend.baseUrl')}/api/{{ pluginId }}`,
|
||||
),
|
||||
}),
|
||||
createApiFactory(alertApiRef, new AlertApiForwarder()),
|
||||
createApiFactory(analyticsApiRef, new NoOpAnalyticsApi()),
|
||||
createApiFactory({
|
||||
api: errorApiRef,
|
||||
deps: { alertApi: alertApiRef },
|
||||
factory: ({ alertApi }) => {
|
||||
const errorApi = new ErrorAlerter(alertApi, new ErrorApiForwarder());
|
||||
UnhandledErrorForwarder.forward(errorApi, { hidden: false });
|
||||
return errorApi;
|
||||
},
|
||||
}),
|
||||
createApiFactory({
|
||||
api: storageApiRef,
|
||||
deps: { errorApi: errorApiRef },
|
||||
factory: ({ errorApi }) => WebStorage.create({ errorApi }),
|
||||
}),
|
||||
createApiFactory(oauthRequestApiRef, new OAuthRequestManager()),
|
||||
createApiFactory({
|
||||
api: googleAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
GoogleAuth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: microsoftAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
MicrosoftAuth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: githubAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
GithubAuth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
defaultScopes: ['read:user'],
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: oktaAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
OktaAuth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: gitlabAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
GitlabAuth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: auth0AuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
Auth0Auth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: oauth2ApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: samlAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, configApi }) =>
|
||||
SamlAuth.create({
|
||||
discoveryApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: oneloginAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
OneLoginAuth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: oidcAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
provider: {
|
||||
id: 'oidc',
|
||||
title: 'Your Identity Provider',
|
||||
icon: OAuth2Icon,
|
||||
},
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: bitbucketAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
|
||||
BitbucketAuth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
defaultScopes: ['team'],
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: atlassianAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi, configApi }) => {
|
||||
return AtlassianAuth.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment: configApi.getOptionalString('auth.environment'),
|
||||
});
|
||||
},
|
||||
}),
|
||||
];
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
export { createApp } from './createApp';
|
||||
export { createSpecializedApp } from './createSpecializedApp';
|
||||
export { defaultConfigLoader } from './defaultConfigLoader';
|
||||
export type { AppIcons } from './icons';
|
||||
export * from './types';
|
||||
|
||||
@@ -200,10 +200,19 @@ export type AppOptions = {
|
||||
*/
|
||||
apis?: Iterable<AnyApiFactory>;
|
||||
|
||||
/**
|
||||
* A collection of ApiFactories to register in the application as default APIs.
|
||||
* Theses APIs can not be overridden by plugin factories, but can be overridden
|
||||
* by plugin APIs provided through the
|
||||
* A collection of ApiFactories to register in the application to either
|
||||
* add add new ones, or override factories provided by default or by plugins.
|
||||
*/
|
||||
defaultApis?: Iterable<AnyApiFactory>;
|
||||
|
||||
/**
|
||||
* Supply icons to override the default ones.
|
||||
*/
|
||||
icons?: Partial<AppIcons> & { [key in string]: IconComponent };
|
||||
icons: AppIcons & { [key in string]: IconComponent };
|
||||
|
||||
/**
|
||||
* A list of all plugins to include in the app.
|
||||
@@ -213,7 +222,7 @@ export type AppOptions = {
|
||||
/**
|
||||
* Supply components to the app to override the default ones.
|
||||
*/
|
||||
components?: Partial<AppComponents>;
|
||||
components: AppComponents;
|
||||
|
||||
/**
|
||||
* Themes provided as a part of the app. By default two themes are included, one
|
||||
@@ -245,7 +254,7 @@ export type AppOptions = {
|
||||
* }]
|
||||
* ```
|
||||
*/
|
||||
themes?: (Partial<AppTheme> & Omit<AppTheme, 'theme'>)[];
|
||||
themes: (Partial<AppTheme> & Omit<AppTheme, 'theme'>)[];
|
||||
|
||||
/**
|
||||
* A function that loads in App configuration that will be accessible via
|
||||
|
||||
Reference in New Issue
Block a user