diff --git a/packages/app-api/package.json b/packages/app-api/package.json index 413ec6a73d..b1bad8cff5 100644 --- a/packages/app-api/package.json +++ b/packages/app-api/package.json @@ -29,7 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { + "@backstage/components": "^0.1.0", "@backstage/config": "^0.1.3", + "@backstage/plugin-api": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/packages/app-api/src/apis/definitions/OAuthRequestApi.ts b/packages/app-api/src/apis/definitions/OAuthRequestApi.ts index b9776ed037..316a9be778 100644 --- a/packages/app-api/src/apis/definitions/OAuthRequestApi.ts +++ b/packages/app-api/src/apis/definitions/OAuthRequestApi.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { IconComponent } from '../../icons'; +import { IconComponent } from '@backstage/plugin-api'; import { Observable } from '../../types'; import { ApiRef, createApiRef } from '../system'; diff --git a/packages/app-api/src/app/App.test.tsx b/packages/app-api/src/app/App.test.tsx index a9f1e81a11..47caae930a 100644 --- a/packages/app-api/src/app/App.test.tsx +++ b/packages/app-api/src/app/App.test.tsx @@ -20,7 +20,7 @@ import { render, screen } from '@testing-library/react'; import React, { PropsWithChildren } from 'react'; import { BrowserRouter, Routes } from 'react-router-dom'; import { createRoutableExtension } from '../extensions'; -import { defaultSystemIcons } from '../icons'; +import { defaultAppIcons } from './icons'; import { createPlugin } from '../plugin'; import { useRouteRef } from '../routing/hooks'; import { @@ -163,7 +163,7 @@ describe('Integration Test', () => { theme: lightTheme, }, ], - icons: defaultSystemIcons, + icons: defaultAppIcons, plugins: [], components, bindRoutes: ({ bind }) => { @@ -214,7 +214,7 @@ describe('Integration Test', () => { theme: lightTheme, }, ], - icons: defaultSystemIcons, + icons: defaultAppIcons, plugins: [], components, bindRoutes: ({ bind }) => { @@ -257,7 +257,7 @@ describe('Integration Test', () => { theme: lightTheme, }, ], - icons: defaultSystemIcons, + icons: defaultAppIcons, plugins: [], components, bindRoutes: ({ bind }) => { diff --git a/packages/app-api/src/app/App.tsx b/packages/app-api/src/app/App.tsx index 9e14c9a5fb..743e39772b 100644 --- a/packages/app-api/src/app/App.tsx +++ b/packages/app-api/src/app/App.tsx @@ -23,6 +23,7 @@ import React, { } from 'react'; import { Navigate, Route, Routes } from 'react-router-dom'; import { useAsync } from 'react-use'; +import { IconComponent } from '@backstage/plugin-api'; import { AnyApiFactory, ApiHolder, @@ -48,7 +49,6 @@ import { routeElementDiscoverer, traverseElementTree, } from '../extensions/traversal'; -import { IconComponent, IconComponentMap, IconKey } from '../icons'; import { BackstagePlugin } from '../plugin'; import { AnyRoutes } from '../plugin/types'; import { RouteRef, ExternalRouteRef } from '../routing'; @@ -103,7 +103,7 @@ export function generateBoundRoutes( type FullAppOptions = { apis: Iterable; - icons: IconComponentMap; + icons: NonNullable; plugins: BackstagePlugin[]; components: AppComponents; themes: AppTheme[]; @@ -156,7 +156,7 @@ class AppContextImpl implements AppContext { return this.app.getPlugins(); } - getSystemIcon(key: IconKey): IconComponent | undefined { + getSystemIcon(key: string): IconComponent | undefined { return this.app.getSystemIcon(key); } @@ -188,7 +188,7 @@ export class PrivateAppImpl implements BackstageApp { private configApi?: ConfigApi; private readonly apis: Iterable; - private readonly icons: IconComponentMap; + private readonly icons: NonNullable; private readonly plugins: BackstagePlugin[]; private readonly components: AppComponents; private readonly themes: AppTheme[]; @@ -213,7 +213,7 @@ export class PrivateAppImpl implements BackstageApp { return this.plugins; } - getSystemIcon(key: IconKey): IconComponent | undefined { + getSystemIcon(key: string): IconComponent | undefined { return this.icons[key]; } diff --git a/packages/app-api/src/app/createApp.test.tsx b/packages/app-api/src/app/createApp.test.tsx new file mode 100644 index 0000000000..31f584b68c --- /dev/null +++ b/packages/app-api/src/app/createApp.test.tsx @@ -0,0 +1,94 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 { defaultConfigLoader } 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 }, + ]); + }); +}); diff --git a/packages/app-api/src/app/createApp.tsx b/packages/app-api/src/app/createApp.tsx new file mode 100644 index 0000000000..50fc9bc0f2 --- /dev/null +++ b/packages/app-api/src/app/createApp.tsx @@ -0,0 +1,145 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 React from 'react'; +import { AppOptions, BootErrorPageProps, AppConfigLoader } from './types'; +import { defaultAppIcons } from './icons'; +import { BrowserRouter, MemoryRouter } from 'react-router-dom'; +import LightIcon from '@material-ui/icons/WbSunny'; +import DarkIcon from '@material-ui/icons/Brightness2'; +import { ErrorPage, Progress } from '@backstage/components'; +import { defaultApis } from './defaultApis'; +import { lightTheme, darkTheme } from '@backstage/theme'; +import { AppConfig, JsonObject } from '@backstage/config'; +import { PrivateAppImpl } from './App'; + +/** + * 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. + */ +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__'.toUpperCase()) { + 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; +}; + +// createApp is defined in core, and not core-api, since we need access +// to the components inside core to provide defaults. +// The actual implementation of the app class still lives in core-api, +// as it needs to be used by dev- and test-utils. + +/** + * Creates a new Backstage App. + */ +export function createApp(options?: AppOptions) { + const DefaultNotFoundPage = () => ( + + ); + const DefaultBootErrorPage = ({ step, error }: BootErrorPageProps) => { + let message = ''; + if (step === 'load-config') { + message = `The configuration failed to load, someone should have a look at this error: ${error.message}`; + } + // TODO: figure out a nicer way to handle routing on the error page, when it can be done. + return ( + + + + ); + }; + + const apis = options?.apis ?? []; + const icons = { ...defaultAppIcons, ...options?.icons }; + const plugins = options?.plugins ?? []; + const components = { + NotFoundErrorPage: DefaultNotFoundPage, + BootErrorPage: DefaultBootErrorPage, + Progress: Progress, + Router: BrowserRouter, + ...options?.components, + }; + const themes = options?.themes ?? [ + { + id: 'light', + title: 'Light Theme', + variant: 'light', + theme: lightTheme, + icon: , + }, + { + id: 'dark', + title: 'Dark Theme', + variant: 'dark', + theme: darkTheme, + icon: , + }, + ]; + const configLoader = options?.configLoader ?? defaultConfigLoader; + + const app = new PrivateAppImpl({ + apis, + icons, + plugins, + components, + themes, + configLoader, + defaultApis, + bindRoutes: options?.bindRoutes, + }); + + app.verify(); + + return app; +} diff --git a/packages/app-api/src/app/defaultApis.ts b/packages/app-api/src/app/defaultApis.ts new file mode 100644 index 0000000000..c8b153a158 --- /dev/null +++ b/packages/app-api/src/app/defaultApis.ts @@ -0,0 +1,220 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 { + alertApiRef, + errorApiRef, + AlertApiForwarder, + ErrorApiForwarder, + ErrorAlerter, + discoveryApiRef, + GoogleAuth, + GithubAuth, + OAuth2, + OktaAuth, + GitlabAuth, + Auth0Auth, + MicrosoftAuth, + oauthRequestApiRef, + OAuthRequestManager, + googleAuthApiRef, + githubAuthApiRef, + oauth2ApiRef, + oktaAuthApiRef, + gitlabAuthApiRef, + auth0AuthApiRef, + microsoftAuthApiRef, + storageApiRef, + WebStorage, + createApiFactory, + configApiRef, + UrlPatternDiscovery, + samlAuthApiRef, + SamlAuth, + oneloginAuthApiRef, + OneLoginAuth, + oidcAuthApiRef, +} from '../apis'; + +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({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => + new ErrorAlerter(alertApi, new ErrorApiForwarder()), + }), + 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'), + }), + }), +]; diff --git a/packages/app-api/src/icons/types.ts b/packages/app-api/src/app/icons.tsx similarity index 56% rename from packages/app-api/src/icons/types.ts rename to packages/app-api/src/app/icons.tsx index c4634bd00a..562114564d 100644 --- a/packages/app-api/src/icons/types.ts +++ b/packages/app-api/src/app/icons.tsx @@ -14,10 +14,20 @@ * limitations under the License. */ -import { ComponentType } from 'react'; -import { SvgIconProps } from '@material-ui/core'; +import { + BrokenImageIcon, + ChatIcon, + DashboardIcon, + EmailIcon, + GitHubIcon, + GroupIcon, + HelpIcon, + UserIcon, + WarningIcon, +} from '@backstage/components'; +import { IconComponent } from '@backstage/plugin-api'; -export type SystemIconKey = +type AppIconsKey = | 'brokenImage' | 'chat' | 'dashboard' @@ -28,6 +38,16 @@ export type SystemIconKey = | 'user' | 'warning'; -export type IconComponent = ComponentType; -export type IconKey = SystemIconKey | string; -export type IconComponentMap = { [key in IconKey]: IconComponent }; +export type AppIcons = { [key in AppIconsKey]: IconComponent }; + +export const defaultAppIcons: AppIcons = { + brokenImage: BrokenImageIcon, + chat: ChatIcon, + dashboard: DashboardIcon, + email: EmailIcon, + github: GitHubIcon, + group: GroupIcon, + help: HelpIcon, + user: UserIcon, + warning: WarningIcon, +}; diff --git a/packages/app-api/src/app/types.ts b/packages/app-api/src/app/types.ts index 5bdf51837d..8498834640 100644 --- a/packages/app-api/src/app/types.ts +++ b/packages/app-api/src/app/types.ts @@ -15,13 +15,14 @@ */ import { ComponentType } from 'react'; -import { IconComponent, IconComponentMap, IconKey } from '../icons'; import { AnyExternalRoutes, BackstagePlugin } from '../plugin/types'; import { ExternalRouteRef, RouteRef } from '../routing'; import { AnyApiFactory } from '../apis'; import { AppTheme, ProfileInfo } from '../apis/definitions'; import { AppConfig } from '@backstage/config'; +import { IconComponent } from '@backstage/plugin-api'; import { SubRouteRef } from '../routing/types'; +import { AppIcons } from './icons'; export type BootErrorPageProps = { step: 'load-config'; @@ -125,7 +126,7 @@ export type AppOptions = { /** * Supply icons to override the default ones. */ - icons?: IconComponentMap; + icons?: AppIcons & { [key in string]: IconComponent }; /** * A list of all plugins to include in the app. @@ -202,7 +203,7 @@ export type BackstageApp = { /** * Get a common or custom icon for this app. */ - getSystemIcon(key: IconKey): IconComponent | undefined; + getSystemIcon(key: string): IconComponent | undefined; /** * Provider component that should wrap the Router created with getRouter() @@ -233,7 +234,7 @@ export type AppContext = { /** * Get a common or custom icon for this app. */ - getSystemIcon(key: IconKey): IconComponent | undefined; + getSystemIcon(key: string): IconComponent | undefined; /** * Get the components registered for various purposes in the app. diff --git a/packages/app-api/src/icons/icons.tsx b/packages/app-api/src/icons/icons.tsx deleted file mode 100644 index 49db90efcc..0000000000 --- a/packages/app-api/src/icons/icons.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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 { SvgIconProps } from '@material-ui/core'; -import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage'; -import MuiChatIcon from '@material-ui/icons/Chat'; -import MuiDashboardIcon from '@material-ui/icons/Dashboard'; -import MuiEmailIcon from '@material-ui/icons/Email'; -import MuiGitHubIcon from '@material-ui/icons/GitHub'; -import MuiHelpIcon from '@material-ui/icons/Help'; -import MuiPeopleIcon from '@material-ui/icons/People'; -import MuiPersonIcon from '@material-ui/icons/Person'; -import MuiWarningIcon from '@material-ui/icons/Warning'; -import React from 'react'; -import { useApp } from '../app/AppContext'; -import { IconComponent, IconComponentMap, SystemIconKey } from './types'; - -export const defaultSystemIcons: IconComponentMap = { - brokenImage: MuiBrokenImageIcon, - chat: MuiChatIcon, - dashboard: MuiDashboardIcon, - email: MuiEmailIcon, - github: MuiGitHubIcon, - group: MuiPeopleIcon, - help: MuiHelpIcon, - user: MuiPersonIcon, - warning: MuiWarningIcon, -}; - -const overridableSystemIcon = (key: SystemIconKey): IconComponent => { - const Component = (props: SvgIconProps) => { - const app = useApp(); - const Icon = app.getSystemIcon(key); - return Icon ? : ; - }; - return Component; -}; - -export const BrokenImageIcon = overridableSystemIcon('brokenImage'); -export const ChatIcon = overridableSystemIcon('chat'); -export const DashboardIcon = overridableSystemIcon('dashboard'); -export const EmailIcon = overridableSystemIcon('email'); -export const GitHubIcon = overridableSystemIcon('github'); -export const GroupIcon = overridableSystemIcon('group'); -export const HelpIcon = overridableSystemIcon('help'); -export const UserIcon = overridableSystemIcon('user'); -export const WarningIcon = overridableSystemIcon('warning'); diff --git a/packages/app-api/src/icons/index.ts b/packages/app-api/src/icons/index.ts deleted file mode 100644 index 4c97d27176..0000000000 --- a/packages/app-api/src/icons/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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. - */ - -export * from './icons'; -export * from './types'; diff --git a/packages/app-api/src/index.ts b/packages/app-api/src/index.ts index 90bde248f6..144e125204 100644 --- a/packages/app-api/src/index.ts +++ b/packages/app-api/src/index.ts @@ -14,7 +14,9 @@ * limitations under the License. */ -export * from './public'; -import * as privateExports from './private'; - -export default privateExports; +export * from './apis'; +export * from './app'; +export * from './extensions'; +export * from './plugin'; +export * from './routing'; +export * from './types'; diff --git a/packages/app-api/src/private.ts b/packages/app-api/src/private.ts deleted file mode 100644 index 65462d8d51..0000000000 --- a/packages/app-api/src/private.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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. - */ - -export { PrivateAppImpl } from './app/App'; diff --git a/packages/app-api/src/public.ts b/packages/app-api/src/public.ts deleted file mode 100644 index f91d97c31d..0000000000 --- a/packages/app-api/src/public.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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. - */ - -export * from './apis'; -export * from './app'; -export * from './extensions'; -export * from './icons'; -export * from './plugin'; -export * from './routing'; -export * from './types'; diff --git a/packages/app-api/src/routing/RouteRef.ts b/packages/app-api/src/routing/RouteRef.ts index 7ce2b2afbd..5d0dd9647f 100644 --- a/packages/app-api/src/routing/RouteRef.ts +++ b/packages/app-api/src/routing/RouteRef.ts @@ -23,7 +23,7 @@ import { ParamKeys, OptionalParams, } from './types'; -import { IconComponent } from '../icons'; +import { IconComponent } from '@backstage/plugin-api'; // TODO(Rugvip): Remove this in the next breaking release, it's exported but unused export type RouteRefConfig = { diff --git a/packages/app-api/src/routing/types.ts b/packages/app-api/src/routing/types.ts index 1fabd39cc4..cf6f572061 100644 --- a/packages/app-api/src/routing/types.ts +++ b/packages/app-api/src/routing/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { IconComponent } from '../icons'; +import { IconComponent } from '@backstage/plugin-api'; import { getOrCreateGlobalSingleton } from '../lib/globalObject'; export type AnyParams = { [param in string]: string } | undefined;