@backstage/core-app-api 1.10.0-next.0 → 1.10.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 +25 -0
- package/alpha/package.json +7 -0
- package/dist/alpha.d.ts +49 -0
- package/dist/alpha.esm.js +11 -0
- package/dist/alpha.esm.js.map +1 -0
- package/dist/esm/AppTranslationImpl-8560b672.esm.js +132 -0
- package/dist/esm/AppTranslationImpl-8560b672.esm.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.esm.js +22 -2
- package/dist/index.esm.js.map +1 -1
- package/package.json +26 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @backstage/core-app-api
|
|
2
2
|
|
|
3
|
+
## 1.10.0-next.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6e30769cc627: Introduced experimental support for internationalization.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 8cec7664e146: Removed `@types/node` dependency
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
- @backstage/core-plugin-api@1.6.0-next.2
|
|
14
|
+
- @backstage/config@1.1.0-next.1
|
|
15
|
+
- @backstage/types@1.1.0
|
|
16
|
+
- @backstage/version-bridge@1.0.4
|
|
17
|
+
|
|
18
|
+
## 1.10.0-next.1
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @backstage/config@1.1.0-next.0
|
|
24
|
+
- @backstage/core-plugin-api@1.6.0-next.1
|
|
25
|
+
- @backstage/types@1.1.0
|
|
26
|
+
- @backstage/version-bridge@1.0.4
|
|
27
|
+
|
|
3
28
|
## 1.10.0-next.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
package/dist/alpha.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { TranslationRef, AppTranslationApi } from '@backstage/core-plugin-api/alpha';
|
|
2
|
+
import { i18n } from 'i18next';
|
|
3
|
+
|
|
4
|
+
/** @alpha */
|
|
5
|
+
type ExperimentalI18n = {
|
|
6
|
+
supportedLanguages: string[];
|
|
7
|
+
fallbackLanguage?: string | string[];
|
|
8
|
+
messages?: Array<{
|
|
9
|
+
ref: TranslationRef;
|
|
10
|
+
messages?: TranslationMessages<TranslationRef>;
|
|
11
|
+
lazyMessages: Record<string, () => Promise<{
|
|
12
|
+
messages: TranslationMessages<TranslationRef>;
|
|
13
|
+
}>>;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
/** @alpha */
|
|
17
|
+
declare class AppTranslationApiImpl implements AppTranslationApi {
|
|
18
|
+
private readonly i18n;
|
|
19
|
+
static create(options?: ExperimentalI18n): AppTranslationApiImpl;
|
|
20
|
+
private readonly cache;
|
|
21
|
+
private readonly lazyCache;
|
|
22
|
+
getI18n(): i18n;
|
|
23
|
+
initMessages(options?: ExperimentalI18n): void;
|
|
24
|
+
addResourcesByRef<Messages extends Record<string, string>>(translationRef: TranslationRef<Messages>): void;
|
|
25
|
+
addResources<Messages extends Record<string, string>>(translationRef: TranslationRef<Messages>, initResources?: TranslationMessages<TranslationRef<Messages>>): void;
|
|
26
|
+
addLazyResources<Messages extends Record<string, string>>(translationRef: TranslationRef<Messages>, initResources?: Record<string, () => Promise<{
|
|
27
|
+
messages: TranslationMessages<TranslationRef>;
|
|
28
|
+
}>>): void;
|
|
29
|
+
private constructor();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** @alpha */
|
|
33
|
+
type TranslationMessages<T> = T extends TranslationRef<infer R> ? Record<string, Partial<R>> : never;
|
|
34
|
+
/** @alpha */
|
|
35
|
+
declare function createTranslationResource<T extends TranslationRef>(options: {
|
|
36
|
+
ref: T;
|
|
37
|
+
messages?: TranslationMessages<T>;
|
|
38
|
+
lazyMessages: Record<string, () => Promise<{
|
|
39
|
+
messages: TranslationMessages<T>;
|
|
40
|
+
}>>;
|
|
41
|
+
}): {
|
|
42
|
+
ref: T;
|
|
43
|
+
messages?: TranslationMessages<T> | undefined;
|
|
44
|
+
lazyMessages: Record<string, () => Promise<{
|
|
45
|
+
messages: TranslationMessages<T>;
|
|
46
|
+
}>>;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { AppTranslationApiImpl, ExperimentalI18n, TranslationMessages, createTranslationResource };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { A as AppTranslationApiImpl } from './esm/AppTranslationImpl-8560b672.esm.js';
|
|
2
|
+
import 'i18next';
|
|
3
|
+
import 'react-i18next';
|
|
4
|
+
import 'i18next-browser-languagedetector';
|
|
5
|
+
|
|
6
|
+
function createTranslationResource(options) {
|
|
7
|
+
return options;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { createTranslationResource };
|
|
11
|
+
//# sourceMappingURL=alpha.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":["../src/app/TranslationResource.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @alpha */\nexport type TranslationMessages<T> = T extends TranslationRef<infer R>\n ? Record<string, Partial<R>>\n : never;\n\n/** @alpha */\nexport function createTranslationResource<T extends TranslationRef>(options: {\n ref: T;\n messages?: TranslationMessages<T>;\n lazyMessages: Record<\n string,\n () => Promise<{ messages: TranslationMessages<T> }>\n >;\n}) {\n return options;\n}\n"],"names":[],"mappings":";;;;;AAwBO,SAAS,0BAAoD,OAOjE,EAAA;AACD,EAAO,OAAA,OAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import { initReactI18next } from 'react-i18next';
|
|
3
|
+
import LanguageDetector from 'i18next-browser-languagedetector';
|
|
4
|
+
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __publicField = (obj, key, value) => {
|
|
8
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
9
|
+
return value;
|
|
10
|
+
};
|
|
11
|
+
class AppTranslationApiImpl {
|
|
12
|
+
constructor(i18n, options) {
|
|
13
|
+
this.i18n = i18n;
|
|
14
|
+
__publicField(this, "cache", /* @__PURE__ */ new WeakSet());
|
|
15
|
+
__publicField(this, "lazyCache", /* @__PURE__ */ new WeakMap());
|
|
16
|
+
this.initMessages(options);
|
|
17
|
+
}
|
|
18
|
+
static create(options) {
|
|
19
|
+
const i18n = i18next.createInstance().use(initReactI18next);
|
|
20
|
+
i18n.use(LanguageDetector);
|
|
21
|
+
i18n.init({
|
|
22
|
+
fallbackLng: (options == null ? void 0 : options.fallbackLanguage) || "en",
|
|
23
|
+
supportedLngs: (options == null ? void 0 : options.supportedLanguages) || ["en"],
|
|
24
|
+
interpolation: {
|
|
25
|
+
escapeValue: false
|
|
26
|
+
},
|
|
27
|
+
react: {
|
|
28
|
+
bindI18n: "loaded languageChanged"
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return new AppTranslationApiImpl(i18n, options);
|
|
32
|
+
}
|
|
33
|
+
getI18n() {
|
|
34
|
+
return this.i18n;
|
|
35
|
+
}
|
|
36
|
+
initMessages(options) {
|
|
37
|
+
var _a;
|
|
38
|
+
if ((_a = options == null ? void 0 : options.messages) == null ? void 0 : _a.length) {
|
|
39
|
+
options.messages.forEach((appMessage) => {
|
|
40
|
+
if (appMessage.messages) {
|
|
41
|
+
this.addResources(appMessage.ref, appMessage.messages);
|
|
42
|
+
}
|
|
43
|
+
if (appMessage.lazyMessages) {
|
|
44
|
+
this.addLazyResources(appMessage.ref, appMessage.lazyMessages);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
addResourcesByRef(translationRef) {
|
|
50
|
+
this.addResources(translationRef);
|
|
51
|
+
this.addLazyResources(translationRef);
|
|
52
|
+
}
|
|
53
|
+
addResources(translationRef, initResources) {
|
|
54
|
+
const resources = initResources || translationRef.getResources();
|
|
55
|
+
if (!resources || this.cache.has(translationRef)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.cache.add(translationRef);
|
|
59
|
+
Object.entries(resources).forEach(([language, messages]) => {
|
|
60
|
+
this.i18n.addResourceBundle(
|
|
61
|
+
language,
|
|
62
|
+
translationRef.getId(),
|
|
63
|
+
messages,
|
|
64
|
+
true,
|
|
65
|
+
false
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
addLazyResources(translationRef, initResources) {
|
|
70
|
+
let cache = this.lazyCache.get(translationRef);
|
|
71
|
+
if (!cache) {
|
|
72
|
+
cache = /* @__PURE__ */ new Set();
|
|
73
|
+
this.lazyCache.set(translationRef, cache);
|
|
74
|
+
}
|
|
75
|
+
const {
|
|
76
|
+
language: currentLanguage,
|
|
77
|
+
services,
|
|
78
|
+
options,
|
|
79
|
+
addResourceBundle,
|
|
80
|
+
reloadResources
|
|
81
|
+
} = this.i18n;
|
|
82
|
+
if (cache.has(currentLanguage)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const namespace = translationRef.getId();
|
|
86
|
+
const lazyResources = initResources || translationRef.getLazyResources();
|
|
87
|
+
const fallbackLanguages = services.languageUtils.getFallbackCodes(
|
|
88
|
+
options.fallbackLng,
|
|
89
|
+
currentLanguage
|
|
90
|
+
);
|
|
91
|
+
Promise.allSettled(
|
|
92
|
+
[...fallbackLanguages, currentLanguage].map(addLanguage)
|
|
93
|
+
).then((results) => {
|
|
94
|
+
if (results.some((result) => result.status === "fulfilled")) {
|
|
95
|
+
this.i18n.emit("loaded");
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
async function addLanguage(language) {
|
|
99
|
+
var _a;
|
|
100
|
+
if (cache.has(language)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
cache.add(language);
|
|
104
|
+
let loadBackend;
|
|
105
|
+
if ((_a = services.backendConnector) == null ? void 0 : _a.backend) {
|
|
106
|
+
loadBackend = reloadResources([language], [namespace]);
|
|
107
|
+
}
|
|
108
|
+
const loadLazyResources = lazyResources == null ? void 0 : lazyResources[language];
|
|
109
|
+
if (!loadLazyResources) {
|
|
110
|
+
await loadBackend;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const [result] = await Promise.allSettled([
|
|
114
|
+
loadLazyResources(),
|
|
115
|
+
loadBackend
|
|
116
|
+
]);
|
|
117
|
+
if (result.status === "rejected") {
|
|
118
|
+
throw result.reason;
|
|
119
|
+
}
|
|
120
|
+
addResourceBundle(
|
|
121
|
+
language,
|
|
122
|
+
namespace,
|
|
123
|
+
result.value.messages,
|
|
124
|
+
true,
|
|
125
|
+
false
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export { AppTranslationApiImpl as A };
|
|
132
|
+
//# sourceMappingURL=AppTranslationImpl-8560b672.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppTranslationImpl-8560b672.esm.js","sources":["../../src/apis/implementations/AppTranslationApi/AppTranslationImpl.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AppTranslationApi,\n TranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport i18next, { type i18n } from 'i18next';\nimport { initReactI18next } from 'react-i18next';\nimport LanguageDetector from 'i18next-browser-languagedetector';\n\nimport { TranslationMessages } from '../../../alpha';\n\n/** @alpha */\nexport type ExperimentalI18n = {\n supportedLanguages: string[];\n fallbackLanguage?: string | string[];\n messages?: Array<{\n ref: TranslationRef;\n messages?: TranslationMessages<TranslationRef>;\n lazyMessages: Record<\n string,\n () => Promise<{ messages: TranslationMessages<TranslationRef> }>\n >;\n }>;\n};\n\n/** @alpha */\nexport class AppTranslationApiImpl implements AppTranslationApi {\n static create(options?: ExperimentalI18n) {\n const i18n = i18next.createInstance().use(initReactI18next);\n\n i18n.use(LanguageDetector);\n\n i18n.init({\n fallbackLng: options?.fallbackLanguage || 'en',\n supportedLngs: options?.supportedLanguages || ['en'],\n interpolation: {\n escapeValue: false,\n },\n react: {\n bindI18n: 'loaded languageChanged',\n },\n });\n\n return new AppTranslationApiImpl(i18n, options);\n }\n\n private readonly cache = new WeakSet<TranslationRef>();\n private readonly lazyCache = new WeakMap<TranslationRef, Set<string>>();\n\n getI18n() {\n return this.i18n;\n }\n\n initMessages(options?: ExperimentalI18n) {\n if (options?.messages?.length) {\n options.messages.forEach(appMessage => {\n if (appMessage.messages) {\n this.addResources(appMessage.ref, appMessage.messages);\n }\n\n if (appMessage.lazyMessages) {\n this.addLazyResources(appMessage.ref, appMessage.lazyMessages);\n }\n });\n }\n }\n\n addResourcesByRef<Messages extends Record<string, string>>(\n translationRef: TranslationRef<Messages>,\n ): void {\n this.addResources(translationRef);\n this.addLazyResources(translationRef);\n }\n\n addResources<Messages extends Record<string, string>>(\n translationRef: TranslationRef<Messages>,\n initResources?: TranslationMessages<TranslationRef<Messages>>,\n ) {\n const resources = initResources || translationRef.getResources();\n if (!resources || this.cache.has(translationRef)) {\n return;\n }\n this.cache.add(translationRef);\n Object.entries(resources).forEach(([language, messages]) => {\n this.i18n.addResourceBundle(\n language,\n translationRef.getId(),\n messages,\n true,\n false,\n );\n });\n }\n\n addLazyResources<Messages extends Record<string, string>>(\n translationRef: TranslationRef<Messages>,\n initResources?: Record<\n string,\n () => Promise<{ messages: TranslationMessages<TranslationRef> }>\n >,\n ) {\n let cache = this.lazyCache.get(translationRef);\n\n if (!cache) {\n cache = new Set();\n this.lazyCache.set(translationRef, cache);\n }\n\n const {\n language: currentLanguage,\n services,\n options,\n addResourceBundle,\n reloadResources,\n } = this.i18n;\n\n if (cache.has(currentLanguage)) {\n return;\n }\n\n const namespace = translationRef.getId();\n const lazyResources = initResources || translationRef.getLazyResources();\n\n const fallbackLanguages = services.languageUtils.getFallbackCodes(\n options.fallbackLng,\n currentLanguage,\n ) as string[];\n\n Promise.allSettled(\n [...fallbackLanguages, currentLanguage].map(addLanguage),\n ).then(results => {\n if (results.some(result => result.status === 'fulfilled')) {\n this.i18n.emit('loaded');\n }\n });\n\n async function addLanguage(language: string) {\n if (cache!.has(language)) {\n return;\n }\n\n cache!.add(language);\n\n let loadBackend: Promise<void> | undefined;\n\n if (services.backendConnector?.backend) {\n loadBackend = reloadResources([language], [namespace]);\n }\n\n const loadLazyResources = lazyResources?.[language];\n\n if (!loadLazyResources) {\n await loadBackend;\n return;\n }\n\n const [result] = await Promise.allSettled([\n loadLazyResources(),\n loadBackend,\n ]);\n\n if (result.status === 'rejected') {\n throw result.reason;\n }\n\n addResourceBundle(\n language,\n namespace,\n result.value.messages,\n true,\n false,\n );\n }\n }\n\n private constructor(private readonly i18n: i18n, options?: ExperimentalI18n) {\n this.initMessages(options);\n }\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import * as _backstage_types from '@backstage/types';
|
|
|
6
6
|
import { Observable, JsonValue } from '@backstage/types';
|
|
7
7
|
import { Config, AppConfig } from '@backstage/config';
|
|
8
8
|
export { ConfigReader } from '@backstage/config';
|
|
9
|
+
import { TranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Prop types for the ApiProvider component.
|
|
@@ -802,6 +803,13 @@ type TargetRouteMap<ExternalRoutes extends {
|
|
|
802
803
|
type AppRouteBinder = <ExternalRoutes extends {
|
|
803
804
|
[name: string]: ExternalRouteRef;
|
|
804
805
|
}>(externalRoutes: ExternalRoutes, targetRoutes: PartialKeys<TargetRouteMap<ExternalRoutes>, KeysWithType<ExternalRoutes, ExternalRouteRef<any, true>>>) => void;
|
|
806
|
+
/**
|
|
807
|
+
* TODO: To be remove when TranslationMessages in packages/core-app-api/src/app/TranslationResource.ts
|
|
808
|
+
* come to be public
|
|
809
|
+
*
|
|
810
|
+
* @ignore
|
|
811
|
+
* */
|
|
812
|
+
type TranslationMessages<T> = T extends TranslationRef<infer R> ? Record<string, Partial<R>> : never;
|
|
805
813
|
/**
|
|
806
814
|
* The options accepted by {@link createSpecializedApp}.
|
|
807
815
|
*
|
|
@@ -900,6 +908,21 @@ type AppOptions = {
|
|
|
900
908
|
bindRoutes?(context: {
|
|
901
909
|
bind: AppRouteBinder;
|
|
902
910
|
}): void;
|
|
911
|
+
/**
|
|
912
|
+
* TODO: Change to ExperimentalI18n type when packages/core-app-api/src/apis/implementations/AppTranslationApi/AppTranslationImpl.ts
|
|
913
|
+
* become to public
|
|
914
|
+
*/
|
|
915
|
+
__experimentalI18n?: {
|
|
916
|
+
supportedLanguages: string[];
|
|
917
|
+
fallbackLanguage?: string | string[];
|
|
918
|
+
messages?: Array<{
|
|
919
|
+
ref: TranslationRef;
|
|
920
|
+
messages?: TranslationMessages<TranslationRef>;
|
|
921
|
+
lazyMessages: Record<string, () => Promise<{
|
|
922
|
+
messages: TranslationMessages<TranslationRef>;
|
|
923
|
+
}>>;
|
|
924
|
+
}>;
|
|
925
|
+
};
|
|
903
926
|
};
|
|
904
927
|
/**
|
|
905
928
|
* The public API of the output of {@link createSpecializedApp}.
|
package/dist/index.esm.js
CHANGED
|
@@ -8,7 +8,12 @@ import { ConfigReader } from '@backstage/config';
|
|
|
8
8
|
export { ConfigReader } from '@backstage/config';
|
|
9
9
|
import { createRoutesFromChildren, Route, useLocation, matchRoutes, Routes, generatePath, useRoutes } from 'react-router-dom';
|
|
10
10
|
import useAsync from 'react-use/lib/useAsync';
|
|
11
|
+
import { appTranslationApiRef } from '@backstage/core-plugin-api/alpha';
|
|
11
12
|
import useObservable from 'react-use/lib/useObservable';
|
|
13
|
+
import { I18nextProvider } from 'react-i18next';
|
|
14
|
+
import { A as AppTranslationApiImpl } from './esm/AppTranslationImpl-8560b672.esm.js';
|
|
15
|
+
import 'i18next';
|
|
16
|
+
import 'i18next-browser-languagedetector';
|
|
12
17
|
|
|
13
18
|
var __defProp$l = Object.defineProperty;
|
|
14
19
|
var __defNormalProp$l = (obj, key, value) => key in obj ? __defProp$l(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -3179,6 +3184,12 @@ function resolveRouteBindings(bindRoutes) {
|
|
|
3179
3184
|
return result;
|
|
3180
3185
|
}
|
|
3181
3186
|
|
|
3187
|
+
function AppTranslationProvider({ children }) {
|
|
3188
|
+
const appTranslationAPi = useApi(appTranslationApiRef);
|
|
3189
|
+
const i18n = appTranslationAPi.getI18n();
|
|
3190
|
+
return /* @__PURE__ */ React.createElement(I18nextProvider, { i18n }, children);
|
|
3191
|
+
}
|
|
3192
|
+
|
|
3182
3193
|
var __defProp = Object.defineProperty;
|
|
3183
3194
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3184
3195
|
var __publicField = (obj, key, value) => {
|
|
@@ -3294,6 +3305,7 @@ class AppManager {
|
|
|
3294
3305
|
__publicField(this, "configLoader");
|
|
3295
3306
|
__publicField(this, "defaultApis");
|
|
3296
3307
|
__publicField(this, "bindRoutes");
|
|
3308
|
+
__publicField(this, "appTranslationApi");
|
|
3297
3309
|
__publicField(this, "appIdentityProxy", new AppIdentityProxy());
|
|
3298
3310
|
__publicField(this, "apiFactoryRegistry");
|
|
3299
3311
|
__privateAdd(this, _getProviderCalled, false);
|
|
@@ -3308,6 +3320,9 @@ class AppManager {
|
|
|
3308
3320
|
this.defaultApis = (_e = options.defaultApis) != null ? _e : [];
|
|
3309
3321
|
this.bindRoutes = options.bindRoutes;
|
|
3310
3322
|
this.apiFactoryRegistry = new ApiFactoryRegistry();
|
|
3323
|
+
this.appTranslationApi = AppTranslationApiImpl.create(
|
|
3324
|
+
options.__experimentalI18n
|
|
3325
|
+
);
|
|
3311
3326
|
}
|
|
3312
3327
|
getPlugins() {
|
|
3313
3328
|
return Array.from(this.plugins);
|
|
@@ -3421,7 +3436,7 @@ class AppManager {
|
|
|
3421
3436
|
}
|
|
3422
3437
|
}
|
|
3423
3438
|
const { ThemeProvider = AppThemeProvider } = this.components;
|
|
3424
|
-
return /* @__PURE__ */ React.createElement(ApiProvider, { apis: this.getApiHolder() }, /* @__PURE__ */ React.createElement(AppContextProvider, { appContext }, /* @__PURE__ */ React.createElement(ThemeProvider, null, /* @__PURE__ */ React.createElement(
|
|
3439
|
+
return /* @__PURE__ */ React.createElement(ApiProvider, { apis: this.getApiHolder() }, /* @__PURE__ */ React.createElement(AppContextProvider, { appContext }, /* @__PURE__ */ React.createElement(AppTranslationProvider, null, /* @__PURE__ */ React.createElement(ThemeProvider, null, /* @__PURE__ */ React.createElement(
|
|
3425
3440
|
RoutingProvider,
|
|
3426
3441
|
{
|
|
3427
3442
|
routePaths: routing.paths,
|
|
@@ -3440,7 +3455,7 @@ class AppManager {
|
|
|
3440
3455
|
},
|
|
3441
3456
|
children
|
|
3442
3457
|
)
|
|
3443
|
-
))));
|
|
3458
|
+
)))));
|
|
3444
3459
|
};
|
|
3445
3460
|
return Provider;
|
|
3446
3461
|
}
|
|
@@ -3484,6 +3499,11 @@ class AppManager {
|
|
|
3484
3499
|
deps: {},
|
|
3485
3500
|
factory: () => this.appIdentityProxy
|
|
3486
3501
|
});
|
|
3502
|
+
this.apiFactoryRegistry.register("static", {
|
|
3503
|
+
api: appTranslationApiRef,
|
|
3504
|
+
deps: {},
|
|
3505
|
+
factory: () => this.appTranslationApi
|
|
3506
|
+
});
|
|
3487
3507
|
this.apiFactoryRegistry.register("default", {
|
|
3488
3508
|
api: featureFlagsApiRef,
|
|
3489
3509
|
deps: {},
|