@backstage/frontend-plugin-api 0.11.0-next.1 → 0.11.0-next.2
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 +108 -0
- package/dist/analytics/useAnalytics.esm.js +1 -1
- package/dist/apis/definitions/AppTreeApi.esm.js.map +1 -1
- package/dist/apis/definitions/DialogApi.esm.js.map +1 -1
- package/dist/apis/definitions/SwappableComponentsApi.esm.js +8 -0
- package/dist/apis/definitions/SwappableComponentsApi.esm.js.map +1 -0
- package/dist/blueprints/PageBlueprint.esm.js +10 -0
- package/dist/blueprints/PageBlueprint.esm.js.map +1 -1
- package/dist/blueprints/SignInPageBlueprint.esm.js +8 -0
- package/dist/blueprints/SignInPageBlueprint.esm.js.map +1 -1
- package/dist/blueprints/SwappableComponentBlueprint.esm.js +27 -0
- package/dist/blueprints/SwappableComponentBlueprint.esm.js.map +1 -0
- package/dist/components/DefaultSwappableComponents.esm.js +16 -0
- package/dist/components/DefaultSwappableComponents.esm.js.map +1 -0
- package/dist/components/ErrorBoundary.esm.js +3 -2
- package/dist/components/ErrorBoundary.esm.js.map +1 -1
- package/dist/components/ExtensionBoundary.esm.js +2 -10
- package/dist/components/ExtensionBoundary.esm.js.map +1 -1
- package/dist/components/createSwappableComponent.esm.js +52 -0
- package/dist/components/createSwappableComponent.esm.js.map +1 -0
- package/dist/frontend-internal/src/wiring/InternalSwappableComponentRef.esm.js +9 -0
- package/dist/frontend-internal/src/wiring/InternalSwappableComponentRef.esm.js.map +1 -0
- package/dist/frontend-internal/src/wiring/createExtensionDataContainer.esm.js +4 -1
- package/dist/frontend-internal/src/wiring/createExtensionDataContainer.esm.js.map +1 -1
- package/dist/index.d.ts +244 -86
- package/dist/index.esm.js +4 -4
- package/dist/routing/useRouteRef.esm.js +1 -1
- package/dist/wiring/createExtension.esm.js +7 -0
- package/dist/wiring/createExtension.esm.js.map +1 -1
- package/dist/wiring/createExtensionBlueprint.esm.js +1 -0
- package/dist/wiring/createExtensionBlueprint.esm.js.map +1 -1
- package/dist/wiring/createFrontendModule.esm.js.map +1 -1
- package/dist/wiring/createFrontendPlugin.esm.js +2 -6
- package/dist/wiring/createFrontendPlugin.esm.js.map +1 -1
- package/dist/wiring/resolveInputOverrides.esm.js +3 -0
- package/dist/wiring/resolveInputOverrides.esm.js.map +1 -1
- package/package.json +4 -4
- package/dist/apis/definitions/ComponentsApi.esm.js +0 -12
- package/dist/apis/definitions/ComponentsApi.esm.js.map +0 -1
- package/dist/components/coreComponentRefs.esm.js +0 -19
- package/dist/components/coreComponentRefs.esm.js.map +0 -1
- package/dist/components/createComponentRef.esm.js +0 -12
- package/dist/components/createComponentRef.esm.js.map +0 -1
- package/dist/extensions/createComponentExtension.esm.js +0 -43
- package/dist/extensions/createComponentExtension.esm.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,113 @@
|
|
|
1
1
|
# @backstage/frontend-plugin-api
|
|
2
2
|
|
|
3
|
+
## 0.11.0-next.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- fda1bbc: **BREAKING**: The component system has been overhauled to use `SwappableComponent` instead of `ComponentRef`. Several APIs have been removed and replaced:
|
|
8
|
+
|
|
9
|
+
- Removed: `createComponentRef`, `createComponentExtension`, `ComponentRef`, `ComponentsApi`, `componentsApiRef`, `useComponentRef`, `coreComponentRefs`
|
|
10
|
+
- Added: `createSwappableComponent`, `SwappableComponentBlueprint`, `SwappableComponentRef`, `SwappableComponentsApi`, `swappableComponentsApiRef`
|
|
11
|
+
|
|
12
|
+
**BREAKING**: The default `componentRefs` and exported `Core*Props` have been removed and have replacement `SwappableComponents` and revised type names instead.
|
|
13
|
+
|
|
14
|
+
- The `errorBoundaryFallback` component and `CoreErrorBoundaryFallbackProps` type have been replaced with `ErrorDisplay` swappable component and `CoreErrorDisplayProps` respectively.
|
|
15
|
+
- The `progress` component and `CoreProgressProps` type have been replaced with `Progress` swappable component and `ProgressProps` respectively.
|
|
16
|
+
- The `notFoundErrorPage` component and `CoreNotFoundErrorPageProps` type have been replaced with `NotFoundErrorPage` swappable component and `NotFoundErrorPageProps` respectively.
|
|
17
|
+
|
|
18
|
+
**Migration for creating swappable components:**
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
// OLD: Using createComponentRef and createComponentExtension
|
|
22
|
+
import {
|
|
23
|
+
createComponentRef,
|
|
24
|
+
createComponentExtension,
|
|
25
|
+
} from '@backstage/frontend-plugin-api';
|
|
26
|
+
|
|
27
|
+
const myComponentRef = createComponentRef<{ title: string }>({
|
|
28
|
+
id: 'my-plugin.my-component',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const myComponentExtension = createComponentExtension({
|
|
32
|
+
ref: myComponentRef,
|
|
33
|
+
loader: {
|
|
34
|
+
lazy: () => import('./MyComponent').then(m => m.MyComponent),
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// NEW: Using createSwappableComponent and SwappableComponentBlueprint
|
|
39
|
+
import {
|
|
40
|
+
createSwappableComponent,
|
|
41
|
+
SwappableComponentBlueprint,
|
|
42
|
+
} from '@backstage/frontend-plugin-api';
|
|
43
|
+
|
|
44
|
+
const MySwappableComponent = createSwappableComponent({
|
|
45
|
+
id: 'my-plugin.my-component',
|
|
46
|
+
loader: () => import('./MyComponent').then(m => m.MyComponent),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const myComponentExtension = SwappableComponentBlueprint.make({
|
|
50
|
+
name: 'my-component',
|
|
51
|
+
params: {
|
|
52
|
+
component: MySwappableComponent,
|
|
53
|
+
loader: () => import('./MyComponent').then(m => m.MyComponent),
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Migration for using components:**
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
// OLD: Using ComponentsApi and useComponentRef
|
|
62
|
+
import {
|
|
63
|
+
useComponentRef,
|
|
64
|
+
componentsApiRef,
|
|
65
|
+
useApi,
|
|
66
|
+
coreComponentRefs,
|
|
67
|
+
} from '@backstage/frontend-plugin-api';
|
|
68
|
+
|
|
69
|
+
const MyComponent = useComponentRef(myComponentRef);
|
|
70
|
+
const ProgressComponent = useComponentRef(coreComponentRefs.progress);
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
// NEW: Direct component usage
|
|
74
|
+
import { Progress } from '@backstage/frontend-plugin-api';
|
|
75
|
+
|
|
76
|
+
// Use directly as React Component
|
|
77
|
+
<Progress />
|
|
78
|
+
<MySwappableComponent title="Hello World" />
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Migration for core component references:**
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
// OLD: Core component refs
|
|
85
|
+
import { coreComponentRefs } from '@backstage/frontend-plugin-api';
|
|
86
|
+
|
|
87
|
+
coreComponentRefs.progress
|
|
88
|
+
coreComponentRefs.notFoundErrorPage
|
|
89
|
+
coreComponentRefs.errorBoundaryFallback
|
|
90
|
+
|
|
91
|
+
// NEW: Direct swappable component imports
|
|
92
|
+
import { Progress, NotFoundErrorPage, ErrorDisplay } from '@backstage/frontend-plugin-api';
|
|
93
|
+
|
|
94
|
+
// Use directly as React components
|
|
95
|
+
<Progress />
|
|
96
|
+
<NotFoundErrorPage />
|
|
97
|
+
<ErrorDisplay plugin={plugin} error={error} resetError={resetError} />
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- 6a75e00: **BREAKING**: Removed the deprecated `createFrontendPlugin` variant where the plugin ID is passed via an `id` option. To update existing code, switch to using the `pluginId` option instead.
|
|
101
|
+
- 1e6410b: **BREAKING**: The `ResolveInputValueOverrides` type is no longer exported.
|
|
102
|
+
|
|
103
|
+
### Patch Changes
|
|
104
|
+
|
|
105
|
+
- 9831f4e: Adjusted the dialog API types to have more sensible defaults
|
|
106
|
+
- 1c2cc37: Improved runtime error message clarity when extension factories don't return an iterable object.
|
|
107
|
+
- 24558f0: Added inline documentation for `createExtension`, `createExtensionBlueprint`, `createFrontendPlugin`, and `createFrontendModule`.
|
|
108
|
+
- Updated dependencies
|
|
109
|
+
- @backstage/core-components@0.17.5-next.2
|
|
110
|
+
|
|
3
111
|
## 0.11.0-next.1
|
|
4
112
|
|
|
5
113
|
### Minor Changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useApi } from '@backstage/core-plugin-api';
|
|
2
2
|
import { useAnalyticsContext } from './AnalyticsContext.esm.js';
|
|
3
3
|
import '../apis/definitions/AppTreeApi.esm.js';
|
|
4
|
-
import '../apis/definitions/
|
|
4
|
+
import '../apis/definitions/SwappableComponentsApi.esm.js';
|
|
5
5
|
import '../apis/definitions/IconsApi.esm.js';
|
|
6
6
|
import '../apis/definitions/DialogApi.esm.js';
|
|
7
7
|
import '../apis/definitions/RouteResolutionApi.esm.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppTreeApi.esm.js","sources":["../../../src/apis/definitions/AppTreeApi.ts"],"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 { createApiRef } from '@backstage/core-plugin-api';\nimport {\n FrontendPlugin,\n Extension,\n ExtensionDataRef,\n ExtensionAttachToSpec,\n} from '../../wiring';\n\n/**\n * The specification for this {@link AppNode} in the {@link AppTree}.\n *\n * @public\n * @remarks\n *\n * The specifications for a collection of app nodes is all the information needed\n * to build the tree and instantiate the nodes.\n */\nexport interface AppNodeSpec {\n readonly id: string;\n readonly attachTo: ExtensionAttachToSpec;\n readonly extension: Extension<unknown, unknown>;\n readonly disabled: boolean;\n readonly config?: unknown;\n readonly plugin
|
|
1
|
+
{"version":3,"file":"AppTreeApi.esm.js","sources":["../../../src/apis/definitions/AppTreeApi.ts"],"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 { createApiRef } from '@backstage/core-plugin-api';\nimport {\n FrontendPlugin,\n Extension,\n ExtensionDataRef,\n ExtensionAttachToSpec,\n} from '../../wiring';\n\n/**\n * The specification for this {@link AppNode} in the {@link AppTree}.\n *\n * @public\n * @remarks\n *\n * The specifications for a collection of app nodes is all the information needed\n * to build the tree and instantiate the nodes.\n */\nexport interface AppNodeSpec {\n readonly id: string;\n readonly attachTo: ExtensionAttachToSpec;\n readonly extension: Extension<unknown, unknown>;\n readonly disabled: boolean;\n readonly config?: unknown;\n readonly plugin: FrontendPlugin;\n}\n\n/**\n * The connections from this {@link AppNode} to other nodes.\n *\n * @public\n * @remarks\n *\n * The app node edges are resolved based on the app node specs, regardless of whether\n * adjacent nodes are disabled or not. If no parent attachment is present or\n */\nexport interface AppNodeEdges {\n readonly attachedTo?: { node: AppNode; input: string };\n readonly attachments: ReadonlyMap<string, AppNode[]>;\n}\n\n/**\n * The instance of this {@link AppNode} in the {@link AppTree}.\n *\n * @public\n * @remarks\n *\n * The app node instance is created when the `factory` function of an extension is called.\n * Instances will only be present for nodes in the app that are connected to the root\n * node and not disabled\n */\nexport interface AppNodeInstance {\n /** Returns a sequence of all extension data refs that were output by this instance */\n getDataRefs(): Iterable<ExtensionDataRef<unknown>>;\n /** Get the output data for a single extension data ref */\n getData<T>(ref: ExtensionDataRef<T>): T | undefined;\n}\n\n/**\n * A node in the {@link AppTree}.\n *\n * @public\n */\nexport interface AppNode {\n /** The specification for how this node should be instantiated */\n readonly spec: AppNodeSpec;\n /** The edges from this node to other nodes in the app tree */\n readonly edges: AppNodeEdges;\n /** The instance of this node, if it was instantiated */\n readonly instance?: AppNodeInstance;\n}\n\n/**\n * The app tree containing all {@link AppNode}s of the app.\n *\n * @public\n */\nexport interface AppTree {\n /** The root node of the app */\n readonly root: AppNode;\n /** A map of all nodes in the app by ID, including orphaned or disabled nodes */\n readonly nodes: ReadonlyMap<string /* id */, AppNode>;\n /** A sequence of all nodes with a parent that is not reachable from the app root node */\n readonly orphans: Iterable<AppNode>;\n}\n\n/**\n * The API for interacting with the {@link AppTree}.\n *\n * @public\n */\nexport interface AppTreeApi {\n /**\n * Get the {@link AppTree} for the app.\n */\n getTree(): { tree: AppTree };\n\n /**\n * Get all nodes in the app that are mounted at a given route path.\n */\n getNodesByRoutePath(routePath: string): { nodes: AppNode[] };\n}\n\n/**\n * The `ApiRef` of {@link AppTreeApi}.\n *\n * @public\n */\nexport const appTreeApiRef = createApiRef<AppTreeApi>({ id: 'core.app-tree' });\n"],"names":[],"mappings":";;AA2HO,MAAM,aAAgB,GAAA,YAAA,CAAyB,EAAE,EAAA,EAAI,iBAAiB;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogApi.esm.js","sources":["../../../src/apis/definitions/DialogApi.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 { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * A handle for an open dialog that can be used to interact with it.\n *\n * @remarks\n *\n * Dialogs can be opened using either {@link DialogApi.show} or {@link DialogApi.showModal}.\n *\n * @public\n */\nexport interface DialogApiDialog<TResult =
|
|
1
|
+
{"version":3,"file":"DialogApi.esm.js","sources":["../../../src/apis/definitions/DialogApi.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 { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * A handle for an open dialog that can be used to interact with it.\n *\n * @remarks\n *\n * Dialogs can be opened using either {@link DialogApi.show} or {@link DialogApi.showModal}.\n *\n * @public\n */\nexport interface DialogApiDialog<TResult = void> {\n /**\n * Closes the dialog with that provided result.\n *\n * @remarks\n *\n * If the dialog is a modal dialog a result must always be provided. If it's a regular dialog then passing a result is optional.\n */\n close(\n ...args: undefined extends TResult ? [result?: TResult] : [result: TResult]\n ): void;\n\n /**\n * Replaces the content of the dialog with the provided element or component, causing it to be rerenedered.\n */\n update(\n elementOrComponent:\n | React.JSX.Element\n | ((props: { dialog: DialogApiDialog<TResult> }) => JSX.Element),\n ): void;\n\n /**\n * Wait until the dialog is closed and return the result.\n *\n * @remarks\n *\n * If the dialog is a modal dialog a result will always be returned. If it's a regular dialog then the result may be `undefined`.\n */\n result(): Promise<TResult>;\n}\n\n/**\n * A Utility API for showing dialogs that render in the React tree and return a result.\n *\n * @public\n */\nexport interface DialogApi {\n /**\n * Opens a modal dialog and returns a handle to it.\n *\n * @remarks\n *\n * This dialog can be closed by calling the `close` method on the returned handle, optionally providing a result.\n * The dialog can also be closed by the user by clicking the backdrop or pressing the escape key.\n *\n * If the dialog is closed without a result, the result will be `undefined`.\n *\n * @example\n *\n * ### Example with inline dialog content\n * ```tsx\n * const dialog = dialogApi.show<boolean>(\n * <DialogContent>\n * <DialogTitle>Are you sure?</DialogTitle>\n * <DialogActions>\n * <Button onClick={() => dialog.close(true)}>Yes</Button>\n * <Button onClick={() => dialog.close(false)}>No</Button>\n * </DialogActions>\n * </DialogContent>\n * );\n * const result = await dialog.result();\n * ```\n *\n * @example\n *\n * ### Example with separate dialog component\n * ```tsx\n * function CustomDialog({ dialog }: { dialog: DialogApiDialog<boolean | undefined> }) {\n * return (\n * <DialogContent>\n * <DialogTitle>Are you sure?</DialogTitle>\n * <DialogActions>\n * <Button onClick={() => dialog.close(true)}>Yes</Button>\n * <Button onClick={() => dialog.close(false)}>No</Button>\n * </DialogActions>\n * </DialogContent>\n * )\n * }\n * const result = await dialogApi.show(CustomDialog).result();\n * ```\n *\n * @param elementOrComponent - The element or component to render in the dialog. If a component is provided, it will be provided with a `dialog` prop that contains the dialog handle.\n * @public\n */\n show<TResult = void>(\n elementOrComponent:\n | JSX.Element\n | ((props: {\n dialog: DialogApiDialog<TResult | undefined>;\n }) => JSX.Element),\n ): DialogApiDialog<TResult | undefined>;\n\n /**\n * Opens a modal dialog and returns a handle to it.\n *\n * @remarks\n *\n * This dialog can not be closed in any other way than calling the `close` method on the returned handle and providing a result.\n *\n * @example\n *\n * ### Example with inline dialog content\n * ```tsx\n * const dialog = dialogApi.showModal<boolean>(\n * <DialogContent>\n * <DialogTitle>Are you sure?</DialogTitle>\n * <DialogActions>\n * <Button onClick={() => dialog.close(true)}>Yes</Button>\n * <Button onClick={() => dialog.close(false)}>No</Button>\n * </DialogActions>\n * </DialogContent>\n * );\n * const result = await dialog.result();\n * ```\n *\n * @example\n *\n * ### Example with separate dialog component\n * ```tsx\n * function CustomDialog({ dialog }: { dialog: DialogApiDialog<boolean> }) {\n * return (\n * <DialogContent>\n * <DialogTitle>Are you sure?</DialogTitle>\n * <DialogActions>\n * <Button onClick={() => dialog.close(true)}>Yes</Button>\n * <Button onClick={() => dialog.close(false)}>No</Button>\n * </DialogActions>\n * </DialogContent>\n * )\n * }\n * const result = await dialogApi.showModal(CustomDialog).result();\n * ```\n *\n * @param elementOrComponent - The element or component to render in the dialog. If a component is provided, it will be provided with a `dialog` prop that contains the dialog handle.\n * @public\n */\n showModal<TResult = void>(\n elementOrComponent:\n | JSX.Element\n | ((props: { dialog: DialogApiDialog<TResult> }) => JSX.Element),\n ): DialogApiDialog<TResult>;\n}\n\n/**\n * The `ApiRef` of {@link DialogApi}.\n *\n * @public\n */\nexport const dialogApiRef = createApiRef<DialogApi>({\n id: 'core.dialog',\n});\n"],"names":[],"mappings":";;AA+KO,MAAM,eAAe,YAAwB,CAAA;AAAA,EAClD,EAAI,EAAA;AACN,CAAC;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwappableComponentsApi.esm.js","sources":["../../../src/apis/definitions/SwappableComponentsApi.ts"],"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 { SwappableComponentRef } from '../../components';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * API for looking up components based on component refs.\n *\n * @public\n */\nexport interface SwappableComponentsApi {\n getComponent<\n TInnerComponentProps extends {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n >(\n ref: SwappableComponentRef<TInnerComponentProps, TExternalComponentProps>,\n ): (props: TInnerComponentProps) => JSX.Element | null;\n}\n\n/**\n * The `ApiRef` of {@link SwappableComponentsApi}.\n *\n * @public\n */\nexport const swappableComponentsApiRef = createApiRef<SwappableComponentsApi>({\n id: 'core.swappable-components',\n});\n"],"names":[],"mappings":";;AAsCO,MAAM,4BAA4B,YAAqC,CAAA;AAAA,EAC5E,EAAI,EAAA;AACN,CAAC;;;;"}
|
|
@@ -3,7 +3,17 @@ import 'zod';
|
|
|
3
3
|
import 'zod-to-json-schema';
|
|
4
4
|
import { createExtensionBlueprint } from '../wiring/createExtensionBlueprint.esm.js';
|
|
5
5
|
import { ExtensionBoundary } from '../components/ExtensionBoundary.esm.js';
|
|
6
|
+
import 'react/jsx-runtime';
|
|
7
|
+
import '../apis/definitions/AppTreeApi.esm.js';
|
|
8
|
+
import '@backstage/core-plugin-api';
|
|
9
|
+
import '../apis/definitions/SwappableComponentsApi.esm.js';
|
|
10
|
+
import '../apis/definitions/IconsApi.esm.js';
|
|
11
|
+
import '../apis/definitions/DialogApi.esm.js';
|
|
12
|
+
import '../apis/definitions/RouteResolutionApi.esm.js';
|
|
13
|
+
import '../apis/definitions/AnalyticsApi.esm.js';
|
|
14
|
+
import 'react';
|
|
6
15
|
import '../components/AppNodeProvider.esm.js';
|
|
16
|
+
import '../components/DefaultSwappableComponents.esm.js';
|
|
7
17
|
|
|
8
18
|
const PageBlueprint = createExtensionBlueprint({
|
|
9
19
|
kind: "page",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageBlueprint.esm.js","sources":["../../src/blueprints/PageBlueprint.tsx"],"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 { RouteRef } from '../routing';\nimport { coreExtensionData, createExtensionBlueprint } from '../wiring';\nimport { ExtensionBoundary } from '../components';\n\n/**\n * Createx extensions that are routable React page components.\n *\n * @public\n */\nexport const PageBlueprint = createExtensionBlueprint({\n kind: 'page',\n attachTo: { id: 'app/routes', input: 'routes' },\n output: [\n coreExtensionData.routePath,\n coreExtensionData.reactElement,\n coreExtensionData.routeRef.optional(),\n ],\n config: {\n schema: {\n path: z => z.string().optional(),\n },\n },\n *factory(\n params: {\n /**\n * @deprecated Use the `path` param instead.\n */\n defaultPath?: [Error: `Use the 'path' param instead`];\n path: string;\n loader: () => Promise<JSX.Element>;\n routeRef?: RouteRef;\n },\n { config, node },\n ) {\n yield coreExtensionData.routePath(config.path ?? params.path);\n yield coreExtensionData.reactElement(\n ExtensionBoundary.lazy(node, params.loader),\n );\n if (params.routeRef) {\n yield coreExtensionData.routeRef(params.routeRef);\n }\n },\n});\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PageBlueprint.esm.js","sources":["../../src/blueprints/PageBlueprint.tsx"],"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 { RouteRef } from '../routing';\nimport { coreExtensionData, createExtensionBlueprint } from '../wiring';\nimport { ExtensionBoundary } from '../components';\n\n/**\n * Createx extensions that are routable React page components.\n *\n * @public\n */\nexport const PageBlueprint = createExtensionBlueprint({\n kind: 'page',\n attachTo: { id: 'app/routes', input: 'routes' },\n output: [\n coreExtensionData.routePath,\n coreExtensionData.reactElement,\n coreExtensionData.routeRef.optional(),\n ],\n config: {\n schema: {\n path: z => z.string().optional(),\n },\n },\n *factory(\n params: {\n /**\n * @deprecated Use the `path` param instead.\n */\n defaultPath?: [Error: `Use the 'path' param instead`];\n path: string;\n loader: () => Promise<JSX.Element>;\n routeRef?: RouteRef;\n },\n { config, node },\n ) {\n yield coreExtensionData.routePath(config.path ?? params.path);\n yield coreExtensionData.reactElement(\n ExtensionBoundary.lazy(node, params.loader),\n );\n if (params.routeRef) {\n yield coreExtensionData.routeRef(params.routeRef);\n }\n },\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAyBO,MAAM,gBAAgB,wBAAyB,CAAA;AAAA,EACpD,IAAM,EAAA,MAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,YAAA,EAAc,OAAO,QAAS,EAAA;AAAA,EAC9C,MAAQ,EAAA;AAAA,IACN,iBAAkB,CAAA,SAAA;AAAA,IAClB,iBAAkB,CAAA,YAAA;AAAA,IAClB,iBAAA,CAAkB,SAAS,QAAS;AAAA,GACtC;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,IAAM,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS;AAAA;AACjC,GACF;AAAA,EACA,CAAC,OACC,CAAA,MAAA,EASA,EAAE,MAAA,EAAQ,MACV,EAAA;AACA,IAAA,MAAM,iBAAkB,CAAA,SAAA,CAAU,MAAO,CAAA,IAAA,IAAQ,OAAO,IAAI,CAAA;AAC5D,IAAA,MAAM,iBAAkB,CAAA,YAAA;AAAA,MACtB,iBAAkB,CAAA,IAAA,CAAK,IAAM,EAAA,MAAA,CAAO,MAAM;AAAA,KAC5C;AACA,IAAA,IAAI,OAAO,QAAU,EAAA;AACnB,MAAM,MAAA,iBAAA,CAAkB,QAAS,CAAA,MAAA,CAAO,QAAQ,CAAA;AAAA;AAClD;AAEJ,CAAC;;;;"}
|
|
@@ -6,7 +6,15 @@ import 'zod-to-json-schema';
|
|
|
6
6
|
import { createExtensionDataRef } from '../wiring/createExtensionDataRef.esm.js';
|
|
7
7
|
import { createExtensionBlueprint } from '../wiring/createExtensionBlueprint.esm.js';
|
|
8
8
|
import { ExtensionBoundary } from '../components/ExtensionBoundary.esm.js';
|
|
9
|
+
import '../apis/definitions/AppTreeApi.esm.js';
|
|
10
|
+
import '@backstage/core-plugin-api';
|
|
11
|
+
import '../apis/definitions/SwappableComponentsApi.esm.js';
|
|
12
|
+
import '../apis/definitions/IconsApi.esm.js';
|
|
13
|
+
import '../apis/definitions/DialogApi.esm.js';
|
|
14
|
+
import '../apis/definitions/RouteResolutionApi.esm.js';
|
|
15
|
+
import '../apis/definitions/AnalyticsApi.esm.js';
|
|
9
16
|
import '../components/AppNodeProvider.esm.js';
|
|
17
|
+
import '../components/DefaultSwappableComponents.esm.js';
|
|
10
18
|
|
|
11
19
|
const componentDataRef = createExtensionDataRef().with({ id: "core.sign-in-page.component" });
|
|
12
20
|
const SignInPageBlueprint = createExtensionBlueprint({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignInPageBlueprint.esm.js","sources":["../../src/blueprints/SignInPageBlueprint.tsx"],"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 { ComponentType, lazy } from 'react';\nimport { createExtensionBlueprint, createExtensionDataRef } from '../wiring';\nimport { SignInPageProps } from '@backstage/core-plugin-api';\nimport { ExtensionBoundary } from '../components';\n\nconst componentDataRef = createExtensionDataRef<\n ComponentType<SignInPageProps>\n>().with({ id: 'core.sign-in-page.component' });\n\n/**\n * Creates an extension that replaces the sign in page.\n *\n * @public\n */\nexport const SignInPageBlueprint = createExtensionBlueprint({\n kind: 'sign-in-page',\n attachTo: { id: 'app/root', input: 'signInPage' },\n output: [componentDataRef],\n dataRefs: {\n component: componentDataRef,\n },\n *factory(\n {\n loader,\n }: {\n loader: () => Promise<ComponentType<SignInPageProps>>;\n },\n { node },\n ) {\n const ExtensionComponent = lazy(() =>\n loader().then(component => ({ default: component })),\n );\n\n yield componentDataRef(props => (\n <ExtensionBoundary node={node}>\n <ExtensionComponent {...props} />\n </ExtensionBoundary>\n ));\n },\n});\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SignInPageBlueprint.esm.js","sources":["../../src/blueprints/SignInPageBlueprint.tsx"],"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 { ComponentType, lazy } from 'react';\nimport { createExtensionBlueprint, createExtensionDataRef } from '../wiring';\nimport { SignInPageProps } from '@backstage/core-plugin-api';\nimport { ExtensionBoundary } from '../components';\n\nconst componentDataRef = createExtensionDataRef<\n ComponentType<SignInPageProps>\n>().with({ id: 'core.sign-in-page.component' });\n\n/**\n * Creates an extension that replaces the sign in page.\n *\n * @public\n */\nexport const SignInPageBlueprint = createExtensionBlueprint({\n kind: 'sign-in-page',\n attachTo: { id: 'app/root', input: 'signInPage' },\n output: [componentDataRef],\n dataRefs: {\n component: componentDataRef,\n },\n *factory(\n {\n loader,\n }: {\n loader: () => Promise<ComponentType<SignInPageProps>>;\n },\n { node },\n ) {\n const ExtensionComponent = lazy(() =>\n loader().then(component => ({ default: component })),\n );\n\n yield componentDataRef(props => (\n <ExtensionBoundary node={node}>\n <ExtensionComponent {...props} />\n </ExtensionBoundary>\n ));\n },\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,mBAAmB,sBAEvB,EAAA,CAAE,KAAK,EAAE,EAAA,EAAI,+BAA+B,CAAA;AAOvC,MAAM,sBAAsB,wBAAyB,CAAA;AAAA,EAC1D,IAAM,EAAA,cAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,UAAA,EAAY,OAAO,YAAa,EAAA;AAAA,EAChD,MAAA,EAAQ,CAAC,gBAAgB,CAAA;AAAA,EACzB,QAAU,EAAA;AAAA,IACR,SAAW,EAAA;AAAA,GACb;AAAA,EACA,CAAC,OACC,CAAA;AAAA,IACE;AAAA,GACF,EAGA,EAAE,IAAA,EACF,EAAA;AACA,IAAA,MAAM,kBAAqB,GAAA,IAAA;AAAA,MAAK,MAC9B,QAAS,CAAA,IAAA,CAAK,gBAAc,EAAE,OAAA,EAAS,WAAY,CAAA;AAAA,KACrD;AAEA,IAAM,MAAA,gBAAA,CAAiB,CACrB,KAAA,qBAAA,GAAA,CAAC,iBAAkB,EAAA,EAAA,IAAA,EACjB,8BAAC,kBAAoB,EAAA,EAAA,GAAG,KAAO,EAAA,CAAA,EACjC,CACD,CAAA;AAAA;AAEL,CAAC;;;;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import '../wiring/coreExtensionData.esm.js';
|
|
2
|
+
import 'zod';
|
|
3
|
+
import 'zod-to-json-schema';
|
|
4
|
+
import { createExtensionDataRef } from '../wiring/createExtensionDataRef.esm.js';
|
|
5
|
+
import { createExtensionBlueprint, createExtensionBlueprintParams } from '../wiring/createExtensionBlueprint.esm.js';
|
|
6
|
+
|
|
7
|
+
const componentDataRef = createExtensionDataRef().with({ id: "core.swappableComponent" });
|
|
8
|
+
const SwappableComponentBlueprint = createExtensionBlueprint({
|
|
9
|
+
kind: "component",
|
|
10
|
+
attachTo: { id: "api:app/swappable-components", input: "components" },
|
|
11
|
+
output: [componentDataRef],
|
|
12
|
+
dataRefs: {
|
|
13
|
+
component: componentDataRef
|
|
14
|
+
},
|
|
15
|
+
defineParams(params) {
|
|
16
|
+
return createExtensionBlueprintParams(params);
|
|
17
|
+
},
|
|
18
|
+
factory: (params) => [
|
|
19
|
+
componentDataRef({
|
|
20
|
+
ref: params.component.ref,
|
|
21
|
+
loader: params.loader
|
|
22
|
+
})
|
|
23
|
+
]
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export { SwappableComponentBlueprint, componentDataRef };
|
|
27
|
+
//# sourceMappingURL=SwappableComponentBlueprint.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwappableComponentBlueprint.esm.js","sources":["../../src/blueprints/SwappableComponentBlueprint.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 */\nimport { SwappableComponentRef } from '../components';\nimport {\n createExtensionBlueprint,\n createExtensionBlueprintParams,\n createExtensionDataRef,\n} from '../wiring';\n\nexport const componentDataRef = createExtensionDataRef<{\n ref: SwappableComponentRef;\n loader:\n | (() => (props: {}) => JSX.Element | null)\n | (() => Promise<(props: {}) => JSX.Element | null>);\n}>().with({ id: 'core.swappableComponent' });\n\n/**\n * Blueprint for creating swappable components from a SwappableComponentRef and a loader\n *\n * @public\n */\nexport const SwappableComponentBlueprint = createExtensionBlueprint({\n kind: 'component',\n attachTo: { id: 'api:app/swappable-components', input: 'components' },\n output: [componentDataRef],\n dataRefs: {\n component: componentDataRef,\n },\n defineParams<Ref extends SwappableComponentRef<any>>(params: {\n component: Ref extends SwappableComponentRef<\n any,\n infer IExternalComponentProps\n >\n ? { ref: Ref } & ((props: IExternalComponentProps) => JSX.Element | null)\n : never;\n loader: Ref extends SwappableComponentRef<infer IInnerComponentProps, any>\n ?\n | (() => (props: IInnerComponentProps) => JSX.Element | null)\n | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>)\n : never;\n }) {\n return createExtensionBlueprintParams(params);\n },\n factory: params => [\n componentDataRef({\n ref: params.component.ref,\n loader: params.loader,\n }),\n ],\n});\n"],"names":[],"mappings":";;;;;;AAsBO,MAAM,mBAAmB,sBAK7B,EAAA,CAAE,KAAK,EAAE,EAAA,EAAI,2BAA2B;AAOpC,MAAM,8BAA8B,wBAAyB,CAAA;AAAA,EAClE,IAAM,EAAA,WAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,8BAAA,EAAgC,OAAO,YAAa,EAAA;AAAA,EACpE,MAAA,EAAQ,CAAC,gBAAgB,CAAA;AAAA,EACzB,QAAU,EAAA;AAAA,IACR,SAAW,EAAA;AAAA,GACb;AAAA,EACA,aAAqD,MAYlD,EAAA;AACD,IAAA,OAAO,+BAA+B,MAAM,CAAA;AAAA,GAC9C;AAAA,EACA,SAAS,CAAU,MAAA,KAAA;AAAA,IACjB,gBAAiB,CAAA;AAAA,MACf,GAAA,EAAK,OAAO,SAAU,CAAA,GAAA;AAAA,MACtB,QAAQ,MAAO,CAAA;AAAA,KAChB;AAAA;AAEL,CAAC;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { createSwappableComponent } from './createSwappableComponent.esm.js';
|
|
3
|
+
|
|
4
|
+
const Progress = createSwappableComponent({
|
|
5
|
+
id: "core-progress"
|
|
6
|
+
});
|
|
7
|
+
const NotFoundErrorPage = createSwappableComponent({
|
|
8
|
+
id: "core-not-found-error-page"
|
|
9
|
+
});
|
|
10
|
+
const ErrorDisplay = createSwappableComponent({
|
|
11
|
+
id: "core-error-display",
|
|
12
|
+
loader: () => (props) => /* @__PURE__ */ jsx("div", { "data-testid": "core-error-display", children: props.error.message })
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export { ErrorDisplay, NotFoundErrorPage, Progress };
|
|
16
|
+
//# sourceMappingURL=DefaultSwappableComponents.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DefaultSwappableComponents.esm.js","sources":["../../src/components/DefaultSwappableComponents.tsx"],"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 ErrorDisplayProps,\n NotFoundErrorPageProps,\n ProgressProps,\n} from '../types';\nimport { createSwappableComponent } from './createSwappableComponent';\n\n/**\n * @public\n */\nexport const Progress = createSwappableComponent<ProgressProps>({\n id: 'core-progress',\n});\n\n/**\n * @public\n */\nexport const NotFoundErrorPage =\n createSwappableComponent<NotFoundErrorPageProps>({\n id: 'core-not-found-error-page',\n });\n\n/**\n * @public\n */\nexport const ErrorDisplay = createSwappableComponent<ErrorDisplayProps>({\n id: 'core-error-display',\n loader: () => props =>\n <div data-testid=\"core-error-display\">{props.error.message}</div>,\n});\n"],"names":[],"mappings":";;;AA0BO,MAAM,WAAW,wBAAwC,CAAA;AAAA,EAC9D,EAAI,EAAA;AACN,CAAC;AAKM,MAAM,oBACX,wBAAiD,CAAA;AAAA,EAC/C,EAAI,EAAA;AACN,CAAC;AAKI,MAAM,eAAe,wBAA4C,CAAA;AAAA,EACtE,EAAI,EAAA,oBAAA;AAAA,EACJ,MAAA,EAAQ,MAAM,CACZ,KAAA,qBAAA,GAAA,CAAC,SAAI,aAAY,EAAA,oBAAA,EAAsB,QAAM,EAAA,KAAA,CAAA,KAAA,CAAM,OAAQ,EAAA;AAC/D,CAAC;;;;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { Component } from 'react';
|
|
3
|
+
import { ErrorDisplay } from './DefaultSwappableComponents.esm.js';
|
|
3
4
|
|
|
4
5
|
class ErrorBoundary extends Component {
|
|
5
6
|
static getDerivedStateFromError(error) {
|
|
@@ -11,10 +12,10 @@ class ErrorBoundary extends Component {
|
|
|
11
12
|
};
|
|
12
13
|
render() {
|
|
13
14
|
const { error } = this.state;
|
|
14
|
-
const { plugin, children
|
|
15
|
+
const { plugin, children } = this.props;
|
|
15
16
|
if (error) {
|
|
16
17
|
return /* @__PURE__ */ jsx(
|
|
17
|
-
|
|
18
|
+
ErrorDisplay,
|
|
18
19
|
{
|
|
19
20
|
plugin,
|
|
20
21
|
error,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorBoundary.esm.js","sources":["../../src/components/ErrorBoundary.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 { Component,
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.esm.js","sources":["../../src/components/ErrorBoundary.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 { Component, PropsWithChildren } from 'react';\nimport { FrontendPlugin } from '../wiring';\nimport { ErrorDisplay } from './DefaultSwappableComponents';\n\ntype ErrorBoundaryProps = PropsWithChildren<{\n plugin?: FrontendPlugin;\n}>;\ntype ErrorBoundaryState = { error?: Error };\n\n/** @internal */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n state: ErrorBoundaryState = { error: undefined };\n\n handleErrorReset = () => {\n this.setState({ error: undefined });\n };\n\n render() {\n const { error } = this.state;\n const { plugin, children } = this.props;\n\n if (error) {\n return (\n <ErrorDisplay\n // todo: do we want to just use useAppNode hook in the ErrorDisplay instead?\n plugin={plugin}\n error={error}\n // todo: probably change this to onResetError\n resetError={this.handleErrorReset}\n />\n );\n }\n\n return children;\n }\n}\n"],"names":[],"mappings":";;;;AA0BO,MAAM,sBAAsB,SAGjC,CAAA;AAAA,EACA,OAAO,yBAAyB,KAAc,EAAA;AAC5C,IAAA,OAAO,EAAE,KAAM,EAAA;AAAA;AACjB,EAEA,KAAA,GAA4B,EAAE,KAAA,EAAO,KAAU,CAAA,EAAA;AAAA,EAE/C,mBAAmB,MAAM;AACvB,IAAA,IAAA,CAAK,QAAS,CAAA,EAAE,KAAO,EAAA,KAAA,CAAA,EAAW,CAAA;AAAA,GACpC;AAAA,EAEA,MAAS,GAAA;AACP,IAAM,MAAA,EAAE,KAAM,EAAA,GAAI,IAAK,CAAA,KAAA;AACvB,IAAA,MAAM,EAAE,MAAA,EAAQ,QAAS,EAAA,GAAI,IAAK,CAAA,KAAA;AAElC,IAAA,IAAI,KAAO,EAAA;AACT,MACE,uBAAA,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UAEC,MAAA;AAAA,UACA,KAAA;AAAA,UAEA,YAAY,IAAK,CAAA;AAAA;AAAA,OACnB;AAAA;AAIJ,IAAO,OAAA,QAAA;AAAA;AAEX;;;;"}
|
|
@@ -3,18 +3,12 @@ import { Suspense, lazy, useEffect } from 'react';
|
|
|
3
3
|
import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';
|
|
4
4
|
import { ErrorBoundary } from './ErrorBoundary.esm.js';
|
|
5
5
|
import { routableExtensionRenderedEvent } from '../core-plugin-api/src/analytics/Tracker.esm.js';
|
|
6
|
-
import '../apis/definitions/AppTreeApi.esm.js';
|
|
7
|
-
import { useComponentRef } from '../apis/definitions/ComponentsApi.esm.js';
|
|
8
|
-
import '../apis/definitions/IconsApi.esm.js';
|
|
9
|
-
import '../apis/definitions/DialogApi.esm.js';
|
|
10
|
-
import '../apis/definitions/RouteResolutionApi.esm.js';
|
|
11
|
-
import '../apis/definitions/AnalyticsApi.esm.js';
|
|
12
|
-
import { coreComponentRefs } from './coreComponentRefs.esm.js';
|
|
13
6
|
import { coreExtensionData } from '../wiring/coreExtensionData.esm.js';
|
|
14
7
|
import 'zod';
|
|
15
8
|
import 'zod-to-json-schema';
|
|
16
9
|
import '../wiring/createExtensionBlueprint.esm.js';
|
|
17
10
|
import { AppNodeProvider } from './AppNodeProvider.esm.js';
|
|
11
|
+
import { Progress } from './DefaultSwappableComponents.esm.js';
|
|
18
12
|
|
|
19
13
|
const RouteTracker = (props) => {
|
|
20
14
|
const { enabled, children } = props;
|
|
@@ -32,13 +26,11 @@ function ExtensionBoundary(props) {
|
|
|
32
26
|
node.instance?.getData(coreExtensionData.routePath)
|
|
33
27
|
);
|
|
34
28
|
const plugin = node.spec.plugin;
|
|
35
|
-
const Progress = useComponentRef(coreComponentRefs.progress);
|
|
36
|
-
const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback);
|
|
37
29
|
const attributes = {
|
|
38
30
|
extensionId: node.spec.id,
|
|
39
31
|
pluginId: node.spec.plugin?.id ?? "app"
|
|
40
32
|
};
|
|
41
|
-
return /* @__PURE__ */ jsx(AppNodeProvider, { node, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Progress, {}), children: /* @__PURE__ */ jsx(ErrorBoundary, { plugin,
|
|
33
|
+
return /* @__PURE__ */ jsx(AppNodeProvider, { node, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Progress, {}), children: /* @__PURE__ */ jsx(ErrorBoundary, { plugin, children: /* @__PURE__ */ jsx(AnalyticsContext, { attributes, children: /* @__PURE__ */ jsx(RouteTracker, { enabled: hasRoutePathOutput, children }) }) }) }) });
|
|
42
34
|
}
|
|
43
35
|
((ExtensionBoundary2) => {
|
|
44
36
|
function lazy$1(appNode, loader) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExtensionBoundary.esm.js","sources":["../../src/components/ExtensionBoundary.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 PropsWithChildren,\n ReactNode,\n Suspense,\n useEffect,\n lazy as reactLazy,\n} from 'react';\nimport { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';\nimport { ErrorBoundary } from './ErrorBoundary';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { routableExtensionRenderedEvent } from '../../../core-plugin-api/src/analytics/Tracker';\nimport { AppNode
|
|
1
|
+
{"version":3,"file":"ExtensionBoundary.esm.js","sources":["../../src/components/ExtensionBoundary.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 PropsWithChildren,\n ReactNode,\n Suspense,\n useEffect,\n lazy as reactLazy,\n} from 'react';\nimport { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';\nimport { ErrorBoundary } from './ErrorBoundary';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { routableExtensionRenderedEvent } from '../../../core-plugin-api/src/analytics/Tracker';\nimport { AppNode } from '../apis';\nimport { coreExtensionData } from '../wiring';\nimport { AppNodeProvider } from './AppNodeProvider';\nimport { Progress } from './DefaultSwappableComponents';\n\ntype RouteTrackerProps = PropsWithChildren<{\n enabled?: boolean;\n}>;\n\nconst RouteTracker = (props: RouteTrackerProps) => {\n const { enabled, children } = props;\n const analytics = useAnalytics();\n\n // This event, never exposed to end-users of the analytics API,\n // helps inform which extension metadata gets associated with a\n // navigation event when the route navigated to is a gathered\n // mountpoint.\n useEffect(() => {\n if (enabled) {\n analytics.captureEvent(routableExtensionRenderedEvent, '');\n }\n }, [analytics, enabled]);\n\n return <>{children}</>;\n};\n\n/** @public */\nexport interface ExtensionBoundaryProps {\n node: AppNode;\n children: ReactNode;\n}\n\n/** @public */\nexport function ExtensionBoundary(props: ExtensionBoundaryProps) {\n const { node, children } = props;\n\n const hasRoutePathOutput = Boolean(\n node.instance?.getData(coreExtensionData.routePath),\n );\n\n const plugin = node.spec.plugin;\n\n // Skipping \"routeRef\" attribute in the new system, the extension \"id\" should provide more insight\n const attributes = {\n extensionId: node.spec.id,\n pluginId: node.spec.plugin?.id ?? 'app',\n };\n\n return (\n <AppNodeProvider node={node}>\n <Suspense fallback={<Progress />}>\n <ErrorBoundary plugin={plugin}>\n <AnalyticsContext attributes={attributes}>\n <RouteTracker enabled={hasRoutePathOutput}>{children}</RouteTracker>\n </AnalyticsContext>\n </ErrorBoundary>\n </Suspense>\n </AppNodeProvider>\n );\n}\n\n/** @public */\nexport namespace ExtensionBoundary {\n export function lazy(\n appNode: AppNode,\n loader: () => Promise<JSX.Element>,\n ): JSX.Element {\n const ExtensionComponent = reactLazy(() =>\n loader().then(element => ({ default: () => element })),\n );\n return (\n <ExtensionBoundary node={appNode}>\n <ExtensionComponent />\n </ExtensionBoundary>\n );\n }\n\n export function lazyComponent<TProps extends {}>(\n appNode: AppNode,\n loader: () => Promise<(props: TProps) => JSX.Element>,\n ): (props: TProps) => JSX.Element {\n const ExtensionComponent = reactLazy(() =>\n loader().then(Component => ({ default: Component })),\n ) as unknown as React.ComponentType<TProps>;\n\n return (props: TProps) => (\n <ExtensionBoundary node={appNode}>\n <ExtensionComponent {...props} />\n </ExtensionBoundary>\n );\n }\n}\n"],"names":["ExtensionBoundary","lazy","reactLazy"],"mappings":";;;;;;;;;;;;AAoCA,MAAM,YAAA,GAAe,CAAC,KAA6B,KAAA;AACjD,EAAM,MAAA,EAAE,OAAS,EAAA,QAAA,EAAa,GAAA,KAAA;AAC9B,EAAA,MAAM,YAAY,YAAa,EAAA;AAM/B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAS,EAAA;AACX,MAAU,SAAA,CAAA,YAAA,CAAa,gCAAgC,EAAE,CAAA;AAAA;AAC3D,GACC,EAAA,CAAC,SAAW,EAAA,OAAO,CAAC,CAAA;AAEvB,EAAA,uCAAU,QAAS,EAAA,CAAA;AACrB,CAAA;AASO,SAAS,kBAAkB,KAA+B,EAAA;AAC/D,EAAM,MAAA,EAAE,IAAM,EAAA,QAAA,EAAa,GAAA,KAAA;AAE3B,EAAA,MAAM,kBAAqB,GAAA,OAAA;AAAA,IACzB,IAAK,CAAA,QAAA,EAAU,OAAQ,CAAA,iBAAA,CAAkB,SAAS;AAAA,GACpD;AAEA,EAAM,MAAA,MAAA,GAAS,KAAK,IAAK,CAAA,MAAA;AAGzB,EAAA,MAAM,UAAa,GAAA;AAAA,IACjB,WAAA,EAAa,KAAK,IAAK,CAAA,EAAA;AAAA,IACvB,QAAU,EAAA,IAAA,CAAK,IAAK,CAAA,MAAA,EAAQ,EAAM,IAAA;AAAA,GACpC;AAEA,EACE,uBAAA,GAAA,CAAC,mBAAgB,IACf,EAAA,QAAA,kBAAA,GAAA,CAAC,YAAS,QAAU,kBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,CAAA,EAC5B,QAAC,kBAAA,GAAA,CAAA,aAAA,EAAA,EAAc,QACb,QAAC,kBAAA,GAAA,CAAA,gBAAA,EAAA,EAAiB,UAChB,EAAA,QAAA,kBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,OAAA,EAAS,oBAAqB,QAAS,EAAA,CAAA,EACvD,CACF,EAAA,CAAA,EACF,CACF,EAAA,CAAA;AAEJ;AAAA,CAGO,CAAUA,kBAAV,KAAA;AACE,EAAS,SAAAC,MAAA,CACd,SACA,MACa,EAAA;AACb,IAAA,MAAM,kBAAqB,GAAAC,IAAA;AAAA,MAAU,MACnC,QAAS,CAAA,IAAA,CAAK,cAAY,EAAE,OAAA,EAAS,MAAM,OAAA,EAAU,CAAA;AAAA,KACvD;AACA,IAAA,2BACGF,kBAAA,EAAA,EAAkB,MAAM,OACvB,EAAA,QAAA,kBAAA,GAAA,CAAC,sBAAmB,CACtB,EAAA,CAAA;AAAA;AAVG,EAAAA,kBAAS,CAAA,IAAA,GAAAC,MAAA;AAcT,EAAS,SAAA,aAAA,CACd,SACA,MACgC,EAAA;AAChC,IAAA,MAAM,kBAAqB,GAAAC,IAAA;AAAA,MAAU,MACnC,QAAS,CAAA,IAAA,CAAK,gBAAc,EAAE,OAAA,EAAS,WAAY,CAAA;AAAA,KACrD;AAEA,IAAO,OAAA,CAAC,KACN,qBAAA,GAAA,CAACF,kBAAA,EAAA,EAAkB,IAAM,EAAA,OAAA,EACvB,QAAC,kBAAA,GAAA,CAAA,kBAAA,EAAA,EAAoB,GAAG,KAAA,EAAO,CACjC,EAAA,CAAA;AAAA;AAXG,EAAAA,kBAAS,CAAA,aAAA,GAAA,aAAA;AAAA,CAfD,EAAA,iBAAA,KAAA,iBAAA,GAAA,EAAA,CAAA,CAAA;;;;"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import '../apis/definitions/AppTreeApi.esm.js';
|
|
3
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
4
|
+
import { swappableComponentsApiRef } from '../apis/definitions/SwappableComponentsApi.esm.js';
|
|
5
|
+
import '../apis/definitions/IconsApi.esm.js';
|
|
6
|
+
import '../apis/definitions/DialogApi.esm.js';
|
|
7
|
+
import '../apis/definitions/RouteResolutionApi.esm.js';
|
|
8
|
+
import '../apis/definitions/AnalyticsApi.esm.js';
|
|
9
|
+
import { lazy } from 'react';
|
|
10
|
+
import { OpaqueSwappableComponentRef } from '../frontend-internal/src/wiring/InternalSwappableComponentRef.esm.js';
|
|
11
|
+
import '../frontend-internal/src/wiring/InternalExtensionDefinition.esm.js';
|
|
12
|
+
import '../frontend-internal/src/wiring/InternalFrontendPlugin.esm.js';
|
|
13
|
+
|
|
14
|
+
const useComponentRefApi = () => {
|
|
15
|
+
try {
|
|
16
|
+
return useApi(swappableComponentsApiRef);
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
function createSwappableComponent(options) {
|
|
22
|
+
const FallbackComponent = (p) => /* @__PURE__ */ jsx("div", { "data-testid": options.id, ...p });
|
|
23
|
+
const ref = OpaqueSwappableComponentRef.createInstance("v1", {
|
|
24
|
+
id: options.id,
|
|
25
|
+
TProps: null,
|
|
26
|
+
TExternalProps: null,
|
|
27
|
+
toString() {
|
|
28
|
+
return `SwappableComponentRef{id=${options.id}}`;
|
|
29
|
+
},
|
|
30
|
+
defaultComponent: lazy(async () => {
|
|
31
|
+
const Component = await options.loader?.() ?? FallbackComponent;
|
|
32
|
+
return { default: Component };
|
|
33
|
+
}),
|
|
34
|
+
transformProps: options.transformProps
|
|
35
|
+
});
|
|
36
|
+
const ComponentRefImpl = (props) => {
|
|
37
|
+
const api = useComponentRefApi();
|
|
38
|
+
if (!api) {
|
|
39
|
+
const internalRef = OpaqueSwappableComponentRef.toInternal(ref);
|
|
40
|
+
const Component2 = internalRef.defaultComponent;
|
|
41
|
+
const innerProps = internalRef.transformProps?.(props) ?? props;
|
|
42
|
+
return /* @__PURE__ */ jsx(Component2, { ...innerProps });
|
|
43
|
+
}
|
|
44
|
+
const Component = api.getComponent(ref);
|
|
45
|
+
return /* @__PURE__ */ jsx(Component, { ...props });
|
|
46
|
+
};
|
|
47
|
+
Object.assign(ComponentRefImpl, { ref });
|
|
48
|
+
return ComponentRefImpl;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { createSwappableComponent };
|
|
52
|
+
//# sourceMappingURL=createSwappableComponent.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createSwappableComponent.esm.js","sources":["../../src/components/createSwappableComponent.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 { OpaqueSwappableComponentRef } from '@internal/frontend';\nimport { swappableComponentsApiRef, useApi } from '../apis';\nimport { lazy } from 'react';\n\n/** @public */\nexport type SwappableComponentRef<\n TInnerComponentProps extends {} = {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n> = {\n id: string;\n TProps: TInnerComponentProps;\n TExternalProps: TExternalComponentProps;\n $$type: '@backstage/SwappableComponentRef';\n};\n\n/**\n * Options for creating an SwappableComponent.\n *\n * @public\n */\nexport type CreateSwappableComponentOptions<\n TInnerComponentProps extends {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n> = {\n id: string;\n loader?:\n | (() => (props: TInnerComponentProps) => JSX.Element | null)\n | (() => Promise<(props: TInnerComponentProps) => JSX.Element | null>);\n transformProps?: (props: TExternalComponentProps) => TInnerComponentProps;\n};\n\nconst useComponentRefApi = () => {\n try {\n return useApi(swappableComponentsApiRef);\n } catch (e) {\n return undefined;\n }\n};\n\n/**\n * Creates a SwappableComponent that can be used to render the component, optionally overridden by the app.\n *\n * @public\n */\nexport function createSwappableComponent<\n TInnerComponentProps extends {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n>(\n options: CreateSwappableComponentOptions<\n TInnerComponentProps,\n TExternalComponentProps\n >,\n): {\n (props: TExternalComponentProps): JSX.Element | null;\n ref: SwappableComponentRef<TInnerComponentProps, TExternalComponentProps>;\n} {\n const FallbackComponent = (p: JSX.IntrinsicAttributes) => (\n <div data-testid={options.id} {...p} />\n );\n\n const ref = OpaqueSwappableComponentRef.createInstance('v1', {\n id: options.id,\n TProps: null as unknown as TInnerComponentProps,\n TExternalProps: null as unknown as TExternalComponentProps,\n toString() {\n return `SwappableComponentRef{id=${options.id}}`;\n },\n defaultComponent: lazy(async () => {\n const Component = (await options.loader?.()) ?? FallbackComponent;\n return { default: Component };\n }) as (typeof OpaqueSwappableComponentRef.TInternal)['defaultComponent'],\n transformProps:\n options.transformProps as (typeof OpaqueSwappableComponentRef.TInternal)['transformProps'],\n });\n\n const ComponentRefImpl = (props: TExternalComponentProps) => {\n const api = useComponentRefApi();\n\n if (!api) {\n const internalRef = OpaqueSwappableComponentRef.toInternal(ref);\n const Component = internalRef.defaultComponent;\n const innerProps = internalRef.transformProps?.(props) ?? props;\n return <Component {...innerProps} />;\n }\n\n const Component = api.getComponent<any>(ref);\n return <Component {...props} />;\n };\n\n Object.assign(ComponentRefImpl, { ref });\n\n return ComponentRefImpl as {\n (props: TExternalComponentProps): JSX.Element | null;\n ref: SwappableComponentRef<TInnerComponentProps, TExternalComponentProps>;\n };\n}\n"],"names":["Component"],"mappings":";;;;;;;;;;;;;AA+CA,MAAM,qBAAqB,MAAM;AAC/B,EAAI,IAAA;AACF,IAAA,OAAO,OAAO,yBAAyB,CAAA;AAAA,WAChC,CAAG,EAAA;AACV,IAAO,OAAA,KAAA,CAAA;AAAA;AAEX,CAAA;AAOO,SAAS,yBAId,OAOA,EAAA;AACA,EAAM,MAAA,iBAAA,GAAoB,CAAC,CACzB,qBAAA,GAAA,CAAC,SAAI,aAAa,EAAA,OAAA,CAAQ,EAAK,EAAA,GAAG,CAAG,EAAA,CAAA;AAGvC,EAAM,MAAA,GAAA,GAAM,2BAA4B,CAAA,cAAA,CAAe,IAAM,EAAA;AAAA,IAC3D,IAAI,OAAQ,CAAA,EAAA;AAAA,IACZ,MAAQ,EAAA,IAAA;AAAA,IACR,cAAgB,EAAA,IAAA;AAAA,IAChB,QAAW,GAAA;AACT,MAAO,OAAA,CAAA,yBAAA,EAA4B,QAAQ,EAAE,CAAA,CAAA,CAAA;AAAA,KAC/C;AAAA,IACA,gBAAA,EAAkB,KAAK,YAAY;AACjC,MAAA,MAAM,SAAa,GAAA,MAAM,OAAQ,CAAA,MAAA,IAAe,IAAA,iBAAA;AAChD,MAAO,OAAA,EAAE,SAAS,SAAU,EAAA;AAAA,KAC7B,CAAA;AAAA,IACD,gBACE,OAAQ,CAAA;AAAA,GACX,CAAA;AAED,EAAM,MAAA,gBAAA,GAAmB,CAAC,KAAmC,KAAA;AAC3D,IAAA,MAAM,MAAM,kBAAmB,EAAA;AAE/B,IAAA,IAAI,CAAC,GAAK,EAAA;AACR,MAAM,MAAA,WAAA,GAAc,2BAA4B,CAAA,UAAA,CAAW,GAAG,CAAA;AAC9D,MAAA,MAAMA,aAAY,WAAY,CAAA,gBAAA;AAC9B,MAAA,MAAM,UAAa,GAAA,WAAA,CAAY,cAAiB,GAAA,KAAK,CAAK,IAAA,KAAA;AAC1D,MAAA,uBAAQA,GAAAA,CAAAA,UAAAA,EAAA,EAAW,GAAG,UAAY,EAAA,CAAA;AAAA;AAGpC,IAAM,MAAA,SAAA,GAAY,GAAI,CAAA,YAAA,CAAkB,GAAG,CAAA;AAC3C,IAAO,uBAAA,GAAA,CAAC,SAAW,EAAA,EAAA,GAAG,KAAO,EAAA,CAAA;AAAA,GAC/B;AAEA,EAAA,MAAA,CAAO,MAAO,CAAA,gBAAA,EAAkB,EAAE,GAAA,EAAK,CAAA;AAEvC,EAAO,OAAA,gBAAA;AAIT;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { OpaqueType } from '../../../opaque-internal/src/OpaqueType.esm.js';
|
|
2
|
+
|
|
3
|
+
const OpaqueSwappableComponentRef = OpaqueType.create({
|
|
4
|
+
versions: ["v1"],
|
|
5
|
+
type: "@backstage/SwappableComponentRef"
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { OpaqueSwappableComponentRef };
|
|
9
|
+
//# sourceMappingURL=InternalSwappableComponentRef.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InternalSwappableComponentRef.esm.js","sources":["../../../../../frontend-internal/src/wiring/InternalSwappableComponentRef.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 { SwappableComponentRef } from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueSwappableComponentRef = OpaqueType.create<{\n public: SwappableComponentRef;\n versions: {\n readonly version: 'v1';\n readonly transformProps?: (props: object) => object;\n readonly defaultComponent: (props: object) => JSX.Element | null;\n };\n}>({\n versions: ['v1'],\n type: '@backstage/SwappableComponentRef',\n});\n"],"names":[],"mappings":";;AAmBa,MAAA,2BAAA,GAA8B,WAAW,MAOnD,CAAA;AAAA,EACD,QAAA,EAAU,CAAC,IAAI,CAAA;AAAA,EACf,IAAM,EAAA;AACR,CAAC;;;;"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
function createExtensionDataContainer(values, declaredRefs) {
|
|
1
|
+
function createExtensionDataContainer(values, contextName, declaredRefs) {
|
|
2
|
+
if (typeof values !== "object" || !values?.[Symbol.iterator]) {
|
|
3
|
+
throw new Error(`${contextName} did not provide an iterable object`);
|
|
4
|
+
}
|
|
2
5
|
const container = /* @__PURE__ */ new Map();
|
|
3
6
|
const verifyRefs = declaredRefs && new Map(declaredRefs.map((ref) => [ref.id, ref]));
|
|
4
7
|
for (const output of values) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createExtensionDataContainer.esm.js","sources":["../../../../../frontend-internal/src/wiring/createExtensionDataContainer.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 {\n ExtensionDataContainer,\n ExtensionDataRef,\n ExtensionDataValue,\n} from '@backstage/frontend-plugin-api';\n\nexport function createExtensionDataContainer<UData extends ExtensionDataRef>(\n values: Iterable<\n UData extends ExtensionDataRef<infer IData, infer IId>\n ? ExtensionDataValue<IData, IId>\n : never\n >,\n declaredRefs?: ExtensionDataRef<any, any, any>[],\n): ExtensionDataContainer<UData> {\n const container = new Map<string, ExtensionDataValue<any, any>>();\n const verifyRefs =\n declaredRefs && new Map(declaredRefs.map(ref => [ref.id, ref]));\n\n for (const output of values) {\n if (verifyRefs) {\n if (!verifyRefs.delete(output.id)) {\n throw new Error(\n `extension data '${output.id}' was provided but not declared`,\n );\n }\n }\n container.set(output.id, output);\n }\n\n const remainingRefs =\n verifyRefs &&\n Array.from(verifyRefs.values()).filter(ref => !ref.config.optional);\n if (remainingRefs && remainingRefs.length > 0) {\n throw new Error(\n `missing required extension data value(s) '${remainingRefs\n .map(ref => ref.id)\n .join(', ')}'`,\n );\n }\n\n return {\n get(ref) {\n return container.get(ref.id)?.value;\n },\n [Symbol.iterator]() {\n return container.values();\n },\n } as ExtensionDataContainer<UData>;\n}\n"],"names":[],"mappings":"AAsBgB,SAAA,4BAAA,CACd,
|
|
1
|
+
{"version":3,"file":"createExtensionDataContainer.esm.js","sources":["../../../../../frontend-internal/src/wiring/createExtensionDataContainer.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 {\n ExtensionDataContainer,\n ExtensionDataRef,\n ExtensionDataValue,\n} from '@backstage/frontend-plugin-api';\n\nexport function createExtensionDataContainer<UData extends ExtensionDataRef>(\n values: Iterable<\n UData extends ExtensionDataRef<infer IData, infer IId>\n ? ExtensionDataValue<IData, IId>\n : never\n >,\n contextName: string,\n declaredRefs?: ExtensionDataRef<any, any, any>[],\n): ExtensionDataContainer<UData> {\n if (typeof values !== 'object' || !values?.[Symbol.iterator]) {\n throw new Error(`${contextName} did not provide an iterable object`);\n }\n\n const container = new Map<string, ExtensionDataValue<any, any>>();\n const verifyRefs =\n declaredRefs && new Map(declaredRefs.map(ref => [ref.id, ref]));\n\n for (const output of values) {\n if (verifyRefs) {\n if (!verifyRefs.delete(output.id)) {\n throw new Error(\n `extension data '${output.id}' was provided but not declared`,\n );\n }\n }\n container.set(output.id, output);\n }\n\n const remainingRefs =\n verifyRefs &&\n Array.from(verifyRefs.values()).filter(ref => !ref.config.optional);\n if (remainingRefs && remainingRefs.length > 0) {\n throw new Error(\n `missing required extension data value(s) '${remainingRefs\n .map(ref => ref.id)\n .join(', ')}'`,\n );\n }\n\n return {\n get(ref) {\n return container.get(ref.id)?.value;\n },\n [Symbol.iterator]() {\n return container.values();\n },\n } as ExtensionDataContainer<UData>;\n}\n"],"names":[],"mappings":"AAsBgB,SAAA,4BAAA,CACd,MAKA,EAAA,WAAA,EACA,YAC+B,EAAA;AAC/B,EAAA,IAAI,OAAO,MAAW,KAAA,QAAA,IAAY,CAAC,MAAS,GAAA,MAAA,CAAO,QAAQ,CAAG,EAAA;AAC5D,IAAA,MAAM,IAAI,KAAA,CAAM,CAAG,EAAA,WAAW,CAAqC,mCAAA,CAAA,CAAA;AAAA;AAGrE,EAAM,MAAA,SAAA,uBAAgB,GAA0C,EAAA;AAChE,EAAA,MAAM,UACJ,GAAA,YAAA,IAAgB,IAAI,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,CAAO,GAAA,KAAA,CAAC,GAAI,CAAA,EAAA,EAAI,GAAG,CAAC,CAAC,CAAA;AAEhE,EAAA,KAAA,MAAW,UAAU,MAAQ,EAAA;AAC3B,IAAA,IAAI,UAAY,EAAA;AACd,MAAA,IAAI,CAAC,UAAA,CAAW,MAAO,CAAA,MAAA,CAAO,EAAE,CAAG,EAAA;AACjC,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,gBAAA,EAAmB,OAAO,EAAE,CAAA,+BAAA;AAAA,SAC9B;AAAA;AACF;AAEF,IAAU,SAAA,CAAA,GAAA,CAAI,MAAO,CAAA,EAAA,EAAI,MAAM,CAAA;AAAA;AAGjC,EAAA,MAAM,aACJ,GAAA,UAAA,IACA,KAAM,CAAA,IAAA,CAAK,UAAW,CAAA,MAAA,EAAQ,CAAA,CAAE,MAAO,CAAA,CAAA,GAAA,KAAO,CAAC,GAAA,CAAI,OAAO,QAAQ,CAAA;AACpE,EAAI,IAAA,aAAA,IAAiB,aAAc,CAAA,MAAA,GAAS,CAAG,EAAA;AAC7C,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,0CAAA,EAA6C,cAC1C,GAAI,CAAA,CAAA,GAAA,KAAO,IAAI,EAAE,CAAA,CACjB,IAAK,CAAA,IAAI,CAAC,CAAA,CAAA;AAAA,KACf;AAAA;AAGF,EAAO,OAAA;AAAA,IACL,IAAI,GAAK,EAAA;AACP,MAAA,OAAO,SAAU,CAAA,GAAA,CAAI,GAAI,CAAA,EAAE,CAAG,EAAA,KAAA;AAAA,KAChC;AAAA,IACA,CAAC,MAAO,CAAA,QAAQ,CAAI,GAAA;AAClB,MAAA,OAAO,UAAU,MAAO,EAAA;AAAA;AAC1B,GACF;AACF;;;;"}
|