core-app-api: removed deprecated internal functions

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-09-07 19:47:20 +02:00
parent 3d238b0283
commit 841666a19b
8 changed files with 8 additions and 283 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-app-api': patch
---
Removed deprecated internal functions.
@@ -1,118 +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 React from 'react';
import { attachComponentData, getComponentData } from './componentData';
describe('elementData', () => {
it('should attach a single piece of data', () => {
const data = { foo: 'bar' };
const Component = () => null;
attachComponentData(Component, 'my-data', data);
const element = <Component />;
expect(getComponentData(element, 'my-data')).toBe(data);
});
it('should attach several distinct pieces of data', () => {
const data1 = { foo: 'bar' };
const data2 = { test: 'value' };
const Component = () => null;
attachComponentData(Component, 'my-data', data1);
attachComponentData(Component, 'second', data2);
const element = <Component />;
expect(getComponentData(element, 'my-data')).toBe(data1);
expect(getComponentData(element, 'second')).toBe(data2);
});
it('returns undefined for missing data', () => {
const data = { foo: 'bar' };
const Component1 = () => null;
const Component2 = () => null;
attachComponentData(Component2, 'my-data', data);
const element1 = <Component1 />;
const element2 = <Component2 />;
expect(getComponentData(element1, 'missing')).toBeUndefined();
expect(getComponentData(element2, 'missing')).toBeUndefined();
});
it('should throw when attempting to overwrite data', () => {
const data = { foo: 'bar' };
const MyComponent = () => null;
attachComponentData(MyComponent, 'my-data', data);
expect(() => attachComponentData(MyComponent, 'my-data', data)).toThrow(
'Attempted to attach duplicate data "my-data" to component "MyComponent"',
);
});
describe('works across versions', () => {
function getDataSymbol() {
const Component = () => null;
attachComponentData(Component, 'my-data', {});
const [symbol] = Object.getOwnPropertySymbols(Component);
return symbol;
}
it('should should be able to get data from older versions', () => {
const symbol = getDataSymbol();
const data = { foo: 'bar' };
const Component = () => null;
attachComponentData(Component, 'my-data', data);
const element = <Component />;
expect((element as any).type[symbol].map.get('my-data')).toBe(data);
});
it('should should be able to attach data for older versions', () => {
const symbol = getDataSymbol();
const data = { foo: 'bar' };
const Component = () => null;
(Component as any)[symbol] = {
map: new Map([['my-data', data]]),
};
const element = <Component />;
expect(getComponentData(element, 'my-data')).toBe(data);
});
it('should be able to get data from newer versions', () => {
const data = { foo: 'bar' };
const Component = () => null;
attachComponentData(Component, 'my-data', data);
const element = <Component />;
const container = (global as any)[
'__@backstage/component-data-store__'
].get(element.type);
expect(container.map.get('my-data')).toBe(data);
});
it('should should be able to attach data for newer versions', () => {
const data = { foo: 'bar' };
const Component = () => null;
(global as any)['__@backstage/component-data-store__'].set(Component, {
map: new Map([['my-data', data]]),
});
const element = <Component />;
expect(getComponentData(element, 'my-data')).toBe(data);
});
});
});
@@ -1,84 +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 { ComponentType, ReactNode } from 'react';
import { getOrCreateGlobalSingleton } from '../lib/globalObject';
// TODO(Rugvip): Access via symbol is deprecated, remove once on 0.3.x
const DATA_KEY = Symbol('backstage-component-data');
type ComponentWithData<P> = ComponentType<P> & {
[DATA_KEY]?: DataContainer;
};
type DataContainer = {
map: Map<string, unknown>;
};
type MaybeComponentNode = ReactNode & {
type?: ComponentType<any> & { [DATA_KEY]?: DataContainer };
};
// The store is bridged across versions using the global object
const store = getOrCreateGlobalSingleton(
'component-data-store',
() => new WeakMap<ComponentType<any>, DataContainer>(),
);
export function attachComponentData<P>(
component: ComponentType<P>,
type: string,
data: unknown,
) {
const dataComponent = component as ComponentWithData<P>;
let container = store.get(component) || dataComponent[DATA_KEY];
if (!container) {
container = { map: new Map() };
store.set(component, container);
dataComponent[DATA_KEY] = container;
}
if (container.map.has(type)) {
const name = component.displayName || component.name;
throw new Error(
`Attempted to attach duplicate data "${type}" to component "${name}"`,
);
}
container.map.set(type, data);
}
export function getComponentData<T>(
node: ReactNode,
type: string,
): T | undefined {
if (!node) {
return undefined;
}
const component = (node as MaybeComponentNode).type;
if (!component) {
return undefined;
}
const container = store.get(component) || component[DATA_KEY];
if (!container) {
return undefined;
}
return container.map.get(type) as T | undefined;
}
@@ -1,54 +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 { Extension, RouteRef } from '@backstage/core-plugin-api';
type ComponentLoader<T> =
| {
lazy: () => Promise<T>;
}
| {
sync: T;
};
const ERROR_MESSAGE = 'Import this from @backstage/core-plugin-api';
/** @deprecated Import from @backstage/core-plugin-api instead */
export function createRoutableExtension<
T extends (props: any) => JSX.Element | null,
>(_options: {
component: () => Promise<T>;
mountPoint: RouteRef;
}): Extension<T> {
throw new Error(ERROR_MESSAGE);
}
/** @deprecated Import from @backstage/core-plugin-api instead */
export function createComponentExtension<
T extends (props: any) => JSX.Element | null,
>(_options: { component: ComponentLoader<T> }): Extension<T> {
throw new Error(ERROR_MESSAGE);
}
/** @deprecated Import from @backstage/core-plugin-api instead */
export function createReactExtension<
T extends (props: any) => JSX.Element | null,
>(_options: {
component: ComponentLoader<T>;
data?: Record<string, unknown>;
}): Extension<T> {
throw new Error(ERROR_MESSAGE);
}
@@ -1,22 +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.
*/
export { attachComponentData, getComponentData } from './componentData';
export {
createReactExtension,
createRoutableExtension,
createComponentExtension,
} from './extensions';
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import { BackstagePlugin } from '@backstage/core-plugin-api';
import { getComponentData } from '../extensions';
import { BackstagePlugin, getComponentData } from '@backstage/core-plugin-api';
import { createCollector } from '../extensions/traversal';
export const pluginCollector = createCollector(
@@ -31,8 +31,8 @@ import {
createRouteRef,
createPlugin,
RouteRef,
attachComponentData,
} from '@backstage/core-plugin-api';
import { attachComponentData } from '../extensions';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
const MockComponent = ({ children }: PropsWithChildren<{ path?: string }>) => (
@@ -15,9 +15,8 @@
*/
import { isValidElement, ReactElement, ReactNode } from 'react';
import { RouteRef } from '@backstage/core-plugin-api';
import { RouteRef, getComponentData } from '@backstage/core-plugin-api';
import { BackstageRouteObject } from './types';
import { getComponentData } from '../extensions';
import { createCollector } from '../extensions/traversal';
import { FeatureFlagged, FeatureFlaggedProps } from './FeatureFlagged';