@backstage/frontend-app-api 0.2.0-next.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/config.d.ts +8 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.esm.js +728 -91
- package/dist/index.esm.js.map +1 -1
- package/package.json +12 -12
package/dist/index.esm.js
CHANGED
|
@@ -6,9 +6,11 @@ import { SidebarPage, sidebarConfig, Sidebar, SidebarDivider, useSidebarOpenStat
|
|
|
6
6
|
import { useRouteRef, 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';
|
|
7
7
|
import { makeStyles } from '@material-ui/core';
|
|
8
8
|
import mapValues from 'lodash/mapValues';
|
|
9
|
-
import { UrlPatternDiscovery, AlertApiForwarder, NoOpAnalyticsApi, ErrorAlerter, ErrorApiForwarder, UnhandledErrorForwarder, WebStorage, createFetchApi, FetchMiddlewares, OAuthRequestManager, GoogleAuth, MicrosoftAuth, GithubAuth, OktaAuth, GitlabAuth, OneLoginAuth, BitbucketAuth, BitbucketServerAuth, AtlassianAuth, ApiFactoryRegistry, AppThemeSelector, ApiResolver
|
|
9
|
+
import { UrlPatternDiscovery, AlertApiForwarder, NoOpAnalyticsApi, ErrorAlerter, ErrorApiForwarder, UnhandledErrorForwarder, WebStorage, createFetchApi, FetchMiddlewares, OAuthRequestManager, GoogleAuth, MicrosoftAuth, GithubAuth, OktaAuth, GitlabAuth, OneLoginAuth, BitbucketAuth, BitbucketServerAuth, AtlassianAuth, ApiProvider, ApiFactoryRegistry, AppThemeSelector, ApiResolver } from '@backstage/core-app-api';
|
|
10
10
|
import useObservable from 'react-use/lib/useObservable';
|
|
11
11
|
import { createVersionedContext, createVersionedValueMap, getOrCreateGlobalSingleton } from '@backstage/version-bridge';
|
|
12
|
+
import ObservableImpl from 'zen-observable';
|
|
13
|
+
import { createInstance } from 'i18next';
|
|
12
14
|
import { permissionApiRef, IdentityPermissionApi } from '@backstage/plugin-permission-react';
|
|
13
15
|
import Button from '@material-ui/core/Button';
|
|
14
16
|
import MuiApartmentIcon from '@material-ui/icons/Apartment';
|
|
@@ -35,6 +37,7 @@ import MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList';
|
|
|
35
37
|
import { UnifiedThemeProvider, themes } from '@backstage/theme';
|
|
36
38
|
import DarkIcon from '@material-ui/icons/Brightness2';
|
|
37
39
|
import LightIcon from '@material-ui/icons/WbSunny';
|
|
40
|
+
import { appLanguageApiRef, translationApiRef } from '@backstage/core-plugin-api/alpha';
|
|
38
41
|
|
|
39
42
|
const Core = createExtension({
|
|
40
43
|
id: "core",
|
|
@@ -42,10 +45,24 @@ const Core = createExtension({
|
|
|
42
45
|
inputs: {
|
|
43
46
|
apis: createExtensionInput({
|
|
44
47
|
api: coreExtensionData.apiFactory
|
|
45
|
-
})
|
|
48
|
+
}),
|
|
49
|
+
themes: createExtensionInput({
|
|
50
|
+
theme: coreExtensionData.theme
|
|
51
|
+
}),
|
|
52
|
+
root: createExtensionInput(
|
|
53
|
+
{
|
|
54
|
+
element: coreExtensionData.reactElement
|
|
55
|
+
},
|
|
56
|
+
{ singleton: true }
|
|
57
|
+
)
|
|
58
|
+
},
|
|
59
|
+
output: {
|
|
60
|
+
root: coreExtensionData.reactElement
|
|
46
61
|
},
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
factory({ bind, inputs }) {
|
|
63
|
+
bind({
|
|
64
|
+
root: inputs.root.element
|
|
65
|
+
});
|
|
49
66
|
}
|
|
50
67
|
});
|
|
51
68
|
|
|
@@ -66,7 +83,7 @@ const CoreRoutes = createExtension({
|
|
|
66
83
|
const Routes = () => {
|
|
67
84
|
const element = useRoutes(
|
|
68
85
|
inputs.routes.map((route) => ({
|
|
69
|
-
path: route.path
|
|
86
|
+
path: `${route.path}/*`,
|
|
70
87
|
element: route.element
|
|
71
88
|
}))
|
|
72
89
|
);
|
|
@@ -80,7 +97,7 @@ const CoreRoutes = createExtension({
|
|
|
80
97
|
|
|
81
98
|
const CoreLayout = createExtension({
|
|
82
99
|
id: "core.layout",
|
|
83
|
-
attachTo: { id: "
|
|
100
|
+
attachTo: { id: "core", input: "root" },
|
|
84
101
|
inputs: {
|
|
85
102
|
nav: createExtensionInput(
|
|
86
103
|
{
|
|
@@ -203,27 +220,27 @@ const CoreNav = createExtension({
|
|
|
203
220
|
}
|
|
204
221
|
});
|
|
205
222
|
|
|
206
|
-
var __defProp$
|
|
207
|
-
var __defNormalProp$
|
|
208
|
-
var __publicField$
|
|
209
|
-
__defNormalProp$
|
|
223
|
+
var __defProp$3 = Object.defineProperty;
|
|
224
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
225
|
+
var __publicField$3 = (obj, key, value) => {
|
|
226
|
+
__defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
210
227
|
return value;
|
|
211
228
|
};
|
|
212
|
-
var __accessCheck = (obj, member, msg) => {
|
|
229
|
+
var __accessCheck$2 = (obj, member, msg) => {
|
|
213
230
|
if (!member.has(obj))
|
|
214
231
|
throw TypeError("Cannot " + msg);
|
|
215
232
|
};
|
|
216
|
-
var __privateGet = (obj, member, getter) => {
|
|
217
|
-
__accessCheck(obj, member, "read from private field");
|
|
233
|
+
var __privateGet$2 = (obj, member, getter) => {
|
|
234
|
+
__accessCheck$2(obj, member, "read from private field");
|
|
218
235
|
return getter ? getter.call(obj) : member.get(obj);
|
|
219
236
|
};
|
|
220
|
-
var __privateAdd = (obj, member, value) => {
|
|
237
|
+
var __privateAdd$2 = (obj, member, value) => {
|
|
221
238
|
if (member.has(obj))
|
|
222
239
|
throw TypeError("Cannot add the same private member more than once");
|
|
223
240
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
224
241
|
};
|
|
225
|
-
var __privateSet = (obj, member, value, setter) => {
|
|
226
|
-
__accessCheck(obj, member, "write to private field");
|
|
242
|
+
var __privateSet$2 = (obj, member, value, setter) => {
|
|
243
|
+
__accessCheck$2(obj, member, "write to private field");
|
|
227
244
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
228
245
|
return value;
|
|
229
246
|
};
|
|
@@ -240,6 +257,16 @@ function resolveInputData(dataMap, attachment, inputName) {
|
|
|
240
257
|
});
|
|
241
258
|
}
|
|
242
259
|
function resolveInputs(inputMap, attachments) {
|
|
260
|
+
const undeclaredAttachments = Array.from(attachments.entries()).filter(
|
|
261
|
+
([inputName]) => inputMap[inputName] === void 0
|
|
262
|
+
);
|
|
263
|
+
if (undeclaredAttachments.length > 0) {
|
|
264
|
+
throw new Error(
|
|
265
|
+
`received undeclared input${undeclaredAttachments.length > 1 ? "s" : ""} ${undeclaredAttachments.map(
|
|
266
|
+
([k, exts]) => `'${k}' from extension${exts.length > 1 ? "s" : ""} '${exts.map((e) => e.id).join("', '")}'`
|
|
267
|
+
).join(" and ")}`
|
|
268
|
+
);
|
|
269
|
+
}
|
|
243
270
|
return mapValues(inputMap, (input, inputName) => {
|
|
244
271
|
var _a;
|
|
245
272
|
const attachedInstances = (_a = attachments.get(inputName)) != null ? _a : [];
|
|
@@ -270,28 +297,28 @@ function indent(str) {
|
|
|
270
297
|
}
|
|
271
298
|
class ExtensionInstanceImpl {
|
|
272
299
|
constructor(id, extensionData, attachments, source) {
|
|
273
|
-
__publicField$
|
|
274
|
-
__publicField$
|
|
275
|
-
__privateAdd(this, _extensionData, void 0);
|
|
276
|
-
__publicField$
|
|
277
|
-
__publicField$
|
|
300
|
+
__publicField$3(this, "$$type", "@backstage/ExtensionInstance");
|
|
301
|
+
__publicField$3(this, "id");
|
|
302
|
+
__privateAdd$2(this, _extensionData, void 0);
|
|
303
|
+
__publicField$3(this, "attachments");
|
|
304
|
+
__publicField$3(this, "source");
|
|
278
305
|
this.id = id;
|
|
279
|
-
__privateSet(this, _extensionData, extensionData);
|
|
306
|
+
__privateSet$2(this, _extensionData, extensionData);
|
|
280
307
|
this.attachments = attachments;
|
|
281
308
|
this.source = source;
|
|
282
309
|
}
|
|
283
310
|
getData(ref) {
|
|
284
|
-
return __privateGet(this, _extensionData).get(ref.id);
|
|
311
|
+
return __privateGet$2(this, _extensionData).get(ref.id);
|
|
285
312
|
}
|
|
286
313
|
toJSON() {
|
|
287
314
|
return {
|
|
288
315
|
id: this.id,
|
|
289
|
-
output: __privateGet(this, _extensionData).size > 0 ? [...__privateGet(this, _extensionData).keys()] : void 0,
|
|
316
|
+
output: __privateGet$2(this, _extensionData).size > 0 ? [...__privateGet$2(this, _extensionData).keys()] : void 0,
|
|
290
317
|
attachments: this.attachments.size > 0 ? Object.fromEntries(this.attachments) : void 0
|
|
291
318
|
};
|
|
292
319
|
}
|
|
293
320
|
toString() {
|
|
294
|
-
const out = __privateGet(this, _extensionData).size > 0 ? ` out=[${[...__privateGet(this, _extensionData).keys()].join(", ")}]` : "";
|
|
321
|
+
const out = __privateGet$2(this, _extensionData).size > 0 ? ` out=[${[...__privateGet$2(this, _extensionData).keys()].join(", ")}]` : "";
|
|
295
322
|
if (this.attachments.size === 0) {
|
|
296
323
|
return `<${this.id}${out} />`;
|
|
297
324
|
}
|
|
@@ -350,6 +377,21 @@ function createExtensionInstance(options) {
|
|
|
350
377
|
);
|
|
351
378
|
}
|
|
352
379
|
|
|
380
|
+
function toInternalExtensionOverrides(overrides) {
|
|
381
|
+
const internal = overrides;
|
|
382
|
+
if (internal.$$type !== "@backstage/ExtensionOverrides") {
|
|
383
|
+
throw new Error(
|
|
384
|
+
`Invalid translation resource, bad type '${internal.$$type}'`
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
if (internal.version !== "v1") {
|
|
388
|
+
throw new Error(
|
|
389
|
+
`Invalid translation resource, bad version '${internal.version}'`
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
return internal;
|
|
393
|
+
}
|
|
394
|
+
|
|
353
395
|
const knownExtensionParameters = ["attachTo", "disabled", "config"];
|
|
354
396
|
function readAppExtensionParameters(rootConfig) {
|
|
355
397
|
const arr = rootConfig.getOptional("app.extensions");
|
|
@@ -462,19 +504,47 @@ function expandShorthandExtensionParameters(arrayEntry, arrayIndex) {
|
|
|
462
504
|
};
|
|
463
505
|
}
|
|
464
506
|
function mergeExtensionParameters(options) {
|
|
465
|
-
|
|
466
|
-
const
|
|
507
|
+
var _a;
|
|
508
|
+
const { builtinExtensions, parameters } = options;
|
|
509
|
+
const plugins = options.features.filter(
|
|
510
|
+
(f) => f.$$type === "@backstage/BackstagePlugin"
|
|
511
|
+
);
|
|
512
|
+
const overrides = options.features.filter(
|
|
513
|
+
(f) => f.$$type === "@backstage/ExtensionOverrides"
|
|
514
|
+
);
|
|
515
|
+
const pluginExtensions = plugins.flatMap((source) => {
|
|
467
516
|
return source.extensions.map((extension) => ({ ...extension, source }));
|
|
468
517
|
});
|
|
469
|
-
|
|
470
|
-
|
|
518
|
+
const overrideExtensions = overrides.flatMap(
|
|
519
|
+
(override) => toInternalExtensionOverrides(override).extensions
|
|
520
|
+
);
|
|
521
|
+
if (pluginExtensions.some(({ id }) => id === "core")) {
|
|
522
|
+
const pluginIds = pluginExtensions.filter(({ id }) => id === "core").map(({ source }) => source.id);
|
|
471
523
|
throw new Error(
|
|
472
|
-
`The following plugin(s) are overriding the '
|
|
524
|
+
`The following plugin(s) are overriding the 'core' extension which is forbidden: ${pluginIds.join(
|
|
473
525
|
","
|
|
474
526
|
)}`
|
|
475
527
|
);
|
|
476
528
|
}
|
|
477
|
-
|
|
529
|
+
if (overrideExtensions.some(({ id }) => id === "root")) {
|
|
530
|
+
throw new Error(
|
|
531
|
+
`An extension override is overriding the 'root' extension which is forbidden`
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
const overrideExtensionIds = overrideExtensions.map(({ id }) => id);
|
|
535
|
+
if (overrideExtensionIds.length !== new Set(overrideExtensionIds).size) {
|
|
536
|
+
const counts = /* @__PURE__ */ new Map();
|
|
537
|
+
for (const id of overrideExtensionIds) {
|
|
538
|
+
counts.set(id, ((_a = counts.get(id)) != null ? _a : 0) + 1);
|
|
539
|
+
}
|
|
540
|
+
const duplicated = Array.from(counts.entries()).filter(([, count]) => count > 1).map(([id]) => id);
|
|
541
|
+
throw new Error(
|
|
542
|
+
`The following extensions had duplicate overrides: ${duplicated.join(
|
|
543
|
+
", "
|
|
544
|
+
)}`
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
const configuredExtensions = [
|
|
478
548
|
...pluginExtensions.map(({ source, ...extension }) => ({
|
|
479
549
|
extension,
|
|
480
550
|
params: {
|
|
@@ -494,14 +564,34 @@ function mergeExtensionParameters(options) {
|
|
|
494
564
|
}
|
|
495
565
|
}))
|
|
496
566
|
];
|
|
567
|
+
for (const extension of overrideExtensions) {
|
|
568
|
+
const index = configuredExtensions.findIndex(
|
|
569
|
+
(e) => e.extension.id === extension.id
|
|
570
|
+
);
|
|
571
|
+
if (index !== -1) {
|
|
572
|
+
configuredExtensions[index].extension = extension;
|
|
573
|
+
configuredExtensions[index].params.attachTo = extension.attachTo;
|
|
574
|
+
configuredExtensions[index].params.disabled = extension.disabled;
|
|
575
|
+
} else {
|
|
576
|
+
configuredExtensions.push({
|
|
577
|
+
extension,
|
|
578
|
+
params: {
|
|
579
|
+
source: void 0,
|
|
580
|
+
attachTo: extension.attachTo,
|
|
581
|
+
disabled: extension.disabled,
|
|
582
|
+
config: void 0
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
}
|
|
497
587
|
const duplicatedExtensionIds = /* @__PURE__ */ new Set();
|
|
498
|
-
const duplicatedExtensionData =
|
|
499
|
-
var
|
|
588
|
+
const duplicatedExtensionData = configuredExtensions.reduce((data, { extension, params }) => {
|
|
589
|
+
var _a2, _b, _c;
|
|
500
590
|
const extensionId = extension.id;
|
|
501
591
|
const extensionData = data == null ? void 0 : data[extensionId];
|
|
502
592
|
if (extensionData)
|
|
503
593
|
duplicatedExtensionIds.add(extensionId);
|
|
504
|
-
const pluginId = (_b = (
|
|
594
|
+
const pluginId = (_b = (_a2 = params.source) == null ? void 0 : _a2.id) != null ? _b : "internal";
|
|
505
595
|
const pluginCount = (_c = extensionData == null ? void 0 : extensionData[pluginId]) != null ? _c : 0;
|
|
506
596
|
return {
|
|
507
597
|
...data,
|
|
@@ -523,16 +613,16 @@ function mergeExtensionParameters(options) {
|
|
|
523
613
|
}
|
|
524
614
|
for (const overrideParam of parameters) {
|
|
525
615
|
const extensionId = overrideParam.id;
|
|
526
|
-
if (extensionId === "
|
|
616
|
+
if (extensionId === "core") {
|
|
527
617
|
throw new Error(
|
|
528
|
-
"A '
|
|
618
|
+
"A 'core' extension configuration was detected, but the core extension is not configurable"
|
|
529
619
|
);
|
|
530
620
|
}
|
|
531
|
-
const existingIndex =
|
|
621
|
+
const existingIndex = configuredExtensions.findIndex(
|
|
532
622
|
(e) => e.extension.id === extensionId
|
|
533
623
|
);
|
|
534
624
|
if (existingIndex !== -1) {
|
|
535
|
-
const existing =
|
|
625
|
+
const existing = configuredExtensions[existingIndex];
|
|
536
626
|
if (overrideParam.attachTo) {
|
|
537
627
|
existing.params.attachTo = overrideParam.attachTo;
|
|
538
628
|
}
|
|
@@ -542,15 +632,15 @@ function mergeExtensionParameters(options) {
|
|
|
542
632
|
if (Boolean(existing.params.disabled) !== Boolean(overrideParam.disabled)) {
|
|
543
633
|
existing.params.disabled = Boolean(overrideParam.disabled);
|
|
544
634
|
if (!existing.params.disabled) {
|
|
545
|
-
|
|
546
|
-
|
|
635
|
+
configuredExtensions.splice(existingIndex, 1);
|
|
636
|
+
configuredExtensions.push(existing);
|
|
547
637
|
}
|
|
548
638
|
}
|
|
549
639
|
} else {
|
|
550
640
|
throw new Error(`Extension ${extensionId} does not exist`);
|
|
551
641
|
}
|
|
552
642
|
}
|
|
553
|
-
return
|
|
643
|
+
return configuredExtensions.filter((override) => !override.params.disabled).map((param) => ({
|
|
554
644
|
extension: param.extension,
|
|
555
645
|
attachTo: param.params.attachTo,
|
|
556
646
|
source: param.params.source,
|
|
@@ -558,14 +648,54 @@ function mergeExtensionParameters(options) {
|
|
|
558
648
|
}));
|
|
559
649
|
}
|
|
560
650
|
|
|
561
|
-
function
|
|
651
|
+
function readPackageDetectionConfig(config) {
|
|
652
|
+
const packages = config.getOptional("app.experimental.packages");
|
|
653
|
+
if (packages === void 0 || packages === null) {
|
|
654
|
+
return void 0;
|
|
655
|
+
}
|
|
656
|
+
if (typeof packages === "string") {
|
|
657
|
+
if (packages !== "all") {
|
|
658
|
+
throw new Error(
|
|
659
|
+
`Invalid app.experimental.packages mode, got '${packages}', expected 'all'`
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
return {};
|
|
663
|
+
}
|
|
664
|
+
if (typeof packages !== "object" || Array.isArray(packages)) {
|
|
665
|
+
throw new Error(
|
|
666
|
+
"Invalid config at 'app.experimental.packages', expected object"
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
const packagesConfig = new ConfigReader(
|
|
670
|
+
packages,
|
|
671
|
+
"app.experimental.packages"
|
|
672
|
+
);
|
|
673
|
+
return {
|
|
674
|
+
include: packagesConfig.getOptionalStringArray("include"),
|
|
675
|
+
exclude: packagesConfig.getOptionalStringArray("exclude")
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
function getAvailableFeatures(config) {
|
|
562
679
|
var _a;
|
|
563
680
|
const discovered = window["__@backstage/discovered__"];
|
|
564
|
-
|
|
681
|
+
const detection = readPackageDetectionConfig(config);
|
|
682
|
+
if (!detection) {
|
|
683
|
+
return [];
|
|
684
|
+
}
|
|
685
|
+
return (_a = discovered == null ? void 0 : discovered.modules.filter(({ name }) => {
|
|
686
|
+
var _a2;
|
|
687
|
+
if ((_a2 = detection.exclude) == null ? void 0 : _a2.includes(name)) {
|
|
688
|
+
return false;
|
|
689
|
+
}
|
|
690
|
+
if (detection.include && !detection.include.includes(name)) {
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
return true;
|
|
694
|
+
}).map((m) => m.default).filter(isBackstageFeature)) != null ? _a : [];
|
|
565
695
|
}
|
|
566
|
-
function
|
|
696
|
+
function isBackstageFeature(obj) {
|
|
567
697
|
if (obj !== null && typeof obj === "object" && "$$type" in obj) {
|
|
568
|
-
return obj.$$type === "@backstage/BackstagePlugin";
|
|
698
|
+
return obj.$$type === "@backstage/BackstagePlugin" || obj.$$type === "@backstage/ExtensionOverrides";
|
|
569
699
|
}
|
|
570
700
|
return false;
|
|
571
701
|
}
|
|
@@ -624,10 +754,10 @@ function AppThemeProvider({ children }) {
|
|
|
624
754
|
return /* @__PURE__ */ React.createElement(appTheme.Provider, { children });
|
|
625
755
|
}
|
|
626
756
|
|
|
627
|
-
var __defProp$
|
|
628
|
-
var __defNormalProp$
|
|
629
|
-
var __publicField$
|
|
630
|
-
__defNormalProp$
|
|
757
|
+
var __defProp$2 = Object.defineProperty;
|
|
758
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
759
|
+
var __publicField$2 = (obj, key, value) => {
|
|
760
|
+
__defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
631
761
|
return value;
|
|
632
762
|
};
|
|
633
763
|
function mkError(thing) {
|
|
@@ -642,11 +772,11 @@ function logDeprecation(thing) {
|
|
|
642
772
|
}
|
|
643
773
|
class AppIdentityProxy {
|
|
644
774
|
constructor() {
|
|
645
|
-
__publicField$
|
|
646
|
-
__publicField$
|
|
647
|
-
__publicField$
|
|
775
|
+
__publicField$2(this, "target");
|
|
776
|
+
__publicField$2(this, "waitForTarget");
|
|
777
|
+
__publicField$2(this, "resolveTarget", () => {
|
|
648
778
|
});
|
|
649
|
-
__publicField$
|
|
779
|
+
__publicField$2(this, "signOutTargetUrl", "/");
|
|
650
780
|
this.waitForTarget = new Promise((resolve) => {
|
|
651
781
|
this.resolveTarget = resolve;
|
|
652
782
|
});
|
|
@@ -718,10 +848,10 @@ const AppContextProvider = ({
|
|
|
718
848
|
return /* @__PURE__ */ React.createElement(AppContext.Provider, { value: versionedValue, children });
|
|
719
849
|
};
|
|
720
850
|
|
|
721
|
-
var __defProp = Object.defineProperty;
|
|
722
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
723
|
-
var __publicField = (obj, key, value) => {
|
|
724
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
851
|
+
var __defProp$1 = Object.defineProperty;
|
|
852
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
853
|
+
var __publicField$1 = (obj, key, value) => {
|
|
854
|
+
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
725
855
|
return value;
|
|
726
856
|
};
|
|
727
857
|
function validateFlagName(name) {
|
|
@@ -743,8 +873,8 @@ function validateFlagName(name) {
|
|
|
743
873
|
}
|
|
744
874
|
class LocalStorageFeatureFlags {
|
|
745
875
|
constructor() {
|
|
746
|
-
__publicField(this, "registeredFeatureFlags", []);
|
|
747
|
-
__publicField(this, "flags");
|
|
876
|
+
__publicField$1(this, "registeredFeatureFlags", []);
|
|
877
|
+
__publicField$1(this, "flags");
|
|
748
878
|
}
|
|
749
879
|
registerFlag(flag) {
|
|
750
880
|
validateFlagName(flag.name);
|
|
@@ -1048,6 +1178,499 @@ const RoutingProvider = ({
|
|
|
1048
1178
|
return /* @__PURE__ */ React.createElement(RoutingContext.Provider, { value: versionedValue }, children);
|
|
1049
1179
|
};
|
|
1050
1180
|
|
|
1181
|
+
function resolveRouteBindings(bindRoutes) {
|
|
1182
|
+
const result = /* @__PURE__ */ new Map();
|
|
1183
|
+
if (bindRoutes) {
|
|
1184
|
+
const bind = (externalRoutes, targetRoutes) => {
|
|
1185
|
+
for (const [key, value] of Object.entries(targetRoutes)) {
|
|
1186
|
+
const externalRoute = externalRoutes[key];
|
|
1187
|
+
if (!externalRoute) {
|
|
1188
|
+
throw new Error(`Key ${key} is not an existing external route`);
|
|
1189
|
+
}
|
|
1190
|
+
if (!value && !externalRoute.optional) {
|
|
1191
|
+
throw new Error(
|
|
1192
|
+
`External route ${key} is required but was undefined`
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
if (value) {
|
|
1196
|
+
result.set(externalRoute, value);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
};
|
|
1200
|
+
bindRoutes({ bind });
|
|
1201
|
+
}
|
|
1202
|
+
return result;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
var __defProp = Object.defineProperty;
|
|
1206
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1207
|
+
var __publicField = (obj, key, value) => {
|
|
1208
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1209
|
+
return value;
|
|
1210
|
+
};
|
|
1211
|
+
class BehaviorSubject {
|
|
1212
|
+
constructor(value) {
|
|
1213
|
+
__publicField(this, "isClosed");
|
|
1214
|
+
__publicField(this, "currentValue");
|
|
1215
|
+
__publicField(this, "terminatingError");
|
|
1216
|
+
__publicField(this, "observable");
|
|
1217
|
+
__publicField(this, "subscribers", /* @__PURE__ */ new Set());
|
|
1218
|
+
this.isClosed = false;
|
|
1219
|
+
this.currentValue = value;
|
|
1220
|
+
this.terminatingError = void 0;
|
|
1221
|
+
this.observable = new ObservableImpl((subscriber) => {
|
|
1222
|
+
if (this.isClosed) {
|
|
1223
|
+
if (this.terminatingError) {
|
|
1224
|
+
subscriber.error(this.terminatingError);
|
|
1225
|
+
} else {
|
|
1226
|
+
subscriber.complete();
|
|
1227
|
+
}
|
|
1228
|
+
return () => {
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
subscriber.next(this.currentValue);
|
|
1232
|
+
this.subscribers.add(subscriber);
|
|
1233
|
+
return () => {
|
|
1234
|
+
this.subscribers.delete(subscriber);
|
|
1235
|
+
};
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
[Symbol.observable]() {
|
|
1239
|
+
return this;
|
|
1240
|
+
}
|
|
1241
|
+
get closed() {
|
|
1242
|
+
return this.isClosed;
|
|
1243
|
+
}
|
|
1244
|
+
next(value) {
|
|
1245
|
+
if (this.isClosed) {
|
|
1246
|
+
throw new Error("BehaviorSubject is closed");
|
|
1247
|
+
}
|
|
1248
|
+
this.currentValue = value;
|
|
1249
|
+
this.subscribers.forEach((subscriber) => subscriber.next(value));
|
|
1250
|
+
}
|
|
1251
|
+
error(error) {
|
|
1252
|
+
if (this.isClosed) {
|
|
1253
|
+
throw new Error("BehaviorSubject is closed");
|
|
1254
|
+
}
|
|
1255
|
+
this.isClosed = true;
|
|
1256
|
+
this.terminatingError = error;
|
|
1257
|
+
this.subscribers.forEach((subscriber) => subscriber.error(error));
|
|
1258
|
+
}
|
|
1259
|
+
complete() {
|
|
1260
|
+
if (this.isClosed) {
|
|
1261
|
+
throw new Error("BehaviorSubject is closed");
|
|
1262
|
+
}
|
|
1263
|
+
this.isClosed = true;
|
|
1264
|
+
this.subscribers.forEach((subscriber) => subscriber.complete());
|
|
1265
|
+
}
|
|
1266
|
+
subscribe(onNext, onError, onComplete) {
|
|
1267
|
+
const observer = typeof onNext === "function" ? {
|
|
1268
|
+
next: onNext,
|
|
1269
|
+
error: onError,
|
|
1270
|
+
complete: onComplete
|
|
1271
|
+
} : onNext;
|
|
1272
|
+
return this.observable.subscribe(observer);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
var __accessCheck$1 = (obj, member, msg) => {
|
|
1277
|
+
if (!member.has(obj))
|
|
1278
|
+
throw TypeError("Cannot " + msg);
|
|
1279
|
+
};
|
|
1280
|
+
var __privateGet$1 = (obj, member, getter) => {
|
|
1281
|
+
__accessCheck$1(obj, member, "read from private field");
|
|
1282
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
1283
|
+
};
|
|
1284
|
+
var __privateAdd$1 = (obj, member, value) => {
|
|
1285
|
+
if (member.has(obj))
|
|
1286
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
1287
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1288
|
+
};
|
|
1289
|
+
var __privateSet$1 = (obj, member, value, setter) => {
|
|
1290
|
+
__accessCheck$1(obj, member, "write to private field");
|
|
1291
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1292
|
+
return value;
|
|
1293
|
+
};
|
|
1294
|
+
var _languages, _language$1, _subject;
|
|
1295
|
+
const STORAGE_KEY = "language";
|
|
1296
|
+
const DEFAULT_LANGUAGE = "en";
|
|
1297
|
+
const _AppLanguageSelector = class _AppLanguageSelector {
|
|
1298
|
+
constructor(languages, initialLanguage) {
|
|
1299
|
+
__privateAdd$1(this, _languages, void 0);
|
|
1300
|
+
__privateAdd$1(this, _language$1, void 0);
|
|
1301
|
+
__privateAdd$1(this, _subject, void 0);
|
|
1302
|
+
__privateSet$1(this, _languages, languages);
|
|
1303
|
+
__privateSet$1(this, _language$1, initialLanguage);
|
|
1304
|
+
__privateSet$1(this, _subject, new BehaviorSubject({
|
|
1305
|
+
language: __privateGet$1(this, _language$1)
|
|
1306
|
+
}));
|
|
1307
|
+
}
|
|
1308
|
+
static create(options) {
|
|
1309
|
+
var _a, _b;
|
|
1310
|
+
const languages = (_a = options == null ? void 0 : options.availableLanguages) != null ? _a : [DEFAULT_LANGUAGE];
|
|
1311
|
+
if (languages.length !== new Set(languages).size) {
|
|
1312
|
+
throw new Error(
|
|
1313
|
+
`Supported languages may not contain duplicates, got '${languages.join(
|
|
1314
|
+
"', '"
|
|
1315
|
+
)}'`
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
if (!languages.includes(DEFAULT_LANGUAGE)) {
|
|
1319
|
+
throw new Error(`Supported languages must include '${DEFAULT_LANGUAGE}'`);
|
|
1320
|
+
}
|
|
1321
|
+
const initialLanguage = (_b = options == null ? void 0 : options.defaultLanguage) != null ? _b : DEFAULT_LANGUAGE;
|
|
1322
|
+
if (!languages.includes(initialLanguage)) {
|
|
1323
|
+
throw new Error(
|
|
1324
|
+
`Initial language must be one of the supported languages, got '${initialLanguage}'`
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
return new _AppLanguageSelector(languages, initialLanguage);
|
|
1328
|
+
}
|
|
1329
|
+
static createWithStorage(options) {
|
|
1330
|
+
const selector = _AppLanguageSelector.create(options);
|
|
1331
|
+
if (!window.localStorage) {
|
|
1332
|
+
return selector;
|
|
1333
|
+
}
|
|
1334
|
+
const storedLanguage = window.localStorage.getItem(STORAGE_KEY);
|
|
1335
|
+
const { languages } = selector.getAvailableLanguages();
|
|
1336
|
+
if (storedLanguage && languages.includes(storedLanguage)) {
|
|
1337
|
+
selector.setLanguage(storedLanguage);
|
|
1338
|
+
}
|
|
1339
|
+
selector.language$().subscribe(({ language }) => {
|
|
1340
|
+
if (language !== window.localStorage.getItem(STORAGE_KEY)) {
|
|
1341
|
+
window.localStorage.setItem(STORAGE_KEY, language);
|
|
1342
|
+
}
|
|
1343
|
+
});
|
|
1344
|
+
window.addEventListener("storage", (event) => {
|
|
1345
|
+
var _a;
|
|
1346
|
+
if (event.key === STORAGE_KEY) {
|
|
1347
|
+
const language = (_a = localStorage.getItem(STORAGE_KEY)) != null ? _a : void 0;
|
|
1348
|
+
if (language) {
|
|
1349
|
+
selector.setLanguage(language);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
});
|
|
1353
|
+
return selector;
|
|
1354
|
+
}
|
|
1355
|
+
getAvailableLanguages() {
|
|
1356
|
+
return { languages: __privateGet$1(this, _languages).slice() };
|
|
1357
|
+
}
|
|
1358
|
+
setLanguage(language) {
|
|
1359
|
+
const lng = language != null ? language : DEFAULT_LANGUAGE;
|
|
1360
|
+
if (lng === __privateGet$1(this, _language$1)) {
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
if (lng && !__privateGet$1(this, _languages).includes(lng)) {
|
|
1364
|
+
throw new Error(
|
|
1365
|
+
`Failed to change language to '${lng}', available languages are '${__privateGet$1(this, _languages).join(
|
|
1366
|
+
"', '"
|
|
1367
|
+
)}'`
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1370
|
+
__privateSet$1(this, _language$1, lng);
|
|
1371
|
+
__privateGet$1(this, _subject).next({ language: lng });
|
|
1372
|
+
}
|
|
1373
|
+
getLanguage() {
|
|
1374
|
+
return { language: __privateGet$1(this, _language$1) };
|
|
1375
|
+
}
|
|
1376
|
+
language$() {
|
|
1377
|
+
return __privateGet$1(this, _subject);
|
|
1378
|
+
}
|
|
1379
|
+
};
|
|
1380
|
+
_languages = new WeakMap();
|
|
1381
|
+
_language$1 = new WeakMap();
|
|
1382
|
+
_subject = new WeakMap();
|
|
1383
|
+
let AppLanguageSelector = _AppLanguageSelector;
|
|
1384
|
+
|
|
1385
|
+
function toInternalTranslationResource(resource) {
|
|
1386
|
+
const r = resource;
|
|
1387
|
+
if (r.$$type !== "@backstage/TranslationResource") {
|
|
1388
|
+
throw new Error(`Invalid translation resource, bad type '${r.$$type}'`);
|
|
1389
|
+
}
|
|
1390
|
+
if (r.version !== "v1") {
|
|
1391
|
+
throw new Error(`Invalid translation resource, bad version '${r.version}'`);
|
|
1392
|
+
}
|
|
1393
|
+
return r;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
function toInternalTranslationRef(ref) {
|
|
1397
|
+
const r = ref;
|
|
1398
|
+
if (r.$$type !== "@backstage/TranslationRef") {
|
|
1399
|
+
throw new Error(`Invalid translation ref, bad type '${r.$$type}'`);
|
|
1400
|
+
}
|
|
1401
|
+
if (r.version !== "v1") {
|
|
1402
|
+
throw new Error(`Invalid translation ref, bad version '${r.version}'`);
|
|
1403
|
+
}
|
|
1404
|
+
return r;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
var __accessCheck = (obj, member, msg) => {
|
|
1408
|
+
if (!member.has(obj))
|
|
1409
|
+
throw TypeError("Cannot " + msg);
|
|
1410
|
+
};
|
|
1411
|
+
var __privateGet = (obj, member, getter) => {
|
|
1412
|
+
__accessCheck(obj, member, "read from private field");
|
|
1413
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
1414
|
+
};
|
|
1415
|
+
var __privateAdd = (obj, member, value) => {
|
|
1416
|
+
if (member.has(obj))
|
|
1417
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
1418
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1419
|
+
};
|
|
1420
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
1421
|
+
__accessCheck(obj, member, "write to private field");
|
|
1422
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1423
|
+
return value;
|
|
1424
|
+
};
|
|
1425
|
+
var __privateMethod = (obj, member, method) => {
|
|
1426
|
+
__accessCheck(obj, member, "access private method");
|
|
1427
|
+
return method;
|
|
1428
|
+
};
|
|
1429
|
+
var _loaded, _loading, _loaders, _getLoaderKey, getLoaderKey_fn, _i18n, _loader, _language, _registeredRefs, _languageChangeListeners, _changeLanguage, changeLanguage_fn, _createSnapshot, createSnapshot_fn, _registerDefaults, registerDefaults_fn;
|
|
1430
|
+
function removeNulls(messages) {
|
|
1431
|
+
return Object.fromEntries(
|
|
1432
|
+
Object.entries(messages).filter(
|
|
1433
|
+
(e) => e[1] !== null
|
|
1434
|
+
)
|
|
1435
|
+
);
|
|
1436
|
+
}
|
|
1437
|
+
class ResourceLoader {
|
|
1438
|
+
constructor(onLoad) {
|
|
1439
|
+
this.onLoad = onLoad;
|
|
1440
|
+
__privateAdd(this, _getLoaderKey);
|
|
1441
|
+
/** Loaded resources by loader key */
|
|
1442
|
+
__privateAdd(this, _loaded, /* @__PURE__ */ new Set());
|
|
1443
|
+
/** Resource loading promises by loader key */
|
|
1444
|
+
__privateAdd(this, _loading, /* @__PURE__ */ new Map());
|
|
1445
|
+
/** Loaders for each resource language */
|
|
1446
|
+
__privateAdd(this, _loaders, /* @__PURE__ */ new Map());
|
|
1447
|
+
}
|
|
1448
|
+
addTranslationResource(resource) {
|
|
1449
|
+
const internalResource = toInternalTranslationResource(resource);
|
|
1450
|
+
for (const entry of internalResource.resources) {
|
|
1451
|
+
const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, entry.language, internalResource.id);
|
|
1452
|
+
if (!__privateGet(this, _loaders).has(key)) {
|
|
1453
|
+
__privateGet(this, _loaders).set(key, entry.loader);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
needsLoading(language, namespace) {
|
|
1458
|
+
const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, language, namespace);
|
|
1459
|
+
const loader = __privateGet(this, _loaders).get(key);
|
|
1460
|
+
if (!loader) {
|
|
1461
|
+
return false;
|
|
1462
|
+
}
|
|
1463
|
+
return !__privateGet(this, _loaded).has(key);
|
|
1464
|
+
}
|
|
1465
|
+
async load(language, namespace) {
|
|
1466
|
+
const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, language, namespace);
|
|
1467
|
+
const loader = __privateGet(this, _loaders).get(key);
|
|
1468
|
+
if (!loader) {
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
if (__privateGet(this, _loaded).has(key)) {
|
|
1472
|
+
return;
|
|
1473
|
+
}
|
|
1474
|
+
const loading = __privateGet(this, _loading).get(key);
|
|
1475
|
+
if (loading) {
|
|
1476
|
+
await loading;
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
const load = loader().then(
|
|
1480
|
+
(result) => {
|
|
1481
|
+
this.onLoad({ language, namespace, messages: result.messages });
|
|
1482
|
+
__privateGet(this, _loaded).add(key);
|
|
1483
|
+
},
|
|
1484
|
+
(error) => {
|
|
1485
|
+
__privateGet(this, _loaded).add(key);
|
|
1486
|
+
throw error;
|
|
1487
|
+
}
|
|
1488
|
+
);
|
|
1489
|
+
__privateGet(this, _loading).set(key, load);
|
|
1490
|
+
await load;
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
_loaded = new WeakMap();
|
|
1494
|
+
_loading = new WeakMap();
|
|
1495
|
+
_loaders = new WeakMap();
|
|
1496
|
+
_getLoaderKey = new WeakSet();
|
|
1497
|
+
getLoaderKey_fn = function(language, namespace) {
|
|
1498
|
+
return `${language}/${namespace}`;
|
|
1499
|
+
};
|
|
1500
|
+
const _I18nextTranslationApi = class _I18nextTranslationApi {
|
|
1501
|
+
constructor(i18n, loader, language) {
|
|
1502
|
+
__privateAdd(this, _changeLanguage);
|
|
1503
|
+
__privateAdd(this, _createSnapshot);
|
|
1504
|
+
__privateAdd(this, _registerDefaults);
|
|
1505
|
+
__privateAdd(this, _i18n, void 0);
|
|
1506
|
+
__privateAdd(this, _loader, void 0);
|
|
1507
|
+
__privateAdd(this, _language, void 0);
|
|
1508
|
+
/** Keep track of which refs we have registered default resources for */
|
|
1509
|
+
__privateAdd(this, _registeredRefs, /* @__PURE__ */ new Set());
|
|
1510
|
+
/** Notify observers when language changes */
|
|
1511
|
+
__privateAdd(this, _languageChangeListeners, /* @__PURE__ */ new Set());
|
|
1512
|
+
__privateSet(this, _i18n, i18n);
|
|
1513
|
+
__privateSet(this, _loader, loader);
|
|
1514
|
+
__privateSet(this, _language, language);
|
|
1515
|
+
}
|
|
1516
|
+
static create(options) {
|
|
1517
|
+
const { languages } = options.languageApi.getAvailableLanguages();
|
|
1518
|
+
const i18n = createInstance({
|
|
1519
|
+
fallbackLng: DEFAULT_LANGUAGE,
|
|
1520
|
+
supportedLngs: languages,
|
|
1521
|
+
interpolation: {
|
|
1522
|
+
escapeValue: false
|
|
1523
|
+
},
|
|
1524
|
+
ns: [],
|
|
1525
|
+
defaultNS: false,
|
|
1526
|
+
fallbackNS: false,
|
|
1527
|
+
// Disable resource loading on init, meaning i18n will be ready to use immediately
|
|
1528
|
+
initImmediate: false
|
|
1529
|
+
});
|
|
1530
|
+
i18n.init();
|
|
1531
|
+
if (!i18n.isInitialized) {
|
|
1532
|
+
throw new Error("i18next was unexpectedly not initialized");
|
|
1533
|
+
}
|
|
1534
|
+
const { language: initialLanguage } = options.languageApi.getLanguage();
|
|
1535
|
+
if (initialLanguage !== DEFAULT_LANGUAGE) {
|
|
1536
|
+
i18n.changeLanguage(initialLanguage);
|
|
1537
|
+
}
|
|
1538
|
+
const loader = new ResourceLoader((loaded) => {
|
|
1539
|
+
i18n.addResourceBundle(
|
|
1540
|
+
loaded.language,
|
|
1541
|
+
loaded.namespace,
|
|
1542
|
+
removeNulls(loaded.messages),
|
|
1543
|
+
false,
|
|
1544
|
+
// do not merge with existing translations
|
|
1545
|
+
true
|
|
1546
|
+
// overwrite translations
|
|
1547
|
+
);
|
|
1548
|
+
});
|
|
1549
|
+
const resources = (options == null ? void 0 : options.resources) || [];
|
|
1550
|
+
for (let i = resources.length - 1; i >= 0; i--) {
|
|
1551
|
+
const resource = resources[i];
|
|
1552
|
+
if (resource.$$type === "@backstage/TranslationResource") {
|
|
1553
|
+
loader.addTranslationResource(resource);
|
|
1554
|
+
} else if (resource.$$type === "@backstage/TranslationMessages") {
|
|
1555
|
+
i18n.addResourceBundle(
|
|
1556
|
+
DEFAULT_LANGUAGE,
|
|
1557
|
+
resource.id,
|
|
1558
|
+
removeNulls(resource.messages),
|
|
1559
|
+
true,
|
|
1560
|
+
// merge with existing translations
|
|
1561
|
+
false
|
|
1562
|
+
// do not overwrite translations
|
|
1563
|
+
);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
const instance = new _I18nextTranslationApi(
|
|
1567
|
+
i18n,
|
|
1568
|
+
loader,
|
|
1569
|
+
options.languageApi.getLanguage().language
|
|
1570
|
+
);
|
|
1571
|
+
options.languageApi.language$().subscribe(({ language }) => {
|
|
1572
|
+
var _a;
|
|
1573
|
+
__privateMethod(_a = instance, _changeLanguage, changeLanguage_fn).call(_a, language);
|
|
1574
|
+
});
|
|
1575
|
+
return instance;
|
|
1576
|
+
}
|
|
1577
|
+
getTranslation(translationRef) {
|
|
1578
|
+
const internalRef = toInternalTranslationRef(translationRef);
|
|
1579
|
+
__privateMethod(this, _registerDefaults, registerDefaults_fn).call(this, internalRef);
|
|
1580
|
+
return __privateMethod(this, _createSnapshot, createSnapshot_fn).call(this, internalRef);
|
|
1581
|
+
}
|
|
1582
|
+
translation$(translationRef) {
|
|
1583
|
+
const internalRef = toInternalTranslationRef(translationRef);
|
|
1584
|
+
__privateMethod(this, _registerDefaults, registerDefaults_fn).call(this, internalRef);
|
|
1585
|
+
return new ObservableImpl((subscriber) => {
|
|
1586
|
+
let loadTicket = {};
|
|
1587
|
+
const loadResource = () => {
|
|
1588
|
+
loadTicket = {};
|
|
1589
|
+
const ticket = loadTicket;
|
|
1590
|
+
__privateGet(this, _loader).load(__privateGet(this, _language), internalRef.id).then(
|
|
1591
|
+
() => {
|
|
1592
|
+
if (ticket === loadTicket) {
|
|
1593
|
+
const snapshot = __privateMethod(this, _createSnapshot, createSnapshot_fn).call(this, internalRef);
|
|
1594
|
+
if (snapshot.ready) {
|
|
1595
|
+
subscriber.next(snapshot);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
},
|
|
1599
|
+
(error) => {
|
|
1600
|
+
if (ticket === loadTicket) {
|
|
1601
|
+
subscriber.error(Array.isArray(error) ? error[0] : error);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
);
|
|
1605
|
+
};
|
|
1606
|
+
const onChange = () => {
|
|
1607
|
+
const snapshot = __privateMethod(this, _createSnapshot, createSnapshot_fn).call(this, internalRef);
|
|
1608
|
+
if (snapshot.ready) {
|
|
1609
|
+
subscriber.next(snapshot);
|
|
1610
|
+
} else {
|
|
1611
|
+
loadResource();
|
|
1612
|
+
}
|
|
1613
|
+
};
|
|
1614
|
+
if (__privateGet(this, _loader).needsLoading(__privateGet(this, _language), internalRef.id)) {
|
|
1615
|
+
loadResource();
|
|
1616
|
+
}
|
|
1617
|
+
__privateGet(this, _languageChangeListeners).add(onChange);
|
|
1618
|
+
return () => {
|
|
1619
|
+
__privateGet(this, _languageChangeListeners).delete(onChange);
|
|
1620
|
+
};
|
|
1621
|
+
});
|
|
1622
|
+
}
|
|
1623
|
+
};
|
|
1624
|
+
_i18n = new WeakMap();
|
|
1625
|
+
_loader = new WeakMap();
|
|
1626
|
+
_language = new WeakMap();
|
|
1627
|
+
_registeredRefs = new WeakMap();
|
|
1628
|
+
_languageChangeListeners = new WeakMap();
|
|
1629
|
+
_changeLanguage = new WeakSet();
|
|
1630
|
+
changeLanguage_fn = function(language) {
|
|
1631
|
+
if (__privateGet(this, _language) !== language) {
|
|
1632
|
+
__privateSet(this, _language, language);
|
|
1633
|
+
__privateGet(this, _i18n).changeLanguage(language);
|
|
1634
|
+
__privateGet(this, _languageChangeListeners).forEach((listener) => listener());
|
|
1635
|
+
}
|
|
1636
|
+
};
|
|
1637
|
+
_createSnapshot = new WeakSet();
|
|
1638
|
+
createSnapshot_fn = function(internalRef) {
|
|
1639
|
+
if (__privateGet(this, _loader).needsLoading(__privateGet(this, _language), internalRef.id)) {
|
|
1640
|
+
return { ready: false };
|
|
1641
|
+
}
|
|
1642
|
+
const t = __privateGet(this, _i18n).getFixedT(
|
|
1643
|
+
null,
|
|
1644
|
+
internalRef.id
|
|
1645
|
+
);
|
|
1646
|
+
return {
|
|
1647
|
+
ready: true,
|
|
1648
|
+
t
|
|
1649
|
+
};
|
|
1650
|
+
};
|
|
1651
|
+
_registerDefaults = new WeakSet();
|
|
1652
|
+
registerDefaults_fn = function(internalRef) {
|
|
1653
|
+
if (__privateGet(this, _registeredRefs).has(internalRef.id)) {
|
|
1654
|
+
return;
|
|
1655
|
+
}
|
|
1656
|
+
__privateGet(this, _registeredRefs).add(internalRef.id);
|
|
1657
|
+
const defaultMessages = internalRef.getDefaultMessages();
|
|
1658
|
+
__privateGet(this, _i18n).addResourceBundle(
|
|
1659
|
+
DEFAULT_LANGUAGE,
|
|
1660
|
+
internalRef.id,
|
|
1661
|
+
defaultMessages,
|
|
1662
|
+
true,
|
|
1663
|
+
// merge with existing translations
|
|
1664
|
+
false
|
|
1665
|
+
// do not overwrite translations
|
|
1666
|
+
);
|
|
1667
|
+
const defaultResource = internalRef.getDefaultResource();
|
|
1668
|
+
if (defaultResource) {
|
|
1669
|
+
__privateGet(this, _loader).addTranslationResource(defaultResource);
|
|
1670
|
+
}
|
|
1671
|
+
};
|
|
1672
|
+
let I18nextTranslationApi = _I18nextTranslationApi;
|
|
1673
|
+
|
|
1051
1674
|
const apis = [
|
|
1052
1675
|
createApiFactory({
|
|
1053
1676
|
api: discoveryApiRef,
|
|
@@ -1343,7 +1966,7 @@ function joinPaths(...paths) {
|
|
|
1343
1966
|
}
|
|
1344
1967
|
return normalized;
|
|
1345
1968
|
}
|
|
1346
|
-
function extractRouteInfoFromInstanceTree(
|
|
1969
|
+
function extractRouteInfoFromInstanceTree(core) {
|
|
1347
1970
|
const routePaths = /* @__PURE__ */ new Map();
|
|
1348
1971
|
const routeParents = /* @__PURE__ */ new Map();
|
|
1349
1972
|
const routeObjects = new Array();
|
|
@@ -1409,16 +2032,14 @@ function extractRouteInfoFromInstanceTree(roots) {
|
|
|
1409
2032
|
}
|
|
1410
2033
|
}
|
|
1411
2034
|
}
|
|
1412
|
-
|
|
1413
|
-
visit(root);
|
|
1414
|
-
}
|
|
2035
|
+
visit(core);
|
|
1415
2036
|
return { routePaths, routeParents, routeObjects };
|
|
1416
2037
|
}
|
|
1417
2038
|
|
|
1418
2039
|
function createExtensionTree(options) {
|
|
1419
|
-
const
|
|
2040
|
+
const features = getAvailableFeatures(options.config);
|
|
1420
2041
|
const { instances } = createInstances({
|
|
1421
|
-
|
|
2042
|
+
features,
|
|
1422
2043
|
config: options.config
|
|
1423
2044
|
});
|
|
1424
2045
|
return {
|
|
@@ -1468,7 +2089,6 @@ function createExtensionTree(options) {
|
|
|
1468
2089
|
};
|
|
1469
2090
|
}
|
|
1470
2091
|
function createInstances(options) {
|
|
1471
|
-
var _a, _b;
|
|
1472
2092
|
const builtinExtensions = [
|
|
1473
2093
|
Core,
|
|
1474
2094
|
CoreRoutes,
|
|
@@ -1478,7 +2098,7 @@ function createInstances(options) {
|
|
|
1478
2098
|
DarkTheme
|
|
1479
2099
|
];
|
|
1480
2100
|
const extensionParams = mergeExtensionParameters({
|
|
1481
|
-
|
|
2101
|
+
features: options.features,
|
|
1482
2102
|
builtinExtensions,
|
|
1483
2103
|
parameters: readAppExtensionParameters(options.config)
|
|
1484
2104
|
});
|
|
@@ -1500,14 +2120,14 @@ function createInstances(options) {
|
|
|
1500
2120
|
}
|
|
1501
2121
|
const instances = /* @__PURE__ */ new Map();
|
|
1502
2122
|
function createInstance(instanceParams) {
|
|
1503
|
-
var
|
|
2123
|
+
var _a, _b;
|
|
1504
2124
|
const extensionId = instanceParams.extension.id;
|
|
1505
2125
|
const existingInstance = instances.get(extensionId);
|
|
1506
2126
|
if (existingInstance) {
|
|
1507
2127
|
return existingInstance;
|
|
1508
2128
|
}
|
|
1509
2129
|
const attachments = new Map(
|
|
1510
|
-
Array.from((
|
|
2130
|
+
Array.from((_b = (_a = attachmentMap.get(extensionId)) == null ? void 0 : _a.entries()) != null ? _b : []).map(
|
|
1511
2131
|
([inputName, attachmentConfigs]) => {
|
|
1512
2132
|
return [inputName, attachmentConfigs.map(createInstance)];
|
|
1513
2133
|
}
|
|
@@ -1522,38 +2142,43 @@ function createInstances(options) {
|
|
|
1522
2142
|
instances.set(extensionId, newInstance);
|
|
1523
2143
|
return newInstance;
|
|
1524
2144
|
}
|
|
1525
|
-
const
|
|
1526
|
-
|
|
1527
|
-
(instanceParams) => createInstance(instanceParams)
|
|
2145
|
+
const coreInstance = createInstance(
|
|
2146
|
+
extensionParams.find((p) => p.extension.id === "core")
|
|
1528
2147
|
);
|
|
1529
|
-
return {
|
|
2148
|
+
return { coreInstance, instances };
|
|
1530
2149
|
}
|
|
1531
2150
|
function createApp(options) {
|
|
1532
2151
|
async function appLoader() {
|
|
1533
|
-
var _a, _b, _c, _d;
|
|
2152
|
+
var _a, _b, _c, _d, _e;
|
|
1534
2153
|
const config = (_b = await ((_a = options == null ? void 0 : options.configLoader) == null ? void 0 : _a.call(options))) != null ? _b : ConfigReader.fromConfigs(
|
|
1535
2154
|
overrideBaseUrlConfigs(defaultConfigLoaderSync())
|
|
1536
2155
|
);
|
|
1537
|
-
const
|
|
1538
|
-
const
|
|
1539
|
-
const
|
|
1540
|
-
/* @__PURE__ */ new Set([
|
|
2156
|
+
const discoveredFeatures = getAvailableFeatures(config);
|
|
2157
|
+
const loadedFeatures = (_d = await ((_c = options.featureLoader) == null ? void 0 : _c.call(options, { config }))) != null ? _d : [];
|
|
2158
|
+
const allFeatures = Array.from(
|
|
2159
|
+
/* @__PURE__ */ new Set([
|
|
2160
|
+
...discoveredFeatures,
|
|
2161
|
+
...(_e = options.features) != null ? _e : [],
|
|
2162
|
+
...loadedFeatures
|
|
2163
|
+
])
|
|
1541
2164
|
);
|
|
1542
|
-
const {
|
|
1543
|
-
|
|
2165
|
+
const { coreInstance } = createInstances({
|
|
2166
|
+
features: allFeatures,
|
|
1544
2167
|
config
|
|
1545
2168
|
});
|
|
1546
|
-
const
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
const
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
2169
|
+
const appContext = createLegacyAppContext(
|
|
2170
|
+
allFeatures.filter(
|
|
2171
|
+
(f) => f.$$type === "@backstage/BackstagePlugin"
|
|
2172
|
+
)
|
|
2173
|
+
);
|
|
2174
|
+
const App = () => /* @__PURE__ */ React.createElement(ApiProvider, { apis: createApiHolder(coreInstance, config) }, /* @__PURE__ */ React.createElement(AppContextProvider, { appContext }, /* @__PURE__ */ React.createElement(AppThemeProvider, null, /* @__PURE__ */ React.createElement(
|
|
2175
|
+
RoutingProvider,
|
|
2176
|
+
{
|
|
2177
|
+
...extractRouteInfoFromInstanceTree(coreInstance),
|
|
2178
|
+
routeBindings: resolveRouteBindings(options.bindRoutes)
|
|
2179
|
+
},
|
|
2180
|
+
/* @__PURE__ */ React.createElement(BrowserRouter, null, coreInstance.getData(coreExtensionData.reactElement))
|
|
2181
|
+
))));
|
|
1557
2182
|
return { default: App };
|
|
1558
2183
|
}
|
|
1559
2184
|
return {
|
|
@@ -1664,6 +2289,18 @@ function createApiHolder(coreExtension, configApi) {
|
|
|
1664
2289
|
deps: {},
|
|
1665
2290
|
factory: () => configApi
|
|
1666
2291
|
});
|
|
2292
|
+
factoryRegistry.register("static", {
|
|
2293
|
+
api: appLanguageApiRef,
|
|
2294
|
+
deps: {},
|
|
2295
|
+
factory: () => AppLanguageSelector.createWithStorage()
|
|
2296
|
+
});
|
|
2297
|
+
factoryRegistry.register("default", {
|
|
2298
|
+
api: translationApiRef,
|
|
2299
|
+
deps: { languageApi: appLanguageApiRef },
|
|
2300
|
+
factory: ({ languageApi }) => I18nextTranslationApi.create({
|
|
2301
|
+
languageApi
|
|
2302
|
+
})
|
|
2303
|
+
});
|
|
1667
2304
|
for (const factory of apis) {
|
|
1668
2305
|
if (!factoryRegistry.register("app", factory)) {
|
|
1669
2306
|
throw new Error(
|