@backstage/frontend-app-api 0.3.1-next.0 → 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 +46 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +514 -238
- package/dist/index.esm.js.map +1 -1
- package/package.json +8 -8
package/dist/index.esm.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import React, { useMemo, useState, useEffect } from 'react';
|
|
1
|
+
import React, { useMemo, useState, useEffect, createContext, useContext } from 'react';
|
|
2
2
|
import { ConfigReader } from '@backstage/config';
|
|
3
|
-
import { createExtension, createExtensionInput, coreExtensionData, useRouteRef, createThemeExtension, appTreeApiRef } from '@backstage/frontend-plugin-api';
|
|
4
|
-
import { useRoutes, BrowserRouter, useInRouterContext, MemoryRouter, matchRoutes, generatePath, Route } from 'react-router-dom';
|
|
3
|
+
import { createExtension, createExtensionInput, coreExtensionData, createTranslationExtension, useComponentRef, coreComponentRefs, useRouteRef, createThemeExtension, createComponentExtension, AnalyticsContext, useAnalytics, appTreeApiRef, componentsApiRef } from '@backstage/frontend-plugin-api';
|
|
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, appThemeApiRef, FeatureFlagState, createApiFactory, discoveryApiRef, configApiRef, alertApiRef, analyticsApiRef, errorApiRef, storageApiRef, fetchApiRef, identityApiRef, oauthRequestApiRef, googleAuthApiRef, microsoftAuthApiRef, githubAuthApiRef, oktaAuthApiRef, gitlabAuthApiRef, oneloginAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, atlassianAuthApiRef, attachComponentData, featureFlagsApiRef } from '@backstage/core-plugin-api';
|
|
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: {
|
|
@@ -50,6 +50,12 @@ const Core = createExtension({
|
|
|
50
50
|
themes: createExtensionInput({
|
|
51
51
|
theme: coreExtensionData.theme
|
|
52
52
|
}),
|
|
53
|
+
components: createExtensionInput({
|
|
54
|
+
component: coreExtensionData.component
|
|
55
|
+
}),
|
|
56
|
+
translations: createExtensionInput({
|
|
57
|
+
translation: createTranslationExtension.translationDataRef
|
|
58
|
+
}),
|
|
53
59
|
root: createExtensionInput(
|
|
54
60
|
{
|
|
55
61
|
element: coreExtensionData.reactElement
|
|
@@ -62,14 +68,15 @@ const Core = createExtension({
|
|
|
62
68
|
},
|
|
63
69
|
factory({ inputs }) {
|
|
64
70
|
return {
|
|
65
|
-
root: inputs.root.element
|
|
71
|
+
root: inputs.root.output.element
|
|
66
72
|
};
|
|
67
73
|
}
|
|
68
74
|
});
|
|
69
75
|
|
|
70
76
|
const CoreRoutes = createExtension({
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
namespace: "core",
|
|
78
|
+
name: "routes",
|
|
79
|
+
attachTo: { id: "core/layout", input: "content" },
|
|
73
80
|
inputs: {
|
|
74
81
|
routes: createExtensionInput({
|
|
75
82
|
path: coreExtensionData.routePath,
|
|
@@ -82,12 +89,19 @@ const CoreRoutes = createExtension({
|
|
|
82
89
|
},
|
|
83
90
|
factory({ inputs }) {
|
|
84
91
|
const Routes = () => {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
path: `${route.path}/*`,
|
|
88
|
-
element: route.element
|
|
89
|
-
}))
|
|
92
|
+
const NotFoundErrorPage = useComponentRef(
|
|
93
|
+
coreComponentRefs.notFoundErrorPage
|
|
90
94
|
);
|
|
95
|
+
const element = useRoutes([
|
|
96
|
+
...inputs.routes.map((route) => ({
|
|
97
|
+
path: `${route.output.path}/*`,
|
|
98
|
+
element: route.output.element
|
|
99
|
+
})),
|
|
100
|
+
{
|
|
101
|
+
path: "*",
|
|
102
|
+
element: /* @__PURE__ */ React.createElement(NotFoundErrorPage, null)
|
|
103
|
+
}
|
|
104
|
+
]);
|
|
91
105
|
return element;
|
|
92
106
|
};
|
|
93
107
|
return {
|
|
@@ -97,8 +111,9 @@ const CoreRoutes = createExtension({
|
|
|
97
111
|
});
|
|
98
112
|
|
|
99
113
|
const CoreLayout = createExtension({
|
|
100
|
-
|
|
101
|
-
|
|
114
|
+
namespace: "core",
|
|
115
|
+
name: "layout",
|
|
116
|
+
attachTo: { id: "core/router", input: "children" },
|
|
102
117
|
inputs: {
|
|
103
118
|
nav: createExtensionInput(
|
|
104
119
|
{
|
|
@@ -118,7 +133,7 @@ const CoreLayout = createExtension({
|
|
|
118
133
|
},
|
|
119
134
|
factory({ inputs }) {
|
|
120
135
|
return {
|
|
121
|
-
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)
|
|
122
137
|
};
|
|
123
138
|
}
|
|
124
139
|
});
|
|
@@ -193,10 +208,11 @@ const useSidebarLogoStyles = makeStyles({
|
|
|
193
208
|
marginLeft: 24
|
|
194
209
|
}
|
|
195
210
|
});
|
|
196
|
-
const SidebarLogo = () => {
|
|
211
|
+
const SidebarLogo = (props) => {
|
|
212
|
+
var _a, _b;
|
|
197
213
|
const classes = useSidebarLogoStyles();
|
|
198
214
|
const { isOpen } = useSidebarOpenState();
|
|
199
|
-
return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Link, { to: "/", underline: "none", className: classes.link, "aria-label": "Home" }, isOpen ? /* @__PURE__ */ React.createElement(LogoFull, null) : /* @__PURE__ */ React.createElement(LogoIcon, null)));
|
|
215
|
+
return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Link, { to: "/", underline: "none", className: classes.link, "aria-label": "Home" }, isOpen ? (_a = props == null ? void 0 : props.logoFull) != null ? _a : /* @__PURE__ */ React.createElement(LogoFull, null) : (_b = props == null ? void 0 : props.logoIcon) != null ? _b : /* @__PURE__ */ React.createElement(LogoIcon, null)));
|
|
200
216
|
};
|
|
201
217
|
const SidebarNavItem = (props) => {
|
|
202
218
|
const { icon: Icon, title, routeRef } = props;
|
|
@@ -204,19 +220,30 @@ const SidebarNavItem = (props) => {
|
|
|
204
220
|
return /* @__PURE__ */ React.createElement(SidebarItem, { to, icon: Icon, text: title });
|
|
205
221
|
};
|
|
206
222
|
const CoreNav = createExtension({
|
|
207
|
-
|
|
208
|
-
|
|
223
|
+
namespace: "core",
|
|
224
|
+
name: "nav",
|
|
225
|
+
attachTo: { id: "core/layout", input: "nav" },
|
|
209
226
|
inputs: {
|
|
210
227
|
items: createExtensionInput({
|
|
211
228
|
target: coreExtensionData.navTarget
|
|
212
|
-
})
|
|
229
|
+
}),
|
|
230
|
+
logos: createExtensionInput(
|
|
231
|
+
{
|
|
232
|
+
elements: coreExtensionData.logoElements
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
singleton: true,
|
|
236
|
+
optional: true
|
|
237
|
+
}
|
|
238
|
+
)
|
|
213
239
|
},
|
|
214
240
|
output: {
|
|
215
241
|
element: coreExtensionData.reactElement
|
|
216
242
|
},
|
|
217
243
|
factory({ inputs }) {
|
|
244
|
+
var _a;
|
|
218
245
|
return {
|
|
219
|
-
element: /* @__PURE__ */ React.createElement(Sidebar, null, /* @__PURE__ */ React.createElement(SidebarLogo, null), /* @__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 })))
|
|
220
247
|
};
|
|
221
248
|
}
|
|
222
249
|
});
|
|
@@ -412,15 +439,6 @@ class AppIdentityProxy {
|
|
|
412
439
|
}
|
|
413
440
|
}
|
|
414
441
|
|
|
415
|
-
const AppContext = createVersionedContext("app-context");
|
|
416
|
-
const AppContextProvider = ({
|
|
417
|
-
appContext,
|
|
418
|
-
children
|
|
419
|
-
}) => {
|
|
420
|
-
const versionedValue = createVersionedValueMap({ 1: appContext });
|
|
421
|
-
return /* @__PURE__ */ React.createElement(AppContext.Provider, { value: versionedValue, children });
|
|
422
|
-
};
|
|
423
|
-
|
|
424
442
|
var __defProp$2 = Object.defineProperty;
|
|
425
443
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
426
444
|
var __publicField$2 = (obj, key, value) => {
|
|
@@ -649,21 +667,21 @@ class BehaviorSubject {
|
|
|
649
667
|
}
|
|
650
668
|
}
|
|
651
669
|
|
|
652
|
-
var __accessCheck$
|
|
670
|
+
var __accessCheck$2 = (obj, member, msg) => {
|
|
653
671
|
if (!member.has(obj))
|
|
654
672
|
throw TypeError("Cannot " + msg);
|
|
655
673
|
};
|
|
656
|
-
var __privateGet$
|
|
657
|
-
__accessCheck$
|
|
674
|
+
var __privateGet$2 = (obj, member, getter) => {
|
|
675
|
+
__accessCheck$2(obj, member, "read from private field");
|
|
658
676
|
return getter ? getter.call(obj) : member.get(obj);
|
|
659
677
|
};
|
|
660
|
-
var __privateAdd$
|
|
678
|
+
var __privateAdd$2 = (obj, member, value) => {
|
|
661
679
|
if (member.has(obj))
|
|
662
680
|
throw TypeError("Cannot add the same private member more than once");
|
|
663
681
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
664
682
|
};
|
|
665
|
-
var __privateSet$
|
|
666
|
-
__accessCheck$
|
|
683
|
+
var __privateSet$2 = (obj, member, value, setter) => {
|
|
684
|
+
__accessCheck$2(obj, member, "write to private field");
|
|
667
685
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
668
686
|
return value;
|
|
669
687
|
};
|
|
@@ -672,13 +690,13 @@ const STORAGE_KEY = "language";
|
|
|
672
690
|
const DEFAULT_LANGUAGE = "en";
|
|
673
691
|
const _AppLanguageSelector = class _AppLanguageSelector {
|
|
674
692
|
constructor(languages, initialLanguage) {
|
|
675
|
-
__privateAdd$
|
|
676
|
-
__privateAdd$
|
|
677
|
-
__privateAdd$
|
|
678
|
-
__privateSet$
|
|
679
|
-
__privateSet$
|
|
680
|
-
__privateSet$
|
|
681
|
-
language: __privateGet$
|
|
693
|
+
__privateAdd$2(this, _languages, void 0);
|
|
694
|
+
__privateAdd$2(this, _language$1, void 0);
|
|
695
|
+
__privateAdd$2(this, _subject, void 0);
|
|
696
|
+
__privateSet$2(this, _languages, languages);
|
|
697
|
+
__privateSet$2(this, _language$1, initialLanguage);
|
|
698
|
+
__privateSet$2(this, _subject, new BehaviorSubject({
|
|
699
|
+
language: __privateGet$2(this, _language$1)
|
|
682
700
|
}));
|
|
683
701
|
}
|
|
684
702
|
static create(options) {
|
|
@@ -729,28 +747,28 @@ const _AppLanguageSelector = class _AppLanguageSelector {
|
|
|
729
747
|
return selector;
|
|
730
748
|
}
|
|
731
749
|
getAvailableLanguages() {
|
|
732
|
-
return { languages: __privateGet$
|
|
750
|
+
return { languages: __privateGet$2(this, _languages).slice() };
|
|
733
751
|
}
|
|
734
752
|
setLanguage(language) {
|
|
735
753
|
const lng = language != null ? language : DEFAULT_LANGUAGE;
|
|
736
|
-
if (lng === __privateGet$
|
|
754
|
+
if (lng === __privateGet$2(this, _language$1)) {
|
|
737
755
|
return;
|
|
738
756
|
}
|
|
739
|
-
if (lng && !__privateGet$
|
|
757
|
+
if (lng && !__privateGet$2(this, _languages).includes(lng)) {
|
|
740
758
|
throw new Error(
|
|
741
|
-
`Failed to change language to '${lng}', available languages are '${__privateGet$
|
|
759
|
+
`Failed to change language to '${lng}', available languages are '${__privateGet$2(this, _languages).join(
|
|
742
760
|
"', '"
|
|
743
761
|
)}'`
|
|
744
762
|
);
|
|
745
763
|
}
|
|
746
|
-
__privateSet$
|
|
747
|
-
__privateGet$
|
|
764
|
+
__privateSet$2(this, _language$1, lng);
|
|
765
|
+
__privateGet$2(this, _subject).next({ language: lng });
|
|
748
766
|
}
|
|
749
767
|
getLanguage() {
|
|
750
|
-
return { language: __privateGet$
|
|
768
|
+
return { language: __privateGet$2(this, _language$1) };
|
|
751
769
|
}
|
|
752
770
|
language$() {
|
|
753
|
-
return __privateGet$
|
|
771
|
+
return __privateGet$2(this, _subject);
|
|
754
772
|
}
|
|
755
773
|
};
|
|
756
774
|
_languages = new WeakMap();
|
|
@@ -780,26 +798,26 @@ function toInternalTranslationRef(ref) {
|
|
|
780
798
|
return r;
|
|
781
799
|
}
|
|
782
800
|
|
|
783
|
-
var __accessCheck = (obj, member, msg) => {
|
|
801
|
+
var __accessCheck$1 = (obj, member, msg) => {
|
|
784
802
|
if (!member.has(obj))
|
|
785
803
|
throw TypeError("Cannot " + msg);
|
|
786
804
|
};
|
|
787
|
-
var __privateGet = (obj, member, getter) => {
|
|
788
|
-
__accessCheck(obj, member, "read from private field");
|
|
805
|
+
var __privateGet$1 = (obj, member, getter) => {
|
|
806
|
+
__accessCheck$1(obj, member, "read from private field");
|
|
789
807
|
return getter ? getter.call(obj) : member.get(obj);
|
|
790
808
|
};
|
|
791
|
-
var __privateAdd = (obj, member, value) => {
|
|
809
|
+
var __privateAdd$1 = (obj, member, value) => {
|
|
792
810
|
if (member.has(obj))
|
|
793
811
|
throw TypeError("Cannot add the same private member more than once");
|
|
794
812
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
795
813
|
};
|
|
796
|
-
var __privateSet = (obj, member, value, setter) => {
|
|
797
|
-
__accessCheck(obj, member, "write to private field");
|
|
814
|
+
var __privateSet$1 = (obj, member, value, setter) => {
|
|
815
|
+
__accessCheck$1(obj, member, "write to private field");
|
|
798
816
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
799
817
|
return value;
|
|
800
818
|
};
|
|
801
819
|
var __privateMethod = (obj, member, method) => {
|
|
802
|
-
__accessCheck(obj, member, "access private method");
|
|
820
|
+
__accessCheck$1(obj, member, "access private method");
|
|
803
821
|
return method;
|
|
804
822
|
};
|
|
805
823
|
var _loaded, _loading, _loaders, _getLoaderKey, getLoaderKey_fn, _i18n, _loader, _language, _registeredRefs, _languageChangeListeners, _changeLanguage, changeLanguage_fn, _createSnapshot, createSnapshot_fn, _registerDefaults, registerDefaults_fn;
|
|
@@ -813,41 +831,41 @@ function removeNulls(messages) {
|
|
|
813
831
|
class ResourceLoader {
|
|
814
832
|
constructor(onLoad) {
|
|
815
833
|
this.onLoad = onLoad;
|
|
816
|
-
__privateAdd(this, _getLoaderKey);
|
|
834
|
+
__privateAdd$1(this, _getLoaderKey);
|
|
817
835
|
/** Loaded resources by loader key */
|
|
818
|
-
__privateAdd(this, _loaded, /* @__PURE__ */ new Set());
|
|
836
|
+
__privateAdd$1(this, _loaded, /* @__PURE__ */ new Set());
|
|
819
837
|
/** Resource loading promises by loader key */
|
|
820
|
-
__privateAdd(this, _loading, /* @__PURE__ */ new Map());
|
|
838
|
+
__privateAdd$1(this, _loading, /* @__PURE__ */ new Map());
|
|
821
839
|
/** Loaders for each resource language */
|
|
822
|
-
__privateAdd(this, _loaders, /* @__PURE__ */ new Map());
|
|
840
|
+
__privateAdd$1(this, _loaders, /* @__PURE__ */ new Map());
|
|
823
841
|
}
|
|
824
842
|
addTranslationResource(resource) {
|
|
825
843
|
const internalResource = toInternalTranslationResource(resource);
|
|
826
844
|
for (const entry of internalResource.resources) {
|
|
827
845
|
const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, entry.language, internalResource.id);
|
|
828
|
-
if (!__privateGet(this, _loaders).has(key)) {
|
|
829
|
-
__privateGet(this, _loaders).set(key, entry.loader);
|
|
846
|
+
if (!__privateGet$1(this, _loaders).has(key)) {
|
|
847
|
+
__privateGet$1(this, _loaders).set(key, entry.loader);
|
|
830
848
|
}
|
|
831
849
|
}
|
|
832
850
|
}
|
|
833
851
|
needsLoading(language, namespace) {
|
|
834
852
|
const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, language, namespace);
|
|
835
|
-
const loader = __privateGet(this, _loaders).get(key);
|
|
853
|
+
const loader = __privateGet$1(this, _loaders).get(key);
|
|
836
854
|
if (!loader) {
|
|
837
855
|
return false;
|
|
838
856
|
}
|
|
839
|
-
return !__privateGet(this, _loaded).has(key);
|
|
857
|
+
return !__privateGet$1(this, _loaded).has(key);
|
|
840
858
|
}
|
|
841
859
|
async load(language, namespace) {
|
|
842
860
|
const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, language, namespace);
|
|
843
|
-
const loader = __privateGet(this, _loaders).get(key);
|
|
861
|
+
const loader = __privateGet$1(this, _loaders).get(key);
|
|
844
862
|
if (!loader) {
|
|
845
863
|
return;
|
|
846
864
|
}
|
|
847
|
-
if (__privateGet(this, _loaded).has(key)) {
|
|
865
|
+
if (__privateGet$1(this, _loaded).has(key)) {
|
|
848
866
|
return;
|
|
849
867
|
}
|
|
850
|
-
const loading = __privateGet(this, _loading).get(key);
|
|
868
|
+
const loading = __privateGet$1(this, _loading).get(key);
|
|
851
869
|
if (loading) {
|
|
852
870
|
await loading;
|
|
853
871
|
return;
|
|
@@ -855,14 +873,14 @@ class ResourceLoader {
|
|
|
855
873
|
const load = loader().then(
|
|
856
874
|
(result) => {
|
|
857
875
|
this.onLoad({ language, namespace, messages: result.messages });
|
|
858
|
-
__privateGet(this, _loaded).add(key);
|
|
876
|
+
__privateGet$1(this, _loaded).add(key);
|
|
859
877
|
},
|
|
860
878
|
(error) => {
|
|
861
|
-
__privateGet(this, _loaded).add(key);
|
|
879
|
+
__privateGet$1(this, _loaded).add(key);
|
|
862
880
|
throw error;
|
|
863
881
|
}
|
|
864
882
|
);
|
|
865
|
-
__privateGet(this, _loading).set(key, load);
|
|
883
|
+
__privateGet$1(this, _loading).set(key, load);
|
|
866
884
|
await load;
|
|
867
885
|
}
|
|
868
886
|
}
|
|
@@ -875,19 +893,19 @@ getLoaderKey_fn = function(language, namespace) {
|
|
|
875
893
|
};
|
|
876
894
|
const _I18nextTranslationApi = class _I18nextTranslationApi {
|
|
877
895
|
constructor(i18n, loader, language) {
|
|
878
|
-
__privateAdd(this, _changeLanguage);
|
|
879
|
-
__privateAdd(this, _createSnapshot);
|
|
880
|
-
__privateAdd(this, _registerDefaults);
|
|
881
|
-
__privateAdd(this, _i18n, void 0);
|
|
882
|
-
__privateAdd(this, _loader, void 0);
|
|
883
|
-
__privateAdd(this, _language, void 0);
|
|
896
|
+
__privateAdd$1(this, _changeLanguage);
|
|
897
|
+
__privateAdd$1(this, _createSnapshot);
|
|
898
|
+
__privateAdd$1(this, _registerDefaults);
|
|
899
|
+
__privateAdd$1(this, _i18n, void 0);
|
|
900
|
+
__privateAdd$1(this, _loader, void 0);
|
|
901
|
+
__privateAdd$1(this, _language, void 0);
|
|
884
902
|
/** Keep track of which refs we have registered default resources for */
|
|
885
|
-
__privateAdd(this, _registeredRefs, /* @__PURE__ */ new Set());
|
|
903
|
+
__privateAdd$1(this, _registeredRefs, /* @__PURE__ */ new Set());
|
|
886
904
|
/** Notify observers when language changes */
|
|
887
|
-
__privateAdd(this, _languageChangeListeners, /* @__PURE__ */ new Set());
|
|
888
|
-
__privateSet(this, _i18n, i18n);
|
|
889
|
-
__privateSet(this, _loader, loader);
|
|
890
|
-
__privateSet(this, _language, language);
|
|
905
|
+
__privateAdd$1(this, _languageChangeListeners, /* @__PURE__ */ new Set());
|
|
906
|
+
__privateSet$1(this, _i18n, i18n);
|
|
907
|
+
__privateSet$1(this, _loader, loader);
|
|
908
|
+
__privateSet$1(this, _language, language);
|
|
891
909
|
}
|
|
892
910
|
static create(options) {
|
|
893
911
|
const { languages } = options.languageApi.getAvailableLanguages();
|
|
@@ -963,7 +981,7 @@ const _I18nextTranslationApi = class _I18nextTranslationApi {
|
|
|
963
981
|
const loadResource = () => {
|
|
964
982
|
loadTicket = {};
|
|
965
983
|
const ticket = loadTicket;
|
|
966
|
-
__privateGet(this, _loader).load(__privateGet(this, _language), internalRef.id).then(
|
|
984
|
+
__privateGet$1(this, _loader).load(__privateGet$1(this, _language), internalRef.id).then(
|
|
967
985
|
() => {
|
|
968
986
|
if (ticket === loadTicket) {
|
|
969
987
|
const snapshot = __privateMethod(this, _createSnapshot, createSnapshot_fn).call(this, internalRef);
|
|
@@ -987,12 +1005,12 @@ const _I18nextTranslationApi = class _I18nextTranslationApi {
|
|
|
987
1005
|
loadResource();
|
|
988
1006
|
}
|
|
989
1007
|
};
|
|
990
|
-
if (__privateGet(this, _loader).needsLoading(__privateGet(this, _language), internalRef.id)) {
|
|
1008
|
+
if (__privateGet$1(this, _loader).needsLoading(__privateGet$1(this, _language), internalRef.id)) {
|
|
991
1009
|
loadResource();
|
|
992
1010
|
}
|
|
993
|
-
__privateGet(this, _languageChangeListeners).add(onChange);
|
|
1011
|
+
__privateGet$1(this, _languageChangeListeners).add(onChange);
|
|
994
1012
|
return () => {
|
|
995
|
-
__privateGet(this, _languageChangeListeners).delete(onChange);
|
|
1013
|
+
__privateGet$1(this, _languageChangeListeners).delete(onChange);
|
|
996
1014
|
};
|
|
997
1015
|
});
|
|
998
1016
|
}
|
|
@@ -1004,18 +1022,18 @@ _registeredRefs = new WeakMap();
|
|
|
1004
1022
|
_languageChangeListeners = new WeakMap();
|
|
1005
1023
|
_changeLanguage = new WeakSet();
|
|
1006
1024
|
changeLanguage_fn = function(language) {
|
|
1007
|
-
if (__privateGet(this, _language) !== language) {
|
|
1008
|
-
__privateSet(this, _language, language);
|
|
1009
|
-
__privateGet(this, _i18n).changeLanguage(language);
|
|
1010
|
-
__privateGet(this, _languageChangeListeners).forEach((listener) => listener());
|
|
1025
|
+
if (__privateGet$1(this, _language) !== language) {
|
|
1026
|
+
__privateSet$1(this, _language, language);
|
|
1027
|
+
__privateGet$1(this, _i18n).changeLanguage(language);
|
|
1028
|
+
__privateGet$1(this, _languageChangeListeners).forEach((listener) => listener());
|
|
1011
1029
|
}
|
|
1012
1030
|
};
|
|
1013
1031
|
_createSnapshot = new WeakSet();
|
|
1014
1032
|
createSnapshot_fn = function(internalRef) {
|
|
1015
|
-
if (__privateGet(this, _loader).needsLoading(__privateGet(this, _language), internalRef.id)) {
|
|
1033
|
+
if (__privateGet$1(this, _loader).needsLoading(__privateGet$1(this, _language), internalRef.id)) {
|
|
1016
1034
|
return { ready: false };
|
|
1017
1035
|
}
|
|
1018
|
-
const t = __privateGet(this, _i18n).getFixedT(
|
|
1036
|
+
const t = __privateGet$1(this, _i18n).getFixedT(
|
|
1019
1037
|
null,
|
|
1020
1038
|
internalRef.id
|
|
1021
1039
|
);
|
|
@@ -1026,12 +1044,12 @@ createSnapshot_fn = function(internalRef) {
|
|
|
1026
1044
|
};
|
|
1027
1045
|
_registerDefaults = new WeakSet();
|
|
1028
1046
|
registerDefaults_fn = function(internalRef) {
|
|
1029
|
-
if (__privateGet(this, _registeredRefs).has(internalRef.id)) {
|
|
1047
|
+
if (__privateGet$1(this, _registeredRefs).has(internalRef.id)) {
|
|
1030
1048
|
return;
|
|
1031
1049
|
}
|
|
1032
|
-
__privateGet(this, _registeredRefs).add(internalRef.id);
|
|
1050
|
+
__privateGet$1(this, _registeredRefs).add(internalRef.id);
|
|
1033
1051
|
const defaultMessages = internalRef.getDefaultMessages();
|
|
1034
|
-
__privateGet(this, _i18n).addResourceBundle(
|
|
1052
|
+
__privateGet$1(this, _i18n).addResourceBundle(
|
|
1035
1053
|
DEFAULT_LANGUAGE,
|
|
1036
1054
|
internalRef.id,
|
|
1037
1055
|
defaultMessages,
|
|
@@ -1042,11 +1060,28 @@ registerDefaults_fn = function(internalRef) {
|
|
|
1042
1060
|
);
|
|
1043
1061
|
const defaultResource = internalRef.getDefaultResource();
|
|
1044
1062
|
if (defaultResource) {
|
|
1045
|
-
__privateGet(this, _loader).addTranslationResource(defaultResource);
|
|
1063
|
+
__privateGet$1(this, _loader).addTranslationResource(defaultResource);
|
|
1046
1064
|
}
|
|
1047
1065
|
};
|
|
1048
1066
|
let I18nextTranslationApi = _I18nextTranslationApi;
|
|
1049
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
|
+
|
|
1050
1085
|
const apis = [
|
|
1051
1086
|
createApiFactory({
|
|
1052
1087
|
api: discoveryApiRef,
|
|
@@ -1285,33 +1320,6 @@ const components = {
|
|
|
1285
1320
|
ErrorBoundaryFallback: DefaultErrorBoundaryFallback
|
|
1286
1321
|
};
|
|
1287
1322
|
|
|
1288
|
-
const icons = {
|
|
1289
|
-
brokenImage: MuiBrokenImageIcon,
|
|
1290
|
-
// To be confirmed: see https://github.com/backstage/backstage/issues/4970
|
|
1291
|
-
catalog: MuiMenuBookIcon,
|
|
1292
|
-
scaffolder: MuiCreateNewFolderIcon,
|
|
1293
|
-
techdocs: MuiSubjectIcon,
|
|
1294
|
-
search: MuiSearchIcon,
|
|
1295
|
-
chat: MuiChatIcon,
|
|
1296
|
-
dashboard: MuiDashboardIcon,
|
|
1297
|
-
docs: MuiDocsIcon,
|
|
1298
|
-
email: MuiEmailIcon,
|
|
1299
|
-
github: MuiGitHubIcon,
|
|
1300
|
-
group: MuiPeopleIcon,
|
|
1301
|
-
help: MuiHelpIcon,
|
|
1302
|
-
"kind:api": MuiExtensionIcon,
|
|
1303
|
-
"kind:component": MuiMemoryIcon,
|
|
1304
|
-
"kind:domain": MuiApartmentIcon,
|
|
1305
|
-
"kind:group": MuiPeopleIcon,
|
|
1306
|
-
"kind:location": MuiLocationOnIcon,
|
|
1307
|
-
"kind:system": MuiCategoryIcon,
|
|
1308
|
-
"kind:user": MuiPersonIcon,
|
|
1309
|
-
"kind:resource": MuiWorkIcon,
|
|
1310
|
-
"kind:template": MuiFeaturedPlayListIcon,
|
|
1311
|
-
user: MuiPersonIcon,
|
|
1312
|
-
warning: MuiWarningIcon
|
|
1313
|
-
};
|
|
1314
|
-
|
|
1315
1323
|
const LightTheme = createThemeExtension({
|
|
1316
1324
|
id: "light",
|
|
1317
1325
|
title: "Light Theme",
|
|
@@ -1394,7 +1402,8 @@ function extractRouteInfoFromAppNode(node) {
|
|
|
1394
1402
|
routeRefs: /* @__PURE__ */ new Set(),
|
|
1395
1403
|
caseSensitive: false,
|
|
1396
1404
|
children: [MATCH_ALL_ROUTE],
|
|
1397
|
-
plugins: /* @__PURE__ */ new Set()
|
|
1405
|
+
plugins: /* @__PURE__ */ new Set(),
|
|
1406
|
+
appNode: current
|
|
1398
1407
|
};
|
|
1399
1408
|
parentChildren.push(currentObj);
|
|
1400
1409
|
newParentRef = candidateParentRef;
|
|
@@ -1731,14 +1740,6 @@ function expandShorthandExtensionParameters(arrayEntry, arrayIndex) {
|
|
|
1731
1740
|
errorMsg("extension ID must not be empty or contain whitespace")
|
|
1732
1741
|
);
|
|
1733
1742
|
}
|
|
1734
|
-
if (id2.includes("/")) {
|
|
1735
|
-
let message = `extension ID must not contain slashes; got '${id2}'`;
|
|
1736
|
-
const good = id2.split("/")[0];
|
|
1737
|
-
if (good) {
|
|
1738
|
-
message += `, did you mean '${good}'?`;
|
|
1739
|
-
}
|
|
1740
|
-
throw new Error(errorMsg(message));
|
|
1741
|
-
}
|
|
1742
1743
|
}
|
|
1743
1744
|
if (typeof arrayEntry === "string") {
|
|
1744
1745
|
assertValidId(arrayEntry);
|
|
@@ -1918,12 +1919,25 @@ function toInternalExtensionOverrides(overrides) {
|
|
|
1918
1919
|
const internal = overrides;
|
|
1919
1920
|
if (internal.$$type !== "@backstage/ExtensionOverrides") {
|
|
1920
1921
|
throw new Error(
|
|
1921
|
-
`Invalid
|
|
1922
|
+
`Invalid extension overrides instance, bad type '${internal.$$type}'`
|
|
1923
|
+
);
|
|
1924
|
+
}
|
|
1925
|
+
if (internal.version !== "v1") {
|
|
1926
|
+
throw new Error(
|
|
1927
|
+
`Invalid extension overrides instance, bad version '${internal.version}'`
|
|
1922
1928
|
);
|
|
1923
1929
|
}
|
|
1930
|
+
return internal;
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
function toInternalBackstagePlugin(plugin) {
|
|
1934
|
+
const internal = plugin;
|
|
1935
|
+
if (internal.$$type !== "@backstage/BackstagePlugin") {
|
|
1936
|
+
throw new Error(`Invalid plugin instance, bad type '${internal.$$type}'`);
|
|
1937
|
+
}
|
|
1924
1938
|
if (internal.version !== "v1") {
|
|
1925
1939
|
throw new Error(
|
|
1926
|
-
`Invalid
|
|
1940
|
+
`Invalid plugin instance, bad version '${internal.version}'`
|
|
1927
1941
|
);
|
|
1928
1942
|
}
|
|
1929
1943
|
return internal;
|
|
@@ -1939,7 +1953,10 @@ function resolveAppNodeSpecs(options) {
|
|
|
1939
1953
|
(f) => f.$$type === "@backstage/ExtensionOverrides"
|
|
1940
1954
|
);
|
|
1941
1955
|
const pluginExtensions = plugins.flatMap((source) => {
|
|
1942
|
-
return source.extensions.map((extension) => ({
|
|
1956
|
+
return toInternalBackstagePlugin(source).extensions.map((extension) => ({
|
|
1957
|
+
...extension,
|
|
1958
|
+
source
|
|
1959
|
+
}));
|
|
1943
1960
|
});
|
|
1944
1961
|
const overrideExtensions = overrides.flatMap(
|
|
1945
1962
|
(override) => toInternalExtensionOverrides(override).extensions
|
|
@@ -2078,10 +2095,11 @@ function resolveAppNodeSpecs(options) {
|
|
|
2078
2095
|
|
|
2079
2096
|
function resolveInputData(dataMap, attachment, inputName) {
|
|
2080
2097
|
return mapValues(dataMap, (ref) => {
|
|
2081
|
-
|
|
2098
|
+
var _a;
|
|
2099
|
+
const value = (_a = attachment.instance) == null ? void 0 : _a.getData(ref);
|
|
2082
2100
|
if (value === void 0 && !ref.config.optional) {
|
|
2083
2101
|
throw new Error(
|
|
2084
|
-
`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}'`
|
|
2085
2103
|
);
|
|
2086
2104
|
}
|
|
2087
2105
|
return value;
|
|
@@ -2094,7 +2112,7 @@ function resolveInputs(inputMap, attachments) {
|
|
|
2094
2112
|
if (undeclaredAttachments.length > 0) {
|
|
2095
2113
|
throw new Error(
|
|
2096
2114
|
`received undeclared input${undeclaredAttachments.length > 1 ? "s" : ""} ${undeclaredAttachments.map(
|
|
2097
|
-
([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("', '")}'`
|
|
2098
2116
|
).join(" and ")}`
|
|
2099
2117
|
);
|
|
2100
2118
|
}
|
|
@@ -2103,7 +2121,7 @@ function resolveInputs(inputMap, attachments) {
|
|
|
2103
2121
|
const attachedNodes = (_a = attachments.get(inputName)) != null ? _a : [];
|
|
2104
2122
|
if (input.config.singleton) {
|
|
2105
2123
|
if (attachedNodes.length > 1) {
|
|
2106
|
-
const attachedNodeIds = attachedNodes.map((e) => e.id);
|
|
2124
|
+
const attachedNodeIds = attachedNodes.map((e) => e.spec.id);
|
|
2107
2125
|
throw Error(
|
|
2108
2126
|
`expected ${input.config.optional ? "at most" : "exactly"} one '${inputName}' input but received multiple: '${attachedNodeIds.join(
|
|
2109
2127
|
"', '"
|
|
@@ -2115,17 +2133,25 @@ function resolveInputs(inputMap, attachments) {
|
|
|
2115
2133
|
}
|
|
2116
2134
|
throw Error(`input '${inputName}' is required but was not received`);
|
|
2117
2135
|
}
|
|
2118
|
-
return
|
|
2136
|
+
return {
|
|
2137
|
+
node: attachedNodes[0],
|
|
2138
|
+
output: resolveInputData(
|
|
2139
|
+
input.extensionData,
|
|
2140
|
+
attachedNodes[0],
|
|
2141
|
+
inputName
|
|
2142
|
+
)
|
|
2143
|
+
};
|
|
2119
2144
|
}
|
|
2120
|
-
return attachedNodes.map(
|
|
2121
|
-
|
|
2122
|
-
|
|
2145
|
+
return attachedNodes.map((attachment) => ({
|
|
2146
|
+
node: attachment,
|
|
2147
|
+
output: resolveInputData(input.extensionData, attachment, inputName)
|
|
2148
|
+
}));
|
|
2123
2149
|
});
|
|
2124
2150
|
}
|
|
2125
2151
|
function createAppNodeInstance(options) {
|
|
2126
2152
|
var _a;
|
|
2127
|
-
const {
|
|
2128
|
-
const { id, extension, config
|
|
2153
|
+
const { node, attachments } = options;
|
|
2154
|
+
const { id, extension, config } = node.spec;
|
|
2129
2155
|
const extensionData = /* @__PURE__ */ new Map();
|
|
2130
2156
|
const extensionDataRefs = /* @__PURE__ */ new Set();
|
|
2131
2157
|
let parsedConfig;
|
|
@@ -2138,7 +2164,7 @@ function createAppNodeInstance(options) {
|
|
|
2138
2164
|
}
|
|
2139
2165
|
try {
|
|
2140
2166
|
const namedOutputs = extension.factory({
|
|
2141
|
-
|
|
2167
|
+
node,
|
|
2142
2168
|
config: parsedConfig,
|
|
2143
2169
|
inputs: resolveInputs(extension.inputs, attachments)
|
|
2144
2170
|
});
|
|
@@ -2157,7 +2183,7 @@ function createAppNodeInstance(options) {
|
|
|
2157
2183
|
}
|
|
2158
2184
|
} catch (e) {
|
|
2159
2185
|
throw new Error(
|
|
2160
|
-
`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}`}`
|
|
2161
2187
|
);
|
|
2162
2188
|
}
|
|
2163
2189
|
return {
|
|
@@ -2184,14 +2210,14 @@ function instantiateAppNodeTree(rootNode) {
|
|
|
2184
2210
|
if (!childInstance) {
|
|
2185
2211
|
return [];
|
|
2186
2212
|
}
|
|
2187
|
-
return [
|
|
2213
|
+
return [child];
|
|
2188
2214
|
});
|
|
2189
2215
|
if (instantiatedChildren.length > 0) {
|
|
2190
2216
|
instantiatedAttachments.set(input, instantiatedChildren);
|
|
2191
2217
|
}
|
|
2192
2218
|
}
|
|
2193
2219
|
node.instance = createAppNodeInstance({
|
|
2194
|
-
|
|
2220
|
+
node,
|
|
2195
2221
|
attachments: instantiatedAttachments
|
|
2196
2222
|
});
|
|
2197
2223
|
return node.instance;
|
|
@@ -2213,14 +2239,271 @@ function createAppTree(options) {
|
|
|
2213
2239
|
return tree;
|
|
2214
2240
|
}
|
|
2215
2241
|
|
|
2242
|
+
const DefaultProgressComponent = createComponentExtension({
|
|
2243
|
+
ref: coreComponentRefs.progress,
|
|
2244
|
+
component: { sync: () => components.Progress }
|
|
2245
|
+
});
|
|
2246
|
+
const DefaultNotFoundErrorPageComponent = createComponentExtension({
|
|
2247
|
+
ref: coreComponentRefs.notFoundErrorPage,
|
|
2248
|
+
component: { sync: () => components.NotFoundErrorPage }
|
|
2249
|
+
});
|
|
2250
|
+
const DefaultErrorBoundaryComponent = createComponentExtension({
|
|
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
|
+
}
|
|
2259
|
+
});
|
|
2260
|
+
|
|
2261
|
+
const InternalAppContext = createContext(void 0);
|
|
2262
|
+
|
|
2263
|
+
getOrCreateGlobalSingleton(
|
|
2264
|
+
"core-plugin-api:analytics-tracker-events",
|
|
2265
|
+
() => ({
|
|
2266
|
+
mostRecentGatheredNavigation: void 0,
|
|
2267
|
+
mostRecentRoutableExtensionRender: void 0,
|
|
2268
|
+
beforeUnloadRegistered: false
|
|
2269
|
+
})
|
|
2270
|
+
);
|
|
2271
|
+
|
|
2272
|
+
createApiRef({ id: "core.app-tree" });
|
|
2273
|
+
|
|
2274
|
+
createApiRef({
|
|
2275
|
+
id: "core.components"
|
|
2276
|
+
});
|
|
2277
|
+
|
|
2278
|
+
createApiRef({
|
|
2279
|
+
id: "core.analytics"
|
|
2280
|
+
});
|
|
2281
|
+
|
|
2282
|
+
function createExtensionDataRef(id) {
|
|
2283
|
+
return {
|
|
2284
|
+
id,
|
|
2285
|
+
$$type: "@backstage/ExtensionDataRef",
|
|
2286
|
+
config: {},
|
|
2287
|
+
optional() {
|
|
2288
|
+
return { ...this, config: { ...this.config, optional: true } };
|
|
2289
|
+
}
|
|
2290
|
+
};
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
const signInPageComponentDataRef = createExtensionDataRef("core.signInPage");
|
|
2294
|
+
|
|
2295
|
+
const getExtensionContext = (pathname, routes) => {
|
|
2296
|
+
var _a, _b;
|
|
2297
|
+
try {
|
|
2298
|
+
const matches = matchRoutes(routes, { pathname });
|
|
2299
|
+
const routeMatch = matches == null ? void 0 : matches.filter((match) => {
|
|
2300
|
+
var _a2;
|
|
2301
|
+
return ((_a2 = match == null ? void 0 : match.route.routeRefs) == null ? void 0 : _a2.size) > 0;
|
|
2302
|
+
}).pop();
|
|
2303
|
+
const routeObject = routeMatch == null ? void 0 : routeMatch.route;
|
|
2304
|
+
if (!routeObject) {
|
|
2305
|
+
return void 0;
|
|
2306
|
+
}
|
|
2307
|
+
if (routeObject.path === "" && pathname !== "/") {
|
|
2308
|
+
return void 0;
|
|
2309
|
+
}
|
|
2310
|
+
const params = Object.entries(
|
|
2311
|
+
(routeMatch == null ? void 0 : routeMatch.params) || {}
|
|
2312
|
+
).reduce((acc, [key, value]) => {
|
|
2313
|
+
if (value !== void 0 && key !== "*") {
|
|
2314
|
+
acc[key] = value;
|
|
2315
|
+
}
|
|
2316
|
+
return acc;
|
|
2317
|
+
}, {});
|
|
2318
|
+
const plugin = (_a = routeObject.appNode) == null ? void 0 : _a.spec.source;
|
|
2319
|
+
const extension = (_b = routeObject.appNode) == null ? void 0 : _b.spec.extension;
|
|
2320
|
+
return {
|
|
2321
|
+
params,
|
|
2322
|
+
pluginId: (plugin == null ? void 0 : plugin.id) || "root",
|
|
2323
|
+
extensionId: (extension == null ? void 0 : extension.id) || "App"
|
|
2324
|
+
};
|
|
2325
|
+
} catch {
|
|
2326
|
+
return void 0;
|
|
2327
|
+
}
|
|
2328
|
+
};
|
|
2329
|
+
const TrackNavigation = ({
|
|
2330
|
+
pathname,
|
|
2331
|
+
search,
|
|
2332
|
+
hash,
|
|
2333
|
+
attributes
|
|
2334
|
+
}) => {
|
|
2335
|
+
const analytics = useAnalytics();
|
|
2336
|
+
useEffect(() => {
|
|
2337
|
+
analytics.captureEvent("navigate", `${pathname}${search}${hash}`, {
|
|
2338
|
+
attributes
|
|
2339
|
+
});
|
|
2340
|
+
}, [analytics, pathname, search, hash, attributes]);
|
|
2341
|
+
return null;
|
|
2342
|
+
};
|
|
2343
|
+
const RouteTracker = ({
|
|
2344
|
+
routeObjects
|
|
2345
|
+
}) => {
|
|
2346
|
+
const { pathname, search, hash } = useLocation();
|
|
2347
|
+
const { params, ...attributes } = getExtensionContext(
|
|
2348
|
+
pathname,
|
|
2349
|
+
routeObjects
|
|
2350
|
+
) || { params: {} };
|
|
2351
|
+
return /* @__PURE__ */ React.createElement(AnalyticsContext, { attributes }, /* @__PURE__ */ React.createElement(
|
|
2352
|
+
TrackNavigation,
|
|
2353
|
+
{
|
|
2354
|
+
pathname,
|
|
2355
|
+
search,
|
|
2356
|
+
hash,
|
|
2357
|
+
attributes: params
|
|
2358
|
+
}
|
|
2359
|
+
));
|
|
2360
|
+
};
|
|
2361
|
+
|
|
2362
|
+
const CoreRouter = createExtension({
|
|
2363
|
+
namespace: "core",
|
|
2364
|
+
name: "router",
|
|
2365
|
+
attachTo: { id: "core", input: "root" },
|
|
2366
|
+
inputs: {
|
|
2367
|
+
signInPage: createExtensionInput(
|
|
2368
|
+
{
|
|
2369
|
+
component: signInPageComponentDataRef
|
|
2370
|
+
},
|
|
2371
|
+
{ singleton: true, optional: true }
|
|
2372
|
+
),
|
|
2373
|
+
children: createExtensionInput(
|
|
2374
|
+
{
|
|
2375
|
+
element: coreExtensionData.reactElement
|
|
2376
|
+
},
|
|
2377
|
+
{ singleton: true }
|
|
2378
|
+
)
|
|
2379
|
+
},
|
|
2380
|
+
output: {
|
|
2381
|
+
element: coreExtensionData.reactElement
|
|
2382
|
+
},
|
|
2383
|
+
factory({ inputs }) {
|
|
2384
|
+
var _a;
|
|
2385
|
+
return {
|
|
2386
|
+
element: /* @__PURE__ */ React.createElement(AppRouter, { SignInPageComponent: (_a = inputs.signInPage) == null ? void 0 : _a.output.component }, inputs.children.output.element)
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
});
|
|
2390
|
+
function getBasePath(configApi) {
|
|
2391
|
+
var _a;
|
|
2392
|
+
let { pathname } = new URL(
|
|
2393
|
+
(_a = configApi.getOptionalString("app.baseUrl")) != null ? _a : "/",
|
|
2394
|
+
"http://sample.dev"
|
|
2395
|
+
// baseUrl can be specified as just a path
|
|
2396
|
+
);
|
|
2397
|
+
pathname = pathname.replace(/\/*$/, "");
|
|
2398
|
+
return pathname;
|
|
2399
|
+
}
|
|
2400
|
+
function SignInPageWrapper({
|
|
2401
|
+
component: Component,
|
|
2402
|
+
appIdentityProxy,
|
|
2403
|
+
children
|
|
2404
|
+
}) {
|
|
2405
|
+
const [identityApi, setIdentityApi] = useState();
|
|
2406
|
+
const configApi = useApi(configApiRef);
|
|
2407
|
+
const basePath = getBasePath(configApi);
|
|
2408
|
+
if (!identityApi) {
|
|
2409
|
+
return /* @__PURE__ */ React.createElement(Component, { onSignInSuccess: setIdentityApi });
|
|
2410
|
+
}
|
|
2411
|
+
appIdentityProxy.setTarget(identityApi, {
|
|
2412
|
+
signOutTargetUrl: basePath || "/"
|
|
2413
|
+
});
|
|
2414
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
2415
|
+
}
|
|
2416
|
+
function AppRouter(props) {
|
|
2417
|
+
const { children, SignInPageComponent } = props;
|
|
2418
|
+
const configApi = useApi(configApiRef);
|
|
2419
|
+
const basePath = getBasePath(configApi);
|
|
2420
|
+
const internalAppContext = useContext(InternalAppContext);
|
|
2421
|
+
if (!internalAppContext) {
|
|
2422
|
+
throw new Error("AppRouter must be rendered within the AppProvider");
|
|
2423
|
+
}
|
|
2424
|
+
const { routeObjects, appIdentityProxy } = internalAppContext;
|
|
2425
|
+
if (!SignInPageComponent) {
|
|
2426
|
+
appIdentityProxy.setTarget(
|
|
2427
|
+
{
|
|
2428
|
+
getUserId: () => "guest",
|
|
2429
|
+
getIdToken: async () => void 0,
|
|
2430
|
+
getProfile: () => ({
|
|
2431
|
+
email: "guest@example.com",
|
|
2432
|
+
displayName: "Guest"
|
|
2433
|
+
}),
|
|
2434
|
+
getProfileInfo: async () => ({
|
|
2435
|
+
email: "guest@example.com",
|
|
2436
|
+
displayName: "Guest"
|
|
2437
|
+
}),
|
|
2438
|
+
getBackstageIdentity: async () => ({
|
|
2439
|
+
type: "user",
|
|
2440
|
+
userEntityRef: "user:default/guest",
|
|
2441
|
+
ownershipEntityRefs: ["user:default/guest"]
|
|
2442
|
+
}),
|
|
2443
|
+
getCredentials: async () => ({}),
|
|
2444
|
+
signOut: async () => {
|
|
2445
|
+
}
|
|
2446
|
+
},
|
|
2447
|
+
{ signOutTargetUrl: basePath || "/" }
|
|
2448
|
+
);
|
|
2449
|
+
return /* @__PURE__ */ React.createElement(BrowserRouter, { basename: basePath }, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), children);
|
|
2450
|
+
}
|
|
2451
|
+
return /* @__PURE__ */ React.createElement(BrowserRouter, { basename: basePath }, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), /* @__PURE__ */ React.createElement(
|
|
2452
|
+
SignInPageWrapper,
|
|
2453
|
+
{
|
|
2454
|
+
component: SignInPageComponent,
|
|
2455
|
+
appIdentityProxy
|
|
2456
|
+
},
|
|
2457
|
+
children
|
|
2458
|
+
));
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
var __accessCheck = (obj, member, msg) => {
|
|
2462
|
+
if (!member.has(obj))
|
|
2463
|
+
throw TypeError("Cannot " + msg);
|
|
2464
|
+
};
|
|
2465
|
+
var __privateGet = (obj, member, getter) => {
|
|
2466
|
+
__accessCheck(obj, member, "read from private field");
|
|
2467
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
2468
|
+
};
|
|
2469
|
+
var __privateAdd = (obj, member, value) => {
|
|
2470
|
+
if (member.has(obj))
|
|
2471
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
2472
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
2473
|
+
};
|
|
2474
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
2475
|
+
__accessCheck(obj, member, "write to private field");
|
|
2476
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
2477
|
+
return value;
|
|
2478
|
+
};
|
|
2479
|
+
var _components;
|
|
2480
|
+
class DefaultComponentsApi {
|
|
2481
|
+
constructor(components) {
|
|
2482
|
+
__privateAdd(this, _components, void 0);
|
|
2483
|
+
__privateSet(this, _components, components);
|
|
2484
|
+
}
|
|
2485
|
+
getComponent(ref) {
|
|
2486
|
+
const impl = __privateGet(this, _components).get(ref);
|
|
2487
|
+
if (!impl) {
|
|
2488
|
+
throw new Error(`No implementation found for component ref ${ref}`);
|
|
2489
|
+
}
|
|
2490
|
+
return impl;
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
_components = new WeakMap();
|
|
2494
|
+
|
|
2216
2495
|
const builtinExtensions = [
|
|
2217
2496
|
Core,
|
|
2497
|
+
CoreRouter,
|
|
2218
2498
|
CoreRoutes,
|
|
2219
2499
|
CoreNav,
|
|
2220
2500
|
CoreLayout,
|
|
2501
|
+
DefaultProgressComponent,
|
|
2502
|
+
DefaultErrorBoundaryComponent,
|
|
2503
|
+
DefaultNotFoundErrorPageComponent,
|
|
2221
2504
|
LightTheme,
|
|
2222
2505
|
DarkTheme
|
|
2223
|
-
];
|
|
2506
|
+
].map((def) => resolveExtensionDefinition(def));
|
|
2224
2507
|
function createExtensionTree(options) {
|
|
2225
2508
|
const features = getAvailableFeatures(options.config);
|
|
2226
2509
|
const tree = createAppTree({
|
|
@@ -2246,7 +2529,7 @@ function createExtensionTree(options) {
|
|
|
2246
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 : [];
|
|
2247
2530
|
},
|
|
2248
2531
|
getRootRoutes() {
|
|
2249
|
-
return this.getExtensionAttachments("core
|
|
2532
|
+
return this.getExtensionAttachments("core/routes", "routes").map((node) => {
|
|
2250
2533
|
const path = node.getData(coreExtensionData.routePath);
|
|
2251
2534
|
const element = node.getData(coreExtensionData.reactElement);
|
|
2252
2535
|
const routeRef = node.getData(coreExtensionData.routeRef);
|
|
@@ -2265,7 +2548,7 @@ function createExtensionTree(options) {
|
|
|
2265
2548
|
const location = useRouteRef(props.routeRef);
|
|
2266
2549
|
return /* @__PURE__ */ React.createElement(SidebarItem, { icon: props.icon, to: location(), text: props.title });
|
|
2267
2550
|
};
|
|
2268
|
-
return this.getExtensionAttachments("core
|
|
2551
|
+
return this.getExtensionAttachments("core/nav", "items").map((node, index) => {
|
|
2269
2552
|
const target = node.getData(coreExtensionData.navTarget);
|
|
2270
2553
|
if (!target) {
|
|
2271
2554
|
return null;
|
|
@@ -2334,12 +2617,26 @@ function createSpecializedApp(options) {
|
|
|
2334
2617
|
builtinExtensions,
|
|
2335
2618
|
config
|
|
2336
2619
|
});
|
|
2337
|
-
const
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2620
|
+
const appIdentityProxy = new AppIdentityProxy();
|
|
2621
|
+
const apiHolder = createApiHolder(tree, config, appIdentityProxy);
|
|
2622
|
+
const featureFlagApi = apiHolder.get(featureFlagsApiRef);
|
|
2623
|
+
if (featureFlagApi) {
|
|
2624
|
+
for (const feature of features) {
|
|
2625
|
+
if (feature.$$type === "@backstage/BackstagePlugin") {
|
|
2626
|
+
toInternalBackstagePlugin(feature).featureFlags.forEach(
|
|
2627
|
+
(flag) => featureFlagApi.registerFlag({
|
|
2628
|
+
name: flag.name,
|
|
2629
|
+
pluginId: feature.id
|
|
2630
|
+
})
|
|
2631
|
+
);
|
|
2632
|
+
}
|
|
2633
|
+
if (feature.$$type === "@backstage/ExtensionOverrides") {
|
|
2634
|
+
toInternalExtensionOverrides(feature).featureFlags.forEach(
|
|
2635
|
+
(flag) => featureFlagApi.registerFlag({ name: flag.name, pluginId: "" })
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2343
2640
|
const routeInfo = extractRouteInfoFromAppNode(tree.root);
|
|
2344
2641
|
const routeBindings = resolveRouteBindings(
|
|
2345
2642
|
options == null ? void 0 : options.bindRoutes,
|
|
@@ -2347,31 +2644,21 @@ function createSpecializedApp(options) {
|
|
|
2347
2644
|
collectRouteIds(features)
|
|
2348
2645
|
);
|
|
2349
2646
|
const rootEl = tree.root.instance.getData(coreExtensionData.reactElement);
|
|
2350
|
-
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(
|
|
2648
|
+
InternalAppContext.Provider,
|
|
2649
|
+
{
|
|
2650
|
+
value: { appIdentityProxy, routeObjects: routeInfo.routeObjects }
|
|
2651
|
+
},
|
|
2652
|
+
rootEl
|
|
2653
|
+
))));
|
|
2351
2654
|
return {
|
|
2352
2655
|
createRoot() {
|
|
2353
2656
|
return /* @__PURE__ */ React.createElement(App, null);
|
|
2354
2657
|
}
|
|
2355
2658
|
};
|
|
2356
2659
|
}
|
|
2357
|
-
function
|
|
2358
|
-
|
|
2359
|
-
getPlugins() {
|
|
2360
|
-
return plugins.map(toLegacyPlugin);
|
|
2361
|
-
},
|
|
2362
|
-
getSystemIcon(key) {
|
|
2363
|
-
return key in icons ? icons[key] : void 0;
|
|
2364
|
-
},
|
|
2365
|
-
getSystemIcons() {
|
|
2366
|
-
return icons;
|
|
2367
|
-
},
|
|
2368
|
-
getComponents() {
|
|
2369
|
-
return components;
|
|
2370
|
-
}
|
|
2371
|
-
};
|
|
2372
|
-
}
|
|
2373
|
-
function createApiHolder(tree, configApi) {
|
|
2374
|
-
var _a, _b, _c, _d;
|
|
2660
|
+
function createApiHolder(tree, configApi, appIdentityProxy) {
|
|
2661
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2375
2662
|
const factoryRegistry = new ApiFactoryRegistry();
|
|
2376
2663
|
const pluginApis = (_b = (_a = tree.root.edges.attachments.get("apis")) == null ? void 0 : _a.map((e) => {
|
|
2377
2664
|
var _a2;
|
|
@@ -2381,6 +2668,14 @@ function createApiHolder(tree, configApi) {
|
|
|
2381
2668
|
var _a2;
|
|
2382
2669
|
return (_a2 = e.instance) == null ? void 0 : _a2.getData(coreExtensionData.theme);
|
|
2383
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 : [];
|
|
2384
2679
|
for (const factory of [...apis, ...pluginApis]) {
|
|
2385
2680
|
factoryRegistry.register("default", factory);
|
|
2386
2681
|
}
|
|
@@ -2392,33 +2687,7 @@ function createApiHolder(tree, configApi) {
|
|
|
2392
2687
|
factoryRegistry.register("static", {
|
|
2393
2688
|
api: identityApiRef,
|
|
2394
2689
|
deps: {},
|
|
2395
|
-
factory: () =>
|
|
2396
|
-
const appIdentityProxy = new AppIdentityProxy();
|
|
2397
|
-
appIdentityProxy.setTarget(
|
|
2398
|
-
{
|
|
2399
|
-
getUserId: () => "guest",
|
|
2400
|
-
getIdToken: async () => void 0,
|
|
2401
|
-
getProfile: () => ({
|
|
2402
|
-
email: "guest@example.com",
|
|
2403
|
-
displayName: "Guest"
|
|
2404
|
-
}),
|
|
2405
|
-
getProfileInfo: async () => ({
|
|
2406
|
-
email: "guest@example.com",
|
|
2407
|
-
displayName: "Guest"
|
|
2408
|
-
}),
|
|
2409
|
-
getBackstageIdentity: async () => ({
|
|
2410
|
-
type: "user",
|
|
2411
|
-
userEntityRef: "user:default/guest",
|
|
2412
|
-
ownershipEntityRefs: ["user:default/guest"]
|
|
2413
|
-
}),
|
|
2414
|
-
getCredentials: async () => ({}),
|
|
2415
|
-
signOut: async () => {
|
|
2416
|
-
}
|
|
2417
|
-
},
|
|
2418
|
-
{ signOutTargetUrl: "/" }
|
|
2419
|
-
);
|
|
2420
|
-
return appIdentityProxy;
|
|
2421
|
-
}
|
|
2690
|
+
factory: () => appIdentityProxy
|
|
2422
2691
|
});
|
|
2423
2692
|
factoryRegistry.register("static", {
|
|
2424
2693
|
api: appTreeApiRef,
|
|
@@ -2427,6 +2696,19 @@ function createApiHolder(tree, configApi) {
|
|
|
2427
2696
|
getTree: () => ({ tree })
|
|
2428
2697
|
})
|
|
2429
2698
|
});
|
|
2699
|
+
const componentsExtensions = (_h = (_g = tree.root.edges.attachments.get("components")) == null ? void 0 : _g.map((e) => {
|
|
2700
|
+
var _a2;
|
|
2701
|
+
return (_a2 = e.instance) == null ? void 0 : _a2.getData(coreExtensionData.component);
|
|
2702
|
+
}).filter((x) => !!x)) != null ? _h : [];
|
|
2703
|
+
const componentsMap = componentsExtensions.reduce(
|
|
2704
|
+
(components, component) => component ? components.set(component.ref, component == null ? void 0 : component.impl) : components,
|
|
2705
|
+
/* @__PURE__ */ new Map()
|
|
2706
|
+
);
|
|
2707
|
+
factoryRegistry.register("static", {
|
|
2708
|
+
api: componentsApiRef,
|
|
2709
|
+
deps: {},
|
|
2710
|
+
factory: () => new DefaultComponentsApi(componentsMap)
|
|
2711
|
+
});
|
|
2430
2712
|
factoryRegistry.register("static", {
|
|
2431
2713
|
api: appThemeApiRef,
|
|
2432
2714
|
deps: {},
|
|
@@ -2438,13 +2720,6 @@ function createApiHolder(tree, configApi) {
|
|
|
2438
2720
|
deps: {},
|
|
2439
2721
|
factory: () => AppLanguageSelector.createWithStorage()
|
|
2440
2722
|
});
|
|
2441
|
-
factoryRegistry.register("default", {
|
|
2442
|
-
api: translationApiRef,
|
|
2443
|
-
deps: { languageApi: appLanguageApiRef },
|
|
2444
|
-
factory: ({ languageApi }) => I18nextTranslationApi.create({
|
|
2445
|
-
languageApi
|
|
2446
|
-
})
|
|
2447
|
-
});
|
|
2448
2723
|
factoryRegistry.register("static", {
|
|
2449
2724
|
api: configApiRef,
|
|
2450
2725
|
deps: {},
|
|
@@ -2455,11 +2730,12 @@ function createApiHolder(tree, configApi) {
|
|
|
2455
2730
|
deps: {},
|
|
2456
2731
|
factory: () => AppLanguageSelector.createWithStorage()
|
|
2457
2732
|
});
|
|
2458
|
-
factoryRegistry.register("
|
|
2733
|
+
factoryRegistry.register("static", {
|
|
2459
2734
|
api: translationApiRef,
|
|
2460
2735
|
deps: { languageApi: appLanguageApiRef },
|
|
2461
2736
|
factory: ({ languageApi }) => I18nextTranslationApi.create({
|
|
2462
|
-
languageApi
|
|
2737
|
+
languageApi,
|
|
2738
|
+
resources: translationResources
|
|
2463
2739
|
})
|
|
2464
2740
|
});
|
|
2465
2741
|
for (const factory of apis) {
|