core-*-api: revert breaking changes and un-deprecate AppContext.getPlugins()

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-05-28 14:05:00 +02:00
parent 6d1badc7c6
commit 1909d0cccf
8 changed files with 92 additions and 5 deletions
+4
View File
@@ -155,6 +155,10 @@ function useConfigLoader(
class AppContextImpl implements AppContext {
constructor(private readonly app: PrivateAppImpl) {}
getPlugins(): BackstagePlugin<any, any>[] {
return this.app.getPlugins();
}
getSystemIcon(key: string): IconComponent | undefined {
return this.app.getSystemIcon(key);
}
@@ -36,6 +36,7 @@ describe('v1 consumer', () => {
it('should provide an app context', () => {
const mockContext: AppContextV1 = {
getPlugins: jest.fn(),
getComponents: jest.fn(),
getSystemIcon: jest.fn(),
};
@@ -47,6 +48,10 @@ describe('v1 consumer', () => {
});
const result = renderedHook.result.current;
expect(mockContext.getPlugins).toHaveBeenCalledTimes(0);
result.getPlugins();
expect(mockContext.getPlugins).toHaveBeenCalledTimes(1);
expect(mockContext.getComponents).toHaveBeenCalledTimes(0);
result.getComponents();
expect(mockContext.getComponents).toHaveBeenCalledTimes(1);
+5
View File
@@ -227,6 +227,11 @@ export type BackstageApp = {
};
export type AppContext = {
/**
* Get a list of all plugins that are installed in the app.
*/
getPlugins(): BackstagePlugin<any, any>[];
/**
* Get a common or custom icon for this app.
*/
+4 -1
View File
@@ -21,7 +21,10 @@ import {
} from '@backstage/core-plugin-api';
import { getOrCreateGlobalSingleton } from '../lib/globalObject';
type RouteRefType = Exclude<keyof RouteRef, 'params'>;
type RouteRefType = Exclude<
keyof RouteRef,
'params' | 'path' | 'title' | 'icon'
>;
export const routeRefType: RouteRefType = getOrCreateGlobalSingleton<any>(
'route-ref-type',
() => Symbol('route-ref-type'),
@@ -16,7 +16,13 @@
import type { ApiRef } from './types';
export type ApiRefConfig = { id: string };
export type ApiRefConfig = {
id: string;
/**
* @deprecated Will be removed in the future
*/
description?: string;
};
class ApiRefImpl<T> implements ApiRef<T> {
constructor(private readonly config: ApiRefConfig) {
@@ -35,6 +41,12 @@ class ApiRefImpl<T> implements ApiRef<T> {
return this.config.id;
}
get description() {
// eslint-disable-next-line no-console
console.warn('Deprecated use of ApiRef.description');
return this.config.description;
}
// Utility for getting type of an api, using `typeof apiRef.T`
get T(): T {
throw new Error(`tried to read ApiRef.T of ${this}`);
@@ -17,6 +17,7 @@
import { ComponentType } from 'react';
import { ProfileInfo } from '../apis/definitions';
import { IconComponent } from '../icons';
import { BackstagePlugin } from '../plugin/types';
export type BootErrorPageProps = {
step: 'load-config' | 'load-chunk';
@@ -68,6 +69,11 @@ export type AppComponents = {
};
export type AppContext = {
/**
* Get a list of all plugins that are installed in the app.
*/
getPlugins(): BackstagePlugin<any, any>[];
/**
* Get a common or custom icon for this app.
*/
@@ -21,6 +21,15 @@ import {
ParamKeys,
OptionalParams,
} from './types';
import { IconComponent } from '../icons/types';
// TODO(Rugvip): Remove this in the next breaking release, it's exported but unused
export type RouteRefConfig<Params extends AnyParams> = {
params?: ParamKeys<Params>;
path?: string;
icon?: IconComponent;
title: string;
};
export class RouteRefImpl<Params extends AnyParams>
implements RouteRef<Params> {
@@ -29,8 +38,26 @@ export class RouteRefImpl<Params extends AnyParams>
constructor(
private readonly id: string,
readonly params: ParamKeys<Params>,
private readonly config: {
path?: string;
icon?: IconComponent;
title?: string;
},
) {}
get icon() {
return this.config.icon;
}
// TODO(Rugvip): Remove this, routes are looked up via the registry instead
get path() {
return this.config.path ?? '';
}
get title() {
return this.config.title ?? this.id;
}
toString() {
return `routeRef{type=absolute,id=${this.id}}`;
}
@@ -46,15 +73,23 @@ export function createRouteRef<
ParamKey extends string = never
>(config: {
/** The id of the route ref, used to identify it when printed */
id: string;
id?: string;
/** A list of parameter names that the path that this route ref is bound to must contain */
params?: ParamKey[];
/** @deprecated Route refs no longer decide their own path */
path?: string;
/** @deprecated Route refs no longer decide their own icon */
icon?: IconComponent;
/** @deprecated Route refs no longer decide their own title */
title?: string;
}): RouteRef<OptionalParams<Params>> {
if (!config.id) {
const id = config.id || config.title;
if (!id) {
throw new Error('RouteRef must be provided a non-empty id');
}
return new RouteRefImpl(
config.id,
id,
(config.params ?? []) as ParamKeys<OptionalParams<Params>>,
config,
);
}
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { IconComponent } from '../icons/types';
import { getOrCreateGlobalSingleton } from '../lib/globalObject';
export type AnyParams = { [param in string]: string } | undefined;
@@ -42,6 +43,14 @@ export type RouteRef<Params extends AnyParams = any> = {
readonly [routeRefType]: 'absolute';
params: ParamKeys<Params>;
// TODO(Rugvip): Remove all of these once plugins don't rely on the path
/** @deprecated paths are no longer accessed directly from RouteRefs, use useRouteRef instead */
path: string;
/** @deprecated icons are no longer accessed via RouteRefs */
icon?: IconComponent;
/** @deprecated titles are no longer accessed via RouteRefs */
title?: string;
};
export type SubRouteRef<Params extends AnyParams = any> = {
@@ -70,6 +79,14 @@ export type AnyRouteRef =
| SubRouteRef<any>
| ExternalRouteRef<any, any>;
// TODO(Rugvip): None of these should be found in the wild anymore, remove in next minor release
/** @deprecated */
export type ConcreteRoute = {};
/** @deprecated */
export type AbsoluteRouteRef = RouteRef<{}>;
/** @deprecated */
export type MutableRouteRef = RouteRef<{}>;
// A duplicate of the react-router RouteObject, but with routeRef added
export interface BackstageRouteObject {
caseSensitive: boolean;