@backstage/frontend-app-api 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,40 +1,241 @@
1
- import React, { createContext } from 'react';
1
+ import React, { createContext, useMemo, useState, useEffect } from 'react';
2
2
  import { ConfigReader } from '@backstage/config';
3
- import { createExtension, coreExtensionData } from '@backstage/frontend-plugin-api';
4
- import { BrowserRouter, useRoutes } from 'react-router-dom';
3
+ import { createExtension, createExtensionInput, coreExtensionData } from '@backstage/frontend-plugin-api';
4
+ import { useRoutes, BrowserRouter, useInRouterContext, MemoryRouter, Route } from 'react-router-dom';
5
+ import { SidebarPage, sidebarConfig, Sidebar, SidebarDivider, SidebarItem, useSidebarOpenState, Link, Progress, ErrorPage, ErrorPanel } from '@backstage/core-components';
6
+ import { makeStyles } from '@material-ui/core';
7
+ import { GraphiQLIcon } from '@backstage/plugin-graphiql';
5
8
  import mapValues from 'lodash/mapValues';
9
+ import { useApi, appThemeApiRef, FeatureFlagState, createApiFactory, discoveryApiRef, configApiRef, alertApiRef, analyticsApiRef, errorApiRef, storageApiRef, fetchApiRef, identityApiRef, oauthRequestApiRef, googleAuthApiRef, microsoftAuthApiRef, githubAuthApiRef, oktaAuthApiRef, gitlabAuthApiRef, oneloginAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, atlassianAuthApiRef, attachComponentData, featureFlagsApiRef, useRouteRef } from '@backstage/core-plugin-api';
10
+ import { UrlPatternDiscovery, AlertApiForwarder, NoOpAnalyticsApi, ErrorAlerter, ErrorApiForwarder, UnhandledErrorForwarder, WebStorage, createFetchApi, FetchMiddlewares, OAuthRequestManager, GoogleAuth, MicrosoftAuth, GithubAuth, OktaAuth, GitlabAuth, OneLoginAuth, BitbucketAuth, BitbucketServerAuth, AtlassianAuth, ApiProvider, ApiFactoryRegistry, AppThemeSelector, ApiResolver } from '@backstage/core-app-api';
11
+ import useObservable from 'react-use/lib/useObservable';
12
+ import { createVersionedContext, createVersionedValueMap } from '@backstage/version-bridge';
13
+ import { permissionApiRef, IdentityPermissionApi } from '@backstage/plugin-permission-react';
14
+ import Button from '@material-ui/core/Button';
15
+ import MuiApartmentIcon from '@material-ui/icons/Apartment';
16
+ import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage';
17
+ import MuiCategoryIcon from '@material-ui/icons/Category';
18
+ import MuiCreateNewFolderIcon from '@material-ui/icons/CreateNewFolder';
19
+ import MuiSubjectIcon from '@material-ui/icons/Subject';
20
+ import MuiSearchIcon from '@material-ui/icons/Search';
21
+ import MuiChatIcon from '@material-ui/icons/Chat';
22
+ import MuiDashboardIcon from '@material-ui/icons/Dashboard';
23
+ import MuiDocsIcon from '@material-ui/icons/Description';
24
+ import MuiEmailIcon from '@material-ui/icons/Email';
25
+ import MuiExtensionIcon from '@material-ui/icons/Extension';
26
+ import MuiGitHubIcon from '@material-ui/icons/GitHub';
27
+ import MuiHelpIcon from '@material-ui/icons/Help';
28
+ import MuiLocationOnIcon from '@material-ui/icons/LocationOn';
29
+ import MuiMemoryIcon from '@material-ui/icons/Memory';
30
+ import MuiMenuBookIcon from '@material-ui/icons/MenuBook';
31
+ import MuiPeopleIcon from '@material-ui/icons/People';
32
+ import MuiPersonIcon from '@material-ui/icons/Person';
33
+ import MuiWarningIcon from '@material-ui/icons/Warning';
34
+ import MuiWorkIcon from '@material-ui/icons/Work';
35
+ import { UnifiedThemeProvider, themes as themes$1 } from '@backstage/theme';
36
+ import DarkIcon from '@material-ui/icons/Brightness2';
37
+ import LightIcon from '@material-ui/icons/WbSunny';
6
38
 
7
- const CoreRouter = createExtension({
8
- id: "core.router",
39
+ const Core = createExtension({
40
+ id: "core",
9
41
  at: "root",
10
42
  inputs: {
11
- routes: {
12
- extensionData: {
13
- path: coreExtensionData.routePath,
14
- ref: coreExtensionData.routeRef,
15
- component: coreExtensionData.reactComponent
16
- }
17
- }
43
+ apis: createExtensionInput({
44
+ api: coreExtensionData.apiFactory
45
+ })
46
+ },
47
+ output: {},
48
+ factory() {
49
+ }
50
+ });
51
+
52
+ const CoreRoutes = createExtension({
53
+ id: "core.routes",
54
+ at: "core.layout/content",
55
+ inputs: {
56
+ routes: createExtensionInput({
57
+ path: coreExtensionData.routePath,
58
+ ref: coreExtensionData.routeRef.optional(),
59
+ element: coreExtensionData.reactElement
60
+ })
18
61
  },
19
62
  output: {
20
- component: coreExtensionData.reactComponent
63
+ element: coreExtensionData.reactElement
21
64
  },
22
65
  factory({ bind, inputs }) {
23
66
  const Routes = () => {
24
67
  const element = useRoutes(
25
68
  inputs.routes.map((route) => ({
26
69
  path: route.path,
27
- element: /* @__PURE__ */ React.createElement(route.component, null)
70
+ element: route.element
28
71
  }))
29
72
  );
30
73
  return element;
31
74
  };
32
75
  bind({
33
- component: () => /* @__PURE__ */ React.createElement(BrowserRouter, null, /* @__PURE__ */ React.createElement(Routes, null))
76
+ element: /* @__PURE__ */ React.createElement(Routes, null)
77
+ });
78
+ }
79
+ });
80
+
81
+ const CoreLayout = createExtension({
82
+ id: "core.layout",
83
+ at: "root",
84
+ inputs: {
85
+ nav: createExtensionInput(
86
+ {
87
+ element: coreExtensionData.reactElement
88
+ },
89
+ { singleton: true }
90
+ ),
91
+ content: createExtensionInput(
92
+ {
93
+ element: coreExtensionData.reactElement
94
+ },
95
+ { singleton: true }
96
+ )
97
+ },
98
+ output: {
99
+ element: coreExtensionData.reactElement
100
+ },
101
+ factory({ bind, inputs }) {
102
+ bind({
103
+ element: /* @__PURE__ */ React.createElement(SidebarPage, null, inputs.nav.element, inputs.content.element)
104
+ });
105
+ }
106
+ });
107
+
108
+ const useStyles$1 = makeStyles({
109
+ svg: {
110
+ width: "auto",
111
+ height: 28
112
+ },
113
+ path: {
114
+ fill: "#7df3e1"
115
+ }
116
+ });
117
+ const LogoIcon = () => {
118
+ const classes = useStyles$1();
119
+ return /* @__PURE__ */ React.createElement(
120
+ "svg",
121
+ {
122
+ className: classes.svg,
123
+ xmlns: "http://www.w3.org/2000/svg",
124
+ viewBox: "0 0 337.46 428.5"
125
+ },
126
+ /* @__PURE__ */ React.createElement(
127
+ "path",
128
+ {
129
+ className: classes.path,
130
+ 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"
131
+ }
132
+ )
133
+ );
134
+ };
135
+
136
+ const useStyles = makeStyles({
137
+ svg: {
138
+ width: "auto",
139
+ height: 30
140
+ },
141
+ path: {
142
+ fill: "#7df3e1"
143
+ }
144
+ });
145
+ const LogoFull = () => {
146
+ const classes = useStyles();
147
+ return /* @__PURE__ */ React.createElement(
148
+ "svg",
149
+ {
150
+ className: classes.svg,
151
+ xmlns: "http://www.w3.org/2000/svg",
152
+ viewBox: "0 0 2079.95 456.05"
153
+ },
154
+ /* @__PURE__ */ React.createElement(
155
+ "path",
156
+ {
157
+ className: classes.path,
158
+ 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"
159
+ }
160
+ )
161
+ );
162
+ };
163
+
164
+ const useSidebarLogoStyles = makeStyles({
165
+ root: {
166
+ width: sidebarConfig.drawerWidthClosed,
167
+ height: 3 * sidebarConfig.logoHeight,
168
+ display: "flex",
169
+ flexFlow: "row nowrap",
170
+ alignItems: "center",
171
+ marginBottom: -14
172
+ },
173
+ link: {
174
+ width: sidebarConfig.drawerWidthClosed,
175
+ marginLeft: 24
176
+ }
177
+ });
178
+ const SidebarLogo = () => {
179
+ const classes = useSidebarLogoStyles();
180
+ const { isOpen } = useSidebarOpenState();
181
+ return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Link, { to: "/", underline: "none", className: classes.link, "aria-label": "Home" }, isOpen ? /* @__PURE__ */ React.createElement(LogoFull, null) : /* @__PURE__ */ React.createElement(LogoIcon, null)));
182
+ };
183
+ const CoreNav = createExtension({
184
+ id: "core.nav",
185
+ at: "core.layout/nav",
186
+ inputs: {
187
+ items: createExtensionInput({
188
+ path: coreExtensionData.navTarget
189
+ })
190
+ },
191
+ output: {
192
+ element: coreExtensionData.reactElement
193
+ },
194
+ factory({ bind }) {
195
+ bind({
196
+ // TODO: set base path using the logic from AppRouter
197
+ element: /* @__PURE__ */ React.createElement(Sidebar, null, /* @__PURE__ */ React.createElement(SidebarLogo, null), /* @__PURE__ */ React.createElement(SidebarDivider, null), /* @__PURE__ */ React.createElement(SidebarItem, { icon: GraphiQLIcon, to: "graphiql", text: "GraphiQL" }))
34
198
  });
35
199
  }
36
200
  });
37
201
 
202
+ function resolveInputData(dataMap, attachment, inputName) {
203
+ return mapValues(dataMap, (ref) => {
204
+ const value = attachment.getData(ref);
205
+ if (value === void 0 && !ref.config.optional) {
206
+ throw new Error(
207
+ `input '${inputName}' did not receive required extension data '${ref.id}' from extension '${attachment.id}'`
208
+ );
209
+ }
210
+ return value;
211
+ });
212
+ }
213
+ function resolveInputs(inputMap, attachments) {
214
+ return mapValues(inputMap, (input, inputName) => {
215
+ var _a;
216
+ const attachedInstances = (_a = attachments.get(inputName)) != null ? _a : [];
217
+ if (input.config.singleton) {
218
+ if (attachedInstances.length > 1) {
219
+ throw Error(
220
+ `expected ${input.config.optional ? "at most" : "exactly"} one '${inputName}' input but received multiple: '${attachedInstances.map((e) => e.id).join("', '")}'`
221
+ );
222
+ } else if (attachedInstances.length === 0) {
223
+ if (input.config.optional) {
224
+ return void 0;
225
+ }
226
+ throw Error(`input '${inputName}' is required but was not received`);
227
+ }
228
+ return resolveInputData(
229
+ input.extensionData,
230
+ attachedInstances[0],
231
+ inputName
232
+ );
233
+ }
234
+ return attachedInstances.map(
235
+ (attachment) => resolveInputData(input.extensionData, attachment, inputName)
236
+ );
237
+ });
238
+ }
38
239
  function createExtensionInstance(options) {
39
240
  var _a;
40
241
  const { extension, config, source, attachments } = options;
@@ -44,7 +245,7 @@ function createExtensionInstance(options) {
44
245
  parsedConfig = (_a = extension.configSchema) == null ? void 0 : _a.parse(config != null ? config : {});
45
246
  } catch (e) {
46
247
  throw new Error(
47
- `Invalid configuration for extension instance '${extension.id}', ${e}`
248
+ `Invalid configuration for extension '${extension.id}'; caused by ${e}`
48
249
  );
49
250
  }
50
251
  try {
@@ -55,33 +256,30 @@ function createExtensionInstance(options) {
55
256
  for (const [name, output] of Object.entries(namedOutputs)) {
56
257
  const ref = extension.output[name];
57
258
  if (!ref) {
259
+ throw new Error(`unknown output provided via '${name}'`);
260
+ }
261
+ if (extensionData.has(ref.id)) {
58
262
  throw new Error(
59
- `Extension instance '${extension.id}' tried to bind unknown output '${name}'`
263
+ `duplicate extension data '${ref.id}' received via output '${name}'`
60
264
  );
61
265
  }
62
266
  extensionData.set(ref.id, output);
63
267
  }
64
268
  },
65
- inputs: mapValues(
66
- extension.inputs,
67
- ({ extensionData: pointData }, inputName) => {
68
- var _a2;
69
- return ((_a2 = attachments.get(inputName)) != null ? _a2 : []).map(
70
- (attachment) => mapValues(pointData, (ref) => attachment.data.get(ref.id))
71
- );
72
- }
73
- )
269
+ inputs: resolveInputs(extension.inputs, attachments)
74
270
  });
75
271
  } catch (e) {
76
272
  throw new Error(
77
- `Failed to instantiate extension instance '${extension.id}', ${e}`
273
+ `Failed to instantiate extension '${extension.id}'${e.name === "Error" ? `, ${e.message}` : `; caused by ${e}`}`
78
274
  );
79
275
  }
80
276
  return {
277
+ $$type: "@backstage/ExtensionInstance",
81
278
  id: options.extension.id,
82
- data: extensionData,
83
- attachments,
84
- $$type: "extension-instance"
279
+ getData(ref) {
280
+ return extensionData.get(ref.id);
281
+ },
282
+ attachments
85
283
  };
86
284
  }
87
285
 
@@ -263,20 +461,571 @@ function getAvailablePlugins() {
263
461
  }
264
462
  function isBackstagePlugin(obj) {
265
463
  if (obj !== null && typeof obj === "object" && "$$type" in obj) {
266
- return obj.$$type === "backstage-plugin";
464
+ return obj.$$type === "@backstage/BackstagePlugin";
267
465
  }
268
466
  return false;
269
467
  }
270
468
 
271
- function createApp(options) {
469
+ function resolveTheme(themeId, shouldPreferDark, themes) {
470
+ if (themeId !== void 0) {
471
+ const selectedTheme = themes.find((theme) => theme.id === themeId);
472
+ if (selectedTheme) {
473
+ return selectedTheme;
474
+ }
475
+ }
476
+ if (shouldPreferDark) {
477
+ const darkTheme = themes.find((theme) => theme.variant === "dark");
478
+ if (darkTheme) {
479
+ return darkTheme;
480
+ }
481
+ }
482
+ const lightTheme = themes.find((theme) => theme.variant === "light");
483
+ if (lightTheme) {
484
+ return lightTheme;
485
+ }
486
+ return themes[0];
487
+ }
488
+ const useShouldPreferDarkTheme = () => {
489
+ const mediaQuery = useMemo(
490
+ () => window.matchMedia("(prefers-color-scheme: dark)"),
491
+ []
492
+ );
493
+ const [shouldPreferDark, setPrefersDark] = useState(mediaQuery.matches);
494
+ useEffect(() => {
495
+ const listener = (event) => {
496
+ setPrefersDark(event.matches);
497
+ };
498
+ mediaQuery.addListener(listener);
499
+ return () => {
500
+ mediaQuery.removeListener(listener);
501
+ };
502
+ }, [mediaQuery]);
503
+ return shouldPreferDark;
504
+ };
505
+ function AppThemeProvider({ children }) {
506
+ const appThemeApi = useApi(appThemeApiRef);
507
+ const themeId = useObservable(
508
+ appThemeApi.activeThemeId$(),
509
+ appThemeApi.getActiveThemeId()
510
+ );
511
+ const shouldPreferDark = Boolean(window.matchMedia) ? useShouldPreferDarkTheme() : false;
512
+ const appTheme = resolveTheme(
513
+ themeId,
514
+ shouldPreferDark,
515
+ appThemeApi.getInstalledThemes()
516
+ );
517
+ if (!appTheme) {
518
+ throw new Error("App has no themes");
519
+ }
520
+ return /* @__PURE__ */ React.createElement(appTheme.Provider, { children });
521
+ }
522
+
523
+ const AppContext = createVersionedContext("app-context");
524
+ const AppContextProvider = ({
525
+ appContext,
526
+ children
527
+ }) => {
528
+ const versionedValue = createVersionedValueMap({ 1: appContext });
529
+ return /* @__PURE__ */ React.createElement(AppContext.Provider, { value: versionedValue, children });
530
+ };
531
+
532
+ var __defProp = Object.defineProperty;
533
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
534
+ var __publicField = (obj, key, value) => {
535
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
536
+ return value;
537
+ };
538
+ function validateFlagName(name) {
539
+ if (name.length < 3) {
540
+ throw new Error(
541
+ `The '${name}' feature flag must have a minimum length of three characters.`
542
+ );
543
+ }
544
+ if (name.length > 150) {
545
+ throw new Error(
546
+ `The '${name}' feature flag must not exceed 150 characters.`
547
+ );
548
+ }
549
+ if (!name.match(/^[a-z]+[a-z0-9-]+$/)) {
550
+ throw new Error(
551
+ `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`
552
+ );
553
+ }
554
+ }
555
+ class LocalStorageFeatureFlags {
556
+ constructor() {
557
+ __publicField(this, "registeredFeatureFlags", []);
558
+ __publicField(this, "flags");
559
+ }
560
+ registerFlag(flag) {
561
+ validateFlagName(flag.name);
562
+ this.registeredFeatureFlags.push(flag);
563
+ }
564
+ getRegisteredFlags() {
565
+ return this.registeredFeatureFlags.slice();
566
+ }
567
+ isActive(name) {
568
+ if (!this.flags) {
569
+ this.flags = this.load();
570
+ }
571
+ return this.flags.get(name) === FeatureFlagState.Active;
572
+ }
573
+ save(options) {
574
+ if (!this.flags) {
575
+ this.flags = this.load();
576
+ }
577
+ if (!options.merge) {
578
+ this.flags.clear();
579
+ }
580
+ for (const [name, state] of Object.entries(options.states)) {
581
+ this.flags.set(name, state);
582
+ }
583
+ const enabled = Array.from(this.flags.entries()).filter(
584
+ ([, state]) => state === FeatureFlagState.Active
585
+ );
586
+ window.localStorage.setItem(
587
+ "featureFlags",
588
+ JSON.stringify(Object.fromEntries(enabled))
589
+ );
590
+ }
591
+ load() {
592
+ try {
593
+ const jsonStr = window.localStorage.getItem("featureFlags");
594
+ if (!jsonStr) {
595
+ return /* @__PURE__ */ new Map();
596
+ }
597
+ const json = JSON.parse(jsonStr);
598
+ if (typeof json !== "object" || json === null || Array.isArray(json)) {
599
+ return /* @__PURE__ */ new Map();
600
+ }
601
+ const entries = Object.entries(json).filter(([name, value]) => {
602
+ validateFlagName(name);
603
+ return value === FeatureFlagState.Active;
604
+ });
605
+ return new Map(entries);
606
+ } catch {
607
+ return /* @__PURE__ */ new Map();
608
+ }
609
+ }
610
+ }
611
+
612
+ function defaultConfigLoaderSync(runtimeConfigJson = "__APP_INJECTED_RUNTIME_CONFIG__") {
613
+ const appConfig = process.env.APP_CONFIG;
614
+ if (!appConfig) {
615
+ throw new Error("No static configuration provided");
616
+ }
617
+ if (!Array.isArray(appConfig)) {
618
+ throw new Error("Static configuration has invalid format");
619
+ }
620
+ const configs = appConfig.slice();
621
+ if (runtimeConfigJson !== "__app_injected_runtime_config__".toLocaleUpperCase("en-US")) {
622
+ try {
623
+ const data = JSON.parse(runtimeConfigJson);
624
+ if (Array.isArray(data)) {
625
+ configs.push(...data);
626
+ } else {
627
+ configs.push({ data, context: "env" });
628
+ }
629
+ } catch (error) {
630
+ throw new Error(`Failed to load runtime configuration, ${error}`);
631
+ }
632
+ }
633
+ const windowAppConfig = window.__APP_CONFIG__;
634
+ if (windowAppConfig) {
635
+ configs.push({
636
+ context: "window",
637
+ data: windowAppConfig
638
+ });
639
+ }
640
+ return configs;
641
+ }
642
+
643
+ function createLocalBaseUrl(fullUrl) {
644
+ const url = new URL(fullUrl);
645
+ url.protocol = document.location.protocol;
646
+ url.hostname = document.location.hostname;
647
+ url.port = document.location.port;
648
+ return url.toString().replace(/\/$/, "");
649
+ }
650
+ function overrideBaseUrlConfigs(inputConfigs) {
651
+ const urlConfigReader = ConfigReader.fromConfigs(inputConfigs);
652
+ const appBaseUrl = urlConfigReader.getOptionalString("app.baseUrl");
653
+ const backendBaseUrl = urlConfigReader.getOptionalString("backend.baseUrl");
654
+ let configs = inputConfigs;
655
+ let newBackendBaseUrl = void 0;
656
+ let newAppBaseUrl = void 0;
657
+ if (appBaseUrl && backendBaseUrl) {
658
+ const appOrigin = new URL(appBaseUrl).origin;
659
+ const backendOrigin = new URL(backendBaseUrl).origin;
660
+ if (appOrigin === backendOrigin) {
661
+ const maybeNewBackendBaseUrl = createLocalBaseUrl(backendBaseUrl);
662
+ if (backendBaseUrl !== maybeNewBackendBaseUrl) {
663
+ newBackendBaseUrl = maybeNewBackendBaseUrl;
664
+ }
665
+ }
666
+ }
667
+ if (appBaseUrl) {
668
+ const maybeNewAppBaseUrl = createLocalBaseUrl(appBaseUrl);
669
+ if (appBaseUrl !== maybeNewAppBaseUrl) {
670
+ newAppBaseUrl = maybeNewAppBaseUrl;
671
+ }
672
+ }
673
+ if (newAppBaseUrl || newBackendBaseUrl) {
674
+ configs = configs.concat({
675
+ data: {
676
+ app: newAppBaseUrl && {
677
+ baseUrl: newAppBaseUrl
678
+ },
679
+ backend: newBackendBaseUrl && {
680
+ baseUrl: newBackendBaseUrl
681
+ }
682
+ },
683
+ context: "relative-resolver"
684
+ });
685
+ }
686
+ return configs;
687
+ }
688
+
689
+ const apis = [
690
+ createApiFactory({
691
+ api: discoveryApiRef,
692
+ deps: { configApi: configApiRef },
693
+ factory: ({ configApi }) => UrlPatternDiscovery.compile(
694
+ `${configApi.getString("backend.baseUrl")}/api/{{ pluginId }}`
695
+ )
696
+ }),
697
+ createApiFactory({
698
+ api: alertApiRef,
699
+ deps: {},
700
+ factory: () => new AlertApiForwarder()
701
+ }),
702
+ createApiFactory({
703
+ api: analyticsApiRef,
704
+ deps: {},
705
+ factory: () => new NoOpAnalyticsApi()
706
+ }),
707
+ createApiFactory({
708
+ api: errorApiRef,
709
+ deps: { alertApi: alertApiRef },
710
+ factory: ({ alertApi }) => {
711
+ const errorApi = new ErrorAlerter(alertApi, new ErrorApiForwarder());
712
+ UnhandledErrorForwarder.forward(errorApi, { hidden: false });
713
+ return errorApi;
714
+ }
715
+ }),
716
+ createApiFactory({
717
+ api: storageApiRef,
718
+ deps: { errorApi: errorApiRef },
719
+ factory: ({ errorApi }) => WebStorage.create({ errorApi })
720
+ }),
721
+ createApiFactory({
722
+ api: fetchApiRef,
723
+ deps: {
724
+ configApi: configApiRef,
725
+ identityApi: identityApiRef,
726
+ discoveryApi: discoveryApiRef
727
+ },
728
+ factory: ({ configApi, identityApi, discoveryApi }) => {
729
+ return createFetchApi({
730
+ middleware: [
731
+ FetchMiddlewares.resolvePluginProtocol({
732
+ discoveryApi
733
+ }),
734
+ FetchMiddlewares.injectIdentityAuth({
735
+ identityApi,
736
+ config: configApi
737
+ })
738
+ ]
739
+ });
740
+ }
741
+ }),
742
+ createApiFactory({
743
+ api: oauthRequestApiRef,
744
+ deps: {},
745
+ factory: () => new OAuthRequestManager()
746
+ }),
747
+ createApiFactory({
748
+ api: googleAuthApiRef,
749
+ deps: {
750
+ discoveryApi: discoveryApiRef,
751
+ oauthRequestApi: oauthRequestApiRef,
752
+ configApi: configApiRef
753
+ },
754
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => GoogleAuth.create({
755
+ configApi,
756
+ discoveryApi,
757
+ oauthRequestApi,
758
+ environment: configApi.getOptionalString("auth.environment")
759
+ })
760
+ }),
761
+ createApiFactory({
762
+ api: microsoftAuthApiRef,
763
+ deps: {
764
+ discoveryApi: discoveryApiRef,
765
+ oauthRequestApi: oauthRequestApiRef,
766
+ configApi: configApiRef
767
+ },
768
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => MicrosoftAuth.create({
769
+ configApi,
770
+ discoveryApi,
771
+ oauthRequestApi,
772
+ environment: configApi.getOptionalString("auth.environment")
773
+ })
774
+ }),
775
+ createApiFactory({
776
+ api: githubAuthApiRef,
777
+ deps: {
778
+ discoveryApi: discoveryApiRef,
779
+ oauthRequestApi: oauthRequestApiRef,
780
+ configApi: configApiRef
781
+ },
782
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => GithubAuth.create({
783
+ configApi,
784
+ discoveryApi,
785
+ oauthRequestApi,
786
+ defaultScopes: ["read:user"],
787
+ environment: configApi.getOptionalString("auth.environment")
788
+ })
789
+ }),
790
+ createApiFactory({
791
+ api: oktaAuthApiRef,
792
+ deps: {
793
+ discoveryApi: discoveryApiRef,
794
+ oauthRequestApi: oauthRequestApiRef,
795
+ configApi: configApiRef
796
+ },
797
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => OktaAuth.create({
798
+ configApi,
799
+ discoveryApi,
800
+ oauthRequestApi,
801
+ environment: configApi.getOptionalString("auth.environment")
802
+ })
803
+ }),
804
+ createApiFactory({
805
+ api: gitlabAuthApiRef,
806
+ deps: {
807
+ discoveryApi: discoveryApiRef,
808
+ oauthRequestApi: oauthRequestApiRef,
809
+ configApi: configApiRef
810
+ },
811
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => GitlabAuth.create({
812
+ configApi,
813
+ discoveryApi,
814
+ oauthRequestApi,
815
+ environment: configApi.getOptionalString("auth.environment")
816
+ })
817
+ }),
818
+ createApiFactory({
819
+ api: oneloginAuthApiRef,
820
+ deps: {
821
+ discoveryApi: discoveryApiRef,
822
+ oauthRequestApi: oauthRequestApiRef,
823
+ configApi: configApiRef
824
+ },
825
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => OneLoginAuth.create({
826
+ configApi,
827
+ discoveryApi,
828
+ oauthRequestApi,
829
+ environment: configApi.getOptionalString("auth.environment")
830
+ })
831
+ }),
832
+ createApiFactory({
833
+ api: bitbucketAuthApiRef,
834
+ deps: {
835
+ discoveryApi: discoveryApiRef,
836
+ oauthRequestApi: oauthRequestApiRef,
837
+ configApi: configApiRef
838
+ },
839
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => BitbucketAuth.create({
840
+ configApi,
841
+ discoveryApi,
842
+ oauthRequestApi,
843
+ defaultScopes: ["team"],
844
+ environment: configApi.getOptionalString("auth.environment")
845
+ })
846
+ }),
847
+ createApiFactory({
848
+ api: bitbucketServerAuthApiRef,
849
+ deps: {
850
+ discoveryApi: discoveryApiRef,
851
+ oauthRequestApi: oauthRequestApiRef,
852
+ configApi: configApiRef
853
+ },
854
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => BitbucketServerAuth.create({
855
+ configApi,
856
+ discoveryApi,
857
+ oauthRequestApi,
858
+ defaultScopes: ["REPO_READ"]
859
+ })
860
+ }),
861
+ createApiFactory({
862
+ api: atlassianAuthApiRef,
863
+ deps: {
864
+ discoveryApi: discoveryApiRef,
865
+ oauthRequestApi: oauthRequestApiRef,
866
+ configApi: configApiRef
867
+ },
868
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) => {
869
+ return AtlassianAuth.create({
870
+ configApi,
871
+ discoveryApi,
872
+ oauthRequestApi,
873
+ environment: configApi.getOptionalString("auth.environment")
874
+ });
875
+ }
876
+ }),
877
+ createApiFactory({
878
+ api: permissionApiRef,
879
+ deps: {
880
+ discovery: discoveryApiRef,
881
+ identity: identityApiRef,
882
+ config: configApiRef
883
+ },
884
+ factory: ({ config, discovery, identity }) => IdentityPermissionApi.create({ config, discovery, identity })
885
+ })
886
+ ];
887
+
888
+ function OptionallyWrapInRouter({ children }) {
889
+ if (useInRouterContext()) {
890
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
891
+ }
892
+ return /* @__PURE__ */ React.createElement(MemoryRouter, null, children);
893
+ }
894
+ const DefaultNotFoundPage = () => /* @__PURE__ */ React.createElement(ErrorPage, { status: "404", statusMessage: "PAGE NOT FOUND" });
895
+ const DefaultBootErrorPage = ({ step, error }) => {
896
+ let message = "";
897
+ if (step === "load-config") {
898
+ message = `The configuration failed to load, someone should have a look at this error: ${error.message}`;
899
+ } else if (step === "load-chunk") {
900
+ message = `Lazy loaded chunk failed to load, try to reload the page: ${error.message}`;
901
+ }
902
+ return /* @__PURE__ */ React.createElement(OptionallyWrapInRouter, null, /* @__PURE__ */ React.createElement(ErrorPage, { status: "501", statusMessage: message }));
903
+ };
904
+ const DefaultErrorBoundaryFallback = ({
905
+ error,
906
+ resetError,
907
+ plugin
908
+ }) => {
909
+ return /* @__PURE__ */ React.createElement(
910
+ ErrorPanel,
911
+ {
912
+ title: `Error in ${plugin == null ? void 0 : plugin.getId()}`,
913
+ defaultExpanded: true,
914
+ error
915
+ },
916
+ /* @__PURE__ */ React.createElement(Button, { variant: "outlined", onClick: resetError }, "Retry")
917
+ );
918
+ };
919
+ const components = {
920
+ Progress,
921
+ Router: BrowserRouter,
922
+ NotFoundErrorPage: DefaultNotFoundPage,
923
+ BootErrorPage: DefaultBootErrorPage,
924
+ ErrorBoundaryFallback: DefaultErrorBoundaryFallback
925
+ };
926
+
927
+ const icons = {
928
+ brokenImage: MuiBrokenImageIcon,
929
+ // To be confirmed: see https://github.com/backstage/backstage/issues/4970
930
+ catalog: MuiMenuBookIcon,
931
+ scaffolder: MuiCreateNewFolderIcon,
932
+ techdocs: MuiSubjectIcon,
933
+ search: MuiSearchIcon,
934
+ chat: MuiChatIcon,
935
+ dashboard: MuiDashboardIcon,
936
+ docs: MuiDocsIcon,
937
+ email: MuiEmailIcon,
938
+ github: MuiGitHubIcon,
939
+ group: MuiPeopleIcon,
940
+ help: MuiHelpIcon,
941
+ "kind:api": MuiExtensionIcon,
942
+ "kind:component": MuiMemoryIcon,
943
+ "kind:domain": MuiApartmentIcon,
944
+ "kind:group": MuiPeopleIcon,
945
+ "kind:location": MuiLocationOnIcon,
946
+ "kind:system": MuiCategoryIcon,
947
+ "kind:user": MuiPersonIcon,
948
+ "kind:resource": MuiWorkIcon,
949
+ user: MuiPersonIcon,
950
+ warning: MuiWarningIcon
951
+ };
952
+
953
+ const themes = [
954
+ {
955
+ id: "light",
956
+ title: "Light Theme",
957
+ variant: "light",
958
+ icon: /* @__PURE__ */ React.createElement(LightIcon, null),
959
+ Provider: ({ children }) => /* @__PURE__ */ React.createElement(UnifiedThemeProvider, { theme: themes$1.light, children })
960
+ },
961
+ {
962
+ id: "dark",
963
+ title: "Dark Theme",
964
+ variant: "dark",
965
+ icon: /* @__PURE__ */ React.createElement(DarkIcon, null),
966
+ Provider: ({ children }) => /* @__PURE__ */ React.createElement(UnifiedThemeProvider, { theme: themes$1.dark, children })
967
+ }
968
+ ];
969
+
970
+ function createExtensionTree(options) {
971
+ const plugins = getAvailablePlugins();
972
+ const { instances } = createInstances({
973
+ plugins,
974
+ config: options.config
975
+ });
976
+ return {
977
+ getExtension(id) {
978
+ return instances.get(id);
979
+ },
980
+ getExtensionAttachments(id, inputName) {
981
+ var _a, _b;
982
+ return (_b = (_a = instances.get(id)) == null ? void 0 : _a.attachments.get(inputName)) != null ? _b : [];
983
+ },
984
+ getRootRoutes() {
985
+ return this.getExtensionAttachments("core.routes", "routes").map((node) => {
986
+ const path = node.getData(coreExtensionData.routePath);
987
+ const element = node.getData(coreExtensionData.reactElement);
988
+ const routeRef = node.getData(coreExtensionData.routeRef);
989
+ if (!path || !element) {
990
+ throw new Error(`Invalid route extension: ${node.id}`);
991
+ }
992
+ const Component = () => {
993
+ return element;
994
+ };
995
+ attachComponentData(Component, "core.mountPoint", routeRef);
996
+ return /* @__PURE__ */ React.createElement(Route, { path, element: /* @__PURE__ */ React.createElement(Component, null) });
997
+ });
998
+ },
999
+ getSidebarItems() {
1000
+ const RoutedSidebarItem = (props) => {
1001
+ const location = useRouteRef(props.routeRef);
1002
+ return /* @__PURE__ */ React.createElement(SidebarItem, { icon: props.icon, to: location(), text: props.title });
1003
+ };
1004
+ return this.getExtensionAttachments("core.nav", "items").map((node, index) => {
1005
+ const target = node.getData(coreExtensionData.navTarget);
1006
+ if (!target) {
1007
+ return null;
1008
+ }
1009
+ return /* @__PURE__ */ React.createElement(
1010
+ RoutedSidebarItem,
1011
+ {
1012
+ key: index,
1013
+ title: target.title,
1014
+ icon: target.icon,
1015
+ routeRef: target.routeRef
1016
+ }
1017
+ );
1018
+ }).filter((x) => !!x);
1019
+ }
1020
+ };
1021
+ }
1022
+ function createInstances(options) {
272
1023
  var _a, _b;
273
- const appConfig = ConfigReader.fromConfigs(process.env.APP_CONFIG);
274
- const builtinExtensions = [CoreRouter];
275
- const discoveredPlugins = getAvailablePlugins();
1024
+ const builtinExtensions = [Core, CoreRoutes, CoreNav, CoreLayout];
276
1025
  const extensionParams = mergeExtensionParameters({
277
- sources: [...options.plugins, ...discoveredPlugins],
1026
+ sources: options.plugins,
278
1027
  builtinExtensions,
279
- parameters: readAppExtensionParameters(appConfig)
1028
+ parameters: readAppExtensionParameters(options.config)
280
1029
  });
281
1030
  const attachmentMap = /* @__PURE__ */ new Map();
282
1031
  for (const instanceParams of extensionParams) {
@@ -321,26 +1070,107 @@ function createApp(options) {
321
1070
  const rootInstances = rootConfigs.map(
322
1071
  (instanceParams) => createInstance(instanceParams)
323
1072
  );
1073
+ return { instances, rootInstances };
1074
+ }
1075
+ function createApp(options) {
1076
+ var _a;
1077
+ const discoveredPlugins = getAvailablePlugins();
1078
+ const allPlugins = [...discoveredPlugins, ...options.plugins];
1079
+ const appConfig = (_a = options == null ? void 0 : options.config) != null ? _a : ConfigReader.fromConfigs(overrideBaseUrlConfigs(defaultConfigLoaderSync()));
1080
+ const { rootInstances } = createInstances({
1081
+ plugins: allPlugins,
1082
+ config: appConfig
1083
+ });
324
1084
  const routePaths = extractRouteInfoFromInstanceTree(rootInstances);
1085
+ const coreInstance = rootInstances.find(({ id }) => id === "core");
1086
+ if (!coreInstance) {
1087
+ throw Error("Unable to find core extension instance");
1088
+ }
1089
+ const apiHolder = createApiHolder(coreInstance, appConfig);
1090
+ const appContext = createLegacyAppContext(allPlugins);
325
1091
  return {
326
1092
  createRoot() {
327
- const rootComponents = rootInstances.map(
328
- (e) => e.data.get(
329
- coreExtensionData.reactComponent.id
330
- )
331
- );
332
- return /* @__PURE__ */ React.createElement(RoutingProvider, { routePaths }, rootComponents.map((Component, i) => /* @__PURE__ */ React.createElement(Component, { key: i })));
1093
+ const rootElements = rootInstances.map((e) => e.getData(coreExtensionData.reactElement)).filter((x) => !!x);
1094
+ return /* @__PURE__ */ React.createElement(ApiProvider, { apis: apiHolder }, /* @__PURE__ */ React.createElement(AppContextProvider, { appContext }, /* @__PURE__ */ React.createElement(AppThemeProvider, null, /* @__PURE__ */ React.createElement(RoutingProvider, { routePaths }, /* @__PURE__ */ React.createElement(BrowserRouter, null, rootElements)))));
333
1095
  }
334
1096
  };
335
1097
  }
1098
+ function toLegacyPlugin(plugin) {
1099
+ const errorMsg = "Not implemented in legacy plugin compatibility layer";
1100
+ const notImplemented = () => {
1101
+ throw new Error(errorMsg);
1102
+ };
1103
+ return {
1104
+ getId() {
1105
+ return plugin.id;
1106
+ },
1107
+ get routes() {
1108
+ throw new Error(errorMsg);
1109
+ },
1110
+ get externalRoutes() {
1111
+ throw new Error(errorMsg);
1112
+ },
1113
+ getApis: notImplemented,
1114
+ getFeatureFlags: notImplemented,
1115
+ provide: notImplemented,
1116
+ __experimentalReconfigure: notImplemented
1117
+ };
1118
+ }
1119
+ function createLegacyAppContext(plugins) {
1120
+ return {
1121
+ getPlugins() {
1122
+ return plugins.map(toLegacyPlugin);
1123
+ },
1124
+ getSystemIcon(key) {
1125
+ return key in icons ? icons[key] : void 0;
1126
+ },
1127
+ getSystemIcons() {
1128
+ return icons;
1129
+ },
1130
+ getComponents() {
1131
+ return components;
1132
+ }
1133
+ };
1134
+ }
1135
+ function createApiHolder(coreExtension, configApi) {
1136
+ var _a, _b;
1137
+ const factoryRegistry = new ApiFactoryRegistry();
1138
+ const apiFactories = (_b = (_a = coreExtension.attachments.get("apis")) == null ? void 0 : _a.map((e) => e.getData(coreExtensionData.apiFactory)).filter((x) => !!x)) != null ? _b : [];
1139
+ for (const factory of apiFactories) {
1140
+ factoryRegistry.register("default", factory);
1141
+ }
1142
+ factoryRegistry.register("default", {
1143
+ api: featureFlagsApiRef,
1144
+ deps: {},
1145
+ factory: () => new LocalStorageFeatureFlags()
1146
+ });
1147
+ factoryRegistry.register("static", {
1148
+ api: appThemeApiRef,
1149
+ deps: {},
1150
+ // TODO: add extension for registering themes
1151
+ factory: () => AppThemeSelector.createWithStorage(themes)
1152
+ });
1153
+ factoryRegistry.register("static", {
1154
+ api: configApiRef,
1155
+ deps: {},
1156
+ factory: () => configApi
1157
+ });
1158
+ for (const factory of apis) {
1159
+ if (!factoryRegistry.register("app", factory)) {
1160
+ throw new Error(
1161
+ `Duplicate or forbidden API factory for ${factory.api} in app`
1162
+ );
1163
+ }
1164
+ }
1165
+ ApiResolver.validateFactories(factoryRegistry, factoryRegistry.getAllApis());
1166
+ return new ApiResolver(factoryRegistry);
1167
+ }
336
1168
  function extractRouteInfoFromInstanceTree(roots) {
337
1169
  const results = /* @__PURE__ */ new Map();
338
1170
  function visit(current, basePath) {
339
1171
  var _a;
340
- const routePath = (_a = current.data.get(coreExtensionData.routePath.id)) != null ? _a : "";
341
- const routeRef = current.data.get(
342
- coreExtensionData.routeRef.id
343
- );
1172
+ const routePath = (_a = current.getData(coreExtensionData.routePath)) != null ? _a : "";
1173
+ const routeRef = current.getData(coreExtensionData.routeRef);
344
1174
  const fullPath = basePath + routePath;
345
1175
  if (routeRef) {
346
1176
  const routeRefId = routeRef.id;
@@ -363,5 +1193,5 @@ function extractRouteInfoFromInstanceTree(roots) {
363
1193
  return results;
364
1194
  }
365
1195
 
366
- export { createApp };
1196
+ export { createApp, createExtensionTree };
367
1197
  //# sourceMappingURL=index.esm.js.map