@backstage/core-compat-api 0.4.1 → 0.4.2-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/collectEntityPageContents.esm.js.map +1 -1
- package/dist/collectLegacyRoutes.esm.js +1 -1
- package/dist/collectLegacyRoutes.esm.js.map +1 -1
- package/dist/compatWrapper/BackwardsCompatProvider.esm.js +1 -1
- package/dist/compatWrapper/BackwardsCompatProvider.esm.js.map +1 -1
- package/dist/convertLegacyPlugin.esm.js +1 -1
- package/dist/convertLegacyPlugin.esm.js.map +1 -1
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @backstage/core-compat-api
|
|
2
2
|
|
|
3
|
+
## 0.4.2-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`.
|
|
8
|
+
- 72d019d: Removed various typos
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
- @backstage/frontend-plugin-api@0.10.2-next.0
|
|
11
|
+
- @backstage/plugin-catalog-react@1.18.0-next.1
|
|
12
|
+
- @backstage/core-plugin-api@1.10.6
|
|
13
|
+
- @backstage/version-bridge@1.0.11
|
|
14
|
+
|
|
15
|
+
## 0.4.2-next.0
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 6eedf46: Updated dependency `@backstage-community/plugin-puppetdb` to `^0.6.0`.
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- @backstage/plugin-catalog-react@1.18.0-next.0
|
|
22
|
+
- @backstage/core-plugin-api@1.10.6
|
|
23
|
+
- @backstage/frontend-plugin-api@0.10.1
|
|
24
|
+
- @backstage/version-bridge@1.0.11
|
|
25
|
+
|
|
3
26
|
## 0.4.1
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectEntityPageContents.esm.js","sources":["../src/collectEntityPageContents.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ApiHolder,\n getComponentData,\n BackstagePlugin as LegacyBackstagePlugin,\n} from '@backstage/core-plugin-api';\nimport { ExtensionDefinition } from '@backstage/frontend-plugin-api';\nimport { JSX, ReactNode, isValidElement, Children } from 'react';\nimport {\n EntityCardBlueprint,\n EntityContentBlueprint,\n} from '@backstage/plugin-catalog-react/alpha';\nimport { normalizeRoutePath } from './normalizeRoutePath';\n\nconst ENTITY_SWITCH_KEY = 'core.backstage.entitySwitch';\nconst ENTITY_ROUTE_KEY = 'plugin.catalog.entityLayoutRoute';\n\n// Placeholder to make sure internal types here are consitent\ntype Entity = { apiVersion: string; kind: string };\n\ntype EntityFilter = (entity: Entity, ctx: { apis: ApiHolder }) => boolean;\ntype AsyncEntityFilter = (\n entity: Entity,\n context: { apis: ApiHolder },\n) => boolean | Promise<boolean>;\n\nfunction allFilters(\n ...ifs: (EntityFilter | undefined)[]\n): EntityFilter | undefined {\n const filtered = ifs.filter(Boolean) as EntityFilter[];\n if (!filtered.length) {\n return undefined;\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n return (entity, ctx) => filtered.every(ifFunc => ifFunc(entity, ctx));\n}\n\nfunction anyFilters(\n ...ifs: (EntityFilter | undefined)[]\n): EntityFilter | undefined {\n const filtered = ifs.filter(Boolean) as EntityFilter[];\n if (!filtered.length) {\n return undefined;\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n return (entity, ctx) => filtered.some(ifFunc => ifFunc(entity, ctx));\n}\n\nfunction invertFilter(ifFunc?: EntityFilter): EntityFilter {\n if (!ifFunc) {\n return () => true;\n }\n return (entity, ctx) => !ifFunc(entity, ctx);\n}\n\nexport function collectEntityPageContents(\n entityPageElement: JSX.Element,\n context: {\n discoverExtension(\n extension: ExtensionDefinition,\n plugin?: LegacyBackstagePlugin,\n ): void;\n },\n) {\n let cardCounter = 1;\n let routeCounter = 1;\n\n function traverse(element: ReactNode, parentFilter?: EntityFilter) {\n if (!isValidElement(element)) {\n return;\n }\n\n const pageNode = maybeParseEntityPageNode(element);\n if (pageNode) {\n if (pageNode.type === 'route') {\n const mergedIf = allFilters(parentFilter, pageNode.if);\n\n if (pageNode.path === '/') {\n context.discoverExtension(\n EntityCardBlueprint.makeWithOverrides({\n name: `discovered-${cardCounter++}`,\n factory(originalFactory, { apis }) {\n return originalFactory({\n type: 'content',\n filter: mergedIf && (entity => mergedIf(entity, { apis })),\n loader: () => Promise.resolve(pageNode.children),\n });\n },\n }),\n );\n } else {\n const name = `discovered-${routeCounter++}`;\n\n context.discoverExtension(\n EntityContentBlueprint.makeWithOverrides({\n name,\n factory(originalFactory, { apis }) {\n return originalFactory({\n defaultPath: normalizeRoutePath(pageNode.path),\n defaultTitle: pageNode.title,\n filter: mergedIf && (entity => mergedIf(entity, { apis })),\n loader: () => Promise.resolve(pageNode.children),\n });\n },\n }),\n getComponentData<LegacyBackstagePlugin>(\n pageNode.children,\n 'core.plugin',\n ),\n );\n }\n }\n if (pageNode.type === 'switch') {\n if (pageNode.renderMultipleMatches === 'all') {\n for (const entityCase of pageNode.cases) {\n traverse(\n entityCase.children,\n allFilters(parentFilter, entityCase.if),\n );\n }\n } else {\n let previousIf: EntityFilter = () => false;\n for (const entityCase of pageNode.cases) {\n const didNotMatchEarlier = invertFilter(previousIf);\n traverse(\n entityCase.children,\n allFilters(parentFilter, entityCase.if, didNotMatchEarlier),\n );\n previousIf = anyFilters(previousIf, entityCase.if)!;\n }\n }\n }\n return;\n }\n\n Children.forEach(\n (element.props as { children?: ReactNode })?.children,\n child => {\n traverse(child, parentFilter);\n },\n );\n }\n\n traverse(entityPageElement);\n}\n\ntype EntityRoute = {\n type: 'route';\n path: string;\n title: string;\n if?: EntityFilter;\n children: JSX.Element;\n};\n\ntype EntitySwitchCase = {\n if?: EntityFilter;\n children: ReactNode;\n};\n\ntype EntitySwitch = {\n type: 'switch';\n cases: EntitySwitchCase[];\n renderMultipleMatches: 'first' | 'all';\n};\n\nfunction wrapAsyncEntityFilter(\n asyncFilter?: AsyncEntityFilter,\n): EntityFilter | undefined {\n if (!asyncFilter) {\n return asyncFilter;\n }\n let loggedError = false;\n return (entity, ctx) => {\n const result = asyncFilter(entity, ctx);\n if (result && typeof result === 'object' && 'then' in result) {\n if (!loggedError) {\n // eslint-disable-next-line no-console\n console.error(\n `collectEntityPageContents does not support async entity filters, skipping filter ${asyncFilter}`,\n );\n loggedError = true;\n }\n return false;\n }\n return result;\n };\n}\n\nfunction maybeParseEntityPageNode(\n element: JSX.Element,\n): EntityRoute | EntitySwitch | undefined {\n if (getComponentData(element, ENTITY_ROUTE_KEY)) {\n const props = element.props as EntityRoute;\n return {\n type: 'route',\n path: props.path,\n title: props.title,\n if: props.if,\n children: props.children,\n };\n }\n\n const parentProps = element.props as {\n children?: ReactNode;\n renderMultipleMatches?: 'first' | 'all';\n };\n\n const children = Children.toArray(parentProps?.children);\n if (!children.length) {\n return undefined;\n }\n\n const cases = [];\n for (const child of children) {\n if (!getComponentData(child, ENTITY_SWITCH_KEY)) {\n return undefined;\n }\n const props = (child as { props: EntitySwitchCase }).props;\n\n cases.push({\n if: wrapAsyncEntityFilter(props.if),\n children: props.children,\n });\n }\n return {\n type: 'switch',\n cases,\n renderMultipleMatches: parentProps?.renderMultipleMatches ?? 'first',\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"collectEntityPageContents.esm.js","sources":["../src/collectEntityPageContents.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ApiHolder,\n getComponentData,\n BackstagePlugin as LegacyBackstagePlugin,\n} from '@backstage/core-plugin-api';\nimport { ExtensionDefinition } from '@backstage/frontend-plugin-api';\nimport { JSX, ReactNode, isValidElement, Children } from 'react';\nimport {\n EntityCardBlueprint,\n EntityContentBlueprint,\n} from '@backstage/plugin-catalog-react/alpha';\nimport { normalizeRoutePath } from './normalizeRoutePath';\n\nconst ENTITY_SWITCH_KEY = 'core.backstage.entitySwitch';\nconst ENTITY_ROUTE_KEY = 'plugin.catalog.entityLayoutRoute';\n\n// Placeholder to make sure internal types here are consistent\ntype Entity = { apiVersion: string; kind: string };\n\ntype EntityFilter = (entity: Entity, ctx: { apis: ApiHolder }) => boolean;\ntype AsyncEntityFilter = (\n entity: Entity,\n context: { apis: ApiHolder },\n) => boolean | Promise<boolean>;\n\nfunction allFilters(\n ...ifs: (EntityFilter | undefined)[]\n): EntityFilter | undefined {\n const filtered = ifs.filter(Boolean) as EntityFilter[];\n if (!filtered.length) {\n return undefined;\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n return (entity, ctx) => filtered.every(ifFunc => ifFunc(entity, ctx));\n}\n\nfunction anyFilters(\n ...ifs: (EntityFilter | undefined)[]\n): EntityFilter | undefined {\n const filtered = ifs.filter(Boolean) as EntityFilter[];\n if (!filtered.length) {\n return undefined;\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n return (entity, ctx) => filtered.some(ifFunc => ifFunc(entity, ctx));\n}\n\nfunction invertFilter(ifFunc?: EntityFilter): EntityFilter {\n if (!ifFunc) {\n return () => true;\n }\n return (entity, ctx) => !ifFunc(entity, ctx);\n}\n\nexport function collectEntityPageContents(\n entityPageElement: JSX.Element,\n context: {\n discoverExtension(\n extension: ExtensionDefinition,\n plugin?: LegacyBackstagePlugin,\n ): void;\n },\n) {\n let cardCounter = 1;\n let routeCounter = 1;\n\n function traverse(element: ReactNode, parentFilter?: EntityFilter) {\n if (!isValidElement(element)) {\n return;\n }\n\n const pageNode = maybeParseEntityPageNode(element);\n if (pageNode) {\n if (pageNode.type === 'route') {\n const mergedIf = allFilters(parentFilter, pageNode.if);\n\n if (pageNode.path === '/') {\n context.discoverExtension(\n EntityCardBlueprint.makeWithOverrides({\n name: `discovered-${cardCounter++}`,\n factory(originalFactory, { apis }) {\n return originalFactory({\n type: 'content',\n filter: mergedIf && (entity => mergedIf(entity, { apis })),\n loader: () => Promise.resolve(pageNode.children),\n });\n },\n }),\n );\n } else {\n const name = `discovered-${routeCounter++}`;\n\n context.discoverExtension(\n EntityContentBlueprint.makeWithOverrides({\n name,\n factory(originalFactory, { apis }) {\n return originalFactory({\n defaultPath: normalizeRoutePath(pageNode.path),\n defaultTitle: pageNode.title,\n filter: mergedIf && (entity => mergedIf(entity, { apis })),\n loader: () => Promise.resolve(pageNode.children),\n });\n },\n }),\n getComponentData<LegacyBackstagePlugin>(\n pageNode.children,\n 'core.plugin',\n ),\n );\n }\n }\n if (pageNode.type === 'switch') {\n if (pageNode.renderMultipleMatches === 'all') {\n for (const entityCase of pageNode.cases) {\n traverse(\n entityCase.children,\n allFilters(parentFilter, entityCase.if),\n );\n }\n } else {\n let previousIf: EntityFilter = () => false;\n for (const entityCase of pageNode.cases) {\n const didNotMatchEarlier = invertFilter(previousIf);\n traverse(\n entityCase.children,\n allFilters(parentFilter, entityCase.if, didNotMatchEarlier),\n );\n previousIf = anyFilters(previousIf, entityCase.if)!;\n }\n }\n }\n return;\n }\n\n Children.forEach(\n (element.props as { children?: ReactNode })?.children,\n child => {\n traverse(child, parentFilter);\n },\n );\n }\n\n traverse(entityPageElement);\n}\n\ntype EntityRoute = {\n type: 'route';\n path: string;\n title: string;\n if?: EntityFilter;\n children: JSX.Element;\n};\n\ntype EntitySwitchCase = {\n if?: EntityFilter;\n children: ReactNode;\n};\n\ntype EntitySwitch = {\n type: 'switch';\n cases: EntitySwitchCase[];\n renderMultipleMatches: 'first' | 'all';\n};\n\nfunction wrapAsyncEntityFilter(\n asyncFilter?: AsyncEntityFilter,\n): EntityFilter | undefined {\n if (!asyncFilter) {\n return asyncFilter;\n }\n let loggedError = false;\n return (entity, ctx) => {\n const result = asyncFilter(entity, ctx);\n if (result && typeof result === 'object' && 'then' in result) {\n if (!loggedError) {\n // eslint-disable-next-line no-console\n console.error(\n `collectEntityPageContents does not support async entity filters, skipping filter ${asyncFilter}`,\n );\n loggedError = true;\n }\n return false;\n }\n return result;\n };\n}\n\nfunction maybeParseEntityPageNode(\n element: JSX.Element,\n): EntityRoute | EntitySwitch | undefined {\n if (getComponentData(element, ENTITY_ROUTE_KEY)) {\n const props = element.props as EntityRoute;\n return {\n type: 'route',\n path: props.path,\n title: props.title,\n if: props.if,\n children: props.children,\n };\n }\n\n const parentProps = element.props as {\n children?: ReactNode;\n renderMultipleMatches?: 'first' | 'all';\n };\n\n const children = Children.toArray(parentProps?.children);\n if (!children.length) {\n return undefined;\n }\n\n const cases = [];\n for (const child of children) {\n if (!getComponentData(child, ENTITY_SWITCH_KEY)) {\n return undefined;\n }\n const props = (child as { props: EntitySwitchCase }).props;\n\n cases.push({\n if: wrapAsyncEntityFilter(props.if),\n children: props.children,\n });\n }\n return {\n type: 'switch',\n cases,\n renderMultipleMatches: parentProps?.renderMultipleMatches ?? 'first',\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -181,7 +181,7 @@ function collectLegacyRoutes(flatRoutesElement, entityPage) {
|
|
|
181
181
|
for (const [plugin, extensions] of pluginExtensions) {
|
|
182
182
|
output.push(
|
|
183
183
|
createFrontendPlugin({
|
|
184
|
-
|
|
184
|
+
pluginId: plugin.getId(),
|
|
185
185
|
extensions: [
|
|
186
186
|
...extensions,
|
|
187
187
|
...Array.from(plugin.getApis()).map(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectLegacyRoutes.esm.js","sources":["../src/collectLegacyRoutes.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AnyRouteRefParams,\n BackstagePlugin as LegacyBackstagePlugin,\n RouteRef,\n createPlugin,\n getComponentData,\n} from '@backstage/core-plugin-api';\nimport {\n FrontendPlugin,\n ExtensionDefinition,\n coreExtensionData,\n createExtension,\n createExtensionInput,\n createFrontendPlugin,\n ApiBlueprint,\n PageBlueprint,\n FrontendModule,\n createFrontendModule,\n} from '@backstage/frontend-plugin-api';\nimport { Children, ReactNode, isValidElement } from 'react';\nimport { Route, Routes } from 'react-router-dom';\nimport {\n convertLegacyRouteRef,\n convertLegacyRouteRefs,\n} from './convertLegacyRouteRef';\nimport { compatWrapper } from './compatWrapper';\nimport { collectEntityPageContents } from './collectEntityPageContents';\nimport { normalizeRoutePath } from './normalizeRoutePath';\n\n/*\n\n# Legacy interoperability\n\nUse-cases (prioritized):\n 1. Slowly migrate over an existing app to DI, piece by piece\n 2. Use a legacy plugin in a new DI app\n 3. Use DI in an existing legacy app\n\nStarting point: use-case #1\n\nPotential solutions:\n 1. Codemods (we're not considering this for now)\n 2. Legacy apps are migrated bottom-up, i.e. keep legacy root, replace pages with DI\n 3. Legacy apps are migrated top-down i.e. switch out base to DI, legacy adapter allows for usage of existing app structure\n\nChosen path: #3\n\nExisting tasks:\n - Adopters can migrate their existing app gradually (~4)\n - Example-app uses legacy base with DI adapters\n - Create an API that lets you inject DI into existing apps - working assumption is that this is enough\n - Adopters can use legacy plugins in DI through adapters (~8)\n - App-next uses DI base with legacy adapters\n - Create a legacy adapter that is able to take an existing extension tree\n\n*/\n\n// Creates a shim extension whose purpose is to build up the tree (anchored at\n// the root page) of paths/routeRefs so that the app can bind them properly.\nfunction makeRoutingShimExtension(options: {\n name: string;\n parentExtensionId: string;\n routePath?: string;\n routeRef?: RouteRef;\n}) {\n const { name, parentExtensionId, routePath, routeRef } = options;\n return createExtension({\n kind: 'routing-shim',\n name,\n attachTo: { id: parentExtensionId, input: 'childRoutingShims' },\n inputs: {\n childRoutingShims: createExtensionInput([\n coreExtensionData.routePath.optional(),\n coreExtensionData.routeRef.optional(),\n ]),\n },\n output: [\n coreExtensionData.routePath.optional(),\n coreExtensionData.routeRef.optional(),\n ],\n *factory() {\n if (routePath !== undefined) {\n yield coreExtensionData.routePath(routePath);\n }\n\n if (routeRef) {\n yield coreExtensionData.routeRef(convertLegacyRouteRef(routeRef));\n }\n },\n });\n}\n\nexport function visitRouteChildren(options: {\n children: ReactNode;\n parentExtensionId: string;\n context: {\n pluginId: string;\n extensions: ExtensionDefinition[];\n getUniqueName: () => string;\n discoverPlugin: (plugin: LegacyBackstagePlugin) => void;\n };\n}): void {\n const { children, parentExtensionId, context } = options;\n const { pluginId, extensions, getUniqueName, discoverPlugin } = context;\n\n Children.forEach(children, node => {\n if (!isValidElement(node)) {\n return;\n }\n\n const plugin = getComponentData<LegacyBackstagePlugin>(node, 'core.plugin');\n const routeRef = getComponentData<RouteRef<AnyRouteRefParams>>(\n node,\n 'core.mountPoint',\n );\n const routePath: string | undefined = node.props?.path;\n\n if (plugin) {\n // We just mark the plugin as discovered, but don't change the context\n discoverPlugin(plugin);\n }\n\n let nextParentExtensionId = parentExtensionId;\n if (routeRef || routePath) {\n const nextParentExtensionName = getUniqueName();\n nextParentExtensionId = `routing-shim:${pluginId}/${nextParentExtensionName}`;\n extensions.push(\n makeRoutingShimExtension({\n name: nextParentExtensionName,\n parentExtensionId,\n routePath,\n routeRef,\n }),\n );\n }\n\n visitRouteChildren({\n children: node.props.children,\n parentExtensionId: nextParentExtensionId,\n context,\n });\n });\n}\n\n/** @internal */\nexport function collectLegacyRoutes(\n flatRoutesElement: JSX.Element,\n entityPage?: JSX.Element,\n): (FrontendPlugin | FrontendModule)[] {\n const output = new Array<FrontendPlugin | FrontendModule>();\n\n const pluginExtensions = new Map<\n LegacyBackstagePlugin,\n ExtensionDefinition[]\n >();\n\n const getUniqueName = (() => {\n let currentIndex = 1;\n return () => String(currentIndex++);\n })();\n\n // Placeholder plugin for any routes that don't belong to a plugin\n const orphanRoutesPlugin = createPlugin({ id: 'converted-orphan-routes' });\n\n const getPluginExtensions = (plugin: LegacyBackstagePlugin) => {\n let extensions = pluginExtensions.get(plugin);\n if (!extensions) {\n extensions = [];\n pluginExtensions.set(plugin, extensions);\n }\n return extensions;\n };\n\n Children.forEach(flatRoutesElement.props.children, (route: ReactNode) => {\n if (route === null) {\n return;\n }\n // TODO(freben): Handle feature flag and permissions framework wrapper elements\n if (!isValidElement(route)) {\n throw new Error(\n `Invalid element inside FlatRoutes, expected Route but found element of type ${typeof route}.`,\n );\n }\n if (route.type !== Route) {\n throw new Error(\n `Invalid element inside FlatRoutes, expected Route but found ${route.type}.`,\n );\n }\n const routeElement = route.props.element;\n const path: string | undefined = route.props.path;\n const plugin =\n getComponentData<LegacyBackstagePlugin>(routeElement, 'core.plugin') ??\n orphanRoutesPlugin;\n const routeRef = getComponentData<RouteRef>(\n routeElement,\n 'core.mountPoint',\n );\n if (path === undefined) {\n throw new Error(\n `Route element inside FlatRoutes had no path prop value given`,\n );\n }\n\n const extensions = getPluginExtensions(plugin);\n const pageExtensionName = extensions.length ? getUniqueName() : undefined;\n const pageExtensionId = `page:${plugin.getId()}${\n pageExtensionName ? `/${pageExtensionName}` : pageExtensionName\n }`;\n\n extensions.push(\n PageBlueprint.makeWithOverrides({\n name: pageExtensionName,\n inputs: {\n childRoutingShims: createExtensionInput([\n coreExtensionData.routePath.optional(),\n coreExtensionData.routeRef.optional(),\n ]),\n },\n factory(originalFactory, { inputs: _inputs }) {\n // todo(blam): why do we not use the inputs here?\n return originalFactory({\n defaultPath: normalizeRoutePath(path),\n routeRef: routeRef ? convertLegacyRouteRef(routeRef) : undefined,\n loader: async () =>\n compatWrapper(\n route.props.children ? (\n <Routes>\n <Route path=\"*\" element={routeElement}>\n <Route path=\"*\" element={route.props.children} />\n </Route>\n </Routes>\n ) : (\n routeElement\n ),\n ),\n });\n },\n }),\n );\n\n visitRouteChildren({\n children: route.props.children,\n parentExtensionId: pageExtensionId,\n context: {\n pluginId: plugin.getId(),\n extensions,\n getUniqueName,\n discoverPlugin: getPluginExtensions,\n },\n });\n });\n\n if (entityPage) {\n collectEntityPageContents(entityPage, {\n discoverExtension(extension, plugin) {\n if (!plugin || plugin.getId() === 'catalog') {\n getPluginExtensions(orphanRoutesPlugin).push(extension);\n } else {\n getPluginExtensions(plugin).push(extension);\n }\n },\n });\n\n const extensions = new Array<ExtensionDefinition>();\n visitRouteChildren({\n children: entityPage,\n parentExtensionId: `page:catalog/entity`,\n context: {\n pluginId: 'catalog',\n extensions,\n getUniqueName,\n discoverPlugin(plugin) {\n if (plugin.getId() !== 'catalog') {\n getPluginExtensions(plugin);\n }\n },\n },\n });\n\n output.push(\n createFrontendModule({\n pluginId: 'catalog',\n extensions,\n }),\n );\n }\n\n for (const [plugin, extensions] of pluginExtensions) {\n output.push(\n createFrontendPlugin({\n id: plugin.getId(),\n extensions: [\n ...extensions,\n ...Array.from(plugin.getApis()).map(factory =>\n ApiBlueprint.make({\n name: factory.api.id,\n params: { factory },\n }),\n ),\n ],\n routes: convertLegacyRouteRefs(plugin.routes ?? {}),\n externalRoutes: convertLegacyRouteRefs(plugin.externalRoutes ?? {}),\n }),\n );\n }\n\n return output;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"collectLegacyRoutes.esm.js","sources":["../src/collectLegacyRoutes.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AnyRouteRefParams,\n BackstagePlugin as LegacyBackstagePlugin,\n RouteRef,\n createPlugin,\n getComponentData,\n} from '@backstage/core-plugin-api';\nimport {\n FrontendPlugin,\n ExtensionDefinition,\n coreExtensionData,\n createExtension,\n createExtensionInput,\n createFrontendPlugin,\n ApiBlueprint,\n PageBlueprint,\n FrontendModule,\n createFrontendModule,\n} from '@backstage/frontend-plugin-api';\nimport { Children, ReactNode, isValidElement } from 'react';\nimport { Route, Routes } from 'react-router-dom';\nimport {\n convertLegacyRouteRef,\n convertLegacyRouteRefs,\n} from './convertLegacyRouteRef';\nimport { compatWrapper } from './compatWrapper';\nimport { collectEntityPageContents } from './collectEntityPageContents';\nimport { normalizeRoutePath } from './normalizeRoutePath';\n\n/*\n\n# Legacy interoperability\n\nUse-cases (prioritized):\n 1. Slowly migrate over an existing app to DI, piece by piece\n 2. Use a legacy plugin in a new DI app\n 3. Use DI in an existing legacy app\n\nStarting point: use-case #1\n\nPotential solutions:\n 1. Codemods (we're not considering this for now)\n 2. Legacy apps are migrated bottom-up, i.e. keep legacy root, replace pages with DI\n 3. Legacy apps are migrated top-down i.e. switch out base to DI, legacy adapter allows for usage of existing app structure\n\nChosen path: #3\n\nExisting tasks:\n - Adopters can migrate their existing app gradually (~4)\n - Example-app uses legacy base with DI adapters\n - Create an API that lets you inject DI into existing apps - working assumption is that this is enough\n - Adopters can use legacy plugins in DI through adapters (~8)\n - App-next uses DI base with legacy adapters\n - Create a legacy adapter that is able to take an existing extension tree\n\n*/\n\n// Creates a shim extension whose purpose is to build up the tree (anchored at\n// the root page) of paths/routeRefs so that the app can bind them properly.\nfunction makeRoutingShimExtension(options: {\n name: string;\n parentExtensionId: string;\n routePath?: string;\n routeRef?: RouteRef;\n}) {\n const { name, parentExtensionId, routePath, routeRef } = options;\n return createExtension({\n kind: 'routing-shim',\n name,\n attachTo: { id: parentExtensionId, input: 'childRoutingShims' },\n inputs: {\n childRoutingShims: createExtensionInput([\n coreExtensionData.routePath.optional(),\n coreExtensionData.routeRef.optional(),\n ]),\n },\n output: [\n coreExtensionData.routePath.optional(),\n coreExtensionData.routeRef.optional(),\n ],\n *factory() {\n if (routePath !== undefined) {\n yield coreExtensionData.routePath(routePath);\n }\n\n if (routeRef) {\n yield coreExtensionData.routeRef(convertLegacyRouteRef(routeRef));\n }\n },\n });\n}\n\nexport function visitRouteChildren(options: {\n children: ReactNode;\n parentExtensionId: string;\n context: {\n pluginId: string;\n extensions: ExtensionDefinition[];\n getUniqueName: () => string;\n discoverPlugin: (plugin: LegacyBackstagePlugin) => void;\n };\n}): void {\n const { children, parentExtensionId, context } = options;\n const { pluginId, extensions, getUniqueName, discoverPlugin } = context;\n\n Children.forEach(children, node => {\n if (!isValidElement(node)) {\n return;\n }\n\n const plugin = getComponentData<LegacyBackstagePlugin>(node, 'core.plugin');\n const routeRef = getComponentData<RouteRef<AnyRouteRefParams>>(\n node,\n 'core.mountPoint',\n );\n const routePath: string | undefined = node.props?.path;\n\n if (plugin) {\n // We just mark the plugin as discovered, but don't change the context\n discoverPlugin(plugin);\n }\n\n let nextParentExtensionId = parentExtensionId;\n if (routeRef || routePath) {\n const nextParentExtensionName = getUniqueName();\n nextParentExtensionId = `routing-shim:${pluginId}/${nextParentExtensionName}`;\n extensions.push(\n makeRoutingShimExtension({\n name: nextParentExtensionName,\n parentExtensionId,\n routePath,\n routeRef,\n }),\n );\n }\n\n visitRouteChildren({\n children: node.props.children,\n parentExtensionId: nextParentExtensionId,\n context,\n });\n });\n}\n\n/** @internal */\nexport function collectLegacyRoutes(\n flatRoutesElement: JSX.Element,\n entityPage?: JSX.Element,\n): (FrontendPlugin | FrontendModule)[] {\n const output = new Array<FrontendPlugin | FrontendModule>();\n\n const pluginExtensions = new Map<\n LegacyBackstagePlugin,\n ExtensionDefinition[]\n >();\n\n const getUniqueName = (() => {\n let currentIndex = 1;\n return () => String(currentIndex++);\n })();\n\n // Placeholder plugin for any routes that don't belong to a plugin\n const orphanRoutesPlugin = createPlugin({ id: 'converted-orphan-routes' });\n\n const getPluginExtensions = (plugin: LegacyBackstagePlugin) => {\n let extensions = pluginExtensions.get(plugin);\n if (!extensions) {\n extensions = [];\n pluginExtensions.set(plugin, extensions);\n }\n return extensions;\n };\n\n Children.forEach(flatRoutesElement.props.children, (route: ReactNode) => {\n if (route === null) {\n return;\n }\n // TODO(freben): Handle feature flag and permissions framework wrapper elements\n if (!isValidElement(route)) {\n throw new Error(\n `Invalid element inside FlatRoutes, expected Route but found element of type ${typeof route}.`,\n );\n }\n if (route.type !== Route) {\n throw new Error(\n `Invalid element inside FlatRoutes, expected Route but found ${route.type}.`,\n );\n }\n const routeElement = route.props.element;\n const path: string | undefined = route.props.path;\n const plugin =\n getComponentData<LegacyBackstagePlugin>(routeElement, 'core.plugin') ??\n orphanRoutesPlugin;\n const routeRef = getComponentData<RouteRef>(\n routeElement,\n 'core.mountPoint',\n );\n if (path === undefined) {\n throw new Error(\n `Route element inside FlatRoutes had no path prop value given`,\n );\n }\n\n const extensions = getPluginExtensions(plugin);\n const pageExtensionName = extensions.length ? getUniqueName() : undefined;\n const pageExtensionId = `page:${plugin.getId()}${\n pageExtensionName ? `/${pageExtensionName}` : pageExtensionName\n }`;\n\n extensions.push(\n PageBlueprint.makeWithOverrides({\n name: pageExtensionName,\n inputs: {\n childRoutingShims: createExtensionInput([\n coreExtensionData.routePath.optional(),\n coreExtensionData.routeRef.optional(),\n ]),\n },\n factory(originalFactory, { inputs: _inputs }) {\n // todo(blam): why do we not use the inputs here?\n return originalFactory({\n defaultPath: normalizeRoutePath(path),\n routeRef: routeRef ? convertLegacyRouteRef(routeRef) : undefined,\n loader: async () =>\n compatWrapper(\n route.props.children ? (\n <Routes>\n <Route path=\"*\" element={routeElement}>\n <Route path=\"*\" element={route.props.children} />\n </Route>\n </Routes>\n ) : (\n routeElement\n ),\n ),\n });\n },\n }),\n );\n\n visitRouteChildren({\n children: route.props.children,\n parentExtensionId: pageExtensionId,\n context: {\n pluginId: plugin.getId(),\n extensions,\n getUniqueName,\n discoverPlugin: getPluginExtensions,\n },\n });\n });\n\n if (entityPage) {\n collectEntityPageContents(entityPage, {\n discoverExtension(extension, plugin) {\n if (!plugin || plugin.getId() === 'catalog') {\n getPluginExtensions(orphanRoutesPlugin).push(extension);\n } else {\n getPluginExtensions(plugin).push(extension);\n }\n },\n });\n\n const extensions = new Array<ExtensionDefinition>();\n visitRouteChildren({\n children: entityPage,\n parentExtensionId: `page:catalog/entity`,\n context: {\n pluginId: 'catalog',\n extensions,\n getUniqueName,\n discoverPlugin(plugin) {\n if (plugin.getId() !== 'catalog') {\n getPluginExtensions(plugin);\n }\n },\n },\n });\n\n output.push(\n createFrontendModule({\n pluginId: 'catalog',\n extensions,\n }),\n );\n }\n\n for (const [plugin, extensions] of pluginExtensions) {\n output.push(\n createFrontendPlugin({\n pluginId: plugin.getId(),\n extensions: [\n ...extensions,\n ...Array.from(plugin.getApis()).map(factory =>\n ApiBlueprint.make({\n name: factory.api.id,\n params: { factory },\n }),\n ),\n ],\n routes: convertLegacyRouteRefs(plugin.routes ?? {}),\n externalRoutes: convertLegacyRouteRefs(plugin.externalRoutes ?? {}),\n }),\n );\n }\n\n return output;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackwardsCompatProvider.esm.js","sources":["../../src/compatWrapper/BackwardsCompatProvider.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useMemo } from 'react';\nimport { ReactNode } from 'react';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppContextProvider } from '../../../core-app-api/src/app/AppContext';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { RouteResolver } from '../../../core-plugin-api/src/routing/useRouteRef';\nimport {\n createFrontendPlugin as createNewPlugin,\n FrontendPlugin as NewFrontendPlugin,\n appTreeApiRef,\n componentsApiRef,\n coreComponentRefs,\n iconsApiRef,\n useApi,\n routeResolutionApiRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n AppComponents,\n IconComponent,\n BackstagePlugin as LegacyBackstagePlugin,\n RouteRef,\n} from '@backstage/core-plugin-api';\nimport {\n VersionedValue,\n createVersionedContext,\n createVersionedValueMap,\n getOrCreateGlobalSingleton,\n} from '@backstage/version-bridge';\nimport { convertLegacyRouteRef } from '../convertLegacyRouteRef';\n\n// Make sure that we only convert each new plugin instance to its legacy equivalent once\nconst legacyPluginStore = getOrCreateGlobalSingleton(\n 'legacy-plugin-compatibility-store',\n () => new WeakMap<NewFrontendPlugin, LegacyBackstagePlugin>(),\n);\n\nexport function toLegacyPlugin(\n plugin: NewFrontendPlugin,\n): LegacyBackstagePlugin {\n let legacy = legacyPluginStore.get(plugin);\n if (legacy) {\n return legacy;\n }\n\n const errorMsg = 'Not implemented in legacy plugin compatibility layer';\n const notImplemented = () => {\n throw new Error(errorMsg);\n };\n\n legacy = {\n getId(): string {\n return plugin.id;\n },\n get routes() {\n return {};\n },\n get externalRoutes() {\n return {};\n },\n getApis: notImplemented,\n getFeatureFlags: notImplemented,\n provide: notImplemented,\n };\n\n legacyPluginStore.set(plugin, legacy);\n return legacy;\n}\n\n// TODO: Currently a very naive implementation, may need some more work\nfunction toNewPlugin(plugin: LegacyBackstagePlugin): NewFrontendPlugin {\n return createNewPlugin({\n
|
|
1
|
+
{"version":3,"file":"BackwardsCompatProvider.esm.js","sources":["../../src/compatWrapper/BackwardsCompatProvider.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useMemo } from 'react';\nimport { ReactNode } from 'react';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppContextProvider } from '../../../core-app-api/src/app/AppContext';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { RouteResolver } from '../../../core-plugin-api/src/routing/useRouteRef';\nimport {\n createFrontendPlugin as createNewPlugin,\n FrontendPlugin as NewFrontendPlugin,\n appTreeApiRef,\n componentsApiRef,\n coreComponentRefs,\n iconsApiRef,\n useApi,\n routeResolutionApiRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n AppComponents,\n IconComponent,\n BackstagePlugin as LegacyBackstagePlugin,\n RouteRef,\n} from '@backstage/core-plugin-api';\nimport {\n VersionedValue,\n createVersionedContext,\n createVersionedValueMap,\n getOrCreateGlobalSingleton,\n} from '@backstage/version-bridge';\nimport { convertLegacyRouteRef } from '../convertLegacyRouteRef';\n\n// Make sure that we only convert each new plugin instance to its legacy equivalent once\nconst legacyPluginStore = getOrCreateGlobalSingleton(\n 'legacy-plugin-compatibility-store',\n () => new WeakMap<NewFrontendPlugin, LegacyBackstagePlugin>(),\n);\n\nexport function toLegacyPlugin(\n plugin: NewFrontendPlugin,\n): LegacyBackstagePlugin {\n let legacy = legacyPluginStore.get(plugin);\n if (legacy) {\n return legacy;\n }\n\n const errorMsg = 'Not implemented in legacy plugin compatibility layer';\n const notImplemented = () => {\n throw new Error(errorMsg);\n };\n\n legacy = {\n getId(): string {\n return plugin.id;\n },\n get routes() {\n return {};\n },\n get externalRoutes() {\n return {};\n },\n getApis: notImplemented,\n getFeatureFlags: notImplemented,\n provide: notImplemented,\n };\n\n legacyPluginStore.set(plugin, legacy);\n return legacy;\n}\n\n// TODO: Currently a very naive implementation, may need some more work\nfunction toNewPlugin(plugin: LegacyBackstagePlugin): NewFrontendPlugin {\n return createNewPlugin({\n pluginId: plugin.getId(),\n });\n}\n\n// Recreates the old AppContext APIs using the various new APIs that replaced it\nfunction LegacyAppContextProvider(props: { children: ReactNode }) {\n const appTreeApi = useApi(appTreeApiRef);\n const componentsApi = useApi(componentsApiRef);\n const iconsApi = useApi(iconsApiRef);\n\n const appContext = useMemo(() => {\n const { tree } = appTreeApi.getTree();\n\n let gatheredPlugins: LegacyBackstagePlugin[] | undefined = undefined;\n\n const ErrorBoundaryFallback = componentsApi.getComponent(\n coreComponentRefs.errorBoundaryFallback,\n );\n const ErrorBoundaryFallbackWrapper: AppComponents['ErrorBoundaryFallback'] =\n ({ plugin, ...rest }) => (\n <ErrorBoundaryFallback\n {...rest}\n plugin={plugin && toNewPlugin(plugin)}\n />\n );\n\n return {\n getPlugins(): LegacyBackstagePlugin[] {\n if (gatheredPlugins) {\n return gatheredPlugins;\n }\n\n const pluginSet = new Set<LegacyBackstagePlugin>();\n for (const node of tree.nodes.values()) {\n const plugin = node.spec.source;\n if (plugin) {\n pluginSet.add(toLegacyPlugin(plugin));\n }\n }\n gatheredPlugins = Array.from(pluginSet);\n\n return gatheredPlugins;\n },\n\n getSystemIcon(key: string): IconComponent | undefined {\n return iconsApi.getIcon(key);\n },\n\n getSystemIcons(): Record<string, IconComponent> {\n return Object.fromEntries(\n iconsApi.listIconKeys().map(key => [key, iconsApi.getIcon(key)!]),\n );\n },\n\n getComponents(): AppComponents {\n return {\n NotFoundErrorPage: componentsApi.getComponent(\n coreComponentRefs.notFoundErrorPage,\n ),\n BootErrorPage() {\n throw new Error(\n 'The BootErrorPage app component should not be accessed by plugins',\n );\n },\n Progress: componentsApi.getComponent(coreComponentRefs.progress),\n Router() {\n throw new Error(\n 'The Router app component should not be accessed by plugins',\n );\n },\n ErrorBoundaryFallback: ErrorBoundaryFallbackWrapper,\n };\n },\n };\n }, [appTreeApi, componentsApi, iconsApi]);\n\n return (\n <AppContextProvider appContext={appContext}>\n {props.children}\n </AppContextProvider>\n );\n}\n\nconst RoutingContext = createVersionedContext<{ 1: RouteResolver }>(\n 'routing-context',\n);\n\nfunction LegacyRoutingProvider(props: { children: ReactNode }) {\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n const value = useMemo<VersionedValue<{ 1: RouteResolver }>>(() => {\n return createVersionedValueMap({\n 1: {\n resolve(anyRouteRef, location) {\n const sourcePath =\n typeof location === 'string' ? location : location.pathname ?? '';\n\n return routeResolutionApi.resolve(\n // This removes the requirement to use convertLegacyRouteRef inside plugins, but\n // they still need to converted when passed to the plugin instance\n convertLegacyRouteRef(anyRouteRef as RouteRef),\n { sourcePath },\n );\n },\n },\n });\n }, [routeResolutionApi]);\n\n return (\n <RoutingContext.Provider value={value}>\n {props.children}\n </RoutingContext.Provider>\n );\n}\n\nexport function BackwardsCompatProvider(props: { children: ReactNode }) {\n return (\n <LegacyRoutingProvider>\n <LegacyAppContextProvider>{props.children}</LegacyAppContextProvider>\n </LegacyRoutingProvider>\n );\n}\n"],"names":["createNewPlugin"],"mappings":";;;;;;;AA+CA,MAAM,iBAAoB,GAAA,0BAAA;AAAA,EACxB,mCAAA;AAAA,EACA,0BAAU,OAAkD;AAC9D,CAAA;AAEO,SAAS,eACd,MACuB,EAAA;AACvB,EAAI,IAAA,MAAA,GAAS,iBAAkB,CAAA,GAAA,CAAI,MAAM,CAAA;AACzC,EAAA,IAAI,MAAQ,EAAA;AACV,IAAO,OAAA,MAAA;AAAA;AAGT,EAAA,MAAM,QAAW,GAAA,sDAAA;AACjB,EAAA,MAAM,iBAAiB,MAAM;AAC3B,IAAM,MAAA,IAAI,MAAM,QAAQ,CAAA;AAAA,GAC1B;AAEA,EAAS,MAAA,GAAA;AAAA,IACP,KAAgB,GAAA;AACd,MAAA,OAAO,MAAO,CAAA,EAAA;AAAA,KAChB;AAAA,IACA,IAAI,MAAS,GAAA;AACX,MAAA,OAAO,EAAC;AAAA,KACV;AAAA,IACA,IAAI,cAAiB,GAAA;AACnB,MAAA,OAAO,EAAC;AAAA,KACV;AAAA,IACA,OAAS,EAAA,cAAA;AAAA,IACT,eAAiB,EAAA,cAAA;AAAA,IACjB,OAAS,EAAA;AAAA,GACX;AAEA,EAAkB,iBAAA,CAAA,GAAA,CAAI,QAAQ,MAAM,CAAA;AACpC,EAAO,OAAA,MAAA;AACT;AAGA,SAAS,YAAY,MAAkD,EAAA;AACrE,EAAA,OAAOA,oBAAgB,CAAA;AAAA,IACrB,QAAA,EAAU,OAAO,KAAM;AAAA,GACxB,CAAA;AACH;AAGA,SAAS,yBAAyB,KAAgC,EAAA;AAChE,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAC7C,EAAM,MAAA,QAAA,GAAW,OAAO,WAAW,CAAA;AAEnC,EAAM,MAAA,UAAA,GAAa,QAAQ,MAAM;AAC/B,IAAA,MAAM,EAAE,IAAA,EAAS,GAAA,UAAA,CAAW,OAAQ,EAAA;AAEpC,IAAA,IAAI,eAAuD,GAAA,KAAA,CAAA;AAE3D,IAAA,MAAM,wBAAwB,aAAc,CAAA,YAAA;AAAA,MAC1C,iBAAkB,CAAA;AAAA,KACpB;AACA,IAAA,MAAM,+BACJ,CAAC,EAAE,MAAQ,EAAA,GAAG,MACZ,qBAAA,GAAA;AAAA,MAAC,qBAAA;AAAA,MAAA;AAAA,QACE,GAAG,IAAA;AAAA,QACJ,MAAA,EAAQ,MAAU,IAAA,WAAA,CAAY,MAAM;AAAA;AAAA,KACtC;AAGJ,IAAO,OAAA;AAAA,MACL,UAAsC,GAAA;AACpC,QAAA,IAAI,eAAiB,EAAA;AACnB,UAAO,OAAA,eAAA;AAAA;AAGT,QAAM,MAAA,SAAA,uBAAgB,GAA2B,EAAA;AACjD,QAAA,KAAA,MAAW,IAAQ,IAAA,IAAA,CAAK,KAAM,CAAA,MAAA,EAAU,EAAA;AACtC,UAAM,MAAA,MAAA,GAAS,KAAK,IAAK,CAAA,MAAA;AACzB,UAAA,IAAI,MAAQ,EAAA;AACV,YAAU,SAAA,CAAA,GAAA,CAAI,cAAe,CAAA,MAAM,CAAC,CAAA;AAAA;AACtC;AAEF,QAAkB,eAAA,GAAA,KAAA,CAAM,KAAK,SAAS,CAAA;AAEtC,QAAO,OAAA,eAAA;AAAA,OACT;AAAA,MAEA,cAAc,GAAwC,EAAA;AACpD,QAAO,OAAA,QAAA,CAAS,QAAQ,GAAG,CAAA;AAAA,OAC7B;AAAA,MAEA,cAAgD,GAAA;AAC9C,QAAA,OAAO,MAAO,CAAA,WAAA;AAAA,UACZ,QAAA,CAAS,YAAa,EAAA,CAAE,GAAI,CAAA,CAAA,GAAA,KAAO,CAAC,GAAA,EAAK,QAAS,CAAA,OAAA,CAAQ,GAAG,CAAE,CAAC;AAAA,SAClE;AAAA,OACF;AAAA,MAEA,aAA+B,GAAA;AAC7B,QAAO,OAAA;AAAA,UACL,mBAAmB,aAAc,CAAA,YAAA;AAAA,YAC/B,iBAAkB,CAAA;AAAA,WACpB;AAAA,UACA,aAAgB,GAAA;AACd,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AAAA,WACF;AAAA,UACA,QAAU,EAAA,aAAA,CAAc,YAAa,CAAA,iBAAA,CAAkB,QAAQ,CAAA;AAAA,UAC/D,MAAS,GAAA;AACP,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AAAA,WACF;AAAA,UACA,qBAAuB,EAAA;AAAA,SACzB;AAAA;AACF,KACF;AAAA,GACC,EAAA,CAAC,UAAY,EAAA,aAAA,EAAe,QAAQ,CAAC,CAAA;AAExC,EAAA,uBACG,GAAA,CAAA,kBAAA,EAAA,EAAmB,UACjB,EAAA,QAAA,EAAA,KAAA,CAAM,QACT,EAAA,CAAA;AAEJ;AAEA,MAAM,cAAiB,GAAA,sBAAA;AAAA,EACrB;AACF,CAAA;AAEA,SAAS,sBAAsB,KAAgC,EAAA;AAC7D,EAAM,MAAA,kBAAA,GAAqB,OAAO,qBAAqB,CAAA;AAEvD,EAAM,MAAA,KAAA,GAAQ,QAA8C,MAAM;AAChE,IAAA,OAAO,uBAAwB,CAAA;AAAA,MAC7B,CAAG,EAAA;AAAA,QACD,OAAA,CAAQ,aAAa,QAAU,EAAA;AAC7B,UAAA,MAAM,aACJ,OAAO,QAAA,KAAa,QAAW,GAAA,QAAA,GAAW,SAAS,QAAY,IAAA,EAAA;AAEjE,UAAA,OAAO,kBAAmB,CAAA,OAAA;AAAA;AAAA;AAAA,YAGxB,sBAAsB,WAAuB,CAAA;AAAA,YAC7C,EAAE,UAAW;AAAA,WACf;AAAA;AACF;AACF,KACD,CAAA;AAAA,GACH,EAAG,CAAC,kBAAkB,CAAC,CAAA;AAEvB,EAAA,2BACG,cAAe,CAAA,QAAA,EAAf,EAAwB,KAAA,EACtB,gBAAM,QACT,EAAA,CAAA;AAEJ;AAEO,SAAS,wBAAwB,KAAgC,EAAA;AACtE,EAAA,2BACG,qBACC,EAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,wBAA0B,EAAA,EAAA,QAAA,EAAA,KAAA,CAAM,UAAS,CAC5C,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -6,7 +6,7 @@ function convertLegacyPlugin(legacyPlugin, options) {
|
|
|
6
6
|
(factory) => ApiBlueprint.make({ name: factory.api.id, params: { factory } })
|
|
7
7
|
);
|
|
8
8
|
return createFrontendPlugin({
|
|
9
|
-
|
|
9
|
+
pluginId: legacyPlugin.getId(),
|
|
10
10
|
featureFlags: [...legacyPlugin.getFeatureFlags()],
|
|
11
11
|
routes: convertLegacyRouteRefs(legacyPlugin.routes ?? {}),
|
|
12
12
|
externalRoutes: convertLegacyRouteRefs(legacyPlugin.externalRoutes ?? {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertLegacyPlugin.esm.js","sources":["../src/convertLegacyPlugin.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackstagePlugin as LegacyBackstagePlugin } from '@backstage/core-plugin-api';\nimport {\n ApiBlueprint,\n ExtensionDefinition,\n FrontendPlugin as NewBackstagePlugin,\n createFrontendPlugin,\n} from '@backstage/frontend-plugin-api';\nimport { convertLegacyRouteRefs } from './convertLegacyRouteRef';\n\n/** @public */\nexport function convertLegacyPlugin(\n legacyPlugin: LegacyBackstagePlugin,\n options: { extensions: ExtensionDefinition[] },\n): NewBackstagePlugin {\n const apiExtensions = Array.from(legacyPlugin.getApis()).map(factory =>\n ApiBlueprint.make({ name: factory.api.id, params: { factory } }),\n );\n return createFrontendPlugin({\n
|
|
1
|
+
{"version":3,"file":"convertLegacyPlugin.esm.js","sources":["../src/convertLegacyPlugin.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackstagePlugin as LegacyBackstagePlugin } from '@backstage/core-plugin-api';\nimport {\n ApiBlueprint,\n ExtensionDefinition,\n FrontendPlugin as NewBackstagePlugin,\n createFrontendPlugin,\n} from '@backstage/frontend-plugin-api';\nimport { convertLegacyRouteRefs } from './convertLegacyRouteRef';\n\n/** @public */\nexport function convertLegacyPlugin(\n legacyPlugin: LegacyBackstagePlugin,\n options: { extensions: ExtensionDefinition[] },\n): NewBackstagePlugin {\n const apiExtensions = Array.from(legacyPlugin.getApis()).map(factory =>\n ApiBlueprint.make({ name: factory.api.id, params: { factory } }),\n );\n return createFrontendPlugin({\n pluginId: legacyPlugin.getId(),\n featureFlags: [...legacyPlugin.getFeatureFlags()],\n routes: convertLegacyRouteRefs(legacyPlugin.routes ?? {}),\n externalRoutes: convertLegacyRouteRefs(legacyPlugin.externalRoutes ?? {}),\n extensions: [...apiExtensions, ...options.extensions],\n });\n}\n"],"names":[],"mappings":";;;AA0BgB,SAAA,mBAAA,CACd,cACA,OACoB,EAAA;AACpB,EAAA,MAAM,gBAAgB,KAAM,CAAA,IAAA,CAAK,YAAa,CAAA,OAAA,EAAS,CAAE,CAAA,GAAA;AAAA,IAAI,CAC3D,OAAA,KAAA,YAAA,CAAa,IAAK,CAAA,EAAE,IAAM,EAAA,OAAA,CAAQ,GAAI,CAAA,EAAA,EAAI,MAAQ,EAAA,EAAE,OAAQ,EAAA,EAAG;AAAA,GACjE;AACA,EAAA,OAAO,oBAAqB,CAAA;AAAA,IAC1B,QAAA,EAAU,aAAa,KAAM,EAAA;AAAA,IAC7B,YAAc,EAAA,CAAC,GAAG,YAAA,CAAa,iBAAiB,CAAA;AAAA,IAChD,MAAQ,EAAA,sBAAA,CAAuB,YAAa,CAAA,MAAA,IAAU,EAAE,CAAA;AAAA,IACxD,cAAgB,EAAA,sBAAA,CAAuB,YAAa,CAAA,cAAA,IAAkB,EAAE,CAAA;AAAA,IACxE,YAAY,CAAC,GAAG,aAAe,EAAA,GAAG,QAAQ,UAAU;AAAA,GACrD,CAAA;AACH;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/core-compat-api",
|
|
3
|
-
"version": "0.4.1",
|
|
3
|
+
"version": "0.4.2-next.1",
|
|
4
4
|
"backstage": {
|
|
5
5
|
"role": "web-library"
|
|
6
6
|
},
|
|
@@ -31,22 +31,22 @@
|
|
|
31
31
|
"test": "backstage-cli package test"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@backstage/core-plugin-api": "
|
|
35
|
-
"@backstage/frontend-plugin-api": "
|
|
36
|
-
"@backstage/plugin-catalog-react": "
|
|
37
|
-
"@backstage/version-bridge": "
|
|
34
|
+
"@backstage/core-plugin-api": "1.10.6",
|
|
35
|
+
"@backstage/frontend-plugin-api": "0.10.2-next.0",
|
|
36
|
+
"@backstage/plugin-catalog-react": "1.18.0-next.1",
|
|
37
|
+
"@backstage/version-bridge": "1.0.11",
|
|
38
38
|
"lodash": "^4.17.21"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@backstage-community/plugin-puppetdb": "^0.
|
|
41
|
+
"@backstage-community/plugin-puppetdb": "^0.6.0",
|
|
42
42
|
"@backstage-community/plugin-stackstorm": "^0.1.16",
|
|
43
|
-
"@backstage/cli": "
|
|
44
|
-
"@backstage/core-app-api": "
|
|
45
|
-
"@backstage/frontend-app-api": "
|
|
46
|
-
"@backstage/frontend-test-utils": "
|
|
47
|
-
"@backstage/plugin-catalog": "
|
|
48
|
-
"@backstage/test-utils": "
|
|
49
|
-
"@backstage/types": "
|
|
43
|
+
"@backstage/cli": "0.32.1-next.1",
|
|
44
|
+
"@backstage/core-app-api": "1.16.1",
|
|
45
|
+
"@backstage/frontend-app-api": "0.11.2-next.1",
|
|
46
|
+
"@backstage/frontend-test-utils": "0.3.2-next.1",
|
|
47
|
+
"@backstage/plugin-catalog": "1.29.1-next.1",
|
|
48
|
+
"@backstage/test-utils": "1.7.8-next.0",
|
|
49
|
+
"@backstage/types": "1.2.1",
|
|
50
50
|
"@oriflame/backstage-plugin-score-card": "^0.9.0",
|
|
51
51
|
"@testing-library/jest-dom": "^6.0.0",
|
|
52
52
|
"@testing-library/react": "^16.0.0",
|