@backstage/frontend-app-api 0.4.0-next.1 → 0.4.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 +23 -0
- package/dist/index.esm.js +126 -146
- package/dist/index.esm.js.map +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @backstage/frontend-app-api
|
|
2
2
|
|
|
3
|
+
## 0.4.0-next.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ea06590: The app no longer provides the `AppContext` from `@backstage/core-plugin-api`. Components that require this context to be available should use the `compatWrapper` helper from `@backstage/core-compat-api`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- aeb8008: Add support for translation extensions.
|
|
12
|
+
- b7adf24: Use the new plugin type for error boundary components.
|
|
13
|
+
- 8f5d6c1: Updates to match the new extension input wrapping.
|
|
14
|
+
- cb4197a: Forward ` node`` instead of `extensionId` to resolved extension inputs.
|
|
15
|
+
- 8837a96: Updates to match the introduction of `ExtensionDefinition` and new extension ID naming patterns.
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @backstage/frontend-plugin-api@0.4.0-next.2
|
|
18
|
+
- @backstage/theme@0.5.0-next.1
|
|
19
|
+
- @backstage/config@1.1.1
|
|
20
|
+
- @backstage/core-app-api@1.11.2-next.1
|
|
21
|
+
- @backstage/core-components@0.13.9-next.2
|
|
22
|
+
- @backstage/core-plugin-api@1.8.1-next.1
|
|
23
|
+
- @backstage/types@1.1.1
|
|
24
|
+
- @backstage/version-bridge@1.0.7
|
|
25
|
+
|
|
3
26
|
## 0.4.0-next.1
|
|
4
27
|
|
|
5
28
|
### Minor Changes
|
package/dist/index.esm.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, createContext, useContext } from 'react';
|
|
2
2
|
import { ConfigReader } from '@backstage/config';
|
|
3
|
-
import { createExtension, createExtensionInput, coreExtensionData,
|
|
3
|
+
import { createExtension, createExtensionInput, coreExtensionData, createTranslationExtension, useComponentRef, coreComponentRefs, useRouteRef, createThemeExtension, createComponentExtension, AnalyticsContext, useAnalytics, appTreeApiRef, componentsApiRef } from '@backstage/frontend-plugin-api';
|
|
4
4
|
import { useRoutes, BrowserRouter, useInRouterContext, MemoryRouter, matchRoutes, generatePath, useLocation, Route } from 'react-router-dom';
|
|
5
5
|
import { SidebarPage, sidebarConfig, Sidebar, SidebarDivider, useSidebarOpenState, Link, SidebarItem, Progress, ErrorPage, ErrorPanel } from '@backstage/core-components';
|
|
6
|
-
import { makeStyles } from '@material-ui/core';
|
|
7
|
-
import { useApi
|
|
6
|
+
import { makeStyles, Button as Button$1 } from '@material-ui/core';
|
|
7
|
+
import { useApi, appThemeApiRef, FeatureFlagState, createApiFactory, discoveryApiRef, configApiRef, alertApiRef, analyticsApiRef, errorApiRef, storageApiRef, fetchApiRef, identityApiRef, oauthRequestApiRef, googleAuthApiRef, microsoftAuthApiRef, githubAuthApiRef, oktaAuthApiRef, gitlabAuthApiRef, oneloginAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, atlassianAuthApiRef, createApiRef, attachComponentData, featureFlagsApiRef } from '@backstage/core-plugin-api';
|
|
8
8
|
import { UrlPatternDiscovery, AlertApiForwarder, NoOpAnalyticsApi, ErrorAlerter, ErrorApiForwarder, UnhandledErrorForwarder, WebStorage, createFetchApi, FetchMiddlewares, OAuthRequestManager, GoogleAuth, MicrosoftAuth, GithubAuth, OktaAuth, GitlabAuth, OneLoginAuth, BitbucketAuth, BitbucketServerAuth, AtlassianAuth, ApiFactoryRegistry, AppThemeSelector, ApiResolver, ApiProvider } from '@backstage/core-app-api';
|
|
9
9
|
import useObservable from 'react-use/lib/useObservable';
|
|
10
|
-
import { createVersionedContext, createVersionedValueMap, getOrCreateGlobalSingleton } from '@backstage/version-bridge';
|
|
11
10
|
import ObservableImpl from 'zen-observable';
|
|
12
11
|
import { createInstance } from 'i18next';
|
|
13
12
|
import { permissionApiRef, IdentityPermissionApi } from '@backstage/plugin-permission-react';
|
|
14
13
|
import Button from '@material-ui/core/Button';
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import
|
|
26
|
-
import
|
|
27
|
-
import
|
|
28
|
-
import
|
|
29
|
-
import
|
|
30
|
-
import
|
|
31
|
-
import
|
|
32
|
-
import
|
|
33
|
-
import
|
|
34
|
-
import
|
|
35
|
-
import
|
|
14
|
+
import '@material-ui/icons/Apartment';
|
|
15
|
+
import '@material-ui/icons/BrokenImage';
|
|
16
|
+
import '@material-ui/icons/Category';
|
|
17
|
+
import '@material-ui/icons/CreateNewFolder';
|
|
18
|
+
import '@material-ui/icons/Subject';
|
|
19
|
+
import '@material-ui/icons/Search';
|
|
20
|
+
import '@material-ui/icons/Chat';
|
|
21
|
+
import '@material-ui/icons/Dashboard';
|
|
22
|
+
import '@material-ui/icons/Description';
|
|
23
|
+
import '@material-ui/icons/Email';
|
|
24
|
+
import '@material-ui/icons/Extension';
|
|
25
|
+
import '@material-ui/icons/GitHub';
|
|
26
|
+
import '@material-ui/icons/Help';
|
|
27
|
+
import '@material-ui/icons/LocationOn';
|
|
28
|
+
import '@material-ui/icons/Memory';
|
|
29
|
+
import '@material-ui/icons/MenuBook';
|
|
30
|
+
import '@material-ui/icons/People';
|
|
31
|
+
import '@material-ui/icons/Person';
|
|
32
|
+
import '@material-ui/icons/Warning';
|
|
33
|
+
import '@material-ui/icons/Work';
|
|
34
|
+
import '@material-ui/icons/FeaturedPlayList';
|
|
36
35
|
import { UnifiedThemeProvider, themes } from '@backstage/theme';
|
|
37
36
|
import DarkIcon from '@material-ui/icons/Brightness2';
|
|
38
37
|
import LightIcon from '@material-ui/icons/WbSunny';
|
|
38
|
+
import { getOrCreateGlobalSingleton, createVersionedContext, createVersionedValueMap } from '@backstage/version-bridge';
|
|
39
39
|
import { appLanguageApiRef, translationApiRef } from '@backstage/core-plugin-api/alpha';
|
|
40
40
|
import mapValues from 'lodash/mapValues';
|
|
41
41
|
|
|
42
42
|
const Core = createExtension({
|
|
43
|
-
|
|
43
|
+
namespace: "core",
|
|
44
44
|
attachTo: { id: "root", input: "default" },
|
|
45
45
|
// ignored
|
|
46
46
|
inputs: {
|
|
@@ -53,6 +53,9 @@ const Core = createExtension({
|
|
|
53
53
|
components: createExtensionInput({
|
|
54
54
|
component: coreExtensionData.component
|
|
55
55
|
}),
|
|
56
|
+
translations: createExtensionInput({
|
|
57
|
+
translation: createTranslationExtension.translationDataRef
|
|
58
|
+
}),
|
|
56
59
|
root: createExtensionInput(
|
|
57
60
|
{
|
|
58
61
|
element: coreExtensionData.reactElement
|
|
@@ -65,14 +68,15 @@ const Core = createExtension({
|
|
|
65
68
|
},
|
|
66
69
|
factory({ inputs }) {
|
|
67
70
|
return {
|
|
68
|
-
root: inputs.root.element
|
|
71
|
+
root: inputs.root.output.element
|
|
69
72
|
};
|
|
70
73
|
}
|
|
71
74
|
});
|
|
72
75
|
|
|
73
76
|
const CoreRoutes = createExtension({
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
namespace: "core",
|
|
78
|
+
name: "routes",
|
|
79
|
+
attachTo: { id: "core/layout", input: "content" },
|
|
76
80
|
inputs: {
|
|
77
81
|
routes: createExtensionInput({
|
|
78
82
|
path: coreExtensionData.routePath,
|
|
@@ -85,14 +89,13 @@ const CoreRoutes = createExtension({
|
|
|
85
89
|
},
|
|
86
90
|
factory({ inputs }) {
|
|
87
91
|
const Routes = () => {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
coreComponentsRefs.notFoundErrorPage
|
|
92
|
+
const NotFoundErrorPage = useComponentRef(
|
|
93
|
+
coreComponentRefs.notFoundErrorPage
|
|
91
94
|
);
|
|
92
95
|
const element = useRoutes([
|
|
93
96
|
...inputs.routes.map((route) => ({
|
|
94
|
-
path: `${route.path}/*`,
|
|
95
|
-
element: route.element
|
|
97
|
+
path: `${route.output.path}/*`,
|
|
98
|
+
element: route.output.element
|
|
96
99
|
})),
|
|
97
100
|
{
|
|
98
101
|
path: "*",
|
|
@@ -108,8 +111,9 @@ const CoreRoutes = createExtension({
|
|
|
108
111
|
});
|
|
109
112
|
|
|
110
113
|
const CoreLayout = createExtension({
|
|
111
|
-
|
|
112
|
-
|
|
114
|
+
namespace: "core",
|
|
115
|
+
name: "layout",
|
|
116
|
+
attachTo: { id: "core/router", input: "children" },
|
|
113
117
|
inputs: {
|
|
114
118
|
nav: createExtensionInput(
|
|
115
119
|
{
|
|
@@ -129,7 +133,7 @@ const CoreLayout = createExtension({
|
|
|
129
133
|
},
|
|
130
134
|
factory({ inputs }) {
|
|
131
135
|
return {
|
|
132
|
-
element: /* @__PURE__ */ React.createElement(SidebarPage, null, inputs.nav.element, inputs.content.element)
|
|
136
|
+
element: /* @__PURE__ */ React.createElement(SidebarPage, null, inputs.nav.output.element, inputs.content.output.element)
|
|
133
137
|
};
|
|
134
138
|
}
|
|
135
139
|
});
|
|
@@ -216,8 +220,9 @@ const SidebarNavItem = (props) => {
|
|
|
216
220
|
return /* @__PURE__ */ React.createElement(SidebarItem, { to, icon: Icon, text: title });
|
|
217
221
|
};
|
|
218
222
|
const CoreNav = createExtension({
|
|
219
|
-
|
|
220
|
-
|
|
223
|
+
namespace: "core",
|
|
224
|
+
name: "nav",
|
|
225
|
+
attachTo: { id: "core/layout", input: "nav" },
|
|
221
226
|
inputs: {
|
|
222
227
|
items: createExtensionInput({
|
|
223
228
|
target: coreExtensionData.navTarget
|
|
@@ -238,7 +243,7 @@ const CoreNav = createExtension({
|
|
|
238
243
|
factory({ inputs }) {
|
|
239
244
|
var _a;
|
|
240
245
|
return {
|
|
241
|
-
element: /* @__PURE__ */ React.createElement(Sidebar, null, /* @__PURE__ */ React.createElement(SidebarLogo, { ...(_a = inputs.logos) == null ? void 0 : _a.elements }), /* @__PURE__ */ React.createElement(SidebarDivider, null), inputs.items.map((item, index) => /* @__PURE__ */ React.createElement(SidebarNavItem, { ...item.target, key: index })))
|
|
246
|
+
element: /* @__PURE__ */ React.createElement(Sidebar, null, /* @__PURE__ */ React.createElement(SidebarLogo, { ...(_a = inputs.logos) == null ? void 0 : _a.output.elements }), /* @__PURE__ */ React.createElement(SidebarDivider, null), inputs.items.map((item, index) => /* @__PURE__ */ React.createElement(SidebarNavItem, { ...item.output.target, key: index })))
|
|
242
247
|
};
|
|
243
248
|
}
|
|
244
249
|
});
|
|
@@ -332,7 +337,7 @@ const useShouldPreferDarkTheme = () => {
|
|
|
332
337
|
return shouldPreferDark;
|
|
333
338
|
};
|
|
334
339
|
function AppThemeProvider({ children }) {
|
|
335
|
-
const appThemeApi = useApi
|
|
340
|
+
const appThemeApi = useApi(appThemeApiRef);
|
|
336
341
|
const themeId = useObservable(
|
|
337
342
|
appThemeApi.activeThemeId$(),
|
|
338
343
|
appThemeApi.getActiveThemeId()
|
|
@@ -434,15 +439,6 @@ class AppIdentityProxy {
|
|
|
434
439
|
}
|
|
435
440
|
}
|
|
436
441
|
|
|
437
|
-
const AppContext = createVersionedContext("app-context");
|
|
438
|
-
const AppContextProvider = ({
|
|
439
|
-
appContext,
|
|
440
|
-
children
|
|
441
|
-
}) => {
|
|
442
|
-
const versionedValue = createVersionedValueMap({ 1: appContext });
|
|
443
|
-
return /* @__PURE__ */ React.createElement(AppContext.Provider, { value: versionedValue, children });
|
|
444
|
-
};
|
|
445
|
-
|
|
446
442
|
var __defProp$2 = Object.defineProperty;
|
|
447
443
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
448
444
|
var __publicField$2 = (obj, key, value) => {
|
|
@@ -1069,6 +1065,23 @@ registerDefaults_fn = function(internalRef) {
|
|
|
1069
1065
|
};
|
|
1070
1066
|
let I18nextTranslationApi = _I18nextTranslationApi;
|
|
1071
1067
|
|
|
1068
|
+
function resolveExtensionDefinition(definition, context) {
|
|
1069
|
+
var _a;
|
|
1070
|
+
const { name, kind, namespace: _, ...rest } = definition;
|
|
1071
|
+
const namespace = (_a = definition.namespace) != null ? _a : context == null ? void 0 : context.namespace;
|
|
1072
|
+
const namePart = name && namespace ? `${namespace}/${name}` : namespace || name;
|
|
1073
|
+
if (!namePart) {
|
|
1074
|
+
throw new Error(
|
|
1075
|
+
`Extension must declare an explicit namespace or name as it could not be resolved from context, kind=${kind} namespace=${namespace} name=${name}`
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
return {
|
|
1079
|
+
...rest,
|
|
1080
|
+
id: kind ? `${kind}:${namePart}` : namePart,
|
|
1081
|
+
$$type: "@backstage/Extension"
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1072
1085
|
const apis = [
|
|
1073
1086
|
createApiFactory({
|
|
1074
1087
|
api: discoveryApiRef,
|
|
@@ -1307,33 +1320,6 @@ const components = {
|
|
|
1307
1320
|
ErrorBoundaryFallback: DefaultErrorBoundaryFallback
|
|
1308
1321
|
};
|
|
1309
1322
|
|
|
1310
|
-
const icons = {
|
|
1311
|
-
brokenImage: MuiBrokenImageIcon,
|
|
1312
|
-
// To be confirmed: see https://github.com/backstage/backstage/issues/4970
|
|
1313
|
-
catalog: MuiMenuBookIcon,
|
|
1314
|
-
scaffolder: MuiCreateNewFolderIcon,
|
|
1315
|
-
techdocs: MuiSubjectIcon,
|
|
1316
|
-
search: MuiSearchIcon,
|
|
1317
|
-
chat: MuiChatIcon,
|
|
1318
|
-
dashboard: MuiDashboardIcon,
|
|
1319
|
-
docs: MuiDocsIcon,
|
|
1320
|
-
email: MuiEmailIcon,
|
|
1321
|
-
github: MuiGitHubIcon,
|
|
1322
|
-
group: MuiPeopleIcon,
|
|
1323
|
-
help: MuiHelpIcon,
|
|
1324
|
-
"kind:api": MuiExtensionIcon,
|
|
1325
|
-
"kind:component": MuiMemoryIcon,
|
|
1326
|
-
"kind:domain": MuiApartmentIcon,
|
|
1327
|
-
"kind:group": MuiPeopleIcon,
|
|
1328
|
-
"kind:location": MuiLocationOnIcon,
|
|
1329
|
-
"kind:system": MuiCategoryIcon,
|
|
1330
|
-
"kind:user": MuiPersonIcon,
|
|
1331
|
-
"kind:resource": MuiWorkIcon,
|
|
1332
|
-
"kind:template": MuiFeaturedPlayListIcon,
|
|
1333
|
-
user: MuiPersonIcon,
|
|
1334
|
-
warning: MuiWarningIcon
|
|
1335
|
-
};
|
|
1336
|
-
|
|
1337
1323
|
const LightTheme = createThemeExtension({
|
|
1338
1324
|
id: "light",
|
|
1339
1325
|
title: "Light Theme",
|
|
@@ -1754,14 +1740,6 @@ function expandShorthandExtensionParameters(arrayEntry, arrayIndex) {
|
|
|
1754
1740
|
errorMsg("extension ID must not be empty or contain whitespace")
|
|
1755
1741
|
);
|
|
1756
1742
|
}
|
|
1757
|
-
if (id2.includes("/")) {
|
|
1758
|
-
let message = `extension ID must not contain slashes; got '${id2}'`;
|
|
1759
|
-
const good = id2.split("/")[0];
|
|
1760
|
-
if (good) {
|
|
1761
|
-
message += `, did you mean '${good}'?`;
|
|
1762
|
-
}
|
|
1763
|
-
throw new Error(errorMsg(message));
|
|
1764
|
-
}
|
|
1765
1743
|
}
|
|
1766
1744
|
if (typeof arrayEntry === "string") {
|
|
1767
1745
|
assertValidId(arrayEntry);
|
|
@@ -2117,10 +2095,11 @@ function resolveAppNodeSpecs(options) {
|
|
|
2117
2095
|
|
|
2118
2096
|
function resolveInputData(dataMap, attachment, inputName) {
|
|
2119
2097
|
return mapValues(dataMap, (ref) => {
|
|
2120
|
-
|
|
2098
|
+
var _a;
|
|
2099
|
+
const value = (_a = attachment.instance) == null ? void 0 : _a.getData(ref);
|
|
2121
2100
|
if (value === void 0 && !ref.config.optional) {
|
|
2122
2101
|
throw new Error(
|
|
2123
|
-
`input '${inputName}' did not receive required extension data '${ref.id}' from extension '${attachment.id}'`
|
|
2102
|
+
`input '${inputName}' did not receive required extension data '${ref.id}' from extension '${attachment.spec.id}'`
|
|
2124
2103
|
);
|
|
2125
2104
|
}
|
|
2126
2105
|
return value;
|
|
@@ -2133,7 +2112,7 @@ function resolveInputs(inputMap, attachments) {
|
|
|
2133
2112
|
if (undeclaredAttachments.length > 0) {
|
|
2134
2113
|
throw new Error(
|
|
2135
2114
|
`received undeclared input${undeclaredAttachments.length > 1 ? "s" : ""} ${undeclaredAttachments.map(
|
|
2136
|
-
([k, exts]) => `'${k}' from extension${exts.length > 1 ? "s" : ""} '${exts.map((e) => e.id).join("', '")}'`
|
|
2115
|
+
([k, exts]) => `'${k}' from extension${exts.length > 1 ? "s" : ""} '${exts.map((e) => e.spec.id).join("', '")}'`
|
|
2137
2116
|
).join(" and ")}`
|
|
2138
2117
|
);
|
|
2139
2118
|
}
|
|
@@ -2142,7 +2121,7 @@ function resolveInputs(inputMap, attachments) {
|
|
|
2142
2121
|
const attachedNodes = (_a = attachments.get(inputName)) != null ? _a : [];
|
|
2143
2122
|
if (input.config.singleton) {
|
|
2144
2123
|
if (attachedNodes.length > 1) {
|
|
2145
|
-
const attachedNodeIds = attachedNodes.map((e) => e.id);
|
|
2124
|
+
const attachedNodeIds = attachedNodes.map((e) => e.spec.id);
|
|
2146
2125
|
throw Error(
|
|
2147
2126
|
`expected ${input.config.optional ? "at most" : "exactly"} one '${inputName}' input but received multiple: '${attachedNodeIds.join(
|
|
2148
2127
|
"', '"
|
|
@@ -2154,11 +2133,19 @@ function resolveInputs(inputMap, attachments) {
|
|
|
2154
2133
|
}
|
|
2155
2134
|
throw Error(`input '${inputName}' is required but was not received`);
|
|
2156
2135
|
}
|
|
2157
|
-
return
|
|
2136
|
+
return {
|
|
2137
|
+
node: attachedNodes[0],
|
|
2138
|
+
output: resolveInputData(
|
|
2139
|
+
input.extensionData,
|
|
2140
|
+
attachedNodes[0],
|
|
2141
|
+
inputName
|
|
2142
|
+
)
|
|
2143
|
+
};
|
|
2158
2144
|
}
|
|
2159
|
-
return attachedNodes.map(
|
|
2160
|
-
|
|
2161
|
-
|
|
2145
|
+
return attachedNodes.map((attachment) => ({
|
|
2146
|
+
node: attachment,
|
|
2147
|
+
output: resolveInputData(input.extensionData, attachment, inputName)
|
|
2148
|
+
}));
|
|
2162
2149
|
});
|
|
2163
2150
|
}
|
|
2164
2151
|
function createAppNodeInstance(options) {
|
|
@@ -2196,7 +2183,7 @@ function createAppNodeInstance(options) {
|
|
|
2196
2183
|
}
|
|
2197
2184
|
} catch (e) {
|
|
2198
2185
|
throw new Error(
|
|
2199
|
-
`Failed to instantiate extension '${id}'${e.name === "Error" ? `, ${e.message}` : `; caused by ${e}`}`
|
|
2186
|
+
`Failed to instantiate extension '${id}'${e.name === "Error" ? `, ${e.message}` : `; caused by ${e.stack}`}`
|
|
2200
2187
|
);
|
|
2201
2188
|
}
|
|
2202
2189
|
return {
|
|
@@ -2223,7 +2210,7 @@ function instantiateAppNodeTree(rootNode) {
|
|
|
2223
2210
|
if (!childInstance) {
|
|
2224
2211
|
return [];
|
|
2225
2212
|
}
|
|
2226
|
-
return [
|
|
2213
|
+
return [child];
|
|
2227
2214
|
});
|
|
2228
2215
|
if (instantiatedChildren.length > 0) {
|
|
2229
2216
|
instantiatedAttachments.set(input, instantiatedChildren);
|
|
@@ -2253,20 +2240,22 @@ function createAppTree(options) {
|
|
|
2253
2240
|
}
|
|
2254
2241
|
|
|
2255
2242
|
const DefaultProgressComponent = createComponentExtension({
|
|
2256
|
-
ref:
|
|
2243
|
+
ref: coreComponentRefs.progress,
|
|
2257
2244
|
component: { sync: () => components.Progress }
|
|
2258
2245
|
});
|
|
2259
|
-
const DefaultBootErrorPageComponent = createComponentExtension({
|
|
2260
|
-
ref: coreComponentsRefs.bootErrorPage,
|
|
2261
|
-
component: { sync: () => components.BootErrorPage }
|
|
2262
|
-
});
|
|
2263
2246
|
const DefaultNotFoundErrorPageComponent = createComponentExtension({
|
|
2264
|
-
ref:
|
|
2247
|
+
ref: coreComponentRefs.notFoundErrorPage,
|
|
2265
2248
|
component: { sync: () => components.NotFoundErrorPage }
|
|
2266
2249
|
});
|
|
2267
2250
|
const DefaultErrorBoundaryComponent = createComponentExtension({
|
|
2268
|
-
ref:
|
|
2269
|
-
component: {
|
|
2251
|
+
ref: coreComponentRefs.errorBoundaryFallback,
|
|
2252
|
+
component: {
|
|
2253
|
+
sync: () => (props) => {
|
|
2254
|
+
const { plugin, error, resetError } = props;
|
|
2255
|
+
const title = `Error in ${plugin == null ? void 0 : plugin.id}`;
|
|
2256
|
+
return /* @__PURE__ */ React.createElement(ErrorPanel, { title, error, defaultExpanded: true }, /* @__PURE__ */ React.createElement(Button$1, { variant: "outlined", onClick: resetError }, "Retry"));
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2270
2259
|
});
|
|
2271
2260
|
|
|
2272
2261
|
const InternalAppContext = createContext(void 0);
|
|
@@ -2280,6 +2269,16 @@ getOrCreateGlobalSingleton(
|
|
|
2280
2269
|
})
|
|
2281
2270
|
);
|
|
2282
2271
|
|
|
2272
|
+
createApiRef({ id: "core.app-tree" });
|
|
2273
|
+
|
|
2274
|
+
createApiRef({
|
|
2275
|
+
id: "core.components"
|
|
2276
|
+
});
|
|
2277
|
+
|
|
2278
|
+
createApiRef({
|
|
2279
|
+
id: "core.analytics"
|
|
2280
|
+
});
|
|
2281
|
+
|
|
2283
2282
|
function createExtensionDataRef(id) {
|
|
2284
2283
|
return {
|
|
2285
2284
|
id,
|
|
@@ -2361,7 +2360,8 @@ const RouteTracker = ({
|
|
|
2361
2360
|
};
|
|
2362
2361
|
|
|
2363
2362
|
const CoreRouter = createExtension({
|
|
2364
|
-
|
|
2363
|
+
namespace: "core",
|
|
2364
|
+
name: "router",
|
|
2365
2365
|
attachTo: { id: "core", input: "root" },
|
|
2366
2366
|
inputs: {
|
|
2367
2367
|
signInPage: createExtensionInput(
|
|
@@ -2383,7 +2383,7 @@ const CoreRouter = createExtension({
|
|
|
2383
2383
|
factory({ inputs }) {
|
|
2384
2384
|
var _a;
|
|
2385
2385
|
return {
|
|
2386
|
-
element: /* @__PURE__ */ React.createElement(AppRouter, { SignInPageComponent: (_a = inputs.signInPage) == null ? void 0 : _a.component }, inputs.children.element)
|
|
2386
|
+
element: /* @__PURE__ */ React.createElement(AppRouter, { SignInPageComponent: (_a = inputs.signInPage) == null ? void 0 : _a.output.component }, inputs.children.output.element)
|
|
2387
2387
|
};
|
|
2388
2388
|
}
|
|
2389
2389
|
});
|
|
@@ -2403,7 +2403,7 @@ function SignInPageWrapper({
|
|
|
2403
2403
|
children
|
|
2404
2404
|
}) {
|
|
2405
2405
|
const [identityApi, setIdentityApi] = useState();
|
|
2406
|
-
const configApi = useApi
|
|
2406
|
+
const configApi = useApi(configApiRef);
|
|
2407
2407
|
const basePath = getBasePath(configApi);
|
|
2408
2408
|
if (!identityApi) {
|
|
2409
2409
|
return /* @__PURE__ */ React.createElement(Component, { onSignInSuccess: setIdentityApi });
|
|
@@ -2415,7 +2415,7 @@ function SignInPageWrapper({
|
|
|
2415
2415
|
}
|
|
2416
2416
|
function AppRouter(props) {
|
|
2417
2417
|
const { children, SignInPageComponent } = props;
|
|
2418
|
-
const configApi = useApi
|
|
2418
|
+
const configApi = useApi(configApiRef);
|
|
2419
2419
|
const basePath = getBasePath(configApi);
|
|
2420
2420
|
const internalAppContext = useContext(InternalAppContext);
|
|
2421
2421
|
if (!internalAppContext) {
|
|
@@ -2500,11 +2500,10 @@ const builtinExtensions = [
|
|
|
2500
2500
|
CoreLayout,
|
|
2501
2501
|
DefaultProgressComponent,
|
|
2502
2502
|
DefaultErrorBoundaryComponent,
|
|
2503
|
-
DefaultBootErrorPageComponent,
|
|
2504
2503
|
DefaultNotFoundErrorPageComponent,
|
|
2505
2504
|
LightTheme,
|
|
2506
2505
|
DarkTheme
|
|
2507
|
-
];
|
|
2506
|
+
].map((def) => resolveExtensionDefinition(def));
|
|
2508
2507
|
function createExtensionTree(options) {
|
|
2509
2508
|
const features = getAvailableFeatures(options.config);
|
|
2510
2509
|
const tree = createAppTree({
|
|
@@ -2530,7 +2529,7 @@ function createExtensionTree(options) {
|
|
|
2530
2529
|
return (_c = (_b = (_a = tree.nodes.get(id)) == null ? void 0 : _a.edges.attachments.get(inputName)) == null ? void 0 : _b.map(convertNode).filter((node) => Boolean(node))) != null ? _c : [];
|
|
2531
2530
|
},
|
|
2532
2531
|
getRootRoutes() {
|
|
2533
|
-
return this.getExtensionAttachments("core
|
|
2532
|
+
return this.getExtensionAttachments("core/routes", "routes").map((node) => {
|
|
2534
2533
|
const path = node.getData(coreExtensionData.routePath);
|
|
2535
2534
|
const element = node.getData(coreExtensionData.reactElement);
|
|
2536
2535
|
const routeRef = node.getData(coreExtensionData.routeRef);
|
|
@@ -2549,7 +2548,7 @@ function createExtensionTree(options) {
|
|
|
2549
2548
|
const location = useRouteRef(props.routeRef);
|
|
2550
2549
|
return /* @__PURE__ */ React.createElement(SidebarItem, { icon: props.icon, to: location(), text: props.title });
|
|
2551
2550
|
};
|
|
2552
|
-
return this.getExtensionAttachments("core
|
|
2551
|
+
return this.getExtensionAttachments("core/nav", "items").map((node, index) => {
|
|
2553
2552
|
const target = node.getData(coreExtensionData.navTarget);
|
|
2554
2553
|
if (!target) {
|
|
2555
2554
|
return null;
|
|
@@ -2618,11 +2617,6 @@ function createSpecializedApp(options) {
|
|
|
2618
2617
|
builtinExtensions,
|
|
2619
2618
|
config
|
|
2620
2619
|
});
|
|
2621
|
-
const appContext = createLegacyAppContext(
|
|
2622
|
-
features.filter(
|
|
2623
|
-
(f) => f.$$type === "@backstage/BackstagePlugin"
|
|
2624
|
-
)
|
|
2625
|
-
);
|
|
2626
2620
|
const appIdentityProxy = new AppIdentityProxy();
|
|
2627
2621
|
const apiHolder = createApiHolder(tree, config, appIdentityProxy);
|
|
2628
2622
|
const featureFlagApi = apiHolder.get(featureFlagsApiRef);
|
|
@@ -2650,37 +2644,21 @@ function createSpecializedApp(options) {
|
|
|
2650
2644
|
collectRouteIds(features)
|
|
2651
2645
|
);
|
|
2652
2646
|
const rootEl = tree.root.instance.getData(coreExtensionData.reactElement);
|
|
2653
|
-
const App = () => /* @__PURE__ */ React.createElement(ApiProvider, { apis: apiHolder }, /* @__PURE__ */ React.createElement(
|
|
2647
|
+
const App = () => /* @__PURE__ */ React.createElement(ApiProvider, { apis: apiHolder }, /* @__PURE__ */ React.createElement(AppThemeProvider, null, /* @__PURE__ */ React.createElement(RoutingProvider, { ...routeInfo, routeBindings }, /* @__PURE__ */ React.createElement(
|
|
2654
2648
|
InternalAppContext.Provider,
|
|
2655
2649
|
{
|
|
2656
2650
|
value: { appIdentityProxy, routeObjects: routeInfo.routeObjects }
|
|
2657
2651
|
},
|
|
2658
2652
|
rootEl
|
|
2659
|
-
))))
|
|
2653
|
+
))));
|
|
2660
2654
|
return {
|
|
2661
2655
|
createRoot() {
|
|
2662
2656
|
return /* @__PURE__ */ React.createElement(App, null);
|
|
2663
2657
|
}
|
|
2664
2658
|
};
|
|
2665
2659
|
}
|
|
2666
|
-
function createLegacyAppContext(plugins) {
|
|
2667
|
-
return {
|
|
2668
|
-
getPlugins() {
|
|
2669
|
-
return plugins.map(toLegacyPlugin);
|
|
2670
|
-
},
|
|
2671
|
-
getSystemIcon(key) {
|
|
2672
|
-
return key in icons ? icons[key] : void 0;
|
|
2673
|
-
},
|
|
2674
|
-
getSystemIcons() {
|
|
2675
|
-
return icons;
|
|
2676
|
-
},
|
|
2677
|
-
getComponents() {
|
|
2678
|
-
return components;
|
|
2679
|
-
}
|
|
2680
|
-
};
|
|
2681
|
-
}
|
|
2682
2660
|
function createApiHolder(tree, configApi, appIdentityProxy) {
|
|
2683
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2661
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2684
2662
|
const factoryRegistry = new ApiFactoryRegistry();
|
|
2685
2663
|
const pluginApis = (_b = (_a = tree.root.edges.attachments.get("apis")) == null ? void 0 : _a.map((e) => {
|
|
2686
2664
|
var _a2;
|
|
@@ -2690,6 +2668,14 @@ function createApiHolder(tree, configApi, appIdentityProxy) {
|
|
|
2690
2668
|
var _a2;
|
|
2691
2669
|
return (_a2 = e.instance) == null ? void 0 : _a2.getData(coreExtensionData.theme);
|
|
2692
2670
|
}).filter((x) => !!x)) != null ? _d : [];
|
|
2671
|
+
const translationResources = (_f = (_e = tree.root.edges.attachments.get("translations")) == null ? void 0 : _e.map(
|
|
2672
|
+
(e) => {
|
|
2673
|
+
var _a2;
|
|
2674
|
+
return (_a2 = e.instance) == null ? void 0 : _a2.getData(createTranslationExtension.translationDataRef);
|
|
2675
|
+
}
|
|
2676
|
+
).filter(
|
|
2677
|
+
(x) => !!x
|
|
2678
|
+
)) != null ? _f : [];
|
|
2693
2679
|
for (const factory of [...apis, ...pluginApis]) {
|
|
2694
2680
|
factoryRegistry.register("default", factory);
|
|
2695
2681
|
}
|
|
@@ -2710,10 +2696,10 @@ function createApiHolder(tree, configApi, appIdentityProxy) {
|
|
|
2710
2696
|
getTree: () => ({ tree })
|
|
2711
2697
|
})
|
|
2712
2698
|
});
|
|
2713
|
-
const componentsExtensions = (
|
|
2699
|
+
const componentsExtensions = (_h = (_g = tree.root.edges.attachments.get("components")) == null ? void 0 : _g.map((e) => {
|
|
2714
2700
|
var _a2;
|
|
2715
2701
|
return (_a2 = e.instance) == null ? void 0 : _a2.getData(coreExtensionData.component);
|
|
2716
|
-
}).filter((x) => !!x)) != null ?
|
|
2702
|
+
}).filter((x) => !!x)) != null ? _h : [];
|
|
2717
2703
|
const componentsMap = componentsExtensions.reduce(
|
|
2718
2704
|
(components, component) => component ? components.set(component.ref, component == null ? void 0 : component.impl) : components,
|
|
2719
2705
|
/* @__PURE__ */ new Map()
|
|
@@ -2734,13 +2720,6 @@ function createApiHolder(tree, configApi, appIdentityProxy) {
|
|
|
2734
2720
|
deps: {},
|
|
2735
2721
|
factory: () => AppLanguageSelector.createWithStorage()
|
|
2736
2722
|
});
|
|
2737
|
-
factoryRegistry.register("default", {
|
|
2738
|
-
api: translationApiRef,
|
|
2739
|
-
deps: { languageApi: appLanguageApiRef },
|
|
2740
|
-
factory: ({ languageApi }) => I18nextTranslationApi.create({
|
|
2741
|
-
languageApi
|
|
2742
|
-
})
|
|
2743
|
-
});
|
|
2744
2723
|
factoryRegistry.register("static", {
|
|
2745
2724
|
api: configApiRef,
|
|
2746
2725
|
deps: {},
|
|
@@ -2751,11 +2730,12 @@ function createApiHolder(tree, configApi, appIdentityProxy) {
|
|
|
2751
2730
|
deps: {},
|
|
2752
2731
|
factory: () => AppLanguageSelector.createWithStorage()
|
|
2753
2732
|
});
|
|
2754
|
-
factoryRegistry.register("
|
|
2733
|
+
factoryRegistry.register("static", {
|
|
2755
2734
|
api: translationApiRef,
|
|
2756
2735
|
deps: { languageApi: appLanguageApiRef },
|
|
2757
2736
|
factory: ({ languageApi }) => I18nextTranslationApi.create({
|
|
2758
|
-
languageApi
|
|
2737
|
+
languageApi,
|
|
2738
|
+
resources: translationResources
|
|
2759
2739
|
})
|
|
2760
2740
|
});
|
|
2761
2741
|
for (const factory of apis) {
|