@backstage/frontend-plugin-api 0.10.4 → 0.11.0-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 +116 -0
- package/dist/blueprints/ApiBlueprint.esm.js +3 -2
- package/dist/blueprints/ApiBlueprint.esm.js.map +1 -1
- package/dist/blueprints/NavContentBlueprint.esm.js +23 -0
- package/dist/blueprints/NavContentBlueprint.esm.js.map +1 -0
- package/dist/components/ExtensionBoundary.esm.js +1 -0
- package/dist/components/ExtensionBoundary.esm.js.map +1 -1
- package/dist/extensions/createComponentExtension.esm.js +1 -0
- package/dist/extensions/createComponentExtension.esm.js.map +1 -1
- package/dist/index.d.ts +304 -190
- package/dist/index.esm.js +2 -2
- package/dist/wiring/createExtension.esm.js.map +1 -1
- package/dist/wiring/createExtensionBlueprint.esm.js +55 -3
- package/dist/wiring/createExtensionBlueprint.esm.js.map +1 -1
- package/dist/wiring/resolveExtensionDefinition.esm.js.map +1 -1
- package/package.json +9 -9
- package/dist/blueprints/NavLogoBlueprint.esm.js +0 -27
- package/dist/blueprints/NavLogoBlueprint.esm.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,121 @@
|
|
|
1
1
|
# @backstage/frontend-plugin-api
|
|
2
2
|
|
|
3
|
+
## 0.11.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 29786f6: **BREAKING**: The `NavLogoBlueprint` has been removed and replaced by `NavContentBlueprint`, which instead replaces the entire navbar. The default navbar has also been switched to a more minimal implementation.
|
|
8
|
+
|
|
9
|
+
To use `NavContentBlueprint` to install new logos, you can use it as follows:
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
NavContentBlueprint.make({
|
|
13
|
+
params: {
|
|
14
|
+
component: ({ items }) => {
|
|
15
|
+
return compatWrapper(
|
|
16
|
+
<Sidebar>
|
|
17
|
+
<SidebarLogo />
|
|
18
|
+
|
|
19
|
+
{/* Other sidebar content */}
|
|
20
|
+
|
|
21
|
+
<SidebarScrollWrapper>
|
|
22
|
+
{items.map((item, index) => (
|
|
23
|
+
<SidebarItem {...item} key={index} />
|
|
24
|
+
))}
|
|
25
|
+
</SidebarScrollWrapper>
|
|
26
|
+
|
|
27
|
+
{/* Other sidebar content */}
|
|
28
|
+
</Sidebar>,
|
|
29
|
+
);
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- 805c298: **BREAKING**: The `ApiBlueprint` has been updated to use the new advanced type parameters through the new `defineParams` blueprint option. This is an immediate breaking change that requires all existing usages of `ApiBlueprint` to switch to the new callback format. Existing extensions created with the old format are still compatible with the latest version of the plugin API however, meaning that this does not break existing plugins.
|
|
36
|
+
|
|
37
|
+
To update existing usages of `ApiBlueprint`, you remove the outer level of the `params` object and replace `createApiFactory(...)` with `define => define(...)`.
|
|
38
|
+
|
|
39
|
+
For example, the following old usage:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
ApiBlueprint.make({
|
|
43
|
+
name: 'error',
|
|
44
|
+
params: {
|
|
45
|
+
factory: createApiFactory({
|
|
46
|
+
api: errorApiRef,
|
|
47
|
+
deps: { alertApi: alertApiRef },
|
|
48
|
+
factory: ({ alertApi }) => {
|
|
49
|
+
return ...;
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
is migrated to the following:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
ApiBlueprint.make({
|
|
60
|
+
name: 'error',
|
|
61
|
+
params: define =>
|
|
62
|
+
define({
|
|
63
|
+
api: errorApiRef,
|
|
64
|
+
deps: { alertApi: alertApiRef },
|
|
65
|
+
factory: ({ alertApi }) => {
|
|
66
|
+
return ...;
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- 805c298: Added support for advanced parameter types in extension blueprints. The primary purpose of this is to allow extension authors to use type inference in the definition of the blueprint parameters. This often removes the need for extra imports and improves discoverability of blueprint parameters.
|
|
73
|
+
|
|
74
|
+
This feature is introduced through the new `defineParams` option of `createExtensionBlueprint`, along with accompanying `createExtensionBlueprintParams` function to help implement the new format.
|
|
75
|
+
|
|
76
|
+
The following is an example of how to create an extension blueprint that uses the new option:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const ExampleBlueprint = createExtensionBlueprint({
|
|
80
|
+
kind: 'example',
|
|
81
|
+
attachTo: { id: 'example', input: 'example' },
|
|
82
|
+
output: [exampleComponentDataRef, exampleFetcherDataRef],
|
|
83
|
+
defineParams<T>(params: {
|
|
84
|
+
component(props: ExampleProps<T>): JSX.Element | null;
|
|
85
|
+
fetcher(options: FetchOptions): Promise<FetchResult<T>>;
|
|
86
|
+
}) {
|
|
87
|
+
// The returned params must be wrapped with `createExtensionBlueprintParams`
|
|
88
|
+
return createExtensionBlueprintParams(params);
|
|
89
|
+
},
|
|
90
|
+
*factory(params) {
|
|
91
|
+
// These params are now inferred
|
|
92
|
+
yield exampleComponentDataRef(params.component);
|
|
93
|
+
yield exampleFetcherDataRef(params.fetcher);
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Usage of the above example looks as follows:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const example = ExampleBlueprint.make({
|
|
102
|
+
params: define => define({
|
|
103
|
+
component: ...,
|
|
104
|
+
fetcher: ...,
|
|
105
|
+
}),
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
This `define => define(<params>)` is also known as the "callback syntax" and is required if a blueprint is created with the new `defineParams` option. The callback syntax can also optionally be used for other blueprints too, which means that it is not a breaking change to remove the `defineParams` option, as long as the external parameter types remain compatible.
|
|
110
|
+
|
|
111
|
+
### Patch Changes
|
|
112
|
+
|
|
113
|
+
- Updated dependencies
|
|
114
|
+
- @backstage/core-components@0.17.5-next.0
|
|
115
|
+
- @backstage/core-plugin-api@1.10.9
|
|
116
|
+
- @backstage/types@1.2.1
|
|
117
|
+
- @backstage/version-bridge@1.0.11
|
|
118
|
+
|
|
3
119
|
## 0.10.4
|
|
4
120
|
|
|
5
121
|
### Patch Changes
|
|
@@ -2,7 +2,7 @@ import '../wiring/coreExtensionData.esm.js';
|
|
|
2
2
|
import 'zod';
|
|
3
3
|
import 'zod-to-json-schema';
|
|
4
4
|
import { createExtensionDataRef } from '../wiring/createExtensionDataRef.esm.js';
|
|
5
|
-
import { createExtensionBlueprint } from '../wiring/createExtensionBlueprint.esm.js';
|
|
5
|
+
import { createExtensionBlueprint, createExtensionBlueprintParams } from '../wiring/createExtensionBlueprint.esm.js';
|
|
6
6
|
|
|
7
7
|
const factoryDataRef = createExtensionDataRef().with({
|
|
8
8
|
id: "core.api.factory"
|
|
@@ -14,8 +14,9 @@ const ApiBlueprint = createExtensionBlueprint({
|
|
|
14
14
|
dataRefs: {
|
|
15
15
|
factory: factoryDataRef
|
|
16
16
|
},
|
|
17
|
+
defineParams: (params) => createExtensionBlueprintParams(params),
|
|
17
18
|
*factory(params) {
|
|
18
|
-
yield factoryDataRef(params
|
|
19
|
+
yield factoryDataRef(params);
|
|
19
20
|
}
|
|
20
21
|
});
|
|
21
22
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiBlueprint.esm.js","sources":["../../src/blueprints/ApiBlueprint.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 { createExtensionBlueprint, createExtensionDataRef } from '../wiring';\nimport {
|
|
1
|
+
{"version":3,"file":"ApiBlueprint.esm.js","sources":["../../src/blueprints/ApiBlueprint.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 { AnyApiFactory, ApiFactory } from '../apis/system';\nimport { createExtensionBlueprint, createExtensionDataRef } from '../wiring';\nimport { createExtensionBlueprintParams } from '../wiring/createExtensionBlueprint';\n\nconst factoryDataRef = createExtensionDataRef<AnyApiFactory>().with({\n id: 'core.api.factory',\n});\n\n/**\n * Creates utility API extensions.\n *\n * @public\n */\nexport const ApiBlueprint = createExtensionBlueprint({\n kind: 'api',\n attachTo: { id: 'root', input: 'apis' },\n output: [factoryDataRef],\n dataRefs: {\n factory: factoryDataRef,\n },\n defineParams: <\n TApi,\n TImpl extends TApi,\n TDeps extends { [name in string]: unknown },\n >(\n params: ApiFactory<TApi, TImpl, TDeps>,\n ) => createExtensionBlueprintParams(params as AnyApiFactory),\n *factory(params) {\n yield factoryDataRef(params);\n },\n});\n"],"names":[],"mappings":";;;;;;AAoBA,MAAM,cAAA,GAAiB,sBAAsC,EAAA,CAAE,IAAK,CAAA;AAAA,EAClE,EAAI,EAAA;AACN,CAAC,CAAA;AAOM,MAAM,eAAe,wBAAyB,CAAA;AAAA,EACnD,IAAM,EAAA,KAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,MAAA,EAAQ,OAAO,MAAO,EAAA;AAAA,EACtC,MAAA,EAAQ,CAAC,cAAc,CAAA;AAAA,EACvB,QAAU,EAAA;AAAA,IACR,OAAS,EAAA;AAAA,GACX;AAAA,EACA,YAAc,EAAA,CAKZ,MACG,KAAA,8BAAA,CAA+B,MAAuB,CAAA;AAAA,EAC3D,CAAC,QAAQ,MAAQ,EAAA;AACf,IAAA,MAAM,eAAe,MAAM,CAAA;AAAA;AAE/B,CAAC;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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 } from '../wiring/createExtensionBlueprint.esm.js';
|
|
6
|
+
|
|
7
|
+
const componentDataRef = createExtensionDataRef().with({
|
|
8
|
+
id: "core.nav-content.component"
|
|
9
|
+
});
|
|
10
|
+
const NavContentBlueprint = createExtensionBlueprint({
|
|
11
|
+
kind: "nav-content",
|
|
12
|
+
attachTo: { id: "app/nav", input: "content" },
|
|
13
|
+
output: [componentDataRef],
|
|
14
|
+
dataRefs: {
|
|
15
|
+
component: componentDataRef
|
|
16
|
+
},
|
|
17
|
+
*factory(params) {
|
|
18
|
+
yield componentDataRef(params.component);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export { NavContentBlueprint };
|
|
23
|
+
//# sourceMappingURL=NavContentBlueprint.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavContentBlueprint.esm.js","sources":["../../src/blueprints/NavContentBlueprint.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 { IconComponent, RouteRef } from '@backstage/frontend-plugin-api';\nimport { createExtensionBlueprint, createExtensionDataRef } from '../wiring';\n\n/**\n * The props for the {@link NavContentComponent}.\n *\n * @public\n */\nexport interface NavContentComponentProps {\n /**\n * The nav items available to the component. These are all the items created\n * with the {@link NavItemBlueprint} in the app.\n *\n * In addition to the original properties from the nav items, these also\n * include a resolved route path as `to`, and duplicated `title` as `text` to\n * simplify rendering.\n */\n items: Array<{\n // Original props from nav items\n icon: IconComponent;\n title: string;\n routeRef: RouteRef<undefined>;\n\n // Additional props to simplify item rendering\n to: string;\n text: string;\n }>;\n}\n\n/**\n * A component that renders the nav bar content, to be passed to the {@link NavContentBlueprint}.\n *\n * @public\n */\nexport type NavContentComponent = (\n props: NavContentComponentProps,\n) => JSX.Element | null;\n\nconst componentDataRef = createExtensionDataRef<NavContentComponent>().with({\n id: 'core.nav-content.component',\n});\n\n/**\n * Creates an extension that replaces the entire nav bar with your own component.\n *\n * @public\n */\nexport const NavContentBlueprint = createExtensionBlueprint({\n kind: 'nav-content',\n attachTo: { id: 'app/nav', input: 'content' },\n output: [componentDataRef],\n dataRefs: {\n component: componentDataRef,\n },\n *factory(params: { component: NavContentComponent }) {\n yield componentDataRef(params.component);\n },\n});\n"],"names":[],"mappings":";;;;;;AAsDA,MAAM,gBAAA,GAAmB,sBAA4C,EAAA,CAAE,IAAK,CAAA;AAAA,EAC1E,EAAI,EAAA;AACN,CAAC,CAAA;AAOM,MAAM,sBAAsB,wBAAyB,CAAA;AAAA,EAC1D,IAAM,EAAA,aAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,SAAA,EAAW,OAAO,SAAU,EAAA;AAAA,EAC5C,MAAA,EAAQ,CAAC,gBAAgB,CAAA;AAAA,EACzB,QAAU,EAAA;AAAA,IACR,SAAW,EAAA;AAAA,GACb;AAAA,EACA,CAAC,QAAQ,MAA4C,EAAA;AACnD,IAAM,MAAA,gBAAA,CAAiB,OAAO,SAAS,CAAA;AAAA;AAE3C,CAAC;;;;"}
|
|
@@ -13,6 +13,7 @@ import { coreComponentRefs } from './coreComponentRefs.esm.js';
|
|
|
13
13
|
import { coreExtensionData } from '../wiring/coreExtensionData.esm.js';
|
|
14
14
|
import 'zod';
|
|
15
15
|
import 'zod-to-json-schema';
|
|
16
|
+
import '../wiring/createExtensionBlueprint.esm.js';
|
|
16
17
|
import { AppNodeProvider } from './AppNodeProvider.esm.js';
|
|
17
18
|
|
|
18
19
|
const RouteTracker = (props) => {
|
|
@@ -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, useComponentRef } from '../apis';\nimport { coreComponentRefs } from './coreComponentRefs';\nimport { coreExtensionData } from '../wiring';\nimport { AppNodeProvider } from './AppNodeProvider';\n\ntype RouteTrackerProps = PropsWithChildren<{\n disableTracking?: boolean;\n}>;\n\nconst RouteTracker = (props: RouteTrackerProps) => {\n const { disableTracking, 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 (disableTracking) return;\n analytics.captureEvent(routableExtensionRenderedEvent, '');\n }, [analytics, disableTracking]);\n\n return <>{children}</>;\n};\n\n/** @public */\nexport interface ExtensionBoundaryProps {\n node: AppNode;\n /**\n * This explicitly marks the extension as routable for the purpose of\n * capturing analytics events. If not provided, the extension boundary will be\n * marked as routable if it outputs a routePath.\n */\n routable?: boolean;\n children: ReactNode;\n}\n\n/** @public */\nexport function ExtensionBoundary(props: ExtensionBoundaryProps) {\n const { node, routable, children } = props;\n\n const doesOutputRoutePath = Boolean(\n node.instance?.getData(coreExtensionData.routePath),\n );\n\n const plugin = node.spec.plugin;\n const Progress = useComponentRef(coreComponentRefs.progress);\n const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback);\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} Fallback={fallback}>\n <AnalyticsContext attributes={attributes}>\n <RouteTracker disableTracking={!(routable ?? doesOutputRoutePath)}>\n {children}\n </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":"
|
|
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, useComponentRef } from '../apis';\nimport { coreComponentRefs } from './coreComponentRefs';\nimport { coreExtensionData } from '../wiring';\nimport { AppNodeProvider } from './AppNodeProvider';\n\ntype RouteTrackerProps = PropsWithChildren<{\n disableTracking?: boolean;\n}>;\n\nconst RouteTracker = (props: RouteTrackerProps) => {\n const { disableTracking, 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 (disableTracking) return;\n analytics.captureEvent(routableExtensionRenderedEvent, '');\n }, [analytics, disableTracking]);\n\n return <>{children}</>;\n};\n\n/** @public */\nexport interface ExtensionBoundaryProps {\n node: AppNode;\n /**\n * This explicitly marks the extension as routable for the purpose of\n * capturing analytics events. If not provided, the extension boundary will be\n * marked as routable if it outputs a routePath.\n */\n routable?: boolean;\n children: ReactNode;\n}\n\n/** @public */\nexport function ExtensionBoundary(props: ExtensionBoundaryProps) {\n const { node, routable, children } = props;\n\n const doesOutputRoutePath = Boolean(\n node.instance?.getData(coreExtensionData.routePath),\n );\n\n const plugin = node.spec.plugin;\n const Progress = useComponentRef(coreComponentRefs.progress);\n const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback);\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} Fallback={fallback}>\n <AnalyticsContext attributes={attributes}>\n <RouteTracker disableTracking={!(routable ?? doesOutputRoutePath)}>\n {children}\n </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,eAAiB,EAAA,QAAA,EAAa,GAAA,KAAA;AACtC,EAAA,MAAM,YAAY,YAAa,EAAA;AAM/B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,eAAiB,EAAA;AACrB,IAAU,SAAA,CAAA,YAAA,CAAa,gCAAgC,EAAE,CAAA;AAAA,GACxD,EAAA,CAAC,SAAW,EAAA,eAAe,CAAC,CAAA;AAE/B,EAAA,uCAAU,QAAS,EAAA,CAAA;AACrB,CAAA;AAeO,SAAS,kBAAkB,KAA+B,EAAA;AAC/D,EAAA,MAAM,EAAE,IAAA,EAAM,QAAU,EAAA,QAAA,EAAa,GAAA,KAAA;AAErC,EAAA,MAAM,mBAAsB,GAAA,OAAA;AAAA,IAC1B,IAAK,CAAA,QAAA,EAAU,OAAQ,CAAA,iBAAA,CAAkB,SAAS;AAAA,GACpD;AAEA,EAAM,MAAA,MAAA,GAAS,KAAK,IAAK,CAAA,MAAA;AACzB,EAAM,MAAA,QAAA,GAAW,eAAgB,CAAA,iBAAA,CAAkB,QAAQ,CAAA;AAC3D,EAAM,MAAA,QAAA,GAAW,eAAgB,CAAA,iBAAA,CAAkB,qBAAqB,CAAA;AAGxE,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,eAAgB,EAAA,EAAA,IAAA,EACf,QAAC,kBAAA,GAAA,CAAA,QAAA,EAAA,EAAS,QAAU,kBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,CAAA,EAC5B,QAAC,kBAAA,GAAA,CAAA,aAAA,EAAA,EAAc,MAAgB,EAAA,QAAA,EAAU,QACvC,EAAA,QAAA,kBAAA,GAAA,CAAC,gBAAiB,EAAA,EAAA,UAAA,EAChB,QAAC,kBAAA,GAAA,CAAA,YAAA,EAAA,EAAa,eAAiB,EAAA,EAAE,QAAY,IAAA,mBAAA,CAAA,EAC1C,QACH,EAAA,CAAA,EACF,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;;;;"}
|
|
@@ -2,6 +2,7 @@ import { lazy } from 'react';
|
|
|
2
2
|
import '../wiring/coreExtensionData.esm.js';
|
|
3
3
|
import { createExtension } from '../wiring/createExtension.esm.js';
|
|
4
4
|
import { createExtensionDataRef } from '../wiring/createExtensionDataRef.esm.js';
|
|
5
|
+
import '../wiring/createExtensionBlueprint.esm.js';
|
|
5
6
|
|
|
6
7
|
function createComponentExtension(options) {
|
|
7
8
|
return createExtension({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createComponentExtension.esm.js","sources":["../../src/extensions/createComponentExtension.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 { lazy, ComponentType } from 'react';\nimport { createExtension, createExtensionDataRef } from '../wiring';\nimport { ComponentRef } from '../components';\n\n/** @public */\nexport function createComponentExtension<TProps extends {}>(options: {\n ref: ComponentRef<TProps>;\n name?: string;\n disabled?: boolean;\n loader:\n | {\n lazy: () => Promise<ComponentType<TProps>>;\n }\n | {\n sync: () => ComponentType<TProps>;\n };\n}) {\n return createExtension({\n kind: 'component',\n name: options.name ?? options.ref.id,\n attachTo: { id: 'api:app/components', input: 'components' },\n disabled: options.disabled,\n output: [createComponentExtension.componentDataRef],\n factory() {\n if ('sync' in options.loader) {\n return [\n createComponentExtension.componentDataRef({\n ref: options.ref,\n impl: options.loader.sync() as ComponentType,\n }),\n ];\n }\n const lazyLoader = options.loader.lazy;\n const ExtensionComponent = lazy(() =>\n lazyLoader().then(Component => ({\n default: Component,\n })),\n ) as unknown as ComponentType;\n\n return [\n createComponentExtension.componentDataRef({\n ref: options.ref,\n impl: ExtensionComponent,\n }),\n ];\n },\n });\n}\n\n/** @public */\nexport namespace createComponentExtension {\n export const componentDataRef = createExtensionDataRef<{\n ref: ComponentRef;\n impl: ComponentType;\n }>().with({ id: 'core.component.component' });\n}\n"],"names":["createComponentExtension"],"mappings":"
|
|
1
|
+
{"version":3,"file":"createComponentExtension.esm.js","sources":["../../src/extensions/createComponentExtension.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 { lazy, ComponentType } from 'react';\nimport { createExtension, createExtensionDataRef } from '../wiring';\nimport { ComponentRef } from '../components';\n\n/** @public */\nexport function createComponentExtension<TProps extends {}>(options: {\n ref: ComponentRef<TProps>;\n name?: string;\n disabled?: boolean;\n loader:\n | {\n lazy: () => Promise<ComponentType<TProps>>;\n }\n | {\n sync: () => ComponentType<TProps>;\n };\n}) {\n return createExtension({\n kind: 'component',\n name: options.name ?? options.ref.id,\n attachTo: { id: 'api:app/components', input: 'components' },\n disabled: options.disabled,\n output: [createComponentExtension.componentDataRef],\n factory() {\n if ('sync' in options.loader) {\n return [\n createComponentExtension.componentDataRef({\n ref: options.ref,\n impl: options.loader.sync() as ComponentType,\n }),\n ];\n }\n const lazyLoader = options.loader.lazy;\n const ExtensionComponent = lazy(() =>\n lazyLoader().then(Component => ({\n default: Component,\n })),\n ) as unknown as ComponentType;\n\n return [\n createComponentExtension.componentDataRef({\n ref: options.ref,\n impl: ExtensionComponent,\n }),\n ];\n },\n });\n}\n\n/** @public */\nexport namespace createComponentExtension {\n export const componentDataRef = createExtensionDataRef<{\n ref: ComponentRef;\n impl: ComponentType;\n }>().with({ id: 'core.component.component' });\n}\n"],"names":["createComponentExtension"],"mappings":";;;;;;AAqBO,SAAS,yBAA4C,OAWzD,EAAA;AACD,EAAA,OAAO,eAAgB,CAAA;AAAA,IACrB,IAAM,EAAA,WAAA;AAAA,IACN,IAAM,EAAA,OAAA,CAAQ,IAAQ,IAAA,OAAA,CAAQ,GAAI,CAAA,EAAA;AAAA,IAClC,QAAU,EAAA,EAAE,EAAI,EAAA,oBAAA,EAAsB,OAAO,YAAa,EAAA;AAAA,IAC1D,UAAU,OAAQ,CAAA,QAAA;AAAA,IAClB,MAAA,EAAQ,CAAC,wBAAA,CAAyB,gBAAgB,CAAA;AAAA,IAClD,OAAU,GAAA;AACR,MAAI,IAAA,MAAA,IAAU,QAAQ,MAAQ,EAAA;AAC5B,QAAO,OAAA;AAAA,UACL,yBAAyB,gBAAiB,CAAA;AAAA,YACxC,KAAK,OAAQ,CAAA,GAAA;AAAA,YACb,IAAA,EAAM,OAAQ,CAAA,MAAA,CAAO,IAAK;AAAA,WAC3B;AAAA,SACH;AAAA;AAEF,MAAM,MAAA,UAAA,GAAa,QAAQ,MAAO,CAAA,IAAA;AAClC,MAAA,MAAM,kBAAqB,GAAA,IAAA;AAAA,QAAK,MAC9B,UAAA,EAAa,CAAA,IAAA,CAAK,CAAc,SAAA,MAAA;AAAA,UAC9B,OAAS,EAAA;AAAA,SACT,CAAA;AAAA,OACJ;AAEA,MAAO,OAAA;AAAA,QACL,yBAAyB,gBAAiB,CAAA;AAAA,UACxC,KAAK,OAAQ,CAAA,GAAA;AAAA,UACb,IAAM,EAAA;AAAA,SACP;AAAA,OACH;AAAA;AACF,GACD,CAAA;AACH;AAAA,CAGO,CAAUA,yBAAV,KAAA;AACE,EAAMA,yBAAAA,CAAA,mBAAmB,sBAG7B,EAAA,CAAE,KAAK,EAAE,EAAA,EAAI,4BAA4B,CAAA;AAAA,CAJ7B,EAAA,wBAAA,KAAA,wBAAA,GAAA,EAAA,CAAA,CAAA;;;;"}
|