@backstage/core-compat-api 0.3.0-next.2 → 0.3.1-next.0

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 CHANGED
@@ -1,5 +1,31 @@
1
1
  # @backstage/core-compat-api
2
2
 
3
+ ## 0.3.1-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 4a5ba19: Internal update to remove deprecated `BackstagePlugin` type and move to `FrontendPlugin`
8
+ - Updated dependencies
9
+ - @backstage/frontend-plugin-api@0.9.0-next.0
10
+ - @backstage/core-plugin-api@1.10.0-next.0
11
+ - @backstage/version-bridge@1.0.9
12
+
13
+ ## 0.3.0
14
+
15
+ ### Minor Changes
16
+
17
+ - 6db849e: **BREAKING**: The `namespace` parameter for API's is now defaulted to the `pluginId` which was discovered. This means that if you're overriding API's by using ID's directly, they might have changed to include the plugin ID too.
18
+
19
+ ### Patch Changes
20
+
21
+ - fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints.
22
+ - c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types.
23
+ - 836127c: Updated dependency `@testing-library/react` to `^16.0.0`.
24
+ - Updated dependencies
25
+ - @backstage/frontend-plugin-api@0.8.0
26
+ - @backstage/core-plugin-api@1.9.4
27
+ - @backstage/version-bridge@1.0.9
28
+
3
29
  ## 0.3.0-next.2
4
30
 
5
31
  ### Patch Changes
@@ -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 getComponentData,\n} from '@backstage/core-plugin-api';\nimport {\n BackstagePlugin,\n ExtensionDefinition,\n coreExtensionData,\n createExtension,\n createExtensionInput,\n createFrontendPlugin,\n ApiBlueprint,\n PageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport React, { Children, ReactNode, isValidElement } from 'react';\nimport { Route, Routes } from 'react-router-dom';\nimport {\n convertLegacyRouteRef,\n convertLegacyRouteRefs,\n} from './convertLegacyRouteRef';\nimport { compatWrapper } from './compatWrapper';\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\nfunction 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): BackstagePlugin[] {\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 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 React.Children.forEach(\n flatRoutesElement.props.children,\n (route: ReactNode) => {\n // TODO(freben): Handle feature flag and permissions framework wrapper elements\n if (!React.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 = getComponentData<LegacyBackstagePlugin>(\n routeElement,\n 'core.plugin',\n );\n const routeRef = getComponentData<RouteRef>(\n routeElement,\n 'core.mountPoint',\n );\n if (!plugin) {\n throw new Error(\n // TODO(vinzscam): add See <link-to-app-migration-docs> for more info\n `Route with path ${path} has en element that can not be converted as it does not belong to a plugin. Make sure that the top-level React element of the element prop is an extension from a Backstage plugin, or remove the Route completely.`,\n );\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: path[0] === '/' ? path.slice(1) : 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\n return Array.from(pluginExtensions).map(([plugin, extensions]) =>\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"],"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 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} from '@backstage/frontend-plugin-api';\nimport React, { Children, ReactNode, isValidElement } from 'react';\nimport { Route, Routes } from 'react-router-dom';\nimport {\n convertLegacyRouteRef,\n convertLegacyRouteRefs,\n} from './convertLegacyRouteRef';\nimport { compatWrapper } from './compatWrapper';\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\nfunction 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): FrontendPlugin[] {\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 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 React.Children.forEach(\n flatRoutesElement.props.children,\n (route: ReactNode) => {\n // TODO(freben): Handle feature flag and permissions framework wrapper elements\n if (!React.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 = getComponentData<LegacyBackstagePlugin>(\n routeElement,\n 'core.plugin',\n );\n const routeRef = getComponentData<RouteRef>(\n routeElement,\n 'core.mountPoint',\n );\n if (!plugin) {\n throw new Error(\n // TODO(vinzscam): add See <link-to-app-migration-docs> for more info\n `Route with path ${path} has en element that can not be converted as it does not belong to a plugin. Make sure that the top-level React element of the element prop is an extension from a Backstage plugin, or remove the Route completely.`,\n );\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: path[0] === '/' ? path.slice(1) : 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\n return Array.from(pluginExtensions).map(([plugin, extensions]) =>\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"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/core-compat-api",
3
- "version": "0.3.0-next.2",
3
+ "version": "0.3.1-next.0",
4
4
  "backstage": {
5
5
  "role": "web-library"
6
6
  },
@@ -31,24 +31,26 @@
31
31
  "test": "backstage-cli package test"
32
32
  },
33
33
  "dependencies": {
34
- "@backstage/core-plugin-api": "^1.9.4-next.0",
35
- "@backstage/frontend-plugin-api": "^0.8.0-next.2",
36
- "@backstage/version-bridge": "^1.0.9-next.0",
34
+ "@backstage/core-plugin-api": "^1.10.0-next.0",
35
+ "@backstage/frontend-plugin-api": "^0.9.0-next.0",
36
+ "@backstage/version-bridge": "^1.0.9",
37
37
  "@types/react": "^16.13.1 || ^17.0.0",
38
38
  "lodash": "^4.17.21"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@backstage-community/plugin-puppetdb": "^0.1.18",
42
42
  "@backstage-community/plugin-stackstorm": "^0.1.16",
43
- "@backstage/cli": "^0.27.1-next.2",
44
- "@backstage/core-app-api": "^1.14.3-next.0",
45
- "@backstage/frontend-app-api": "^0.9.0-next.2",
46
- "@backstage/frontend-test-utils": "^0.2.0-next.2",
47
- "@backstage/plugin-catalog": "^1.23.0-next.2",
48
- "@backstage/test-utils": "^1.6.0-next.1",
43
+ "@backstage/cli": "^0.28.0-next.0",
44
+ "@backstage/core-app-api": "^1.15.1-next.0",
45
+ "@backstage/frontend-app-api": "^0.10.0-next.0",
46
+ "@backstage/frontend-test-utils": "^0.2.1-next.0",
47
+ "@backstage/plugin-catalog": "^1.24.0-next.0",
48
+ "@backstage/test-utils": "^1.6.1-next.0",
49
+ "@backstage/types": "^1.1.1",
49
50
  "@oriflame/backstage-plugin-score-card": "^0.8.0",
50
51
  "@testing-library/jest-dom": "^6.0.0",
51
- "@testing-library/react": "^16.0.0"
52
+ "@testing-library/react": "^16.0.0",
53
+ "zod": "^3.22.4"
52
54
  },
53
55
  "peerDependencies": {
54
56
  "react": "^16.13.1 || ^17.0.0 || ^18.0.0",