packages/core-api: temporary solution for giving access to config when creating APIs
This commit is contained in:
@@ -18,7 +18,7 @@ import { createApp, AlertDisplay, OAuthRequestDialog } from '@backstage/core';
|
||||
import React, { FC } from 'react';
|
||||
import Root from './components/Root';
|
||||
import * as plugins from './plugins';
|
||||
import apis from './apis';
|
||||
import { apis } from './apis';
|
||||
import { hot } from 'react-hot-loader/root';
|
||||
|
||||
const app = createApp({
|
||||
|
||||
+52
-47
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
ApiHolder,
|
||||
ApiRegistry,
|
||||
alertApiRef,
|
||||
errorApiRef,
|
||||
AlertApiForwarder,
|
||||
ConfigApi,
|
||||
ErrorApiForwarder,
|
||||
ErrorAlerter,
|
||||
featureFlagsApiRef,
|
||||
@@ -46,59 +46,64 @@ import { catalogApiRef, CatalogClient } from '@backstage/plugin-catalog';
|
||||
|
||||
import { gitOpsApiRef, GitOpsRestApi } from '@backstage/plugin-gitops-profiles';
|
||||
|
||||
const builder = ApiRegistry.builder();
|
||||
export const apis = (config: ConfigApi) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Creating APIs for ${config.getString('app.title')}`);
|
||||
|
||||
const alertApi = builder.add(alertApiRef, new AlertApiForwarder());
|
||||
const errorApi = builder.add(
|
||||
errorApiRef,
|
||||
new ErrorAlerter(alertApi, new ErrorApiForwarder()),
|
||||
);
|
||||
const builder = ApiRegistry.builder();
|
||||
|
||||
builder.add(storageApiRef, WebStorage.create({ errorApi }));
|
||||
builder.add(circleCIApiRef, new CircleCIApi());
|
||||
builder.add(featureFlagsApiRef, new FeatureFlags());
|
||||
const alertApi = builder.add(alertApiRef, new AlertApiForwarder());
|
||||
const errorApi = builder.add(
|
||||
errorApiRef,
|
||||
new ErrorAlerter(alertApi, new ErrorApiForwarder()),
|
||||
);
|
||||
|
||||
builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003'));
|
||||
builder.add(storageApiRef, WebStorage.create({ errorApi }));
|
||||
builder.add(circleCIApiRef, new CircleCIApi());
|
||||
builder.add(featureFlagsApiRef, new FeatureFlags());
|
||||
|
||||
const oauthRequestApi = builder.add(
|
||||
oauthRequestApiRef,
|
||||
new OAuthRequestManager(),
|
||||
);
|
||||
builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003'));
|
||||
|
||||
builder.add(
|
||||
googleAuthApiRef,
|
||||
GoogleAuth.create({
|
||||
apiOrigin: 'http://localhost:7000',
|
||||
basePath: '/auth/',
|
||||
oauthRequestApi,
|
||||
}),
|
||||
);
|
||||
const oauthRequestApi = builder.add(
|
||||
oauthRequestApiRef,
|
||||
new OAuthRequestManager(),
|
||||
);
|
||||
|
||||
builder.add(
|
||||
githubAuthApiRef,
|
||||
GithubAuth.create({
|
||||
apiOrigin: 'http://localhost:7000',
|
||||
basePath: '/auth/',
|
||||
oauthRequestApi,
|
||||
}),
|
||||
);
|
||||
builder.add(
|
||||
googleAuthApiRef,
|
||||
GoogleAuth.create({
|
||||
apiOrigin: 'http://localhost:7000',
|
||||
basePath: '/auth/',
|
||||
oauthRequestApi,
|
||||
}),
|
||||
);
|
||||
|
||||
builder.add(
|
||||
techRadarApiRef,
|
||||
new TechRadar({
|
||||
width: 1500,
|
||||
height: 800,
|
||||
}),
|
||||
);
|
||||
builder.add(
|
||||
githubAuthApiRef,
|
||||
GithubAuth.create({
|
||||
apiOrigin: 'http://localhost:7000',
|
||||
basePath: '/auth/',
|
||||
oauthRequestApi,
|
||||
}),
|
||||
);
|
||||
|
||||
builder.add(
|
||||
catalogApiRef,
|
||||
new CatalogClient({
|
||||
apiOrigin: 'http://localhost:3000',
|
||||
basePath: '/catalog/api',
|
||||
}),
|
||||
);
|
||||
builder.add(
|
||||
techRadarApiRef,
|
||||
new TechRadar({
|
||||
width: 1500,
|
||||
height: 800,
|
||||
}),
|
||||
);
|
||||
|
||||
builder.add(gitOpsApiRef, new GitOpsRestApi('http://localhost:3008'));
|
||||
builder.add(
|
||||
catalogApiRef,
|
||||
new CatalogClient({
|
||||
apiOrigin: 'http://localhost:3000',
|
||||
basePath: '/catalog/api',
|
||||
}),
|
||||
);
|
||||
|
||||
export default builder.build() as ApiHolder;
|
||||
builder.add(gitOpsApiRef, new GitOpsRestApi('http://localhost:3008'));
|
||||
|
||||
return builder.build();
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import React, { ComponentType, FC, useMemo } from 'react';
|
||||
import { Route, Switch, Redirect } from 'react-router-dom';
|
||||
import { AppContextProvider } from './AppContext';
|
||||
import { BackstageApp, AppComponents, AppConfigLoader } from './types';
|
||||
import { BackstageApp, AppComponents, AppConfigLoader, Apis } from './types';
|
||||
import { BackstagePlugin } from '../plugin';
|
||||
import { FeatureFlagsRegistryItem } from './FeatureFlags';
|
||||
import { featureFlagsApiRef } from '../apis/definitions';
|
||||
@@ -38,7 +38,7 @@ import { ApiAggregator } from '../apis/ApiAggregator';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
type FullAppOptions = {
|
||||
apis: ApiHolder;
|
||||
apis: Apis;
|
||||
icons: SystemIcons;
|
||||
plugins: BackstagePlugin[];
|
||||
components: AppComponents;
|
||||
@@ -47,15 +47,17 @@ type FullAppOptions = {
|
||||
};
|
||||
|
||||
export class PrivateAppImpl implements BackstageApp {
|
||||
private readonly apis: ApiHolder;
|
||||
private apis?: ApiHolder = undefined;
|
||||
private readonly icons: SystemIcons;
|
||||
private readonly plugins: BackstagePlugin[];
|
||||
private readonly components: AppComponents;
|
||||
private readonly themes: AppTheme[];
|
||||
private readonly configLoader?: AppConfigLoader;
|
||||
|
||||
private apisOrFactory: Apis;
|
||||
|
||||
constructor(options: FullAppOptions) {
|
||||
this.apis = options.apis;
|
||||
this.apisOrFactory = options.apis;
|
||||
this.icons = options.icons;
|
||||
this.plugins = options.plugins;
|
||||
this.components = options.components;
|
||||
@@ -64,6 +66,9 @@ export class PrivateAppImpl implements BackstageApp {
|
||||
}
|
||||
|
||||
getApis(): ApiHolder {
|
||||
if (!this.apis) {
|
||||
throw new Error('Tried to access APIs before app was loaded');
|
||||
}
|
||||
return this.apis;
|
||||
}
|
||||
|
||||
@@ -196,6 +201,15 @@ export class PrivateAppImpl implements BackstageApp {
|
||||
[appThemeApiRef, AppThemeSelector.createWithStorage(this.themes)],
|
||||
[configApiRef, configReader],
|
||||
]);
|
||||
|
||||
if (!this.apis) {
|
||||
if ('get' in this.apisOrFactory) {
|
||||
this.apis = this.apisOrFactory;
|
||||
} else {
|
||||
this.apis = this.apisOrFactory(configReader);
|
||||
}
|
||||
}
|
||||
|
||||
const apis = new ApiAggregator(this.apis, appApis);
|
||||
|
||||
const { Router } = this.components;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { ComponentType } from 'react';
|
||||
import { IconComponent, SystemIconKey, SystemIcons } from '../icons';
|
||||
import { BackstagePlugin } from '../plugin';
|
||||
import { ApiHolder } from '../apis';
|
||||
import { AppTheme } from '../apis/definitions';
|
||||
import { AppTheme, ConfigApi } from '../apis/definitions';
|
||||
import { AppConfig } from '@backstage/config';
|
||||
|
||||
export type BootErrorPageProps = {
|
||||
@@ -41,13 +41,16 @@ export type AppComponents = {
|
||||
*/
|
||||
export type AppConfigLoader = () => Promise<AppConfig[]>;
|
||||
|
||||
// TODO(Rugvip): Temporary workaround for accessing config when instantiating APIs, we might want to do this differently
|
||||
export type Apis = ApiHolder | ((config: ConfigApi) => ApiHolder);
|
||||
|
||||
export type AppOptions = {
|
||||
/**
|
||||
* A holder of all APIs available in the app.
|
||||
*
|
||||
* Use for example ApiRegistry or ApiTestRegistry.
|
||||
*/
|
||||
apis?: ApiHolder;
|
||||
apis?: Apis;
|
||||
|
||||
/**
|
||||
* Supply icons to override the default ones.
|
||||
|
||||
Reference in New Issue
Block a user