@backstage/core-app-api 0.1.10 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @backstage/core-app-api
2
2
 
3
+ ## 0.1.14
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/core-components@0.5.0
9
+ - @backstage/config@0.1.10
10
+
11
+ ## 0.1.13
12
+
13
+ ### Patch Changes
14
+
15
+ - 671015f132: Switch to using utilities from `@backstage/version-bridge'.
16
+ - bd1981d609: Allow users to specify their own AppThemeProvider
17
+ - Updated dependencies
18
+ - @backstage/core-components@0.4.2
19
+ - @backstage/core-plugin-api@0.1.8
20
+
21
+ ## 0.1.12
22
+
23
+ ### Patch Changes
24
+
25
+ - 841666a19: Removed deprecated internal functions.
26
+ - Updated dependencies
27
+ - @backstage/core-components@0.4.1
28
+ - @backstage/config@0.1.9
29
+ - @backstage/core-plugin-api@0.1.7
30
+
31
+ ## 0.1.11
32
+
33
+ ### Patch Changes
34
+
35
+ - Updated dependencies
36
+ - @backstage/core-components@0.4.0
37
+
3
38
  ## 0.1.10
4
39
 
5
40
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -393,6 +393,7 @@ declare type AppComponents = {
393
393
  Progress: ComponentType<{}>;
394
394
  Router: ComponentType<{}>;
395
395
  ErrorBoundaryFallback: ComponentType<ErrorBoundaryFallbackProps>;
396
+ ThemeProvider: ComponentType<{}>;
396
397
  /**
397
398
  * An optional sign-in page that will be rendered instead of the AppRouter at startup.
398
399
  *
package/dist/index.esm.js CHANGED
@@ -1,8 +1,9 @@
1
- import React, { useContext, createContext, Children, isValidElement, useMemo, useState, useEffect } from 'react';
1
+ import React, { useContext, Children, isValidElement, useMemo, useEffect, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import { createVersionedContext, createVersionedValueMap, getOrCreateGlobalSingleton } from '@backstage/version-bridge';
3
4
  import OAuth2Icon from '@material-ui/icons/AcUnit';
4
5
  import ObservableImpl from 'zen-observable';
5
- import { SessionState, FeatureFlagState, useApi, featureFlagsApiRef, attachComponentData, appThemeApiRef, configApiRef, identityApiRef, createApiFactory, discoveryApiRef, alertApiRef, errorApiRef, storageApiRef, oauthRequestApiRef, googleAuthApiRef, microsoftAuthApiRef, githubAuthApiRef, oktaAuthApiRef, gitlabAuthApiRef, auth0AuthApiRef, oauth2ApiRef, samlAuthApiRef, oneloginAuthApiRef, oidcAuthApiRef, useApp, useElementFilter } from '@backstage/core-plugin-api';
6
+ import { SessionState, FeatureFlagState, getComponentData, useApi, featureFlagsApiRef, attachComponentData, appThemeApiRef, configApiRef, identityApiRef, createApiFactory, discoveryApiRef, alertApiRef, errorApiRef, storageApiRef, oauthRequestApiRef, googleAuthApiRef, microsoftAuthApiRef, githubAuthApiRef, oktaAuthApiRef, gitlabAuthApiRef, auth0AuthApiRef, oauth2ApiRef, samlAuthApiRef, oneloginAuthApiRef, oidcAuthApiRef, useApp, useElementFilter } from '@backstage/core-plugin-api';
6
7
  import { ConfigReader } from '@backstage/config';
7
8
  export { ConfigReader } from '@backstage/config';
8
9
  import { ThemeProvider, CssBaseline, Button } from '@material-ui/core';
@@ -11,7 +12,7 @@ import { lightTheme, darkTheme } from '@backstage/theme';
11
12
  import DarkIcon from '@material-ui/icons/Brightness2';
12
13
  import LightIcon from '@material-ui/icons/WbSunny';
13
14
  import { matchRoutes, generatePath, Routes, Route, BrowserRouter, useInRouterContext, MemoryRouter, useRoutes } from 'react-router-dom';
14
- import { useObservable, useAsync } from 'react-use';
15
+ import { useAsync, useObservable } from 'react-use';
15
16
  import MuiApartmentIcon from '@material-ui/icons/Apartment';
16
17
  import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage';
17
18
  import MuiCategoryIcon from '@material-ui/icons/Category';
@@ -44,38 +45,7 @@ class ApiAggregator {
44
45
  }
45
46
  }
46
47
 
47
- function getGlobalObject() {
48
- if (typeof window !== "undefined" && window.Math === Math) {
49
- return window;
50
- }
51
- if (typeof self !== "undefined" && self.Math === Math) {
52
- return self;
53
- }
54
- return Function("return this")();
55
- }
56
- const globalObject = getGlobalObject();
57
- const makeKey = (id) => `__@backstage/${id}__`;
58
- function getOrCreateGlobalSingleton(id, supplier) {
59
- const key = makeKey(id);
60
- let value = globalObject[key];
61
- if (value) {
62
- return value;
63
- }
64
- value = supplier();
65
- globalObject[key] = value;
66
- return value;
67
- }
68
-
69
- function createVersionedValueMap(versions) {
70
- Object.freeze(versions);
71
- return {
72
- atVersion(version) {
73
- return versions[version];
74
- }
75
- };
76
- }
77
-
78
- const ApiContext = getOrCreateGlobalSingleton("api-context", () => createContext(void 0));
48
+ const ApiContext = createVersionedContext("api-context");
79
49
  const ApiProvider = ({
80
50
  apis,
81
51
  children
@@ -1677,23 +1647,6 @@ function routeElementDiscoverer(element) {
1677
1647
  return void 0;
1678
1648
  }
1679
1649
 
1680
- const DATA_KEY = Symbol("backstage-component-data");
1681
- const store = getOrCreateGlobalSingleton("component-data-store", () => new WeakMap());
1682
- function getComponentData(node, type) {
1683
- if (!node) {
1684
- return void 0;
1685
- }
1686
- const component = node.type;
1687
- if (!component) {
1688
- return void 0;
1689
- }
1690
- const container = store.get(component) || component[DATA_KEY];
1691
- if (!container) {
1692
- return void 0;
1693
- }
1694
- return container.map.get(type);
1695
- }
1696
-
1697
1650
  const pluginCollector = createCollector(() => new Set(), (acc, node) => {
1698
1651
  const plugin = getComponentData(node, "core.plugin");
1699
1652
  if (plugin) {
@@ -1929,7 +1882,7 @@ class RouteResolver {
1929
1882
  }
1930
1883
  }
1931
1884
 
1932
- const RoutingContext = getOrCreateGlobalSingleton("routing-context", () => createContext(void 0));
1885
+ const RoutingContext = createVersionedContext("routing-context");
1933
1886
  const RoutingProvider = ({
1934
1887
  routePaths,
1935
1888
  routeParents,
@@ -1975,7 +1928,7 @@ function validateRoutes(routePaths, routeParents) {
1975
1928
  }
1976
1929
  }
1977
1930
 
1978
- const AppContext = getOrCreateGlobalSingleton("app-context", () => createContext(void 0));
1931
+ const AppContext = createVersionedContext("app-context");
1979
1932
  const AppContextProvider = ({
1980
1933
  appContext,
1981
1934
  children
@@ -2036,52 +1989,6 @@ class AppIdentity {
2036
1989
  }
2037
1990
  }
2038
1991
 
2039
- function resolveTheme(themeId, shouldPreferDark, themes) {
2040
- if (themeId !== void 0) {
2041
- const selectedTheme = themes.find((theme) => theme.id === themeId);
2042
- if (selectedTheme) {
2043
- return selectedTheme;
2044
- }
2045
- }
2046
- if (shouldPreferDark) {
2047
- const darkTheme = themes.find((theme) => theme.variant === "dark");
2048
- if (darkTheme) {
2049
- return darkTheme;
2050
- }
2051
- }
2052
- const lightTheme = themes.find((theme) => theme.variant === "light");
2053
- if (lightTheme) {
2054
- return lightTheme;
2055
- }
2056
- return themes[0];
2057
- }
2058
- const useShouldPreferDarkTheme = () => {
2059
- const mediaQuery = useMemo(() => window.matchMedia("(prefers-color-scheme: dark)"), []);
2060
- const [shouldPreferDark, setPrefersDark] = useState(mediaQuery.matches);
2061
- useEffect(() => {
2062
- const listener = (event) => {
2063
- setPrefersDark(event.matches);
2064
- };
2065
- mediaQuery.addListener(listener);
2066
- return () => {
2067
- mediaQuery.removeListener(listener);
2068
- };
2069
- }, [mediaQuery]);
2070
- return shouldPreferDark;
2071
- };
2072
- function AppThemeProvider({children}) {
2073
- const appThemeApi = useApi(appThemeApiRef);
2074
- const themeId = useObservable(appThemeApi.activeThemeId$(), appThemeApi.getActiveThemeId());
2075
- const shouldPreferDark = Boolean(window.matchMedia) ? useShouldPreferDarkTheme() : false;
2076
- const appTheme = resolveTheme(themeId, shouldPreferDark, appThemeApi.getInstalledThemes());
2077
- if (!appTheme) {
2078
- throw new Error("App has no themes");
2079
- }
2080
- return /* @__PURE__ */ React.createElement(ThemeProvider, {
2081
- theme: appTheme.theme
2082
- }, /* @__PURE__ */ React.createElement(CssBaseline, null, children));
2083
- }
2084
-
2085
1992
  function generateBoundRoutes(bindRoutes) {
2086
1993
  const result = new Map();
2087
1994
  if (bindRoutes) {
@@ -2124,11 +2031,12 @@ function useConfigLoader(configLoader, components, appThemeApi) {
2124
2031
  error: config.error
2125
2032
  });
2126
2033
  }
2034
+ const {ThemeProvider} = components;
2127
2035
  if (noConfigNode) {
2128
2036
  return {
2129
2037
  node: /* @__PURE__ */ React.createElement(ApiProvider, {
2130
2038
  apis: ApiRegistry.from([[appThemeApiRef, appThemeApi]])
2131
- }, /* @__PURE__ */ React.createElement(AppThemeProvider, null, noConfigNode))
2039
+ }, /* @__PURE__ */ React.createElement(ThemeProvider, null, noConfigNode))
2132
2040
  };
2133
2041
  }
2134
2042
  const configReader = ConfigReader.fromConfigs((_a = config.value) != null ? _a : []);
@@ -2221,11 +2129,12 @@ class PrivateAppImpl {
2221
2129
  if ("node" in loadedConfig) {
2222
2130
  return loadedConfig.node;
2223
2131
  }
2132
+ const {ThemeProvider} = this.components;
2224
2133
  return /* @__PURE__ */ React.createElement(ApiProvider, {
2225
2134
  apis: this.getApiHolder()
2226
2135
  }, /* @__PURE__ */ React.createElement(AppContextProvider, {
2227
2136
  appContext
2228
- }, /* @__PURE__ */ React.createElement(AppThemeProvider, null, /* @__PURE__ */ React.createElement(RoutingProvider, {
2137
+ }, /* @__PURE__ */ React.createElement(ThemeProvider, null, /* @__PURE__ */ React.createElement(RoutingProvider, {
2229
2138
  routePaths,
2230
2139
  routeParents,
2231
2140
  routeObjects,
@@ -2336,6 +2245,52 @@ class PrivateAppImpl {
2336
2245
  }
2337
2246
  }
2338
2247
 
2248
+ function resolveTheme(themeId, shouldPreferDark, themes) {
2249
+ if (themeId !== void 0) {
2250
+ const selectedTheme = themes.find((theme) => theme.id === themeId);
2251
+ if (selectedTheme) {
2252
+ return selectedTheme;
2253
+ }
2254
+ }
2255
+ if (shouldPreferDark) {
2256
+ const darkTheme = themes.find((theme) => theme.variant === "dark");
2257
+ if (darkTheme) {
2258
+ return darkTheme;
2259
+ }
2260
+ }
2261
+ const lightTheme = themes.find((theme) => theme.variant === "light");
2262
+ if (lightTheme) {
2263
+ return lightTheme;
2264
+ }
2265
+ return themes[0];
2266
+ }
2267
+ const useShouldPreferDarkTheme = () => {
2268
+ const mediaQuery = useMemo(() => window.matchMedia("(prefers-color-scheme: dark)"), []);
2269
+ const [shouldPreferDark, setPrefersDark] = useState(mediaQuery.matches);
2270
+ useEffect(() => {
2271
+ const listener = (event) => {
2272
+ setPrefersDark(event.matches);
2273
+ };
2274
+ mediaQuery.addListener(listener);
2275
+ return () => {
2276
+ mediaQuery.removeListener(listener);
2277
+ };
2278
+ }, [mediaQuery]);
2279
+ return shouldPreferDark;
2280
+ };
2281
+ function AppThemeProvider({children}) {
2282
+ const appThemeApi = useApi(appThemeApiRef);
2283
+ const themeId = useObservable(appThemeApi.activeThemeId$(), appThemeApi.getActiveThemeId());
2284
+ const shouldPreferDark = Boolean(window.matchMedia) ? useShouldPreferDarkTheme() : false;
2285
+ const appTheme = resolveTheme(themeId, shouldPreferDark, appThemeApi.getInstalledThemes());
2286
+ if (!appTheme) {
2287
+ throw new Error("App has no themes");
2288
+ }
2289
+ return /* @__PURE__ */ React.createElement(ThemeProvider, {
2290
+ theme: appTheme.theme
2291
+ }, /* @__PURE__ */ React.createElement(CssBaseline, null, children));
2292
+ }
2293
+
2339
2294
  const defaultApis = [
2340
2295
  createApiFactory({
2341
2296
  api: discoveryApiRef,
@@ -2592,6 +2547,7 @@ function createApp(options) {
2592
2547
  Progress,
2593
2548
  Router: BrowserRouter,
2594
2549
  ErrorBoundaryFallback: DefaultErrorBoundaryFallback,
2550
+ ThemeProvider: AppThemeProvider,
2595
2551
  ...options == null ? void 0 : options.components
2596
2552
  };
2597
2553
  const themes = (_c = options == null ? void 0 : options.themes) != null ? _c : [