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