@backstage/frontend-app-api 0.6.4 → 0.6.5-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/apis/implementations/ComponentsApi/DefaultComponentsApi.esm.js +53 -0
  3. package/dist/apis/implementations/ComponentsApi/DefaultComponentsApi.esm.js.map +1 -0
  4. package/dist/apis/implementations/IconsApi/DefaultIconsApi.esm.js +35 -0
  5. package/dist/apis/implementations/IconsApi/DefaultIconsApi.esm.js.map +1 -0
  6. package/dist/app/src/components/Root/LogoFull.esm.js +33 -0
  7. package/dist/app/src/components/Root/LogoFull.esm.js.map +1 -0
  8. package/dist/app/src/components/Root/LogoIcon.esm.js +33 -0
  9. package/dist/app/src/components/Root/LogoIcon.esm.js.map +1 -0
  10. package/dist/app-defaults/src/defaults/apis.esm.js +221 -0
  11. package/dist/app-defaults/src/defaults/apis.esm.js.map +1 -0
  12. package/dist/app-defaults/src/defaults/components.esm.js +46 -0
  13. package/dist/app-defaults/src/defaults/components.esm.js.map +1 -0
  14. package/dist/app-defaults/src/defaults/icons.esm.js +51 -0
  15. package/dist/app-defaults/src/defaults/icons.esm.js.map +1 -0
  16. package/dist/core-app-api/src/apis/implementations/AppLanguageApi/AppLanguageSelector.esm.js +114 -0
  17. package/dist/core-app-api/src/apis/implementations/AppLanguageApi/AppLanguageSelector.esm.js.map +1 -0
  18. package/dist/core-app-api/src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js +84 -0
  19. package/dist/core-app-api/src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js.map +1 -0
  20. package/dist/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.esm.js +128 -0
  21. package/dist/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.esm.js.map +1 -0
  22. package/dist/core-app-api/src/apis/implementations/IdentityApi/startCookieAuthRefresh.esm.js +105 -0
  23. package/dist/core-app-api/src/apis/implementations/IdentityApi/startCookieAuthRefresh.esm.js.map +1 -0
  24. package/dist/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js +275 -0
  25. package/dist/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js.map +1 -0
  26. package/dist/core-app-api/src/app/AppThemeProvider.esm.js +60 -0
  27. package/dist/core-app-api/src/app/AppThemeProvider.esm.js.map +1 -0
  28. package/dist/core-app-api/src/app/defaultConfigLoader.esm.js +33 -0
  29. package/dist/core-app-api/src/app/defaultConfigLoader.esm.js.map +1 -0
  30. package/dist/core-app-api/src/app/isProtectedApp.esm.js +9 -0
  31. package/dist/core-app-api/src/app/isProtectedApp.esm.js.map +1 -0
  32. package/dist/core-app-api/src/app/overrideBaseUrlConfigs.esm.js +50 -0
  33. package/dist/core-app-api/src/app/overrideBaseUrlConfigs.esm.js.map +1 -0
  34. package/dist/core-app-api/src/lib/subjects.esm.js +75 -0
  35. package/dist/core-app-api/src/lib/subjects.esm.js.map +1 -0
  36. package/dist/core-plugin-api/src/translation/TranslationRef.esm.js +13 -0
  37. package/dist/core-plugin-api/src/translation/TranslationRef.esm.js.map +1 -0
  38. package/dist/core-plugin-api/src/translation/TranslationResource.esm.js +13 -0
  39. package/dist/core-plugin-api/src/translation/TranslationResource.esm.js.map +1 -0
  40. package/dist/extensions/App.esm.js +39 -0
  41. package/dist/extensions/App.esm.js.map +1 -0
  42. package/dist/extensions/AppLayout.esm.js +34 -0
  43. package/dist/extensions/AppLayout.esm.js.map +1 -0
  44. package/dist/extensions/AppNav.esm.js +63 -0
  45. package/dist/extensions/AppNav.esm.js.map +1 -0
  46. package/dist/extensions/AppRoot.esm.js +125 -0
  47. package/dist/extensions/AppRoot.esm.js.map +1 -0
  48. package/dist/extensions/AppRoutes.esm.js +43 -0
  49. package/dist/extensions/AppRoutes.esm.js.map +1 -0
  50. package/dist/extensions/components.esm.js +52 -0
  51. package/dist/extensions/components.esm.js.map +1 -0
  52. package/dist/extensions/elements.esm.js +26 -0
  53. package/dist/extensions/elements.esm.js.map +1 -0
  54. package/dist/extensions/themes.esm.js +23 -0
  55. package/dist/extensions/themes.esm.js.map +1 -0
  56. package/dist/frontend-plugin-api/src/routing/ExternalRouteRef.esm.js +13 -0
  57. package/dist/frontend-plugin-api/src/routing/ExternalRouteRef.esm.js.map +1 -0
  58. package/dist/frontend-plugin-api/src/routing/RouteRef.esm.js +13 -0
  59. package/dist/frontend-plugin-api/src/routing/RouteRef.esm.js.map +1 -0
  60. package/dist/frontend-plugin-api/src/routing/SubRouteRef.esm.js +13 -0
  61. package/dist/frontend-plugin-api/src/routing/SubRouteRef.esm.js.map +1 -0
  62. package/dist/frontend-plugin-api/src/wiring/createExtension.esm.js +17 -0
  63. package/dist/frontend-plugin-api/src/wiring/createExtension.esm.js.map +1 -0
  64. package/dist/frontend-plugin-api/src/wiring/createExtensionOverrides.esm.js +17 -0
  65. package/dist/frontend-plugin-api/src/wiring/createExtensionOverrides.esm.js.map +1 -0
  66. package/dist/frontend-plugin-api/src/wiring/createPlugin.esm.js +15 -0
  67. package/dist/frontend-plugin-api/src/wiring/createPlugin.esm.js.map +1 -0
  68. package/dist/frontend-plugin-api/src/wiring/resolveExtensionDefinition.esm.js +41 -0
  69. package/dist/frontend-plugin-api/src/wiring/resolveExtensionDefinition.esm.js.map +1 -0
  70. package/dist/index.esm.js +1 -3030
  71. package/dist/index.esm.js.map +1 -1
  72. package/dist/routing/RouteResolver.esm.js +133 -0
  73. package/dist/routing/RouteResolver.esm.js.map +1 -0
  74. package/dist/routing/RouteTracker.esm.js +73 -0
  75. package/dist/routing/RouteTracker.esm.js.map +1 -0
  76. package/dist/routing/collectRouteIds.esm.js +40 -0
  77. package/dist/routing/collectRouteIds.esm.js.map +1 -0
  78. package/dist/routing/extractRouteInfoFromAppNode.esm.js +85 -0
  79. package/dist/routing/extractRouteInfoFromAppNode.esm.js.map +1 -0
  80. package/dist/routing/getBasePath.esm.js +13 -0
  81. package/dist/routing/getBasePath.esm.js.map +1 -0
  82. package/dist/routing/resolveRouteBindings.esm.js +66 -0
  83. package/dist/routing/resolveRouteBindings.esm.js.map +1 -0
  84. package/dist/routing/toLegacyPlugin.esm.js +35 -0
  85. package/dist/routing/toLegacyPlugin.esm.js.map +1 -0
  86. package/dist/tree/createAppTree.esm.js +21 -0
  87. package/dist/tree/createAppTree.esm.js.map +1 -0
  88. package/dist/tree/instantiateAppNodeTree.esm.js +146 -0
  89. package/dist/tree/instantiateAppNodeTree.esm.js.map +1 -0
  90. package/dist/tree/readAppExtensionsConfig.esm.js +106 -0
  91. package/dist/tree/readAppExtensionsConfig.esm.js.map +1 -0
  92. package/dist/tree/resolveAppNodeSpecs.esm.js +168 -0
  93. package/dist/tree/resolveAppNodeSpecs.esm.js.map +1 -0
  94. package/dist/tree/resolveAppTree.esm.js +97 -0
  95. package/dist/tree/resolveAppTree.esm.js.map +1 -0
  96. package/dist/wiring/InternalAppContext.esm.js +6 -0
  97. package/dist/wiring/InternalAppContext.esm.js.map +1 -0
  98. package/dist/wiring/createApp.esm.js +285 -0
  99. package/dist/wiring/createApp.esm.js.map +1 -0
  100. package/dist/wiring/discovery.esm.js +56 -0
  101. package/dist/wiring/discovery.esm.js.map +1 -0
  102. package/package.json +6 -6
package/dist/index.esm.js CHANGED
@@ -1,3031 +1,2 @@
1
- import React, { useMemo, useState, useEffect, createContext, Fragment, useContext } from 'react';
2
- import { ConfigReader } from '@backstage/config';
3
- import { createExtension, createExtensionInput, createApiExtension, createThemeExtension, createComponentExtension, createTranslationExtension, coreExtensionData, ExtensionBoundary, useComponentRef, coreComponentRefs, createNavItemExtension, createNavLogoExtension, useRouteRef, createAppRootElementExtension, createSchemaFromZod, AnalyticsContext, useAnalytics, createRouterExtension, createSignInPageExtension, createAppRootWrapperExtension, appTreeApiRef, routeResolutionApiRef, componentsApiRef, iconsApiRef } from '@backstage/frontend-plugin-api';
4
- import { useRoutes, BrowserRouter, useInRouterContext, MemoryRouter, matchRoutes, generatePath, useLocation } from 'react-router-dom';
5
- import { SidebarPage, sidebarConfig, Sidebar, SidebarDivider, useSidebarOpenState, Link, SidebarItem, Progress, ErrorPage, ErrorPanel, OAuthRequestDialog, AlertDisplay } from '@backstage/core-components';
6
- import { makeStyles as makeStyles$1 } from '@material-ui/core/styles';
7
- import { makeStyles } from '@material-ui/core';
8
- import { useApi, appThemeApiRef, FeatureFlagState, createApiFactory, discoveryApiRef, configApiRef, alertApiRef, analyticsApiRef, errorApiRef, storageApiRef, fetchApiRef, identityApiRef, oauthRequestApiRef, googleAuthApiRef, microsoftAuthApiRef, githubAuthApiRef, oktaAuthApiRef, gitlabAuthApiRef, oneloginAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, atlassianAuthApiRef, vmwareCloudAuthApiRef, featureFlagsApiRef } from '@backstage/core-plugin-api';
9
- import { UrlPatternDiscovery, AlertApiForwarder, NoOpAnalyticsApi, ErrorAlerter, ErrorApiForwarder, UnhandledErrorForwarder, WebStorage, createFetchApi, FetchMiddlewares, OAuthRequestManager, GoogleAuth, MicrosoftAuth, GithubAuth, OktaAuth, GitlabAuth, OneLoginAuth, BitbucketAuth, BitbucketServerAuth, AtlassianAuth, VMwareCloudAuth, ApiFactoryRegistry, AppThemeSelector, ApiResolver, ApiProvider } from '@backstage/core-app-api';
10
- import useObservable from 'react-use/esm/useObservable';
11
- import ObservableImpl from 'zen-observable';
12
- import { createInstance } from 'i18next';
13
- import { permissionApiRef, IdentityPermissionApi } from '@backstage/plugin-permission-react';
14
- import Button from '@material-ui/core/Button';
15
- import MuiApartmentIcon from '@material-ui/icons/Apartment';
16
- import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage';
17
- import MuiCategoryIcon from '@material-ui/icons/Category';
18
- import MuiCreateNewFolderIcon from '@material-ui/icons/CreateNewFolder';
19
- import MuiSubjectIcon from '@material-ui/icons/Subject';
20
- import MuiSearchIcon from '@material-ui/icons/Search';
21
- import MuiChatIcon from '@material-ui/icons/Chat';
22
- import MuiDashboardIcon from '@material-ui/icons/Dashboard';
23
- import MuiDocsIcon from '@material-ui/icons/Description';
24
- import MuiEmailIcon from '@material-ui/icons/Email';
25
- import MuiExtensionIcon from '@material-ui/icons/Extension';
26
- import MuiGitHubIcon from '@material-ui/icons/GitHub';
27
- import MuiHelpIcon from '@material-ui/icons/Help';
28
- import MuiLocationOnIcon from '@material-ui/icons/LocationOn';
29
- import MuiMemoryIcon from '@material-ui/icons/Memory';
30
- import MuiMenuBookIcon from '@material-ui/icons/MenuBook';
31
- import MuiPeopleIcon from '@material-ui/icons/People';
32
- import MuiPersonIcon from '@material-ui/icons/Person';
33
- import MuiWarningIcon from '@material-ui/icons/Warning';
34
- import MuiStorageIcon from '@material-ui/icons/Storage';
35
- import MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList';
36
- import { UnifiedThemeProvider, themes } from '@backstage/theme';
37
- import DarkIcon from '@material-ui/icons/Brightness2';
38
- import LightIcon from '@material-ui/icons/WbSunny';
39
- import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
40
- import { appLanguageApiRef, translationApiRef } from '@backstage/core-plugin-api/alpha';
41
- import mapValues from 'lodash/mapValues';
42
- import { stringifyError } from '@backstage/errors';
43
-
44
- const App = createExtension({
45
- namespace: "app",
46
- attachTo: { id: "root", input: "default" },
47
- // ignored
48
- inputs: {
49
- apis: createExtensionInput({
50
- api: createApiExtension.factoryDataRef
51
- }),
52
- themes: createExtensionInput({
53
- theme: createThemeExtension.themeDataRef
54
- }),
55
- components: createExtensionInput({
56
- component: createComponentExtension.componentDataRef
57
- }),
58
- translations: createExtensionInput({
59
- translation: createTranslationExtension.translationDataRef
60
- }),
61
- root: createExtensionInput(
62
- {
63
- element: coreExtensionData.reactElement
64
- },
65
- { singleton: true }
66
- )
67
- },
68
- output: {
69
- root: coreExtensionData.reactElement
70
- },
71
- factory({ node, inputs }) {
72
- return {
73
- root: /* @__PURE__ */ React.createElement(ExtensionBoundary, { node }, inputs.root.output.element)
74
- };
75
- }
76
- });
77
-
78
- const AppRoutes = createExtension({
79
- namespace: "app",
80
- name: "routes",
81
- attachTo: { id: "app/layout", input: "content" },
82
- inputs: {
83
- routes: createExtensionInput({
84
- path: coreExtensionData.routePath,
85
- ref: coreExtensionData.routeRef.optional(),
86
- element: coreExtensionData.reactElement
87
- })
88
- },
89
- output: {
90
- element: coreExtensionData.reactElement
91
- },
92
- factory({ inputs }) {
93
- const Routes = () => {
94
- const NotFoundErrorPage = useComponentRef(
95
- coreComponentRefs.notFoundErrorPage
96
- );
97
- const element = useRoutes([
98
- ...inputs.routes.map((route) => ({
99
- path: `${route.output.path}/*`,
100
- element: route.output.element
101
- })),
102
- {
103
- path: "*",
104
- element: /* @__PURE__ */ React.createElement(NotFoundErrorPage, null)
105
- }
106
- ]);
107
- return element;
108
- };
109
- return {
110
- element: /* @__PURE__ */ React.createElement(Routes, null)
111
- };
112
- }
113
- });
114
-
115
- const AppLayout = createExtension({
116
- namespace: "app",
117
- name: "layout",
118
- attachTo: { id: "app/root", input: "children" },
119
- inputs: {
120
- nav: createExtensionInput(
121
- {
122
- element: coreExtensionData.reactElement
123
- },
124
- { singleton: true }
125
- ),
126
- content: createExtensionInput(
127
- {
128
- element: coreExtensionData.reactElement
129
- },
130
- { singleton: true }
131
- )
132
- },
133
- output: {
134
- element: coreExtensionData.reactElement
135
- },
136
- factory({ inputs }) {
137
- return {
138
- element: /* @__PURE__ */ React.createElement(SidebarPage, null, inputs.nav.output.element, inputs.content.output.element)
139
- };
140
- }
141
- });
142
-
143
- const useStyles$1 = makeStyles({
144
- svg: {
145
- width: "auto",
146
- height: 28
147
- },
148
- path: {
149
- fill: "#7df3e1"
150
- }
151
- });
152
- const LogoIcon = () => {
153
- const classes = useStyles$1();
154
- return /* @__PURE__ */ React.createElement(
155
- "svg",
156
- {
157
- className: classes.svg,
158
- xmlns: "http://www.w3.org/2000/svg",
159
- viewBox: "0 0 337.46 428.5"
160
- },
161
- /* @__PURE__ */ React.createElement(
162
- "path",
163
- {
164
- className: classes.path,
165
- d: "M303,166.05a80.69,80.69,0,0,0,13.45-10.37c.79-.77,1.55-1.53,2.3-2.3a83.12,83.12,0,0,0,7.93-9.38A63.69,63.69,0,0,0,333,133.23a48.58,48.58,0,0,0,4.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56,0,78.3,115.23,0,190.25l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.69,19.16-18.36,25.52-42.12,13.7-61.87a49.22,49.22,0,0,0-6.8-8.87A89.17,89.17,0,0,0,259,178.29h.15a85.08,85.08,0,0,0,31-5.79A80.88,80.88,0,0,0,303,166.05ZM202.45,225.86c-19.32,18.51-50.4,21.23-75.7,5.9L51.61,186.15l67.45-64.64,76.41,46.38C223,184.58,221.49,207.61,202.45,225.86Zm8.93-82.22-70.65-42.89L205.14,39,274.51,81.1c25.94,15.72,29.31,37,10.55,55A60.69,60.69,0,0,1,211.38,143.64Zm29.86,190c-19.57,18.75-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,282.52v24.67L108.6,373.1a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.27,87.27,0,0,1,241.24,333.68Zm0-39c-19.57,18.75-46.17,29.08-74.88,29.08a123.81,123.81,0,0,1-64.1-18.19L0,243.53v24.68l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.5v-1.78A87.27,87.27,0,0,1,241.24,294.7Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.81,123.81,0,0,1-64.1-18.19L0,204.55v24.68l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.68,12.88-12.35,20-27.13,19.68-41.5v-1.82A86.09,86.09,0,0,1,241.24,255.71Zm83.7,25.74a94.15,94.15,0,0,1-60.2,25.86h0V334a81.6,81.6,0,0,0,51.74-22.37c14-13.38,21.14-28.11,21-42.64v-2.19A94.92,94.92,0,0,1,324.94,281.45Zm-83.7,91.21c-19.57,18.76-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,321.5v24.68l108.6,65.9a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.8,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A86.29,86.29,0,0,1,241.24,372.66ZM327,162.45c-.68.69-1.35,1.38-2.05,2.06a94.37,94.37,0,0,1-10.64,8.65,91.35,91.35,0,0,1-11.6,7,94.53,94.53,0,0,1-26.24,8.71,97.69,97.69,0,0,1-14.16,1.57c.5,1.61.9,3.25,1.25,4.9a53.27,53.27,0,0,1,1.14,12V217h.05a84.41,84.41,0,0,0,25.35-5.55,81,81,0,0,0,26.39-16.82c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,172.17a48.55,48.55,0,0,0,4.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08,1.54-2.25,3.09A96.73,96.73,0,0,1,327,162.45Zm0,77.92c-.69.7-1.31,1.41-2,2.1a94.2,94.2,0,0,1-60.2,25.86h0l0,26.67h0a81.6,81.6,0,0,0,51.74-22.37A73.51,73.51,0,0,0,333,250.13a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74,1.07-1.46,2.15-2.27,3.21A95.68,95.68,0,0,1,327,240.37Zm0-39c-.69.7-1.31,1.41-2,2.1a93.18,93.18,0,0,1-10.63,8.65,91.63,91.63,0,0,1-11.63,7,95.47,95.47,0,0,1-37.94,10.18h0V256h0a81.65,81.65,0,0,0,51.74-22.37c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,211.15a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74,1.08-1.46,2.16-2.27,3.22A95.68,95.68,0,0,1,327,201.39Z"
166
- }
167
- )
168
- );
169
- };
170
-
171
- const useStyles = makeStyles({
172
- svg: {
173
- width: "auto",
174
- height: 30
175
- },
176
- path: {
177
- fill: "#7df3e1"
178
- }
179
- });
180
- const LogoFull = () => {
181
- const classes = useStyles();
182
- return /* @__PURE__ */ React.createElement(
183
- "svg",
184
- {
185
- className: classes.svg,
186
- xmlns: "http://www.w3.org/2000/svg",
187
- viewBox: "0 0 2079.95 456.05"
188
- },
189
- /* @__PURE__ */ React.createElement(
190
- "path",
191
- {
192
- className: classes.path,
193
- d: "M302.9,180a80.62,80.62,0,0,0,13.44-10.37c.8-.77,1.55-1.54,2.31-2.31a81.89,81.89,0,0,0,7.92-9.37,62.37,62.37,0,0,0,6.27-10.77,48.6,48.6,0,0,0,4.36-16.4c1.49-19.39-10-38.67-35.62-54.22L198.42,14,78.16,129.22l-78.29,75,108.6,65.9a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.8,66.42-25.69,19.16-18.36,25.52-42.12,13.7-61.87a49.69,49.69,0,0,0-6.8-8.87,89.78,89.78,0,0,0,19.28,2.15H259a85.09,85.09,0,0,0,31-5.79A80.88,80.88,0,0,0,302.9,180Zm-100.59,59.8c-19.32,18.51-50.4,21.24-75.7,5.9l-75.13-45.6,67.44-64.65,76.42,46.39C222.88,198.57,221.36,221.6,202.31,239.84Zm8.94-82.21L140.6,114.74,205,53l69.37,42.11c25.94,15.73,29.31,37.05,10.55,55A60.71,60.71,0,0,1,211.25,157.63Zm29.86,190c-19.57,18.75-46.17,29.08-74.88,29.08a123.84,123.84,0,0,1-64.11-18.19L-.13,296.51v24.67l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.85,87.85,0,0,1,241.11,347.67Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.84,123.84,0,0,1-64.11-18.19L-.13,257.52V282.2l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.68,12.88-12.35,20-27.13,19.68-41.5v-1.79A86.86,86.86,0,0,1,241.11,308.68Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.84,123.84,0,0,1-64.11-18.19L-.13,218.54v24.68l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.69,12.88-12.34,20-27.12,19.68-41.49v-1.82A87.14,87.14,0,0,1,241.11,269.7Zm83.69,25.74a94.16,94.16,0,0,1-60.19,25.86h0V348a81.6,81.6,0,0,0,51.73-22.37c14-13.38,21.15-28.11,21-42.64v-2.2A95.14,95.14,0,0,1,324.8,295.44Zm-83.69,91.21c-19.57,18.75-46.17,29.09-74.88,29.09a123.76,123.76,0,0,1-64.11-18.2L-.13,335.49v24.67l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.35,87.35,0,0,1,241.11,386.65Zm85.75-210.21c-.68.69-1.35,1.38-2.06,2.05a99.19,99.19,0,0,1-22.23,15.69,94.53,94.53,0,0,1-26.24,8.71,97.84,97.84,0,0,1-14.16,1.57c.5,1.61.9,3.25,1.25,4.9a52.7,52.7,0,0,1,1.13,12V231h.05A84.48,84.48,0,0,0,290,225.47a80.83,80.83,0,0,0,26.38-16.82c.81-.77,1.51-1.56,2.27-2.34a82,82,0,0,0,7.92-9.38,62.85,62.85,0,0,0,6.29-10.78,48.5,48.5,0,0,0,4.32-16.44c.09-1.23.2-2.47.19-3.7v-2c-.72,1-1.48,2.06-2.26,3.09A98,98,0,0,1,326.86,176.44Zm0,77.92c-.68.7-1.3,1.41-2,2.1a94.09,94.09,0,0,1-60.19,25.85h0V309h0a81.65,81.65,0,0,0,51.73-22.37,73.51,73.51,0,0,0,16.48-22.49,48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74,1.08-1.47,2.16-2.27,3.22A95.81,95.81,0,0,1,326.82,254.36Zm0-39c-.68.7-1.3,1.41-2,2.1a92.22,92.22,0,0,1-10.62,8.65,93.53,93.53,0,0,1-11.63,7,95.63,95.63,0,0,1-37.94,10.18h-.05l0,26.67h0a81.63,81.63,0,0,0,51.73-22.37c.81-.77,1.51-1.56,2.27-2.34a82,82,0,0,0,7.92-9.38,63.16,63.16,0,0,0,6.29-10.77,48.55,48.55,0,0,0,4.32-16.45c.09-1.23.2-2.47.19-3.7v-2.2c-.74,1.08-1.47,2.16-2.27,3.22A98.19,98.19,0,0,1,326.82,215.38Zm241-88.84q7.94,0,17.09.17t18.12,1a139.3,139.3,0,0,1,16.74,2.57,42.78,42.78,0,0,1,13.3,5.14,64.27,64.27,0,0,1,20.54,19.89Q662,168,662,186.54q0,19.54-9.49,33.78t-27.1,21.09v.68q22.78,4.82,34.87,20.58t12.08,38.4a72.62,72.62,0,0,1-4.83,26.06,65.29,65.29,0,0,1-14.33,22.46,71.57,71.57,0,0,1-23.47,15.78q-14,6-32.28,6H478.38V126.54Zm9,105.27q28,0,40.21-9.78t12.26-29.31q0-13-4.14-20.58a29.47,29.47,0,0,0-11.4-11.66A45,45,0,0,0,597,155.17a161.2,161.2,0,0,0-20.19-1.2h-65.6v77.84Zm16.57,112.13q21.74,0,34-11.66T639.59,300q0-12-4.48-19.88a34.85,34.85,0,0,0-11.91-12.52,50.14,50.14,0,0,0-17.09-6.52,105,105,0,0,0-20-1.88H511.17v84.7Zm274.79,26.74q-7.61,4.45-21.06,4.46-11.4,0-18.12-6.34t-6.74-20.75a70.17,70.17,0,0,1-28.13,20.75,97.87,97.87,0,0,1-57.65,3.6,53.51,53.51,0,0,1-18.82-8.58A41.19,41.19,0,0,1,705,348.56q-4.65-9.42-4.66-22.8,0-15.09,5.18-24.69a44.92,44.92,0,0,1,13.64-15.6,62.63,62.63,0,0,1,19.33-9.09q10.88-3.08,22.27-5.14,12.08-2.4,23-3.6a128,128,0,0,0,19.16-3.43c5.53-1.48,9.89-3.65,13.12-6.51s4.83-7,4.83-12.52q0-9.6-3.62-15.43a24.94,24.94,0,0,0-9.32-8.92,38.38,38.38,0,0,0-12.78-4.11,96.54,96.54,0,0,0-14-1q-18.63,0-31.07,7T736.6,249.29H707.26q.69-16.46,6.9-27.77a52.21,52.21,0,0,1,16.57-18.35,70,70,0,0,1,23.65-10.11A125.51,125.51,0,0,1,782.86,190a168.63,168.63,0,0,1,24,1.72,63.26,63.26,0,0,1,21.58,7A41.23,41.23,0,0,1,844,213.59q5.87,9.57,5.87,25v91q0,10.26,1.21,15.05t8.11,4.79a35.57,35.57,0,0,0,9-1.37Zm-47.64-90.87c-3.69,2.74-8.52,4.72-14.5,6s-12.26,2.27-18.82,3.07-13.17,1.71-19.85,2.73a73.7,73.7,0,0,0-18,4.94,32.62,32.62,0,0,0-12.94,9.73q-5,6.32-5,17.23a23.31,23.31,0,0,0,2.94,12.11,24.11,24.11,0,0,0,7.59,8,32,32,0,0,0,10.88,4.44,60.94,60.94,0,0,0,13.11,1.36q14.5,0,24.86-3.92a52.49,52.49,0,0,0,16.91-9.9,39.1,39.1,0,0,0,9.67-13,32.53,32.53,0,0,0,3.11-13.14ZM1002.07,225q-11.05-9.25-29.69-9.26-15.89,0-26.58,5.83A47.29,47.29,0,0,0,928.71,237a64.66,64.66,0,0,0-9.15,22.12A119.83,119.83,0,0,0,916.8,285a98.22,98.22,0,0,0,2.93,24,64.18,64.18,0,0,0,9.15,20.74,46.2,46.2,0,0,0,16.23,14.58q10,5.49,23.82,5.48,21.75,0,34-11.31t15-31.89h30q-4.83,32.91-24.68,50.75t-54,17.83q-20.37,0-36.07-6.52A69.86,69.86,0,0,1,907,350.11a79.92,79.92,0,0,1-15.88-28.63A118.64,118.64,0,0,1,885.73,285a129.41,129.41,0,0,1,5.18-37.21,85.63,85.63,0,0,1,15.71-30.17A73.46,73.46,0,0,1,933,197.35Q948.91,190,970,190a108.54,108.54,0,0,1,28.48,3.6,69.59,69.59,0,0,1,23.48,11.15,61,61,0,0,1,16.74,19q6.55,11.49,8.29,27.26h-30.38Q1013.11,234.21,1002.07,225Zm109.77-98.41v145l81.47-77.49h39.36l-70.77,64.46,75.95,112.82h-37.29l-61.1-92.59-27.62,25.38v67.21H1082.5V126.54Zm170.54,205.22a31.07,31.07,0,0,0,10.87,10.63,49,49,0,0,0,15.19,5.66,87.06,87.06,0,0,0,17.44,1.71,109.18,109.18,0,0,0,14.5-1,53.22,53.22,0,0,0,14-3.78,26.27,26.27,0,0,0,10.53-8q4.14-5.32,4.14-13.55,0-11.31-8.63-17.14a73.69,73.69,0,0,0-21.58-9.43q-12.94-3.6-28.13-6.52a146,146,0,0,1-28.14-8.23A58.16,58.16,0,0,1,1261,267.13q-8.64-9.6-8.63-26.75,0-13.38,6-23a49.26,49.26,0,0,1,15.53-15.61,71.76,71.76,0,0,1,21.4-8.91A99.41,99.41,0,0,1,1319,190a141.31,141.31,0,0,1,28,2.58,64.85,64.85,0,0,1,22.62,8.91,46.16,46.16,0,0,1,15.7,17.15q5.87,10.8,6.91,26.91h-29.35q-.69-8.57-4.48-14.23a29.36,29.36,0,0,0-9.67-9.08,44.16,44.16,0,0,0-12.94-5,67.68,67.68,0,0,0-14.33-1.54,87.29,87.29,0,0,0-13.29,1,45.28,45.28,0,0,0-12.26,3.6,24.49,24.49,0,0,0-9,6.86q-3.46,4.29-3.46,11.14a16.32,16.32,0,0,0,5.36,12.52,42.75,42.75,0,0,0,13.63,8.23,120,120,0,0,0,18.64,5.48q10.37,2.24,20.72,4.63,11,2.4,21.57,5.83A70.74,70.74,0,0,1,1382,284.1a44.55,44.55,0,0,1,13.12,14.23q5,8.58,5,21.26,0,16.13-6.73,26.75a52.5,52.5,0,0,1-17.61,17.14,73.89,73.89,0,0,1-24.51,9.09,146.3,146.3,0,0,1-27.1,2.57,126.24,126.24,0,0,1-28.31-3.09A69.56,69.56,0,0,1,1272,361.94a51.74,51.74,0,0,1-16.57-18.52q-6.21-11.49-6.9-27.95h29.34A32.65,32.65,0,0,0,1282.38,331.76Zm226.46-137.67v25.72h-35.56V329.88a31.37,31.37,0,0,0,.87,8.23,8.42,8.42,0,0,0,3.28,4.8,14.61,14.61,0,0,0,6.73,2.23,99.19,99.19,0,0,0,11.22.51h13.46v25.72H1486.4a105.8,105.8,0,0,1-19.5-1.55,28.65,28.65,0,0,1-13.12-5.65,24.09,24.09,0,0,1-7.42-11.66q-2.43-7.54-2.42-19.89V219.81h-30.38V194.09h30.38V140.94h29.34v53.15ZM1699.4,370.68q-7.61,4.45-21.06,4.46-11.4,0-18.12-6.34t-6.74-20.75a70.17,70.17,0,0,1-28.13,20.75,97.87,97.87,0,0,1-57.65,3.6,53.51,53.51,0,0,1-18.82-8.58,41.19,41.19,0,0,1-12.6-15.26q-4.65-9.42-4.66-22.8,0-15.09,5.18-24.69a44.92,44.92,0,0,1,13.64-15.6,62.63,62.63,0,0,1,19.33-9.09q10.88-3.08,22.27-5.14,12.07-2.4,23-3.6a128,128,0,0,0,19.16-3.43c5.53-1.48,9.89-3.65,13.12-6.51s4.83-7,4.83-12.52q0-9.6-3.62-15.43a24.94,24.94,0,0,0-9.32-8.92,38.38,38.38,0,0,0-12.78-4.11,96.54,96.54,0,0,0-14-1q-18.63,0-31.07,7t-13.46,26.57h-29.34q.67-16.46,6.9-27.77A52.21,52.21,0,0,1,1562,203.17a70,70,0,0,1,23.65-10.11,125.51,125.51,0,0,1,28.48-3.09,168.63,168.63,0,0,1,24,1.72,63.26,63.26,0,0,1,21.58,7,41.23,41.23,0,0,1,15.53,14.89q5.87,9.57,5.87,25v91q0,10.26,1.21,15.05t8.11,4.79a35.57,35.57,0,0,0,9-1.37Zm-47.64-90.87c-3.69,2.74-8.52,4.72-14.5,6s-12.26,2.27-18.82,3.07-13.17,1.71-19.85,2.73a73.7,73.7,0,0,0-17.95,4.94,32.62,32.62,0,0,0-12.94,9.73q-5,6.32-5,17.23a23.31,23.31,0,0,0,2.94,12.11,24.11,24.11,0,0,0,7.59,8,32,32,0,0,0,10.88,4.44,60.94,60.94,0,0,0,13.11,1.36q14.51,0,24.86-3.92a52.49,52.49,0,0,0,16.91-9.9,39.1,39.1,0,0,0,9.67-13,32.53,32.53,0,0,0,3.11-13.14Zm208.85,141.62q-20,21.6-62.83,21.6a122.11,122.11,0,0,1-25.37-2.74,78,78,0,0,1-23.48-8.92,54.41,54.41,0,0,1-17.43-16.11q-6.91-10-7.6-24.35h29.35a21.47,21.47,0,0,0,5,13.38,36.67,36.67,0,0,0,11.4,8.91,55.52,55.52,0,0,0,14.67,5,79.51,79.51,0,0,0,15.19,1.55q14.49,0,24.51-5A46,46,0,0,0,1840.59,401a56.53,56.53,0,0,0,9.49-21.09,117.46,117.46,0,0,0,2.94-27.09V341.19h-.7q-7.59,16.46-23,24.18a71.8,71.8,0,0,1-32.63,7.71q-20,0-34.86-7.2A72.88,72.88,0,0,1,1737,346.51a82.13,82.13,0,0,1-15-28.46,116.62,116.62,0,0,1-5-34.47,133.92,133.92,0,0,1,4.14-32.4A88.17,88.17,0,0,1,1735,221a75.49,75.49,0,0,1,25.55-22.29q15.87-8.75,39-8.75a66.21,66.21,0,0,1,31.07,7.38,52.13,52.13,0,0,1,22.09,22.11h.35V194.09h27.61V356.28Q1880.63,399.83,1860.61,421.43Zm-37.46-79.72a47.94,47.94,0,0,0,16.4-15.78,71.89,71.89,0,0,0,9.15-22.11,106.77,106.77,0,0,0,2.93-24.69,96.71,96.71,0,0,0-2.76-23,64,64,0,0,0-8.8-20.4,45.76,45.76,0,0,0-15.71-14.57q-9.66-5.49-23.47-5.49-14.16,0-24.17,5.32a46.77,46.77,0,0,0-16.4,14.23,60.14,60.14,0,0,0-9.32,20.57,99.69,99.69,0,0,0-2.93,24.35,120.63,120.63,0,0,0,2.42,24,67.5,67.5,0,0,0,8.28,21.77,46.37,46.37,0,0,0,15.54,15.78q9.66,6,24.16,6T1823.15,341.71Zm228,18.34q-20,15.09-50.41,15.09-21.4,0-37.11-6.86a73.16,73.16,0,0,1-26.41-19.2,81.52,81.52,0,0,1-16-29.49,141.12,141.12,0,0,1-6-37.38,106.1,106.1,0,0,1,6.21-37A88.56,88.56,0,0,1,1938.8,216a79.09,79.09,0,0,1,26.58-19.2A81.66,81.66,0,0,1,1999,190q23.82,0,39.53,9.78a78,78,0,0,1,25.2,24.86,98.18,98.18,0,0,1,13.12,32.91,140.6,140.6,0,0,1,2.93,34h-133.6a70,70,0,0,0,2.76,22.12,49.9,49.9,0,0,0,10,18.51A49.1,49.1,0,0,0,1976.6,345q10.7,4.82,25.2,4.8,18.65,0,30.55-8.57t15.71-26.06h29Q2071.18,345,2051.17,360.05Zm-7.08-113.84a50,50,0,0,0-10.7-16,53.1,53.1,0,0,0-56.62-10.63,47.48,47.48,0,0,0-15.71,10.81,51.69,51.69,0,0,0-10.35,15.94,60.18,60.18,0,0,0-4.49,19.37h102.53A59.47,59.47,0,0,0,2044.09,246.21ZM302.9,180a80.62,80.62,0,0,0,13.44-10.37c.8-.77,1.55-1.54,2.31-2.31a81.89,81.89,0,0,0,7.92-9.37,62.37,62.37,0,0,0,6.27-10.77,48.6,48.6,0,0,0,4.36-16.4c1.49-19.39-10-38.67-35.62-54.22L198.42,14,78.16,129.22l-78.29,75,108.6,65.9a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.8,66.42-25.69,19.16-18.36,25.52-42.12,13.7-61.87a49.69,49.69,0,0,0-6.8-8.87,89.78,89.78,0,0,0,19.28,2.15H259a85.09,85.09,0,0,0,31-5.79A80.88,80.88,0,0,0,302.9,180Zm-100.59,59.8c-19.32,18.51-50.4,21.24-75.7,5.9l-75.13-45.6,67.44-64.65,76.42,46.39C222.88,198.57,221.36,221.6,202.31,239.84Zm8.94-82.21L140.6,114.74,205,53l69.37,42.11c25.94,15.73,29.31,37.05,10.55,55A60.71,60.71,0,0,1,211.25,157.63Zm29.86,190c-19.57,18.75-46.17,29.08-74.88,29.08a123.84,123.84,0,0,1-64.11-18.19L-.13,296.51v24.67l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.85,87.85,0,0,1,241.11,347.67Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.84,123.84,0,0,1-64.11-18.19L-.13,257.52V282.2l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.68,12.88-12.35,20-27.13,19.68-41.5v-1.79A86.86,86.86,0,0,1,241.11,308.68Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.84,123.84,0,0,1-64.11-18.19L-.13,218.54v24.68l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.69,12.88-12.34,20-27.12,19.68-41.49v-1.82A87.14,87.14,0,0,1,241.11,269.7Zm83.69,25.74a94.16,94.16,0,0,1-60.19,25.86h0V348a81.6,81.6,0,0,0,51.73-22.37c14-13.38,21.15-28.11,21-42.64v-2.2A95.14,95.14,0,0,1,324.8,295.44Zm-83.69,91.21c-19.57,18.75-46.17,29.09-74.88,29.09a123.76,123.76,0,0,1-64.11-18.2L-.13,335.49v24.67l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.35,87.35,0,0,1,241.11,386.65Zm85.75-210.21c-.68.69-1.35,1.38-2.06,2.05a99.19,99.19,0,0,1-22.23,15.69,94.53,94.53,0,0,1-26.24,8.71,97.84,97.84,0,0,1-14.16,1.57c.5,1.61.9,3.25,1.25,4.9a52.7,52.7,0,0,1,1.13,12V231h.05A84.48,84.48,0,0,0,290,225.47a80.83,80.83,0,0,0,26.38-16.82c.81-.77,1.51-1.56,2.27-2.34a82,82,0,0,0,7.92-9.38,62.85,62.85,0,0,0,6.29-10.78,48.5,48.5,0,0,0,4.32-16.44c.09-1.23.2-2.47.19-3.7v-2c-.72,1-1.48,2.06-2.26,3.09A98,98,0,0,1,326.86,176.44Zm0,77.92c-.68.7-1.3,1.41-2,2.1a94.09,94.09,0,0,1-60.19,25.85h0V309h0a81.65,81.65,0,0,0,51.73-22.37,73.51,73.51,0,0,0,16.48-22.49,48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74,1.08-1.47,2.16-2.27,3.22A95.81,95.81,0,0,1,326.82,254.36Zm0-39c-.68.7-1.3,1.41-2,2.1a92.22,92.22,0,0,1-10.62,8.65,93.53,93.53,0,0,1-11.63,7,95.63,95.63,0,0,1-37.94,10.18h-.05l0,26.67h0a81.63,81.63,0,0,0,51.73-22.37c.81-.77,1.51-1.56,2.27-2.34a82,82,0,0,0,7.92-9.38,63.16,63.16,0,0,0,6.29-10.77,48.55,48.55,0,0,0,4.32-16.45c.09-1.23.2-2.47.19-3.7v-2.2c-.74,1.08-1.47,2.16-2.27,3.22A98.19,98.19,0,0,1,326.82,215.38Z"
194
- }
195
- )
196
- );
197
- };
198
-
199
- const useSidebarLogoStyles = makeStyles$1({
200
- root: {
201
- width: sidebarConfig.drawerWidthClosed,
202
- height: 3 * sidebarConfig.logoHeight,
203
- display: "flex",
204
- flexFlow: "row nowrap",
205
- alignItems: "center",
206
- marginBottom: -14
207
- },
208
- link: {
209
- width: sidebarConfig.drawerWidthClosed,
210
- marginLeft: 24
211
- }
212
- });
213
- const SidebarLogo = (props) => {
214
- var _a, _b;
215
- const classes = useSidebarLogoStyles();
216
- const { isOpen } = useSidebarOpenState();
217
- 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)));
218
- };
219
- const SidebarNavItem = (props) => {
220
- const { icon: Icon, title, routeRef } = props;
221
- const to = useRouteRef(routeRef)();
222
- return /* @__PURE__ */ React.createElement(SidebarItem, { to, icon: Icon, text: title });
223
- };
224
- const AppNav = createExtension({
225
- namespace: "app",
226
- name: "nav",
227
- attachTo: { id: "app/layout", input: "nav" },
228
- inputs: {
229
- items: createExtensionInput({
230
- target: createNavItemExtension.targetDataRef
231
- }),
232
- logos: createExtensionInput(
233
- {
234
- elements: createNavLogoExtension.logoElementsDataRef
235
- },
236
- {
237
- singleton: true,
238
- optional: true
239
- }
240
- )
241
- },
242
- output: {
243
- element: coreExtensionData.reactElement
244
- },
245
- factory({ inputs }) {
246
- var _a;
247
- return {
248
- 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 })))
249
- };
250
- }
251
- });
252
-
253
- function readPackageDetectionConfig(config) {
254
- const packages = config.getOptional("app.experimental.packages");
255
- if (packages === void 0 || packages === null) {
256
- return void 0;
257
- }
258
- if (typeof packages === "string") {
259
- if (packages !== "all") {
260
- throw new Error(
261
- `Invalid app.experimental.packages mode, got '${packages}', expected 'all'`
262
- );
263
- }
264
- return {};
265
- }
266
- if (typeof packages !== "object" || Array.isArray(packages)) {
267
- throw new Error(
268
- "Invalid config at 'app.experimental.packages', expected object"
269
- );
270
- }
271
- const packagesConfig = new ConfigReader(
272
- packages,
273
- "app.experimental.packages"
274
- );
275
- return {
276
- include: packagesConfig.getOptionalStringArray("include"),
277
- exclude: packagesConfig.getOptionalStringArray("exclude")
278
- };
279
- }
280
- function getAvailableFeatures(config) {
281
- var _a;
282
- const discovered = window["__@backstage/discovered__"];
283
- const detection = readPackageDetectionConfig(config);
284
- if (!detection) {
285
- return [];
286
- }
287
- return (_a = discovered == null ? void 0 : discovered.modules.filter(({ name }) => {
288
- var _a2;
289
- if ((_a2 = detection.exclude) == null ? void 0 : _a2.includes(name)) {
290
- return false;
291
- }
292
- if (detection.include && !detection.include.includes(name)) {
293
- return false;
294
- }
295
- return true;
296
- }).map((m) => m.default).filter(isBackstageFeature)) != null ? _a : [];
297
- }
298
- function isBackstageFeature(obj) {
299
- if (obj !== null && typeof obj === "object" && "$$type" in obj) {
300
- return obj.$$type === "@backstage/BackstagePlugin" || obj.$$type === "@backstage/ExtensionOverrides";
301
- }
302
- return false;
303
- }
304
-
305
- function isProtectedApp() {
306
- var _a;
307
- const element = document.querySelector('meta[name="backstage-app-mode"]');
308
- const appMode = (_a = element == null ? void 0 : element.getAttribute("content")) != null ? _a : "public";
309
- return appMode === "protected";
310
- }
311
-
312
- function resolveTheme(themeId, shouldPreferDark, themes) {
313
- if (themeId !== void 0) {
314
- const selectedTheme = themes.find((theme) => theme.id === themeId);
315
- if (selectedTheme) {
316
- return selectedTheme;
317
- }
318
- }
319
- if (shouldPreferDark) {
320
- const darkTheme = themes.find((theme) => theme.variant === "dark");
321
- if (darkTheme) {
322
- return darkTheme;
323
- }
324
- }
325
- const lightTheme = themes.find((theme) => theme.variant === "light");
326
- if (lightTheme) {
327
- return lightTheme;
328
- }
329
- return themes[0];
330
- }
331
- const useShouldPreferDarkTheme = () => {
332
- const mediaQuery = useMemo(
333
- () => window.matchMedia("(prefers-color-scheme: dark)"),
334
- []
335
- );
336
- const [shouldPreferDark, setPrefersDark] = useState(mediaQuery.matches);
337
- useEffect(() => {
338
- const listener = (event) => {
339
- setPrefersDark(event.matches);
340
- };
341
- mediaQuery.addListener(listener);
342
- return () => {
343
- mediaQuery.removeListener(listener);
344
- };
345
- }, [mediaQuery]);
346
- return shouldPreferDark;
347
- };
348
- function AppThemeProvider({ children }) {
349
- const appThemeApi = useApi(appThemeApiRef);
350
- const themeId = useObservable(
351
- appThemeApi.activeThemeId$(),
352
- appThemeApi.getActiveThemeId()
353
- );
354
- const shouldPreferDark = Boolean(window.matchMedia) ? useShouldPreferDarkTheme() : false;
355
- const appTheme = resolveTheme(
356
- themeId,
357
- shouldPreferDark,
358
- appThemeApi.getInstalledThemes()
359
- );
360
- if (!appTheme) {
361
- throw new Error("App has no themes");
362
- }
363
- return /* @__PURE__ */ React.createElement(appTheme.Provider, { children });
364
- }
365
-
366
- const PLUGIN_ID = "app";
367
- const CHANNEL_ID = `${PLUGIN_ID}-auth-cookie-expires-at`;
368
- const MIN_BASE_DELAY_MS = 5 * 6e4;
369
- const ERROR_BACKOFF_START = 5e3;
370
- const ERROR_BACKOFF_FACTOR = 2;
371
- const ERROR_BACKOFF_MAX = 5 * 6e4;
372
- function startCookieAuthRefresh({
373
- discoveryApi,
374
- fetchApi,
375
- errorApi
376
- }) {
377
- let stopped = false;
378
- let timeout;
379
- let firstError = true;
380
- let errorBackoff = ERROR_BACKOFF_START;
381
- const channel = "BroadcastChannel" in window ? new BroadcastChannel(CHANNEL_ID) : void 0;
382
- const getDelay = (expiresAt) => {
383
- const margin = (1 + 3 * Math.random()) * 6e4;
384
- const delay = Math.max(expiresAt - Date.now(), MIN_BASE_DELAY_MS) - margin;
385
- return delay;
386
- };
387
- const refresh = async () => {
388
- try {
389
- const baseUrl = await discoveryApi.getBaseUrl(PLUGIN_ID);
390
- const requestUrl = `${baseUrl}/.backstage/auth/v1/cookie`;
391
- const res = await fetchApi.fetch(requestUrl, {
392
- credentials: "include"
393
- });
394
- if (!res.ok) {
395
- throw new Error(
396
- `Request failed with status ${res.status} ${res.statusText}, see request towards ${requestUrl} for more details`
397
- );
398
- }
399
- const data = await res.json();
400
- if (!data.expiresAt) {
401
- throw new Error("No expiration date in response");
402
- }
403
- const expiresAt = Date.parse(data.expiresAt);
404
- if (Number.isNaN(expiresAt)) {
405
- throw new Error("Invalid expiration date in response");
406
- }
407
- firstError = true;
408
- channel == null ? void 0 : channel.postMessage({
409
- action: "COOKIE_REFRESH_SUCCESS",
410
- payload: { expiresAt: new Date(expiresAt).toISOString() }
411
- });
412
- scheduleRefresh(getDelay(expiresAt));
413
- } catch (error) {
414
- if (firstError) {
415
- firstError = false;
416
- errorBackoff = ERROR_BACKOFF_START;
417
- } else {
418
- errorBackoff = Math.min(
419
- ERROR_BACKOFF_MAX,
420
- errorBackoff * ERROR_BACKOFF_FACTOR
421
- );
422
- console.error("Session cookie refresh failed", error);
423
- errorApi.post(
424
- new Error(
425
- `Session refresh failed, see developer console for details`
426
- )
427
- );
428
- }
429
- scheduleRefresh(errorBackoff);
430
- }
431
- };
432
- const onMessage = (event) => {
433
- const { data } = event;
434
- if (data === null || typeof data !== "object") {
435
- return;
436
- }
437
- if ("action" in data && data.action === "COOKIE_REFRESH_SUCCESS") {
438
- const expiresAt = Date.parse(data.payload.expiresAt);
439
- if (Number.isNaN(expiresAt)) {
440
- console.warn(
441
- "Received invalid expiration from session refresh channel"
442
- );
443
- return;
444
- }
445
- scheduleRefresh(getDelay(expiresAt));
446
- }
447
- };
448
- function scheduleRefresh(delayMs) {
449
- if (stopped) {
450
- return;
451
- }
452
- if (timeout) {
453
- clearTimeout(timeout);
454
- }
455
- timeout = setTimeout(refresh, delayMs);
456
- }
457
- channel == null ? void 0 : channel.addEventListener("message", onMessage);
458
- refresh();
459
- return () => {
460
- stopped = true;
461
- if (timeout) {
462
- clearTimeout(timeout);
463
- }
464
- channel == null ? void 0 : channel.removeEventListener("message", onMessage);
465
- channel == null ? void 0 : channel.close();
466
- };
467
- }
468
-
469
- var __defProp$3 = Object.defineProperty;
470
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
471
- var __publicField$3 = (obj, key, value) => {
472
- __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
473
- return value;
474
- };
475
- var __accessCheck$4 = (obj, member, msg) => {
476
- if (!member.has(obj))
477
- throw TypeError("Cannot " + msg);
478
- };
479
- var __privateGet$4 = (obj, member, getter) => {
480
- __accessCheck$4(obj, member, "read from private field");
481
- return getter ? getter.call(obj) : member.get(obj);
482
- };
483
- var __privateAdd$4 = (obj, member, value) => {
484
- if (member.has(obj))
485
- throw TypeError("Cannot add the same private member more than once");
486
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
487
- };
488
- var __privateSet$4 = (obj, member, value, setter) => {
489
- __accessCheck$4(obj, member, "write to private field");
490
- setter ? setter.call(obj, value) : member.set(obj, value);
491
- return value;
492
- };
493
- var _cookieAuthSignOut;
494
- function mkError(thing) {
495
- return new Error(
496
- `Tried to access IdentityApi ${thing} before app was loaded`
497
- );
498
- }
499
- function logDeprecation(thing) {
500
- console.warn(
501
- `WARNING: Call to ${thing} is deprecated and will break in the future`
502
- );
503
- }
504
- class AppIdentityProxy {
505
- constructor() {
506
- __publicField$3(this, "target");
507
- __publicField$3(this, "waitForTarget");
508
- __publicField$3(this, "resolveTarget", () => {
509
- });
510
- __publicField$3(this, "signOutTargetUrl", "/");
511
- __privateAdd$4(this, _cookieAuthSignOut, void 0);
512
- this.waitForTarget = new Promise((resolve) => {
513
- this.resolveTarget = resolve;
514
- });
515
- }
516
- // This is called by the app manager once the sign-in page provides us with an implementation
517
- setTarget(identityApi, targetOptions) {
518
- this.target = identityApi;
519
- this.signOutTargetUrl = targetOptions.signOutTargetUrl;
520
- this.resolveTarget(identityApi);
521
- }
522
- getUserId() {
523
- if (!this.target) {
524
- throw mkError("getUserId");
525
- }
526
- if (!this.target.getUserId) {
527
- throw new Error("IdentityApi does not implement getUserId");
528
- }
529
- logDeprecation("getUserId");
530
- return this.target.getUserId();
531
- }
532
- getProfile() {
533
- if (!this.target) {
534
- throw mkError("getProfile");
535
- }
536
- if (!this.target.getProfile) {
537
- throw new Error("IdentityApi does not implement getProfile");
538
- }
539
- logDeprecation("getProfile");
540
- return this.target.getProfile();
541
- }
542
- async getProfileInfo() {
543
- return this.waitForTarget.then((target) => target.getProfileInfo());
544
- }
545
- async getBackstageIdentity() {
546
- const identity = await this.waitForTarget.then(
547
- (target) => target.getBackstageIdentity()
548
- );
549
- if (!identity.userEntityRef.match(/^.*:.*\/.*$/)) {
550
- console.warn(
551
- `WARNING: The App IdentityApi provided an invalid userEntityRef, '${identity.userEntityRef}'. It must be a full Entity Reference of the form '<kind>:<namespace>/<name>'.`
552
- );
553
- }
554
- return identity;
555
- }
556
- async getCredentials() {
557
- return this.waitForTarget.then((target) => target.getCredentials());
558
- }
559
- async getIdToken() {
560
- return this.waitForTarget.then((target) => {
561
- if (!target.getIdToken) {
562
- throw new Error("IdentityApi does not implement getIdToken");
563
- }
564
- logDeprecation("getIdToken");
565
- return target.getIdToken();
566
- });
567
- }
568
- async signOut() {
569
- var _a;
570
- await this.waitForTarget.then((target) => target.signOut());
571
- await ((_a = __privateGet$4(this, _cookieAuthSignOut)) == null ? void 0 : _a.call(this));
572
- window.location.href = this.signOutTargetUrl;
573
- }
574
- enableCookieAuth(ctx) {
575
- if (__privateGet$4(this, _cookieAuthSignOut)) {
576
- return;
577
- }
578
- const stopRefresh = startCookieAuthRefresh(ctx);
579
- __privateSet$4(this, _cookieAuthSignOut, async () => {
580
- stopRefresh();
581
- const appBaseUrl = await ctx.discoveryApi.getBaseUrl("app");
582
- try {
583
- await ctx.fetchApi.fetch(`${appBaseUrl}/.backstage/auth/v1/cookie`, {
584
- method: "DELETE"
585
- });
586
- } catch {
587
- }
588
- });
589
- }
590
- }
591
- _cookieAuthSignOut = new WeakMap();
592
-
593
- var __defProp$2 = Object.defineProperty;
594
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
595
- var __publicField$2 = (obj, key, value) => {
596
- __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
597
- return value;
598
- };
599
- function validateFlagName(name) {
600
- if (name.length < 3) {
601
- throw new Error(
602
- `The '${name}' feature flag must have a minimum length of three characters.`
603
- );
604
- }
605
- if (name.length > 150) {
606
- throw new Error(
607
- `The '${name}' feature flag must not exceed 150 characters.`
608
- );
609
- }
610
- if (!name.match(/^[a-z]+[a-z0-9-]+$/)) {
611
- throw new Error(
612
- `The '${name}' feature flag must start with a lowercase letter and only contain lowercase letters, numbers and hyphens. Examples: feature-flag-one, alpha, release-2020`
613
- );
614
- }
615
- }
616
- class LocalStorageFeatureFlags {
617
- constructor() {
618
- __publicField$2(this, "registeredFeatureFlags", []);
619
- __publicField$2(this, "flags");
620
- }
621
- registerFlag(flag) {
622
- validateFlagName(flag.name);
623
- this.registeredFeatureFlags.push(flag);
624
- }
625
- getRegisteredFlags() {
626
- return this.registeredFeatureFlags.slice();
627
- }
628
- isActive(name) {
629
- if (!this.flags) {
630
- this.flags = this.load();
631
- }
632
- return this.flags.get(name) === FeatureFlagState.Active;
633
- }
634
- save(options) {
635
- if (!this.flags) {
636
- this.flags = this.load();
637
- }
638
- if (!options.merge) {
639
- this.flags.clear();
640
- }
641
- for (const [name, state] of Object.entries(options.states)) {
642
- this.flags.set(name, state);
643
- }
644
- const enabled = Array.from(this.flags.entries()).filter(
645
- ([, state]) => state === FeatureFlagState.Active
646
- );
647
- window.localStorage.setItem(
648
- "featureFlags",
649
- JSON.stringify(Object.fromEntries(enabled))
650
- );
651
- }
652
- load() {
653
- try {
654
- const jsonStr = window.localStorage.getItem("featureFlags");
655
- if (!jsonStr) {
656
- return /* @__PURE__ */ new Map();
657
- }
658
- const json = JSON.parse(jsonStr);
659
- if (typeof json !== "object" || json === null || Array.isArray(json)) {
660
- return /* @__PURE__ */ new Map();
661
- }
662
- const entries = Object.entries(json).filter(([name, value]) => {
663
- validateFlagName(name);
664
- return value === FeatureFlagState.Active;
665
- });
666
- return new Map(entries);
667
- } catch {
668
- return /* @__PURE__ */ new Map();
669
- }
670
- }
671
- }
672
-
673
- function defaultConfigLoaderSync(runtimeConfigJson = "__APP_INJECTED_RUNTIME_CONFIG__") {
674
- const appConfig = process.env.APP_CONFIG;
675
- if (!appConfig) {
676
- throw new Error("No static configuration provided");
677
- }
678
- if (!Array.isArray(appConfig)) {
679
- throw new Error("Static configuration has invalid format");
680
- }
681
- const configs = appConfig.slice();
682
- if (runtimeConfigJson !== "__app_injected_runtime_config__".toLocaleUpperCase("en-US")) {
683
- try {
684
- const data = JSON.parse(runtimeConfigJson);
685
- if (Array.isArray(data)) {
686
- configs.push(...data);
687
- } else {
688
- configs.push({ data, context: "env" });
689
- }
690
- } catch (error) {
691
- throw new Error(`Failed to load runtime configuration, ${error}`);
692
- }
693
- }
694
- const windowAppConfig = window.__APP_CONFIG__;
695
- if (windowAppConfig) {
696
- configs.push({
697
- context: "window",
698
- data: windowAppConfig
699
- });
700
- }
701
- return configs;
702
- }
703
-
704
- function createLocalBaseUrl(fullUrl) {
705
- const url = new URL(fullUrl);
706
- url.protocol = document.location.protocol;
707
- url.hostname = document.location.hostname;
708
- url.port = document.location.port;
709
- return url.toString().replace(/\/$/, "");
710
- }
711
- function overrideBaseUrlConfigs(inputConfigs) {
712
- const urlConfigReader = ConfigReader.fromConfigs(inputConfigs);
713
- const appBaseUrl = urlConfigReader.getOptionalString("app.baseUrl");
714
- const backendBaseUrl = urlConfigReader.getOptionalString("backend.baseUrl");
715
- let configs = inputConfigs;
716
- let newBackendBaseUrl = void 0;
717
- let newAppBaseUrl = void 0;
718
- if (appBaseUrl && backendBaseUrl) {
719
- const appOrigin = new URL(appBaseUrl).origin;
720
- const backendOrigin = new URL(backendBaseUrl).origin;
721
- if (appOrigin === backendOrigin) {
722
- const maybeNewBackendBaseUrl = createLocalBaseUrl(backendBaseUrl);
723
- if (backendBaseUrl !== maybeNewBackendBaseUrl) {
724
- newBackendBaseUrl = maybeNewBackendBaseUrl;
725
- }
726
- }
727
- }
728
- if (appBaseUrl) {
729
- const maybeNewAppBaseUrl = createLocalBaseUrl(appBaseUrl);
730
- if (appBaseUrl !== maybeNewAppBaseUrl) {
731
- newAppBaseUrl = maybeNewAppBaseUrl;
732
- }
733
- }
734
- if (newAppBaseUrl || newBackendBaseUrl) {
735
- configs = configs.concat({
736
- data: {
737
- app: newAppBaseUrl && {
738
- baseUrl: newAppBaseUrl
739
- },
740
- backend: newBackendBaseUrl && {
741
- baseUrl: newBackendBaseUrl
742
- }
743
- },
744
- context: "relative-resolver"
745
- });
746
- }
747
- return configs;
748
- }
749
-
750
- var __defProp$1 = Object.defineProperty;
751
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
752
- var __publicField$1 = (obj, key, value) => {
753
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
754
- return value;
755
- };
756
- class BehaviorSubject {
757
- constructor(value) {
758
- __publicField$1(this, "isClosed");
759
- __publicField$1(this, "currentValue");
760
- __publicField$1(this, "terminatingError");
761
- __publicField$1(this, "observable");
762
- __publicField$1(this, "subscribers", /* @__PURE__ */ new Set());
763
- this.isClosed = false;
764
- this.currentValue = value;
765
- this.terminatingError = void 0;
766
- this.observable = new ObservableImpl((subscriber) => {
767
- if (this.isClosed) {
768
- if (this.terminatingError) {
769
- subscriber.error(this.terminatingError);
770
- } else {
771
- subscriber.complete();
772
- }
773
- return () => {
774
- };
775
- }
776
- subscriber.next(this.currentValue);
777
- this.subscribers.add(subscriber);
778
- return () => {
779
- this.subscribers.delete(subscriber);
780
- };
781
- });
782
- }
783
- [Symbol.observable]() {
784
- return this;
785
- }
786
- get closed() {
787
- return this.isClosed;
788
- }
789
- next(value) {
790
- if (this.isClosed) {
791
- throw new Error("BehaviorSubject is closed");
792
- }
793
- this.currentValue = value;
794
- this.subscribers.forEach((subscriber) => subscriber.next(value));
795
- }
796
- error(error) {
797
- if (this.isClosed) {
798
- throw new Error("BehaviorSubject is closed");
799
- }
800
- this.isClosed = true;
801
- this.terminatingError = error;
802
- this.subscribers.forEach((subscriber) => subscriber.error(error));
803
- }
804
- complete() {
805
- if (this.isClosed) {
806
- throw new Error("BehaviorSubject is closed");
807
- }
808
- this.isClosed = true;
809
- this.subscribers.forEach((subscriber) => subscriber.complete());
810
- }
811
- subscribe(onNext, onError, onComplete) {
812
- const observer = typeof onNext === "function" ? {
813
- next: onNext,
814
- error: onError,
815
- complete: onComplete
816
- } : onNext;
817
- return this.observable.subscribe(observer);
818
- }
819
- }
820
-
821
- var __accessCheck$3 = (obj, member, msg) => {
822
- if (!member.has(obj))
823
- throw TypeError("Cannot " + msg);
824
- };
825
- var __privateGet$3 = (obj, member, getter) => {
826
- __accessCheck$3(obj, member, "read from private field");
827
- return getter ? getter.call(obj) : member.get(obj);
828
- };
829
- var __privateAdd$3 = (obj, member, value) => {
830
- if (member.has(obj))
831
- throw TypeError("Cannot add the same private member more than once");
832
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
833
- };
834
- var __privateSet$3 = (obj, member, value, setter) => {
835
- __accessCheck$3(obj, member, "write to private field");
836
- setter ? setter.call(obj, value) : member.set(obj, value);
837
- return value;
838
- };
839
- var _languages, _language$1, _subject;
840
- const STORAGE_KEY = "language";
841
- const DEFAULT_LANGUAGE = "en";
842
- const _AppLanguageSelector = class _AppLanguageSelector {
843
- constructor(languages, initialLanguage) {
844
- __privateAdd$3(this, _languages, void 0);
845
- __privateAdd$3(this, _language$1, void 0);
846
- __privateAdd$3(this, _subject, void 0);
847
- __privateSet$3(this, _languages, languages);
848
- __privateSet$3(this, _language$1, initialLanguage);
849
- __privateSet$3(this, _subject, new BehaviorSubject({
850
- language: __privateGet$3(this, _language$1)
851
- }));
852
- }
853
- static create(options) {
854
- var _a, _b;
855
- const languages = (_a = options == null ? void 0 : options.availableLanguages) != null ? _a : [DEFAULT_LANGUAGE];
856
- if (languages.length !== new Set(languages).size) {
857
- throw new Error(
858
- `Supported languages may not contain duplicates, got '${languages.join(
859
- "', '"
860
- )}'`
861
- );
862
- }
863
- if (!languages.includes(DEFAULT_LANGUAGE)) {
864
- throw new Error(`Supported languages must include '${DEFAULT_LANGUAGE}'`);
865
- }
866
- const initialLanguage = (_b = options == null ? void 0 : options.defaultLanguage) != null ? _b : DEFAULT_LANGUAGE;
867
- if (!languages.includes(initialLanguage)) {
868
- throw new Error(
869
- `Initial language must be one of the supported languages, got '${initialLanguage}'`
870
- );
871
- }
872
- return new _AppLanguageSelector(languages, initialLanguage);
873
- }
874
- static createWithStorage(options) {
875
- const selector = _AppLanguageSelector.create(options);
876
- if (!window.localStorage) {
877
- return selector;
878
- }
879
- const storedLanguage = window.localStorage.getItem(STORAGE_KEY);
880
- const { languages } = selector.getAvailableLanguages();
881
- if (storedLanguage && languages.includes(storedLanguage)) {
882
- selector.setLanguage(storedLanguage);
883
- }
884
- selector.language$().subscribe(({ language }) => {
885
- if (language !== window.localStorage.getItem(STORAGE_KEY)) {
886
- window.localStorage.setItem(STORAGE_KEY, language);
887
- }
888
- });
889
- window.addEventListener("storage", (event) => {
890
- var _a;
891
- if (event.key === STORAGE_KEY) {
892
- const language = (_a = localStorage.getItem(STORAGE_KEY)) != null ? _a : void 0;
893
- if (language) {
894
- selector.setLanguage(language);
895
- }
896
- }
897
- });
898
- return selector;
899
- }
900
- getAvailableLanguages() {
901
- return { languages: __privateGet$3(this, _languages).slice() };
902
- }
903
- setLanguage(language) {
904
- const lng = language != null ? language : DEFAULT_LANGUAGE;
905
- if (lng === __privateGet$3(this, _language$1)) {
906
- return;
907
- }
908
- if (lng && !__privateGet$3(this, _languages).includes(lng)) {
909
- throw new Error(
910
- `Failed to change language to '${lng}', available languages are '${__privateGet$3(this, _languages).join(
911
- "', '"
912
- )}'`
913
- );
914
- }
915
- __privateSet$3(this, _language$1, lng);
916
- __privateGet$3(this, _subject).next({ language: lng });
917
- }
918
- getLanguage() {
919
- return { language: __privateGet$3(this, _language$1) };
920
- }
921
- language$() {
922
- return __privateGet$3(this, _subject);
923
- }
924
- };
925
- _languages = new WeakMap();
926
- _language$1 = new WeakMap();
927
- _subject = new WeakMap();
928
- let AppLanguageSelector = _AppLanguageSelector;
929
-
930
- function toInternalTranslationResource(resource) {
931
- const r = resource;
932
- if (r.$$type !== "@backstage/TranslationResource") {
933
- throw new Error(`Invalid translation resource, bad type '${r.$$type}'`);
934
- }
935
- if (r.version !== "v1") {
936
- throw new Error(`Invalid translation resource, bad version '${r.version}'`);
937
- }
938
- return r;
939
- }
940
-
941
- function toInternalTranslationRef(ref) {
942
- const r = ref;
943
- if (r.$$type !== "@backstage/TranslationRef") {
944
- throw new Error(`Invalid translation ref, bad type '${r.$$type}'`);
945
- }
946
- if (r.version !== "v1") {
947
- throw new Error(`Invalid translation ref, bad version '${r.version}'`);
948
- }
949
- return r;
950
- }
951
-
952
- var __accessCheck$2 = (obj, member, msg) => {
953
- if (!member.has(obj))
954
- throw TypeError("Cannot " + msg);
955
- };
956
- var __privateGet$2 = (obj, member, getter) => {
957
- __accessCheck$2(obj, member, "read from private field");
958
- return getter ? getter.call(obj) : member.get(obj);
959
- };
960
- var __privateAdd$2 = (obj, member, value) => {
961
- if (member.has(obj))
962
- throw TypeError("Cannot add the same private member more than once");
963
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
964
- };
965
- var __privateSet$2 = (obj, member, value, setter) => {
966
- __accessCheck$2(obj, member, "write to private field");
967
- setter ? setter.call(obj, value) : member.set(obj, value);
968
- return value;
969
- };
970
- var __privateMethod = (obj, member, method) => {
971
- __accessCheck$2(obj, member, "access private method");
972
- return method;
973
- };
974
- var _loaded, _loading, _loaders, _getLoaderKey, getLoaderKey_fn, _i18n, _loader, _language, _registeredRefs, _languageChangeListeners, _changeLanguage, changeLanguage_fn, _createSnapshot, createSnapshot_fn, _registerDefaults, registerDefaults_fn;
975
- function removeNulls(messages) {
976
- return Object.fromEntries(
977
- Object.entries(messages).filter(
978
- (e) => e[1] !== null
979
- )
980
- );
981
- }
982
- class ResourceLoader {
983
- constructor(onLoad) {
984
- this.onLoad = onLoad;
985
- __privateAdd$2(this, _getLoaderKey);
986
- /** Loaded resources by loader key */
987
- __privateAdd$2(this, _loaded, /* @__PURE__ */ new Set());
988
- /** Resource loading promises by loader key */
989
- __privateAdd$2(this, _loading, /* @__PURE__ */ new Map());
990
- /** Loaders for each resource language */
991
- __privateAdd$2(this, _loaders, /* @__PURE__ */ new Map());
992
- }
993
- addTranslationResource(resource) {
994
- const internalResource = toInternalTranslationResource(resource);
995
- for (const entry of internalResource.resources) {
996
- const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, entry.language, internalResource.id);
997
- if (!__privateGet$2(this, _loaders).has(key)) {
998
- __privateGet$2(this, _loaders).set(key, entry.loader);
999
- }
1000
- }
1001
- }
1002
- needsLoading(language, namespace) {
1003
- const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, language, namespace);
1004
- const loader = __privateGet$2(this, _loaders).get(key);
1005
- if (!loader) {
1006
- return false;
1007
- }
1008
- return !__privateGet$2(this, _loaded).has(key);
1009
- }
1010
- async load(language, namespace) {
1011
- const key = __privateMethod(this, _getLoaderKey, getLoaderKey_fn).call(this, language, namespace);
1012
- const loader = __privateGet$2(this, _loaders).get(key);
1013
- if (!loader) {
1014
- return;
1015
- }
1016
- if (__privateGet$2(this, _loaded).has(key)) {
1017
- return;
1018
- }
1019
- const loading = __privateGet$2(this, _loading).get(key);
1020
- if (loading) {
1021
- await loading;
1022
- return;
1023
- }
1024
- const load = loader().then(
1025
- (result) => {
1026
- this.onLoad({ language, namespace, messages: result.messages });
1027
- __privateGet$2(this, _loaded).add(key);
1028
- },
1029
- (error) => {
1030
- __privateGet$2(this, _loaded).add(key);
1031
- throw error;
1032
- }
1033
- );
1034
- __privateGet$2(this, _loading).set(key, load);
1035
- await load;
1036
- }
1037
- }
1038
- _loaded = new WeakMap();
1039
- _loading = new WeakMap();
1040
- _loaders = new WeakMap();
1041
- _getLoaderKey = new WeakSet();
1042
- getLoaderKey_fn = function(language, namespace) {
1043
- return `${language}/${namespace}`;
1044
- };
1045
- const _I18nextTranslationApi = class _I18nextTranslationApi {
1046
- constructor(i18n, loader, language) {
1047
- __privateAdd$2(this, _changeLanguage);
1048
- __privateAdd$2(this, _createSnapshot);
1049
- __privateAdd$2(this, _registerDefaults);
1050
- __privateAdd$2(this, _i18n, void 0);
1051
- __privateAdd$2(this, _loader, void 0);
1052
- __privateAdd$2(this, _language, void 0);
1053
- /** Keep track of which refs we have registered default resources for */
1054
- __privateAdd$2(this, _registeredRefs, /* @__PURE__ */ new Set());
1055
- /** Notify observers when language changes */
1056
- __privateAdd$2(this, _languageChangeListeners, /* @__PURE__ */ new Set());
1057
- __privateSet$2(this, _i18n, i18n);
1058
- __privateSet$2(this, _loader, loader);
1059
- __privateSet$2(this, _language, language);
1060
- }
1061
- static create(options) {
1062
- const { languages } = options.languageApi.getAvailableLanguages();
1063
- const i18n = createInstance({
1064
- fallbackLng: DEFAULT_LANGUAGE,
1065
- supportedLngs: languages,
1066
- interpolation: {
1067
- escapeValue: false
1068
- },
1069
- ns: [],
1070
- defaultNS: false,
1071
- fallbackNS: false,
1072
- // Disable resource loading on init, meaning i18n will be ready to use immediately
1073
- initImmediate: false
1074
- });
1075
- i18n.init();
1076
- if (!i18n.isInitialized) {
1077
- throw new Error("i18next was unexpectedly not initialized");
1078
- }
1079
- const { language: initialLanguage } = options.languageApi.getLanguage();
1080
- if (initialLanguage !== DEFAULT_LANGUAGE) {
1081
- i18n.changeLanguage(initialLanguage);
1082
- }
1083
- const loader = new ResourceLoader((loaded) => {
1084
- i18n.addResourceBundle(
1085
- loaded.language,
1086
- loaded.namespace,
1087
- removeNulls(loaded.messages),
1088
- false,
1089
- // do not merge with existing translations
1090
- true
1091
- // overwrite translations
1092
- );
1093
- });
1094
- const resources = (options == null ? void 0 : options.resources) || [];
1095
- for (let i = resources.length - 1; i >= 0; i--) {
1096
- const resource = resources[i];
1097
- if (resource.$$type === "@backstage/TranslationResource") {
1098
- loader.addTranslationResource(resource);
1099
- } else if (resource.$$type === "@backstage/TranslationMessages") {
1100
- i18n.addResourceBundle(
1101
- DEFAULT_LANGUAGE,
1102
- resource.id,
1103
- removeNulls(resource.messages),
1104
- true,
1105
- // merge with existing translations
1106
- false
1107
- // do not overwrite translations
1108
- );
1109
- }
1110
- }
1111
- const instance = new _I18nextTranslationApi(
1112
- i18n,
1113
- loader,
1114
- options.languageApi.getLanguage().language
1115
- );
1116
- options.languageApi.language$().subscribe(({ language }) => {
1117
- var _a;
1118
- __privateMethod(_a = instance, _changeLanguage, changeLanguage_fn).call(_a, language);
1119
- });
1120
- return instance;
1121
- }
1122
- getTranslation(translationRef) {
1123
- const internalRef = toInternalTranslationRef(translationRef);
1124
- __privateMethod(this, _registerDefaults, registerDefaults_fn).call(this, internalRef);
1125
- return __privateMethod(this, _createSnapshot, createSnapshot_fn).call(this, internalRef);
1126
- }
1127
- translation$(translationRef) {
1128
- const internalRef = toInternalTranslationRef(translationRef);
1129
- __privateMethod(this, _registerDefaults, registerDefaults_fn).call(this, internalRef);
1130
- return new ObservableImpl((subscriber) => {
1131
- let loadTicket = {};
1132
- const loadResource = () => {
1133
- loadTicket = {};
1134
- const ticket = loadTicket;
1135
- __privateGet$2(this, _loader).load(__privateGet$2(this, _language), internalRef.id).then(
1136
- () => {
1137
- if (ticket === loadTicket) {
1138
- const snapshot = __privateMethod(this, _createSnapshot, createSnapshot_fn).call(this, internalRef);
1139
- if (snapshot.ready) {
1140
- subscriber.next(snapshot);
1141
- }
1142
- }
1143
- },
1144
- (error) => {
1145
- if (ticket === loadTicket) {
1146
- subscriber.error(Array.isArray(error) ? error[0] : error);
1147
- }
1148
- }
1149
- );
1150
- };
1151
- const onChange = () => {
1152
- const snapshot = __privateMethod(this, _createSnapshot, createSnapshot_fn).call(this, internalRef);
1153
- if (snapshot.ready) {
1154
- subscriber.next(snapshot);
1155
- } else {
1156
- loadResource();
1157
- }
1158
- };
1159
- if (__privateGet$2(this, _loader).needsLoading(__privateGet$2(this, _language), internalRef.id)) {
1160
- loadResource();
1161
- }
1162
- __privateGet$2(this, _languageChangeListeners).add(onChange);
1163
- return () => {
1164
- __privateGet$2(this, _languageChangeListeners).delete(onChange);
1165
- };
1166
- });
1167
- }
1168
- };
1169
- _i18n = new WeakMap();
1170
- _loader = new WeakMap();
1171
- _language = new WeakMap();
1172
- _registeredRefs = new WeakMap();
1173
- _languageChangeListeners = new WeakMap();
1174
- _changeLanguage = new WeakSet();
1175
- changeLanguage_fn = function(language) {
1176
- if (__privateGet$2(this, _language) !== language) {
1177
- __privateSet$2(this, _language, language);
1178
- __privateGet$2(this, _i18n).changeLanguage(language);
1179
- __privateGet$2(this, _languageChangeListeners).forEach((listener) => listener());
1180
- }
1181
- };
1182
- _createSnapshot = new WeakSet();
1183
- createSnapshot_fn = function(internalRef) {
1184
- if (__privateGet$2(this, _loader).needsLoading(__privateGet$2(this, _language), internalRef.id)) {
1185
- return { ready: false };
1186
- }
1187
- const t = __privateGet$2(this, _i18n).getFixedT(
1188
- null,
1189
- internalRef.id
1190
- );
1191
- return {
1192
- ready: true,
1193
- t
1194
- };
1195
- };
1196
- _registerDefaults = new WeakSet();
1197
- registerDefaults_fn = function(internalRef) {
1198
- if (__privateGet$2(this, _registeredRefs).has(internalRef.id)) {
1199
- return;
1200
- }
1201
- __privateGet$2(this, _registeredRefs).add(internalRef.id);
1202
- const defaultMessages = internalRef.getDefaultMessages();
1203
- __privateGet$2(this, _i18n).addResourceBundle(
1204
- DEFAULT_LANGUAGE,
1205
- internalRef.id,
1206
- defaultMessages,
1207
- true,
1208
- // merge with existing translations
1209
- false
1210
- // do not overwrite translations
1211
- );
1212
- const defaultResource = internalRef.getDefaultResource();
1213
- if (defaultResource) {
1214
- __privateGet$2(this, _loader).addTranslationResource(defaultResource);
1215
- }
1216
- };
1217
- let I18nextTranslationApi = _I18nextTranslationApi;
1218
-
1219
- function toInternalExtensionDefinition(overrides) {
1220
- const internal = overrides;
1221
- if (internal.$$type !== "@backstage/ExtensionDefinition") {
1222
- throw new Error(
1223
- `Invalid extension definition instance, bad type '${internal.$$type}'`
1224
- );
1225
- }
1226
- if (internal.version !== "v1") {
1227
- throw new Error(
1228
- `Invalid extension definition instance, bad version '${internal.version}'`
1229
- );
1230
- }
1231
- return internal;
1232
- }
1233
-
1234
- function toInternalExtension(overrides) {
1235
- const internal = overrides;
1236
- if (internal.$$type !== "@backstage/Extension") {
1237
- throw new Error(
1238
- `Invalid extension instance, bad type '${internal.$$type}'`
1239
- );
1240
- }
1241
- if (internal.version !== "v1") {
1242
- throw new Error(
1243
- `Invalid extension instance, bad version '${internal.version}'`
1244
- );
1245
- }
1246
- return internal;
1247
- }
1248
- function resolveExtensionDefinition(definition, context) {
1249
- var _a;
1250
- const internalDefinition = toInternalExtensionDefinition(definition);
1251
- const { name, kind, namespace: _, ...rest } = internalDefinition;
1252
- const namespace = (_a = internalDefinition.namespace) != null ? _a : context == null ? void 0 : context.namespace;
1253
- const namePart = name && namespace ? `${namespace}/${name}` : namespace || name;
1254
- if (!namePart) {
1255
- throw new Error(
1256
- `Extension must declare an explicit namespace or name as it could not be resolved from context, kind=${kind} namespace=${namespace} name=${name}`
1257
- );
1258
- }
1259
- const id = kind ? `${kind}:${namePart}` : namePart;
1260
- return {
1261
- ...rest,
1262
- $$type: "@backstage/Extension",
1263
- version: "v1",
1264
- id,
1265
- toString() {
1266
- return `Extension{id=${id}}`;
1267
- }
1268
- };
1269
- }
1270
-
1271
- const apis = [
1272
- createApiFactory({
1273
- api: discoveryApiRef,
1274
- deps: { configApi: configApiRef },
1275
- factory: ({ configApi }) => UrlPatternDiscovery.compile(
1276
- `${configApi.getString("backend.baseUrl")}/api/{{ pluginId }}`
1277
- )
1278
- }),
1279
- createApiFactory({
1280
- api: alertApiRef,
1281
- deps: {},
1282
- factory: () => new AlertApiForwarder()
1283
- }),
1284
- createApiFactory({
1285
- api: analyticsApiRef,
1286
- deps: {},
1287
- factory: () => new NoOpAnalyticsApi()
1288
- }),
1289
- createApiFactory({
1290
- api: errorApiRef,
1291
- deps: { alertApi: alertApiRef },
1292
- factory: ({ alertApi }) => {
1293
- const errorApi = new ErrorAlerter(alertApi, new ErrorApiForwarder());
1294
- UnhandledErrorForwarder.forward(errorApi, { hidden: false });
1295
- return errorApi;
1296
- }
1297
- }),
1298
- createApiFactory({
1299
- api: storageApiRef,
1300
- deps: { errorApi: errorApiRef },
1301
- factory: ({ errorApi }) => WebStorage.create({ errorApi })
1302
- }),
1303
- createApiFactory({
1304
- api: fetchApiRef,
1305
- deps: {
1306
- configApi: configApiRef,
1307
- identityApi: identityApiRef,
1308
- discoveryApi: discoveryApiRef
1309
- },
1310
- factory: ({ configApi, identityApi, discoveryApi }) => {
1311
- return createFetchApi({
1312
- middleware: [
1313
- FetchMiddlewares.resolvePluginProtocol({
1314
- discoveryApi
1315
- }),
1316
- FetchMiddlewares.injectIdentityAuth({
1317
- identityApi,
1318
- config: configApi
1319
- })
1320
- ]
1321
- });
1322
- }
1323
- }),
1324
- createApiFactory({
1325
- api: oauthRequestApiRef,
1326
- deps: {},
1327
- factory: () => new OAuthRequestManager()
1328
- }),
1329
- createApiFactory({
1330
- api: googleAuthApiRef,
1331
- deps: {
1332
- discoveryApi: discoveryApiRef,
1333
- oauthRequestApi: oauthRequestApiRef,
1334
- configApi: configApiRef
1335
- },
1336
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => GoogleAuth.create({
1337
- configApi,
1338
- discoveryApi,
1339
- oauthRequestApi,
1340
- environment: configApi.getOptionalString("auth.environment")
1341
- })
1342
- }),
1343
- createApiFactory({
1344
- api: microsoftAuthApiRef,
1345
- deps: {
1346
- discoveryApi: discoveryApiRef,
1347
- oauthRequestApi: oauthRequestApiRef,
1348
- configApi: configApiRef
1349
- },
1350
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => MicrosoftAuth.create({
1351
- configApi,
1352
- discoveryApi,
1353
- oauthRequestApi,
1354
- environment: configApi.getOptionalString("auth.environment")
1355
- })
1356
- }),
1357
- createApiFactory({
1358
- api: githubAuthApiRef,
1359
- deps: {
1360
- discoveryApi: discoveryApiRef,
1361
- oauthRequestApi: oauthRequestApiRef,
1362
- configApi: configApiRef
1363
- },
1364
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => GithubAuth.create({
1365
- configApi,
1366
- discoveryApi,
1367
- oauthRequestApi,
1368
- defaultScopes: ["read:user"],
1369
- environment: configApi.getOptionalString("auth.environment")
1370
- })
1371
- }),
1372
- createApiFactory({
1373
- api: oktaAuthApiRef,
1374
- deps: {
1375
- discoveryApi: discoveryApiRef,
1376
- oauthRequestApi: oauthRequestApiRef,
1377
- configApi: configApiRef
1378
- },
1379
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => OktaAuth.create({
1380
- configApi,
1381
- discoveryApi,
1382
- oauthRequestApi,
1383
- environment: configApi.getOptionalString("auth.environment")
1384
- })
1385
- }),
1386
- createApiFactory({
1387
- api: gitlabAuthApiRef,
1388
- deps: {
1389
- discoveryApi: discoveryApiRef,
1390
- oauthRequestApi: oauthRequestApiRef,
1391
- configApi: configApiRef
1392
- },
1393
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => GitlabAuth.create({
1394
- configApi,
1395
- discoveryApi,
1396
- oauthRequestApi,
1397
- environment: configApi.getOptionalString("auth.environment")
1398
- })
1399
- }),
1400
- createApiFactory({
1401
- api: oneloginAuthApiRef,
1402
- deps: {
1403
- discoveryApi: discoveryApiRef,
1404
- oauthRequestApi: oauthRequestApiRef,
1405
- configApi: configApiRef
1406
- },
1407
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => OneLoginAuth.create({
1408
- configApi,
1409
- discoveryApi,
1410
- oauthRequestApi,
1411
- environment: configApi.getOptionalString("auth.environment")
1412
- })
1413
- }),
1414
- createApiFactory({
1415
- api: bitbucketAuthApiRef,
1416
- deps: {
1417
- discoveryApi: discoveryApiRef,
1418
- oauthRequestApi: oauthRequestApiRef,
1419
- configApi: configApiRef
1420
- },
1421
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => BitbucketAuth.create({
1422
- configApi,
1423
- discoveryApi,
1424
- oauthRequestApi,
1425
- defaultScopes: ["account"],
1426
- environment: configApi.getOptionalString("auth.environment")
1427
- })
1428
- }),
1429
- createApiFactory({
1430
- api: bitbucketServerAuthApiRef,
1431
- deps: {
1432
- discoveryApi: discoveryApiRef,
1433
- oauthRequestApi: oauthRequestApiRef,
1434
- configApi: configApiRef
1435
- },
1436
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => BitbucketServerAuth.create({
1437
- configApi,
1438
- discoveryApi,
1439
- oauthRequestApi,
1440
- defaultScopes: ["REPO_READ"]
1441
- })
1442
- }),
1443
- createApiFactory({
1444
- api: atlassianAuthApiRef,
1445
- deps: {
1446
- discoveryApi: discoveryApiRef,
1447
- oauthRequestApi: oauthRequestApiRef,
1448
- configApi: configApiRef
1449
- },
1450
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => {
1451
- return AtlassianAuth.create({
1452
- configApi,
1453
- discoveryApi,
1454
- oauthRequestApi,
1455
- environment: configApi.getOptionalString("auth.environment")
1456
- });
1457
- }
1458
- }),
1459
- createApiFactory({
1460
- api: vmwareCloudAuthApiRef,
1461
- deps: {
1462
- discoveryApi: discoveryApiRef,
1463
- oauthRequestApi: oauthRequestApiRef,
1464
- configApi: configApiRef
1465
- },
1466
- factory: ({ discoveryApi, oauthRequestApi, configApi }) => {
1467
- return VMwareCloudAuth.create({
1468
- configApi,
1469
- discoveryApi,
1470
- oauthRequestApi,
1471
- environment: configApi.getOptionalString("auth.environment")
1472
- });
1473
- }
1474
- }),
1475
- createApiFactory({
1476
- api: permissionApiRef,
1477
- deps: {
1478
- discovery: discoveryApiRef,
1479
- identity: identityApiRef,
1480
- config: configApiRef
1481
- },
1482
- factory: ({ config, discovery, identity }) => IdentityPermissionApi.create({ config, discovery, identity })
1483
- })
1484
- ];
1485
-
1486
- function OptionallyWrapInRouter({ children }) {
1487
- if (useInRouterContext()) {
1488
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
1489
- }
1490
- return /* @__PURE__ */ React.createElement(MemoryRouter, null, children);
1491
- }
1492
- const DefaultNotFoundPage = () => /* @__PURE__ */ React.createElement(ErrorPage, { status: "404", statusMessage: "PAGE NOT FOUND" });
1493
- const DefaultBootErrorPage = ({ step, error }) => {
1494
- let message = "";
1495
- if (step === "load-config") {
1496
- message = `The configuration failed to load, someone should have a look at this error: ${error.message}`;
1497
- } else if (step === "load-chunk") {
1498
- message = `Lazy loaded chunk failed to load, try to reload the page: ${error.message}`;
1499
- }
1500
- return /* @__PURE__ */ React.createElement(OptionallyWrapInRouter, null, /* @__PURE__ */ React.createElement(ErrorPage, { statusMessage: message, stack: error.stack }));
1501
- };
1502
- const DefaultErrorBoundaryFallback = ({
1503
- error,
1504
- resetError,
1505
- plugin
1506
- }) => {
1507
- return /* @__PURE__ */ React.createElement(
1508
- ErrorPanel,
1509
- {
1510
- title: `Error in ${plugin == null ? void 0 : plugin.getId()}`,
1511
- defaultExpanded: true,
1512
- error
1513
- },
1514
- /* @__PURE__ */ React.createElement(Button, { variant: "outlined", onClick: resetError }, "Retry")
1515
- );
1516
- };
1517
- const components = {
1518
- Progress,
1519
- Router: BrowserRouter,
1520
- NotFoundErrorPage: DefaultNotFoundPage,
1521
- BootErrorPage: DefaultBootErrorPage,
1522
- ErrorBoundaryFallback: DefaultErrorBoundaryFallback
1523
- };
1524
-
1525
- const icons = {
1526
- brokenImage: MuiBrokenImageIcon,
1527
- // To be confirmed: see https://github.com/backstage/backstage/issues/4970
1528
- catalog: MuiMenuBookIcon,
1529
- scaffolder: MuiCreateNewFolderIcon,
1530
- techdocs: MuiSubjectIcon,
1531
- search: MuiSearchIcon,
1532
- chat: MuiChatIcon,
1533
- dashboard: MuiDashboardIcon,
1534
- docs: MuiDocsIcon,
1535
- email: MuiEmailIcon,
1536
- github: MuiGitHubIcon,
1537
- group: MuiPeopleIcon,
1538
- help: MuiHelpIcon,
1539
- "kind:api": MuiExtensionIcon,
1540
- "kind:component": MuiMemoryIcon,
1541
- "kind:domain": MuiApartmentIcon,
1542
- "kind:group": MuiPeopleIcon,
1543
- "kind:location": MuiLocationOnIcon,
1544
- "kind:system": MuiCategoryIcon,
1545
- "kind:user": MuiPersonIcon,
1546
- "kind:resource": MuiStorageIcon,
1547
- "kind:template": MuiFeaturedPlayListIcon,
1548
- user: MuiPersonIcon,
1549
- warning: MuiWarningIcon
1550
- };
1551
-
1552
- const LightTheme = createThemeExtension({
1553
- id: "light",
1554
- title: "Light Theme",
1555
- variant: "light",
1556
- icon: /* @__PURE__ */ React.createElement(LightIcon, null),
1557
- Provider: ({ children }) => /* @__PURE__ */ React.createElement(UnifiedThemeProvider, { theme: themes.light, children })
1558
- });
1559
- const DarkTheme = createThemeExtension({
1560
- id: "dark",
1561
- title: "Dark Theme",
1562
- variant: "dark",
1563
- icon: /* @__PURE__ */ React.createElement(DarkIcon, null),
1564
- Provider: ({ children }) => /* @__PURE__ */ React.createElement(UnifiedThemeProvider, { theme: themes.dark, children })
1565
- });
1566
-
1567
- const oauthRequestDialogAppRootElement = createAppRootElementExtension({
1568
- namespace: "app",
1569
- name: "oauth-request-dialog",
1570
- element: /* @__PURE__ */ React.createElement(OAuthRequestDialog, null)
1571
- });
1572
- const alertDisplayAppRootElement = createAppRootElementExtension({
1573
- namespace: "app",
1574
- name: "alert-display",
1575
- configSchema: createSchemaFromZod(
1576
- (z) => z.object({
1577
- transientTimeoutMs: z.number().default(5e3),
1578
- anchorOrigin: z.object({
1579
- vertical: z.enum(["top", "bottom"]).default("top"),
1580
- horizontal: z.enum(["left", "center", "right"]).default("center")
1581
- }).default({})
1582
- })
1583
- ),
1584
- element: ({ config }) => /* @__PURE__ */ React.createElement(AlertDisplay, { ...config })
1585
- });
1586
-
1587
- const legacyPluginStore = getOrCreateGlobalSingleton(
1588
- "legacy-plugin-compatibility-store",
1589
- () => /* @__PURE__ */ new WeakMap()
1590
- );
1591
- function toLegacyPlugin(plugin) {
1592
- let legacy = legacyPluginStore.get(plugin);
1593
- if (legacy) {
1594
- return legacy;
1595
- }
1596
- const errorMsg = "Not implemented in legacy plugin compatibility layer";
1597
- const notImplemented = () => {
1598
- throw new Error(errorMsg);
1599
- };
1600
- legacy = {
1601
- getId() {
1602
- return plugin.id;
1603
- },
1604
- get routes() {
1605
- return {};
1606
- },
1607
- get externalRoutes() {
1608
- return {};
1609
- },
1610
- getApis: notImplemented,
1611
- getFeatureFlags: notImplemented,
1612
- provide: notImplemented
1613
- };
1614
- legacyPluginStore.set(plugin, legacy);
1615
- return legacy;
1616
- }
1617
-
1618
- const MATCH_ALL_ROUTE = {
1619
- caseSensitive: false,
1620
- path: "*",
1621
- element: "match-all",
1622
- // These elements aren't used, so we add in a bit of debug information
1623
- routeRefs: /* @__PURE__ */ new Set(),
1624
- plugins: /* @__PURE__ */ new Set()
1625
- };
1626
- function joinPaths$1(...paths) {
1627
- const normalized = paths.join("/").replace(/\/\/+/g, "/");
1628
- if (normalized !== "/" && normalized.endsWith("/")) {
1629
- return normalized.slice(0, -1);
1630
- }
1631
- return normalized;
1632
- }
1633
- function extractRouteInfoFromAppNode(node) {
1634
- const routePaths = /* @__PURE__ */ new Map();
1635
- const routeParents = /* @__PURE__ */ new Map();
1636
- const routeObjects = new Array();
1637
- function visit(current, collectedPath, foundRefForCollectedPath = false, parentRef, candidateParentRef, parentObj) {
1638
- var _a, _b, _c, _d;
1639
- const routePath = (_b = (_a = current.instance) == null ? void 0 : _a.getData(coreExtensionData.routePath)) == null ? void 0 : _b.replace(/^\//, "");
1640
- const routeRef = (_c = current.instance) == null ? void 0 : _c.getData(coreExtensionData.routeRef);
1641
- const parentChildren = (_d = parentObj == null ? void 0 : parentObj.children) != null ? _d : routeObjects;
1642
- let currentObj = parentObj;
1643
- let newCollectedPath = collectedPath;
1644
- let newFoundRefForCollectedPath = foundRefForCollectedPath;
1645
- let newParentRef = parentRef;
1646
- let newCandidateParentRef = candidateParentRef;
1647
- if (routePath !== void 0) {
1648
- currentObj = {
1649
- path: routePath,
1650
- element: "mounted",
1651
- routeRefs: /* @__PURE__ */ new Set(),
1652
- caseSensitive: false,
1653
- children: [MATCH_ALL_ROUTE],
1654
- plugins: /* @__PURE__ */ new Set(),
1655
- appNode: current
1656
- };
1657
- parentChildren.push(currentObj);
1658
- newParentRef = candidateParentRef;
1659
- newCandidateParentRef = void 0;
1660
- if (newFoundRefForCollectedPath) {
1661
- newCollectedPath = routePath;
1662
- newFoundRefForCollectedPath = false;
1663
- } else {
1664
- newCollectedPath = collectedPath ? joinPaths$1(collectedPath, routePath) : routePath;
1665
- }
1666
- }
1667
- if (routeRef) {
1668
- if (!newCandidateParentRef) {
1669
- newCandidateParentRef = routeRef;
1670
- }
1671
- if (newCollectedPath !== void 0) {
1672
- routePaths.set(routeRef, newCollectedPath);
1673
- newFoundRefForCollectedPath = true;
1674
- }
1675
- routeParents.set(routeRef, newParentRef);
1676
- currentObj == null ? void 0 : currentObj.routeRefs.add(routeRef);
1677
- if (current.spec.source) {
1678
- currentObj == null ? void 0 : currentObj.plugins.add(toLegacyPlugin(current.spec.source));
1679
- }
1680
- }
1681
- for (const children of current.edges.attachments.values()) {
1682
- for (const child of children) {
1683
- visit(
1684
- child,
1685
- newCollectedPath,
1686
- newFoundRefForCollectedPath,
1687
- newParentRef,
1688
- newCandidateParentRef,
1689
- currentObj
1690
- );
1691
- }
1692
- }
1693
- }
1694
- visit(node);
1695
- return { routePaths, routeParents, routeObjects };
1696
- }
1697
-
1698
- function toInternalRouteRef(resource) {
1699
- const r = resource;
1700
- if (r.$$type !== "@backstage/RouteRef") {
1701
- throw new Error(`Invalid RouteRef, bad type '${r.$$type}'`);
1702
- }
1703
- return r;
1704
- }
1705
- function isRouteRef(opaque) {
1706
- return opaque.$$type === "@backstage/RouteRef";
1707
- }
1708
-
1709
- function toInternalSubRouteRef(resource) {
1710
- const r = resource;
1711
- if (r.$$type !== "@backstage/SubRouteRef") {
1712
- throw new Error(`Invalid SubRouteRef, bad type '${r.$$type}'`);
1713
- }
1714
- return r;
1715
- }
1716
- function isSubRouteRef(opaque) {
1717
- return opaque.$$type === "@backstage/SubRouteRef";
1718
- }
1719
-
1720
- function toInternalExternalRouteRef(resource) {
1721
- const r = resource;
1722
- if (r.$$type !== "@backstage/ExternalRouteRef") {
1723
- throw new Error(`Invalid ExternalRouteRef, bad type '${r.$$type}'`);
1724
- }
1725
- return r;
1726
- }
1727
- function isExternalRouteRef(opaque) {
1728
- return opaque.$$type === "@backstage/ExternalRouteRef";
1729
- }
1730
-
1731
- function joinPaths(...paths) {
1732
- const normalized = paths.join("/").replace(/\/\/+/g, "/");
1733
- if (normalized !== "/" && normalized.endsWith("/")) {
1734
- return normalized.slice(0, -1);
1735
- }
1736
- return normalized;
1737
- }
1738
- function resolveTargetRef(anyRouteRef, routePaths, routeBindings) {
1739
- let targetRef;
1740
- let subRoutePath = "";
1741
- if (isRouteRef(anyRouteRef)) {
1742
- targetRef = anyRouteRef;
1743
- } else if (isSubRouteRef(anyRouteRef)) {
1744
- const internal = toInternalSubRouteRef(anyRouteRef);
1745
- targetRef = internal.getParent();
1746
- subRoutePath = internal.path;
1747
- } else if (isExternalRouteRef(anyRouteRef)) {
1748
- const resolvedRoute = routeBindings.get(anyRouteRef);
1749
- if (!resolvedRoute) {
1750
- return [void 0, ""];
1751
- }
1752
- if (isRouteRef(resolvedRoute)) {
1753
- targetRef = resolvedRoute;
1754
- } else if (isSubRouteRef(resolvedRoute)) {
1755
- const internal = toInternalSubRouteRef(resolvedRoute);
1756
- targetRef = internal.getParent();
1757
- subRoutePath = resolvedRoute.path;
1758
- } else {
1759
- throw new Error(
1760
- `ExternalRouteRef was bound to invalid target, ${resolvedRoute}`
1761
- );
1762
- }
1763
- } else {
1764
- throw new Error(`Unknown object passed to useRouteRef, got ${anyRouteRef}`);
1765
- }
1766
- if (!targetRef) {
1767
- return [void 0, ""];
1768
- }
1769
- const resolvedPath = routePaths.get(targetRef);
1770
- if (resolvedPath === void 0) {
1771
- return [void 0, ""];
1772
- }
1773
- const targetPath = joinPaths(resolvedPath, subRoutePath);
1774
- return [targetRef, targetPath];
1775
- }
1776
- function resolveBasePath(targetRef, sourceLocation, routePaths, routeParents, routeObjects) {
1777
- var _a;
1778
- const match = (_a = matchRoutes(routeObjects, sourceLocation)) != null ? _a : [];
1779
- const refDiffList = Array();
1780
- let matchIndex = -1;
1781
- for (let targetSearchRef = targetRef; targetSearchRef; targetSearchRef = routeParents.get(targetSearchRef)) {
1782
- matchIndex = match.findIndex(
1783
- (m) => m.route.routeRefs.has(targetSearchRef)
1784
- );
1785
- if (matchIndex !== -1) {
1786
- break;
1787
- }
1788
- refDiffList.unshift(targetSearchRef);
1789
- }
1790
- if (refDiffList.length === 0) {
1791
- matchIndex -= 1;
1792
- }
1793
- const parentPath = matchIndex === -1 ? "" : match[matchIndex].pathname;
1794
- const diffPaths = refDiffList.slice(0, -1).map((ref) => {
1795
- const path = routePaths.get(ref);
1796
- if (path === void 0) {
1797
- throw new Error(`No path for ${ref}`);
1798
- }
1799
- if (path.includes(":")) {
1800
- throw new Error(
1801
- `Cannot route to ${targetRef} with parent ${ref} as it has parameters`
1802
- );
1803
- }
1804
- return path;
1805
- });
1806
- return `${joinPaths(parentPath, ...diffPaths)}/`;
1807
- }
1808
- class RouteResolver {
1809
- constructor(routePaths, routeParents, routeObjects, routeBindings, appBasePath) {
1810
- this.routePaths = routePaths;
1811
- this.routeParents = routeParents;
1812
- this.routeObjects = routeObjects;
1813
- this.routeBindings = routeBindings;
1814
- this.appBasePath = appBasePath;
1815
- }
1816
- resolve(anyRouteRef, options) {
1817
- var _a;
1818
- const [targetRef, targetPath] = resolveTargetRef(
1819
- anyRouteRef,
1820
- this.routePaths,
1821
- this.routeBindings
1822
- );
1823
- if (!targetRef) {
1824
- return void 0;
1825
- }
1826
- const relativeSourceLocation = this.trimPath((_a = options == null ? void 0 : options.sourcePath) != null ? _a : "");
1827
- const basePath = resolveBasePath(
1828
- targetRef,
1829
- relativeSourceLocation,
1830
- this.routePaths,
1831
- this.routeParents,
1832
- this.routeObjects
1833
- );
1834
- const routeFunc = (...[params]) => {
1835
- const encodedParams = params && mapValues(params, (value) => {
1836
- if (typeof value === "string") {
1837
- return value.replaceAll(/[&?#;\/]/g, (c) => encodeURIComponent(c));
1838
- }
1839
- return value;
1840
- });
1841
- return joinPaths(basePath, generatePath(targetPath, encodedParams));
1842
- };
1843
- return routeFunc;
1844
- }
1845
- trimPath(targetPath) {
1846
- if (!targetPath) {
1847
- return targetPath;
1848
- }
1849
- if (targetPath.startsWith(this.appBasePath)) {
1850
- return targetPath.slice(this.appBasePath.length);
1851
- }
1852
- return targetPath;
1853
- }
1854
- }
1855
-
1856
- function resolveRouteBindings(bindRoutes, config, routesById) {
1857
- var _a;
1858
- const result = /* @__PURE__ */ new Map();
1859
- if (bindRoutes) {
1860
- const bind = (externalRoutes, targetRoutes) => {
1861
- for (const [key, value] of Object.entries(targetRoutes)) {
1862
- const externalRoute = externalRoutes[key];
1863
- if (!externalRoute) {
1864
- throw new Error(`Key ${key} is not an existing external route`);
1865
- }
1866
- if (!value && !externalRoute.optional) {
1867
- throw new Error(
1868
- `External route ${key} is required but was undefined`
1869
- );
1870
- }
1871
- if (value) {
1872
- result.set(externalRoute, value);
1873
- }
1874
- }
1875
- };
1876
- bindRoutes({ bind });
1877
- }
1878
- const bindings = (_a = config.getOptionalConfig("app.routes.bindings")) == null ? void 0 : _a.get();
1879
- if (bindings) {
1880
- for (const [externalRefId, targetRefId] of Object.entries(bindings)) {
1881
- if (typeof targetRefId !== "string" || targetRefId === "") {
1882
- throw new Error(
1883
- `Invalid config at app.routes.bindings['${externalRefId}'], value must be a non-empty string`
1884
- );
1885
- }
1886
- const externalRef = routesById.externalRoutes.get(externalRefId);
1887
- if (!externalRef) {
1888
- throw new Error(
1889
- `Invalid config at app.routes.bindings, '${externalRefId}' is not a valid external route`
1890
- );
1891
- }
1892
- if (result.has(externalRef)) {
1893
- continue;
1894
- }
1895
- const targetRef = routesById.routes.get(targetRefId);
1896
- if (!targetRef) {
1897
- throw new Error(
1898
- `Invalid config at app.routes.bindings['${externalRefId}'], '${targetRefId}' is not a valid route`
1899
- );
1900
- }
1901
- result.set(externalRef, targetRef);
1902
- }
1903
- }
1904
- for (const externalRef of routesById.externalRoutes.values()) {
1905
- if (!result.has(externalRef)) {
1906
- const defaultRefId = toInternalExternalRouteRef(externalRef).getDefaultTarget();
1907
- if (defaultRefId) {
1908
- const defaultRef = routesById.routes.get(defaultRefId);
1909
- if (defaultRef) {
1910
- result.set(externalRef, defaultRef);
1911
- }
1912
- }
1913
- }
1914
- }
1915
- return result;
1916
- }
1917
-
1918
- function collectRouteIds(features) {
1919
- const routesById = /* @__PURE__ */ new Map();
1920
- const externalRoutesById = /* @__PURE__ */ new Map();
1921
- for (const feature of features) {
1922
- if (feature.$$type !== "@backstage/BackstagePlugin") {
1923
- continue;
1924
- }
1925
- for (const [name, ref] of Object.entries(feature.routes)) {
1926
- const refId = `${feature.id}.${name}`;
1927
- if (routesById.has(refId)) {
1928
- throw new Error(`Unexpected duplicate route '${refId}'`);
1929
- }
1930
- if (isRouteRef(ref)) {
1931
- const internalRef = toInternalRouteRef(ref);
1932
- internalRef.setId(refId);
1933
- routesById.set(refId, ref);
1934
- } else {
1935
- const internalRef = toInternalSubRouteRef(ref);
1936
- routesById.set(refId, internalRef);
1937
- }
1938
- }
1939
- for (const [name, ref] of Object.entries(feature.externalRoutes)) {
1940
- const refId = `${feature.id}.${name}`;
1941
- if (externalRoutesById.has(refId)) {
1942
- throw new Error(`Unexpected duplicate external route '${refId}'`);
1943
- }
1944
- const internalRef = toInternalExternalRouteRef(ref);
1945
- internalRef.setId(refId);
1946
- externalRoutesById.set(refId, ref);
1947
- }
1948
- }
1949
- return { routes: routesById, externalRoutes: externalRoutesById };
1950
- }
1951
-
1952
- const knownExtensionParameters = ["attachTo", "disabled", "config"];
1953
- function readAppExtensionsConfig(rootConfig) {
1954
- const arr = rootConfig.getOptional("app.extensions");
1955
- if (!Array.isArray(arr)) {
1956
- if (arr === void 0) {
1957
- return [];
1958
- }
1959
- rootConfig.getConfigArray("app.extensions");
1960
- return [];
1961
- }
1962
- return arr.map(
1963
- (arrayEntry, arrayIndex) => expandShorthandExtensionParameters(arrayEntry, arrayIndex)
1964
- );
1965
- }
1966
- function expandShorthandExtensionParameters(arrayEntry, arrayIndex) {
1967
- function errorMsg(msg, key, prop) {
1968
- return `Invalid extension configuration at app.extensions[${arrayIndex}]${key ? `[${key}]` : ""}${prop ? `.${prop}` : ""}, ${msg}`;
1969
- }
1970
- function assertValidId(id2) {
1971
- if (!id2 || id2 !== id2.trim()) {
1972
- throw new Error(
1973
- errorMsg("extension ID must not be empty or contain whitespace")
1974
- );
1975
- }
1976
- }
1977
- if (typeof arrayEntry === "string") {
1978
- assertValidId(arrayEntry);
1979
- return {
1980
- id: arrayEntry,
1981
- disabled: false
1982
- };
1983
- }
1984
- if (typeof arrayEntry !== "object" || arrayEntry === null || Array.isArray(arrayEntry)) {
1985
- throw new Error(errorMsg("must be a string or an object"));
1986
- }
1987
- const keys = Object.keys(arrayEntry);
1988
- if (keys.length !== 1) {
1989
- const joinedKeys = keys.length ? `'${keys.join("', '")}'` : "none";
1990
- throw new Error(errorMsg(`must have exactly one key, got ${joinedKeys}`));
1991
- }
1992
- const id = String(keys[0]);
1993
- const value = arrayEntry[id];
1994
- assertValidId(id);
1995
- if (value === null) {
1996
- return {
1997
- id,
1998
- disabled: false
1999
- };
2000
- }
2001
- if (typeof value === "boolean") {
2002
- return {
2003
- id,
2004
- disabled: !value
2005
- };
2006
- }
2007
- if (typeof value !== "object" || Array.isArray(value)) {
2008
- throw new Error(errorMsg("value must be a boolean or object", id));
2009
- }
2010
- const attachTo = value.attachTo;
2011
- const disabled = value.disabled;
2012
- const config = value.config;
2013
- if (attachTo !== void 0) {
2014
- if (attachTo === null || typeof attachTo !== "object" || Array.isArray(attachTo)) {
2015
- throw new Error(errorMsg("must be an object", id, "attachTo"));
2016
- }
2017
- if (typeof attachTo.id !== "string" || attachTo.id === "") {
2018
- throw new Error(
2019
- errorMsg("must be a non-empty string", id, "attachTo.id")
2020
- );
2021
- }
2022
- if (typeof attachTo.input !== "string" || attachTo.input === "") {
2023
- throw new Error(
2024
- errorMsg("must be a non-empty string", id, "attachTo.input")
2025
- );
2026
- }
2027
- }
2028
- if (disabled !== void 0 && typeof disabled !== "boolean") {
2029
- throw new Error(errorMsg("must be a boolean", id, "disabled"));
2030
- }
2031
- if (config !== void 0 && (typeof config !== "object" || config === null || Array.isArray(config))) {
2032
- throw new Error(errorMsg("must be an object", id, "config"));
2033
- }
2034
- const unknownKeys = Object.keys(value).filter(
2035
- (k) => !knownExtensionParameters.includes(k)
2036
- );
2037
- if (unknownKeys.length > 0) {
2038
- throw new Error(
2039
- errorMsg(
2040
- `unknown parameter; expected one of '${knownExtensionParameters.join(
2041
- "', '"
2042
- )}'`,
2043
- id,
2044
- unknownKeys.join(", ")
2045
- )
2046
- );
2047
- }
2048
- return {
2049
- id,
2050
- attachTo,
2051
- disabled,
2052
- config
2053
- };
2054
- }
2055
-
2056
- var __defProp = Object.defineProperty;
2057
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2058
- var __publicField = (obj, key, value) => {
2059
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
2060
- return value;
2061
- };
2062
- function indent(str) {
2063
- return str.replace(/^/gm, " ");
2064
- }
2065
- class SerializableAppNode {
2066
- constructor(spec) {
2067
- __publicField(this, "spec");
2068
- __publicField(this, "edges", {
2069
- attachedTo: void 0,
2070
- attachments: /* @__PURE__ */ new Map()
2071
- });
2072
- __publicField(this, "instance");
2073
- this.spec = spec;
2074
- }
2075
- setParent(parent) {
2076
- const input = this.spec.attachTo.input;
2077
- this.edges.attachedTo = { node: parent, input };
2078
- const parentInputEdges = parent.edges.attachments.get(input);
2079
- if (parentInputEdges) {
2080
- parentInputEdges.push(this);
2081
- } else {
2082
- parent.edges.attachments.set(input, [this]);
2083
- }
2084
- }
2085
- toJSON() {
2086
- const dataRefs = this.instance && [...this.instance.getDataRefs()];
2087
- return {
2088
- id: this.spec.id,
2089
- output: dataRefs && dataRefs.length > 0 ? dataRefs.map((ref) => ref.id) : void 0,
2090
- attachments: this.edges.attachments.size > 0 ? Object.fromEntries(this.edges.attachments) : void 0
2091
- };
2092
- }
2093
- toString() {
2094
- const dataRefs = this.instance && [...this.instance.getDataRefs()];
2095
- const out = dataRefs && dataRefs.length > 0 ? ` out=[${[...dataRefs].map((r) => r.id).join(", ")}]` : "";
2096
- if (this.edges.attachments.size === 0) {
2097
- return `<${this.spec.id}${out} />`;
2098
- }
2099
- return [
2100
- `<${this.spec.id}${out}>`,
2101
- ...[...this.edges.attachments.entries()].map(
2102
- ([k, v]) => indent([`${k} [`, ...v.map((e) => indent(e.toString())), `]`].join("\n"))
2103
- ),
2104
- `</${this.spec.id}>`
2105
- ].join("\n");
2106
- }
2107
- }
2108
- function resolveAppTree(rootNodeId, specs) {
2109
- const nodes = /* @__PURE__ */ new Map();
2110
- let rootNode = void 0;
2111
- const orphansByParent = /* @__PURE__ */ new Map();
2112
- for (const spec of specs) {
2113
- if (nodes.has(spec.id)) {
2114
- throw new Error(`Unexpected duplicate extension id '${spec.id}'`);
2115
- }
2116
- const node = new SerializableAppNode(spec);
2117
- nodes.set(spec.id, node);
2118
- if (spec.id === rootNodeId) {
2119
- rootNode = node;
2120
- } else {
2121
- const parent = nodes.get(spec.attachTo.id);
2122
- if (parent) {
2123
- node.setParent(parent);
2124
- } else {
2125
- const orphanNodesForParent = orphansByParent.get(spec.attachTo.id);
2126
- if (orphanNodesForParent) {
2127
- orphanNodesForParent.push(node);
2128
- } else {
2129
- orphansByParent.set(spec.attachTo.id, [node]);
2130
- }
2131
- }
2132
- }
2133
- const orphanedChildren = orphansByParent.get(spec.id);
2134
- if (orphanedChildren) {
2135
- orphansByParent.delete(spec.id);
2136
- for (const orphan of orphanedChildren) {
2137
- orphan.setParent(node);
2138
- }
2139
- }
2140
- }
2141
- if (!rootNode) {
2142
- throw new Error(`No root node with id '${rootNodeId}' found in app tree`);
2143
- }
2144
- return {
2145
- root: rootNode,
2146
- nodes,
2147
- orphans: Array.from(orphansByParent.values()).flat()
2148
- };
2149
- }
2150
-
2151
- function toInternalExtensionOverrides(overrides) {
2152
- const internal = overrides;
2153
- if (internal.$$type !== "@backstage/ExtensionOverrides") {
2154
- throw new Error(
2155
- `Invalid extension overrides instance, bad type '${internal.$$type}'`
2156
- );
2157
- }
2158
- if (internal.version !== "v1") {
2159
- throw new Error(
2160
- `Invalid extension overrides instance, bad version '${internal.version}'`
2161
- );
2162
- }
2163
- return internal;
2164
- }
2165
-
2166
- function toInternalBackstagePlugin(plugin) {
2167
- const internal = plugin;
2168
- if (internal.$$type !== "@backstage/BackstagePlugin") {
2169
- throw new Error(`Invalid plugin instance, bad type '${internal.$$type}'`);
2170
- }
2171
- if (internal.version !== "v1") {
2172
- throw new Error(
2173
- `Invalid plugin instance, bad version '${internal.version}'`
2174
- );
2175
- }
2176
- return internal;
2177
- }
2178
-
2179
- function resolveAppNodeSpecs(options) {
2180
- var _a;
2181
- const {
2182
- builtinExtensions = [],
2183
- parameters = [],
2184
- forbidden = /* @__PURE__ */ new Set(),
2185
- features = []
2186
- } = options;
2187
- const plugins = features.filter(
2188
- (f) => f.$$type === "@backstage/BackstagePlugin"
2189
- );
2190
- const overrides = features.filter(
2191
- (f) => f.$$type === "@backstage/ExtensionOverrides"
2192
- );
2193
- const pluginExtensions = plugins.flatMap((source) => {
2194
- return toInternalBackstagePlugin(source).extensions.map((extension) => ({
2195
- ...extension,
2196
- source
2197
- }));
2198
- });
2199
- const overrideExtensions = overrides.flatMap(
2200
- (override) => toInternalExtensionOverrides(override).extensions
2201
- );
2202
- if (pluginExtensions.some(({ id }) => forbidden.has(id))) {
2203
- const pluginsStr = pluginExtensions.filter(({ id }) => forbidden.has(id)).map(({ source }) => `'${source.id}'`).join(", ");
2204
- const forbiddenStr = [...forbidden].map((id) => `'${id}'`).join(", ");
2205
- throw new Error(
2206
- `It is forbidden to override the following extension(s): ${forbiddenStr}, which is done by the following plugin(s): ${pluginsStr}`
2207
- );
2208
- }
2209
- if (overrideExtensions.some(({ id }) => forbidden.has(id))) {
2210
- const forbiddenStr = [...forbidden].map((id) => `'${id}'`).join(", ");
2211
- throw new Error(
2212
- `It is forbidden to override the following extension(s): ${forbiddenStr}, which is done by one or more extension overrides`
2213
- );
2214
- }
2215
- const overrideExtensionIds = overrideExtensions.map(({ id }) => id);
2216
- if (overrideExtensionIds.length !== new Set(overrideExtensionIds).size) {
2217
- const counts = /* @__PURE__ */ new Map();
2218
- for (const id of overrideExtensionIds) {
2219
- counts.set(id, ((_a = counts.get(id)) != null ? _a : 0) + 1);
2220
- }
2221
- const duplicated = Array.from(counts.entries()).filter(([, count]) => count > 1).map(([id]) => id);
2222
- throw new Error(
2223
- `The following extensions had duplicate overrides: ${duplicated.join(
2224
- ", "
2225
- )}`
2226
- );
2227
- }
2228
- const configuredExtensions = [
2229
- ...pluginExtensions.map(({ source, ...extension }) => {
2230
- const internalExtension = toInternalExtension(extension);
2231
- return {
2232
- extension: internalExtension,
2233
- params: {
2234
- source,
2235
- attachTo: internalExtension.attachTo,
2236
- disabled: internalExtension.disabled,
2237
- config: void 0
2238
- }
2239
- };
2240
- }),
2241
- ...builtinExtensions.map((extension) => {
2242
- const internalExtension = toInternalExtension(extension);
2243
- return {
2244
- extension: internalExtension,
2245
- params: {
2246
- source: void 0,
2247
- attachTo: internalExtension.attachTo,
2248
- disabled: internalExtension.disabled,
2249
- config: void 0
2250
- }
2251
- };
2252
- })
2253
- ];
2254
- for (const extension of overrideExtensions) {
2255
- const internalExtension = toInternalExtension(extension);
2256
- const index = configuredExtensions.findIndex(
2257
- (e) => e.extension.id === extension.id
2258
- );
2259
- if (index !== -1) {
2260
- configuredExtensions[index].extension = internalExtension;
2261
- configuredExtensions[index].params.attachTo = internalExtension.attachTo;
2262
- configuredExtensions[index].params.disabled = internalExtension.disabled;
2263
- } else {
2264
- configuredExtensions.push({
2265
- extension: internalExtension,
2266
- params: {
2267
- source: void 0,
2268
- attachTo: internalExtension.attachTo,
2269
- disabled: internalExtension.disabled,
2270
- config: void 0
2271
- }
2272
- });
2273
- }
2274
- }
2275
- const duplicatedExtensionIds = /* @__PURE__ */ new Set();
2276
- const duplicatedExtensionData = configuredExtensions.reduce((data, { extension, params }) => {
2277
- var _a2, _b, _c;
2278
- const extensionId = extension.id;
2279
- const extensionData = data == null ? void 0 : data[extensionId];
2280
- if (extensionData)
2281
- duplicatedExtensionIds.add(extensionId);
2282
- const pluginId = (_b = (_a2 = params.source) == null ? void 0 : _a2.id) != null ? _b : "internal";
2283
- const pluginCount = (_c = extensionData == null ? void 0 : extensionData[pluginId]) != null ? _c : 0;
2284
- return {
2285
- ...data,
2286
- [extensionId]: { ...extensionData, [pluginId]: pluginCount + 1 }
2287
- };
2288
- }, {});
2289
- if (duplicatedExtensionIds.size > 0) {
2290
- throw new Error(
2291
- `The following extensions are duplicated: ${Array.from(
2292
- duplicatedExtensionIds
2293
- ).map(
2294
- (extensionId) => `The extension '${extensionId}' was provided ${Object.keys(
2295
- duplicatedExtensionData[extensionId]
2296
- ).map(
2297
- (pluginId) => `${duplicatedExtensionData[extensionId][pluginId]} time(s) by the plugin '${pluginId}'`
2298
- ).join(" and ")}`
2299
- ).join(", ")}`
2300
- );
2301
- }
2302
- for (const overrideParam of parameters) {
2303
- const extensionId = overrideParam.id;
2304
- if (forbidden.has(extensionId)) {
2305
- throw new Error(
2306
- `Configuration of the '${extensionId}' extension is forbidden`
2307
- );
2308
- }
2309
- const existingIndex = configuredExtensions.findIndex(
2310
- (e) => e.extension.id === extensionId
2311
- );
2312
- if (existingIndex !== -1) {
2313
- const existing = configuredExtensions[existingIndex];
2314
- if (overrideParam.attachTo) {
2315
- existing.params.attachTo = overrideParam.attachTo;
2316
- }
2317
- if (overrideParam.config) {
2318
- existing.params.config = overrideParam.config;
2319
- }
2320
- if (Boolean(existing.params.disabled) !== Boolean(overrideParam.disabled)) {
2321
- existing.params.disabled = Boolean(overrideParam.disabled);
2322
- if (!existing.params.disabled) {
2323
- configuredExtensions.splice(existingIndex, 1);
2324
- configuredExtensions.push(existing);
2325
- }
2326
- }
2327
- } else {
2328
- throw new Error(`Extension ${extensionId} does not exist`);
2329
- }
2330
- }
2331
- return configuredExtensions.map((param) => ({
2332
- id: param.extension.id,
2333
- attachTo: param.params.attachTo,
2334
- extension: param.extension,
2335
- disabled: param.params.disabled,
2336
- source: param.params.source,
2337
- config: param.params.config
2338
- }));
2339
- }
2340
-
2341
- function resolveInputData(dataMap, attachment, inputName) {
2342
- return mapValues(dataMap, (ref) => {
2343
- var _a, _b, _c;
2344
- const value = (_a = attachment.instance) == null ? void 0 : _a.getData(ref);
2345
- if (value === void 0 && !ref.config.optional) {
2346
- const expected = Object.values(dataMap).filter((r) => !r.config.optional).map((r) => `'${r.id}'`).join(", ");
2347
- const provided = [...(_c = (_b = attachment.instance) == null ? void 0 : _b.getDataRefs()) != null ? _c : []].map((r) => `'${r.id}'`).join(", ");
2348
- throw new Error(
2349
- `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`
2350
- );
2351
- }
2352
- return value;
2353
- });
2354
- }
2355
- function resolveInputs(id, inputMap, attachments) {
2356
- const undeclaredAttachments = Array.from(attachments.entries()).filter(
2357
- ([inputName]) => inputMap[inputName] === void 0
2358
- );
2359
- if (process.env.NODE_ENV !== "production") {
2360
- const inputNames = Object.keys(inputMap);
2361
- for (const [name, nodes] of undeclaredAttachments) {
2362
- const pl = nodes.length > 1;
2363
- console.warn(
2364
- [
2365
- `The extension${pl ? "s" : ""} '${nodes.map((n) => n.spec.id).join("', '")}' ${pl ? "are" : "is"}`,
2366
- `attached to the input '${name}' of the extension '${id}', but it`,
2367
- inputNames.length === 0 ? "has no inputs" : `has no such input (candidates are '${inputNames.join("', '")}')`
2368
- ].join(" ")
2369
- );
2370
- }
2371
- }
2372
- return mapValues(inputMap, (input, inputName) => {
2373
- var _a;
2374
- const attachedNodes = (_a = attachments.get(inputName)) != null ? _a : [];
2375
- if (input.config.singleton) {
2376
- if (attachedNodes.length > 1) {
2377
- const attachedNodeIds = attachedNodes.map((e) => e.spec.id);
2378
- throw Error(
2379
- `expected ${input.config.optional ? "at most" : "exactly"} one '${inputName}' input but received multiple: '${attachedNodeIds.join(
2380
- "', '"
2381
- )}'`
2382
- );
2383
- } else if (attachedNodes.length === 0) {
2384
- if (input.config.optional) {
2385
- return void 0;
2386
- }
2387
- throw Error(`input '${inputName}' is required but was not received`);
2388
- }
2389
- return {
2390
- node: attachedNodes[0],
2391
- output: resolveInputData(
2392
- input.extensionData,
2393
- attachedNodes[0],
2394
- inputName
2395
- )
2396
- };
2397
- }
2398
- return attachedNodes.map((attachment) => ({
2399
- node: attachment,
2400
- output: resolveInputData(input.extensionData, attachment, inputName)
2401
- }));
2402
- });
2403
- }
2404
- function createAppNodeInstance(options) {
2405
- var _a;
2406
- const { node, attachments } = options;
2407
- const { id, extension, config } = node.spec;
2408
- const extensionData = /* @__PURE__ */ new Map();
2409
- const extensionDataRefs = /* @__PURE__ */ new Set();
2410
- let parsedConfig;
2411
- try {
2412
- parsedConfig = (_a = extension.configSchema) == null ? void 0 : _a.parse(config != null ? config : {});
2413
- } catch (e) {
2414
- throw new Error(
2415
- `Invalid configuration for extension '${id}'; caused by ${e}`
2416
- );
2417
- }
2418
- try {
2419
- const internalExtension = toInternalExtension(extension);
2420
- const namedOutputs = internalExtension.factory({
2421
- node,
2422
- config: parsedConfig,
2423
- inputs: resolveInputs(id, internalExtension.inputs, attachments)
2424
- });
2425
- for (const [name, output] of Object.entries(namedOutputs)) {
2426
- const ref = internalExtension.output[name];
2427
- if (!ref) {
2428
- throw new Error(`unknown output provided via '${name}'`);
2429
- }
2430
- if (extensionData.has(ref.id)) {
2431
- throw new Error(
2432
- `duplicate extension data '${ref.id}' received via output '${name}'`
2433
- );
2434
- }
2435
- extensionData.set(ref.id, output);
2436
- extensionDataRefs.add(ref);
2437
- }
2438
- } catch (e) {
2439
- throw new Error(
2440
- `Failed to instantiate extension '${id}'${e.name === "Error" ? `, ${e.message}` : `; caused by ${e.stack}`}`
2441
- );
2442
- }
2443
- return {
2444
- getDataRefs() {
2445
- return extensionDataRefs.values();
2446
- },
2447
- getData(ref) {
2448
- return extensionData.get(ref.id);
2449
- }
2450
- };
2451
- }
2452
- function instantiateAppNodeTree(rootNode) {
2453
- function createInstance(node) {
2454
- if (node.instance) {
2455
- return node.instance;
2456
- }
2457
- if (node.spec.disabled) {
2458
- return void 0;
2459
- }
2460
- const instantiatedAttachments = /* @__PURE__ */ new Map();
2461
- for (const [input, children] of node.edges.attachments) {
2462
- const instantiatedChildren = children.flatMap((child) => {
2463
- const childInstance = createInstance(child);
2464
- if (!childInstance) {
2465
- return [];
2466
- }
2467
- return [child];
2468
- });
2469
- if (instantiatedChildren.length > 0) {
2470
- instantiatedAttachments.set(input, instantiatedChildren);
2471
- }
2472
- }
2473
- node.instance = createAppNodeInstance({
2474
- node,
2475
- attachments: instantiatedAttachments
2476
- });
2477
- return node.instance;
2478
- }
2479
- createInstance(rootNode);
2480
- }
2481
-
2482
- function createAppTree(options) {
2483
- const tree = resolveAppTree(
2484
- "app",
2485
- resolveAppNodeSpecs({
2486
- features: options.features,
2487
- builtinExtensions: options.builtinExtensions,
2488
- parameters: readAppExtensionsConfig(options.config),
2489
- forbidden: /* @__PURE__ */ new Set(["app"])
2490
- })
2491
- );
2492
- instantiateAppNodeTree(tree.root);
2493
- return tree;
2494
- }
2495
-
2496
- const DefaultProgressComponent = createComponentExtension({
2497
- ref: coreComponentRefs.progress,
2498
- loader: { sync: () => components.Progress }
2499
- });
2500
- const DefaultNotFoundErrorPageComponent = createComponentExtension({
2501
- ref: coreComponentRefs.notFoundErrorPage,
2502
- loader: { sync: () => components.NotFoundErrorPage }
2503
- });
2504
- const DefaultErrorBoundaryComponent = createComponentExtension({
2505
- ref: coreComponentRefs.errorBoundaryFallback,
2506
- loader: {
2507
- sync: () => (props) => {
2508
- const { plugin, error, resetError } = props;
2509
- const title = `Error in ${plugin == null ? void 0 : plugin.id}`;
2510
- return /* @__PURE__ */ React.createElement(ErrorPanel, { title, error, defaultExpanded: true }, /* @__PURE__ */ React.createElement(Button, { variant: "outlined", onClick: resetError }, "Retry"));
2511
- }
2512
- }
2513
- });
2514
-
2515
- const InternalAppContext = createContext(void 0);
2516
-
2517
- const getExtensionContext = (pathname, routes) => {
2518
- var _a, _b;
2519
- try {
2520
- const matches = matchRoutes(routes, { pathname });
2521
- const routeMatch = matches == null ? void 0 : matches.filter((match) => {
2522
- var _a2;
2523
- return ((_a2 = match == null ? void 0 : match.route.routeRefs) == null ? void 0 : _a2.size) > 0;
2524
- }).pop();
2525
- const routeObject = routeMatch == null ? void 0 : routeMatch.route;
2526
- if (!routeObject) {
2527
- return void 0;
2528
- }
2529
- if (routeObject.path === "" && pathname !== "/") {
2530
- return void 0;
2531
- }
2532
- const params = Object.entries(
2533
- (routeMatch == null ? void 0 : routeMatch.params) || {}
2534
- ).reduce((acc, [key, value]) => {
2535
- if (value !== void 0 && key !== "*") {
2536
- acc[key] = value;
2537
- }
2538
- return acc;
2539
- }, {});
2540
- const plugin = (_a = routeObject.appNode) == null ? void 0 : _a.spec.source;
2541
- const extension = (_b = routeObject.appNode) == null ? void 0 : _b.spec.extension;
2542
- return {
2543
- params,
2544
- pluginId: (plugin == null ? void 0 : plugin.id) || "root",
2545
- extensionId: (extension == null ? void 0 : extension.id) || "App"
2546
- };
2547
- } catch {
2548
- return void 0;
2549
- }
2550
- };
2551
- const TrackNavigation = ({
2552
- pathname,
2553
- search,
2554
- hash,
2555
- attributes
2556
- }) => {
2557
- const analytics = useAnalytics();
2558
- useEffect(() => {
2559
- analytics.captureEvent("navigate", `${pathname}${search}${hash}`, {
2560
- attributes
2561
- });
2562
- }, [analytics, pathname, search, hash, attributes]);
2563
- return null;
2564
- };
2565
- const RouteTracker = ({
2566
- routeObjects
2567
- }) => {
2568
- const { pathname, search, hash } = useLocation();
2569
- const { params, ...attributes } = getExtensionContext(
2570
- pathname,
2571
- routeObjects
2572
- ) || { params: {} };
2573
- return /* @__PURE__ */ React.createElement(AnalyticsContext, { attributes }, /* @__PURE__ */ React.createElement(
2574
- TrackNavigation,
2575
- {
2576
- pathname,
2577
- search,
2578
- hash,
2579
- attributes: params
2580
- }
2581
- ));
2582
- };
2583
-
2584
- function getBasePath(configApi) {
2585
- var _a;
2586
- let { pathname } = new URL(
2587
- (_a = configApi.getOptionalString("app.baseUrl")) != null ? _a : "/",
2588
- "http://sample.dev"
2589
- // baseUrl can be specified as just a path
2590
- );
2591
- pathname = pathname.replace(/\/*$/, "");
2592
- return pathname;
2593
- }
2594
-
2595
- const AppRoot = createExtension({
2596
- namespace: "app",
2597
- name: "root",
2598
- attachTo: { id: "app", input: "root" },
2599
- inputs: {
2600
- router: createExtensionInput(
2601
- { component: createRouterExtension.componentDataRef },
2602
- { singleton: true, optional: true }
2603
- ),
2604
- signInPage: createExtensionInput(
2605
- { component: createSignInPageExtension.componentDataRef },
2606
- { singleton: true, optional: true }
2607
- ),
2608
- children: createExtensionInput(
2609
- { element: coreExtensionData.reactElement },
2610
- { singleton: true }
2611
- ),
2612
- elements: createExtensionInput({
2613
- element: coreExtensionData.reactElement
2614
- }),
2615
- wrappers: createExtensionInput({
2616
- component: createAppRootWrapperExtension.componentDataRef
2617
- })
2618
- },
2619
- output: {
2620
- element: coreExtensionData.reactElement
2621
- },
2622
- factory({ inputs }) {
2623
- var _a, _b;
2624
- let content = /* @__PURE__ */ React.createElement(React.Fragment, null, inputs.elements.map((el) => /* @__PURE__ */ React.createElement(Fragment, { key: el.node.spec.id }, el.output.element)), inputs.children.output.element);
2625
- for (const wrapper of inputs.wrappers) {
2626
- content = /* @__PURE__ */ React.createElement(wrapper.output.component, null, content);
2627
- }
2628
- return {
2629
- element: /* @__PURE__ */ React.createElement(
2630
- AppRouter,
2631
- {
2632
- SignInPageComponent: (_a = inputs.signInPage) == null ? void 0 : _a.output.component,
2633
- RouterComponent: (_b = inputs.router) == null ? void 0 : _b.output.component
2634
- },
2635
- content
2636
- )
2637
- };
2638
- }
2639
- });
2640
- function SignInPageWrapper({
2641
- component: Component,
2642
- appIdentityProxy,
2643
- children
2644
- }) {
2645
- const [identityApi, setIdentityApi] = useState();
2646
- const configApi = useApi(configApiRef);
2647
- const basePath = getBasePath(configApi);
2648
- if (!identityApi) {
2649
- return /* @__PURE__ */ React.createElement(Component, { onSignInSuccess: setIdentityApi });
2650
- }
2651
- appIdentityProxy.setTarget(identityApi, {
2652
- signOutTargetUrl: basePath || "/"
2653
- });
2654
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
2655
- }
2656
- function DefaultRouter(props) {
2657
- const configApi = useApi(configApiRef);
2658
- const basePath = getBasePath(configApi);
2659
- return /* @__PURE__ */ React.createElement(BrowserRouter, { basename: basePath }, props.children);
2660
- }
2661
- function AppRouter(props) {
2662
- const {
2663
- children,
2664
- SignInPageComponent,
2665
- RouterComponent = DefaultRouter
2666
- } = props;
2667
- const configApi = useApi(configApiRef);
2668
- const basePath = getBasePath(configApi);
2669
- const internalAppContext = useContext(InternalAppContext);
2670
- if (!internalAppContext) {
2671
- throw new Error("AppRouter must be rendered within the AppProvider");
2672
- }
2673
- const { routeObjects, appIdentityProxy } = internalAppContext;
2674
- if (!SignInPageComponent) {
2675
- appIdentityProxy.setTarget(
2676
- {
2677
- getUserId: () => "guest",
2678
- getIdToken: async () => void 0,
2679
- getProfile: () => ({
2680
- email: "guest@example.com",
2681
- displayName: "Guest"
2682
- }),
2683
- getProfileInfo: async () => ({
2684
- email: "guest@example.com",
2685
- displayName: "Guest"
2686
- }),
2687
- getBackstageIdentity: async () => ({
2688
- type: "user",
2689
- userEntityRef: "user:default/guest",
2690
- ownershipEntityRefs: ["user:default/guest"]
2691
- }),
2692
- getCredentials: async () => ({}),
2693
- signOut: async () => {
2694
- }
2695
- },
2696
- { signOutTargetUrl: basePath || "/" }
2697
- );
2698
- return /* @__PURE__ */ React.createElement(RouterComponent, null, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), children);
2699
- }
2700
- return /* @__PURE__ */ React.createElement(RouterComponent, null, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), /* @__PURE__ */ React.createElement(
2701
- SignInPageWrapper,
2702
- {
2703
- component: SignInPageComponent,
2704
- appIdentityProxy
2705
- },
2706
- children
2707
- ));
2708
- }
2709
-
2710
- var __accessCheck$1 = (obj, member, msg) => {
2711
- if (!member.has(obj))
2712
- throw TypeError("Cannot " + msg);
2713
- };
2714
- var __privateGet$1 = (obj, member, getter) => {
2715
- __accessCheck$1(obj, member, "read from private field");
2716
- return getter ? getter.call(obj) : member.get(obj);
2717
- };
2718
- var __privateAdd$1 = (obj, member, value) => {
2719
- if (member.has(obj))
2720
- throw TypeError("Cannot add the same private member more than once");
2721
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2722
- };
2723
- var __privateSet$1 = (obj, member, value, setter) => {
2724
- __accessCheck$1(obj, member, "write to private field");
2725
- setter ? setter.call(obj, value) : member.set(obj, value);
2726
- return value;
2727
- };
2728
- var _components;
2729
- const _DefaultComponentsApi = class _DefaultComponentsApi {
2730
- constructor(components) {
2731
- __privateAdd$1(this, _components, void 0);
2732
- __privateSet$1(this, _components, components);
2733
- }
2734
- static fromTree(tree) {
2735
- var _a;
2736
- const componentEntries = (_a = tree.root.edges.attachments.get("components")) == null ? void 0 : _a.reduce((map, e) => {
2737
- var _a2;
2738
- const data = (_a2 = e.instance) == null ? void 0 : _a2.getData(
2739
- createComponentExtension.componentDataRef
2740
- );
2741
- if (data) {
2742
- map.set(data.ref.id, data.impl);
2743
- }
2744
- return map;
2745
- }, /* @__PURE__ */ new Map());
2746
- return new _DefaultComponentsApi(componentEntries != null ? componentEntries : /* @__PURE__ */ new Map());
2747
- }
2748
- getComponent(ref) {
2749
- const impl = __privateGet$1(this, _components).get(ref.id);
2750
- if (!impl) {
2751
- throw new Error(`No implementation found for component ref ${ref}`);
2752
- }
2753
- return impl;
2754
- }
2755
- };
2756
- _components = new WeakMap();
2757
- let DefaultComponentsApi = _DefaultComponentsApi;
2758
-
2759
- var __accessCheck = (obj, member, msg) => {
2760
- if (!member.has(obj))
2761
- throw TypeError("Cannot " + msg);
2762
- };
2763
- var __privateGet = (obj, member, getter) => {
2764
- __accessCheck(obj, member, "read from private field");
2765
- return getter ? getter.call(obj) : member.get(obj);
2766
- };
2767
- var __privateAdd = (obj, member, value) => {
2768
- if (member.has(obj))
2769
- throw TypeError("Cannot add the same private member more than once");
2770
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2771
- };
2772
- var __privateSet = (obj, member, value, setter) => {
2773
- __accessCheck(obj, member, "write to private field");
2774
- setter ? setter.call(obj, value) : member.set(obj, value);
2775
- return value;
2776
- };
2777
- var _icons;
2778
- class DefaultIconsApi {
2779
- constructor(icons) {
2780
- __privateAdd(this, _icons, void 0);
2781
- __privateSet(this, _icons, new Map(Object.entries(icons)));
2782
- }
2783
- getIcon(key) {
2784
- return __privateGet(this, _icons).get(key);
2785
- }
2786
- listIconKeys() {
2787
- return Array.from(__privateGet(this, _icons).keys());
2788
- }
2789
- }
2790
- _icons = new WeakMap();
2791
-
2792
- const DefaultApis = apis.map((factory) => createApiExtension({ factory }));
2793
- const builtinExtensions = [
2794
- App,
2795
- AppRoot,
2796
- AppRoutes,
2797
- AppNav,
2798
- AppLayout,
2799
- DefaultProgressComponent,
2800
- DefaultErrorBoundaryComponent,
2801
- DefaultNotFoundErrorPageComponent,
2802
- LightTheme,
2803
- DarkTheme,
2804
- oauthRequestDialogAppRootElement,
2805
- alertDisplayAppRootElement,
2806
- ...DefaultApis
2807
- ].map((def) => resolveExtensionDefinition(def));
2808
- function deduplicateFeatures(allFeatures) {
2809
- const features = Array.from(new Set(allFeatures));
2810
- const seenIds = /* @__PURE__ */ new Set();
2811
- return features.reverse().filter((feature) => {
2812
- if (feature.$$type !== "@backstage/BackstagePlugin") {
2813
- return true;
2814
- }
2815
- if (seenIds.has(feature.id)) {
2816
- return false;
2817
- }
2818
- seenIds.add(feature.id);
2819
- return true;
2820
- }).reverse();
2821
- }
2822
- function createApp(options) {
2823
- let suspenseFallback = options == null ? void 0 : options.loadingComponent;
2824
- if (suspenseFallback === void 0) {
2825
- suspenseFallback = "Loading...";
2826
- }
2827
- async function appLoader() {
2828
- var _a, _b, _c;
2829
- const config = (_b = await ((_a = options == null ? void 0 : options.configLoader) == null ? void 0 : _a.call(options).then((c) => c.config))) != null ? _b : ConfigReader.fromConfigs(
2830
- overrideBaseUrlConfigs(defaultConfigLoaderSync())
2831
- );
2832
- const discoveredFeatures = getAvailableFeatures(config);
2833
- const providedFeatures = [];
2834
- for (const entry of (_c = options == null ? void 0 : options.features) != null ? _c : []) {
2835
- if ("load" in entry) {
2836
- try {
2837
- const result = await entry.load({ config });
2838
- providedFeatures.push(...result.features);
2839
- } catch (e) {
2840
- throw new Error(
2841
- `Failed to read frontend features from loader '${entry.getLoaderName()}', ${stringifyError(
2842
- e
2843
- )}`
2844
- );
2845
- }
2846
- } else {
2847
- providedFeatures.push(entry);
2848
- }
2849
- }
2850
- const app = createSpecializedApp({
2851
- icons: options == null ? void 0 : options.icons,
2852
- config,
2853
- features: [...discoveredFeatures, ...providedFeatures],
2854
- bindRoutes: options == null ? void 0 : options.bindRoutes
2855
- }).createRoot();
2856
- return { default: () => app };
2857
- }
2858
- return {
2859
- createRoot() {
2860
- const LazyApp = React.lazy(appLoader);
2861
- return /* @__PURE__ */ React.createElement(React.Suspense, { fallback: suspenseFallback }, /* @__PURE__ */ React.createElement(LazyApp, null));
2862
- }
2863
- };
2864
- }
2865
- function createSpecializedApp(options) {
2866
- const {
2867
- features: duplicatedFeatures = [],
2868
- config = new ConfigReader({}, "empty-config")
2869
- } = options != null ? options : {};
2870
- const features = deduplicateFeatures(duplicatedFeatures);
2871
- const tree = createAppTree({
2872
- features,
2873
- builtinExtensions,
2874
- config
2875
- });
2876
- const routeInfo = extractRouteInfoFromAppNode(tree.root);
2877
- const routeBindings = resolveRouteBindings(
2878
- options == null ? void 0 : options.bindRoutes,
2879
- config,
2880
- collectRouteIds(features)
2881
- );
2882
- const appIdentityProxy = new AppIdentityProxy();
2883
- const apiHolder = createApiHolder(
2884
- tree,
2885
- config,
2886
- appIdentityProxy,
2887
- new RouteResolver(
2888
- routeInfo.routePaths,
2889
- routeInfo.routeParents,
2890
- routeInfo.routeObjects,
2891
- routeBindings,
2892
- getBasePath(config)
2893
- ),
2894
- options == null ? void 0 : options.icons
2895
- );
2896
- if (isProtectedApp()) {
2897
- const discoveryApi = apiHolder.get(discoveryApiRef);
2898
- const errorApi = apiHolder.get(errorApiRef);
2899
- const fetchApi = apiHolder.get(fetchApiRef);
2900
- if (!discoveryApi || !errorApi || !fetchApi) {
2901
- throw new Error(
2902
- "App is running in protected mode but missing required APIs"
2903
- );
2904
- }
2905
- appIdentityProxy.enableCookieAuth({
2906
- discoveryApi,
2907
- errorApi,
2908
- fetchApi
2909
- });
2910
- }
2911
- const featureFlagApi = apiHolder.get(featureFlagsApiRef);
2912
- if (featureFlagApi) {
2913
- for (const feature of features) {
2914
- if (feature.$$type === "@backstage/BackstagePlugin") {
2915
- toInternalBackstagePlugin(feature).featureFlags.forEach(
2916
- (flag) => featureFlagApi.registerFlag({
2917
- name: flag.name,
2918
- pluginId: feature.id
2919
- })
2920
- );
2921
- }
2922
- if (feature.$$type === "@backstage/ExtensionOverrides") {
2923
- toInternalExtensionOverrides(feature).featureFlags.forEach(
2924
- (flag) => featureFlagApi.registerFlag({ name: flag.name, pluginId: "" })
2925
- );
2926
- }
2927
- }
2928
- }
2929
- const rootEl = tree.root.instance.getData(coreExtensionData.reactElement);
2930
- const AppComponent = () => /* @__PURE__ */ React.createElement(ApiProvider, { apis: apiHolder }, /* @__PURE__ */ React.createElement(AppThemeProvider, null, /* @__PURE__ */ React.createElement(
2931
- InternalAppContext.Provider,
2932
- {
2933
- value: { appIdentityProxy, routeObjects: routeInfo.routeObjects }
2934
- },
2935
- rootEl
2936
- )));
2937
- return {
2938
- createRoot() {
2939
- return /* @__PURE__ */ React.createElement(AppComponent, null);
2940
- }
2941
- };
2942
- }
2943
- function createApiHolder(tree, configApi, appIdentityProxy, routeResolutionApi, icons$1) {
2944
- var _a, _b, _c, _d, _e, _f;
2945
- const factoryRegistry = new ApiFactoryRegistry();
2946
- const pluginApis = (_b = (_a = tree.root.edges.attachments.get("apis")) == null ? void 0 : _a.map((e) => {
2947
- var _a2;
2948
- return (_a2 = e.instance) == null ? void 0 : _a2.getData(createApiExtension.factoryDataRef);
2949
- }).filter((x) => !!x)) != null ? _b : [];
2950
- const themeExtensions = (_d = (_c = tree.root.edges.attachments.get("themes")) == null ? void 0 : _c.map((e) => {
2951
- var _a2;
2952
- return (_a2 = e.instance) == null ? void 0 : _a2.getData(createThemeExtension.themeDataRef);
2953
- }).filter((x) => !!x)) != null ? _d : [];
2954
- const translationResources = (_f = (_e = tree.root.edges.attachments.get("translations")) == null ? void 0 : _e.map(
2955
- (e) => {
2956
- var _a2;
2957
- return (_a2 = e.instance) == null ? void 0 : _a2.getData(createTranslationExtension.translationDataRef);
2958
- }
2959
- ).filter(
2960
- (x) => !!x
2961
- )) != null ? _f : [];
2962
- for (const factory of pluginApis) {
2963
- factoryRegistry.register("default", factory);
2964
- }
2965
- factoryRegistry.register("default", {
2966
- api: featureFlagsApiRef,
2967
- deps: {},
2968
- factory: () => new LocalStorageFeatureFlags()
2969
- });
2970
- factoryRegistry.register("static", {
2971
- api: identityApiRef,
2972
- deps: {},
2973
- factory: () => appIdentityProxy
2974
- });
2975
- factoryRegistry.register("static", {
2976
- api: appTreeApiRef,
2977
- deps: {},
2978
- factory: () => ({
2979
- getTree: () => ({ tree })
2980
- })
2981
- });
2982
- factoryRegistry.register("static", {
2983
- api: routeResolutionApiRef,
2984
- deps: {},
2985
- factory: () => routeResolutionApi
2986
- });
2987
- factoryRegistry.register("static", {
2988
- api: componentsApiRef,
2989
- deps: {},
2990
- factory: () => DefaultComponentsApi.fromTree(tree)
2991
- });
2992
- factoryRegistry.register("static", {
2993
- api: iconsApiRef,
2994
- deps: {},
2995
- factory: () => new DefaultIconsApi({ ...icons, ...icons$1 })
2996
- });
2997
- factoryRegistry.register("static", {
2998
- api: appThemeApiRef,
2999
- deps: {},
3000
- // TODO: add extension for registering themes
3001
- factory: () => AppThemeSelector.createWithStorage(themeExtensions)
3002
- });
3003
- factoryRegistry.register("static", {
3004
- api: appLanguageApiRef,
3005
- deps: {},
3006
- factory: () => AppLanguageSelector.createWithStorage()
3007
- });
3008
- factoryRegistry.register("static", {
3009
- api: configApiRef,
3010
- deps: {},
3011
- factory: () => configApi
3012
- });
3013
- factoryRegistry.register("static", {
3014
- api: appLanguageApiRef,
3015
- deps: {},
3016
- factory: () => AppLanguageSelector.createWithStorage()
3017
- });
3018
- factoryRegistry.register("static", {
3019
- api: translationApiRef,
3020
- deps: { languageApi: appLanguageApiRef },
3021
- factory: ({ languageApi }) => I18nextTranslationApi.create({
3022
- languageApi,
3023
- resources: translationResources
3024
- })
3025
- });
3026
- ApiResolver.validateFactories(factoryRegistry, factoryRegistry.getAllApis());
3027
- return new ApiResolver(factoryRegistry);
3028
- }
3029
-
3030
- export { createApp, createSpecializedApp };
1
+ export { createApp, createSpecializedApp } from './wiring/createApp.esm.js';
3031
2
  //# sourceMappingURL=index.esm.js.map