diff --git a/.changeset/tall-beds-bake.md b/.changeset/tall-beds-bake.md new file mode 100644 index 0000000000..2a0c9f7023 --- /dev/null +++ b/.changeset/tall-beds-bake.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-app-api': patch +--- + +Removed deprecated internal functions. diff --git a/packages/core-app-api/src/extensions/componentData.test.tsx b/packages/core-app-api/src/extensions/componentData.test.tsx deleted file mode 100644 index 808ab08cf1..0000000000 --- a/packages/core-app-api/src/extensions/componentData.test.tsx +++ /dev/null @@ -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 = ; - 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 = ; - 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 = ; - const element2 = ; - 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 = ; - 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 = ; - 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 = ; - 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 = ; - expect(getComponentData(element, 'my-data')).toBe(data); - }); - }); -}); diff --git a/packages/core-app-api/src/extensions/componentData.tsx b/packages/core-app-api/src/extensions/componentData.tsx deleted file mode 100644 index d4975d9eef..0000000000 --- a/packages/core-app-api/src/extensions/componentData.tsx +++ /dev/null @@ -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

= ComponentType

& { - [DATA_KEY]?: DataContainer; -}; - -type DataContainer = { - map: Map; -}; - -type MaybeComponentNode = ReactNode & { - type?: ComponentType & { [DATA_KEY]?: DataContainer }; -}; - -// The store is bridged across versions using the global object -const store = getOrCreateGlobalSingleton( - 'component-data-store', - () => new WeakMap, DataContainer>(), -); - -export function attachComponentData

( - component: ComponentType

, - type: string, - data: unknown, -) { - const dataComponent = component as ComponentWithData

; - - 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( - 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; -} diff --git a/packages/core-app-api/src/extensions/extensions.tsx b/packages/core-app-api/src/extensions/extensions.tsx deleted file mode 100644 index 199430c619..0000000000 --- a/packages/core-app-api/src/extensions/extensions.tsx +++ /dev/null @@ -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 = - | { - lazy: () => Promise; - } - | { - 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; - mountPoint: RouteRef; -}): Extension { - 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 }): Extension { - 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; - data?: Record; -}): Extension { - throw new Error(ERROR_MESSAGE); -} diff --git a/packages/core-app-api/src/extensions/index.ts b/packages/core-app-api/src/extensions/index.ts deleted file mode 100644 index 914d76aebf..0000000000 --- a/packages/core-app-api/src/extensions/index.ts +++ /dev/null @@ -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'; diff --git a/packages/core-app-api/src/plugins/collectors.ts b/packages/core-app-api/src/plugins/collectors.ts index 11e5cd51b3..0f8b65ad62 100644 --- a/packages/core-app-api/src/plugins/collectors.ts +++ b/packages/core-app-api/src/plugins/collectors.ts @@ -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( diff --git a/packages/core-app-api/src/routing/collectors.test.tsx b/packages/core-app-api/src/routing/collectors.test.tsx index d37b5e3016..36d99d2938 100644 --- a/packages/core-app-api/src/routing/collectors.test.tsx +++ b/packages/core-app-api/src/routing/collectors.test.tsx @@ -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 }>) => ( diff --git a/packages/core-app-api/src/routing/collectors.tsx b/packages/core-app-api/src/routing/collectors.tsx index fcbe3ca923..0ba83e90f8 100644 --- a/packages/core-app-api/src/routing/collectors.tsx +++ b/packages/core-app-api/src/routing/collectors.tsx @@ -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';