@backstage/core-app-api 1.0.0 → 1.0.1
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 +31 -0
- package/README.md +2 -3
- package/dist/index.esm.js +79 -105
- package/dist/index.esm.js.map +1 -1
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @backstage/core-app-api
|
|
2
2
|
|
|
3
|
+
## 1.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7c7919777e: build(deps-dev): bump `@testing-library/react-hooks` from 7.0.2 to 8.0.0
|
|
8
|
+
- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0
|
|
9
|
+
- 3ff2bfb66e: Refactored the route collection logic to prepare for future changes and avoid duplicate element tree traversal for the analytics context.
|
|
10
|
+
- a7bb762dab: fixed empty body issue for POST requests using FetchAPI with 'plugin://' prefix
|
|
11
|
+
- 230ad0826f: Bump to using `@types/node` v16
|
|
12
|
+
- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values.
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/core-plugin-api@1.0.1
|
|
15
|
+
- @backstage/version-bridge@1.0.1
|
|
16
|
+
|
|
17
|
+
## 1.0.1-next.1
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0
|
|
22
|
+
- 3ff2bfb66e: Refactored the route collection logic to prepare for future changes and avoid duplicate element tree traversal for the analytics context.
|
|
23
|
+
- 230ad0826f: Bump to using `@types/node` v16
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- @backstage/core-plugin-api@1.0.1-next.0
|
|
26
|
+
|
|
27
|
+
## 1.0.1-next.0
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- a7bb762dab: fixed empty body issue for POST requests using FetchAPI with 'plugin://' prefix
|
|
32
|
+
- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values.
|
|
33
|
+
|
|
3
34
|
## 1.0.0
|
|
4
35
|
|
|
5
36
|
### Major Changes
|
package/README.md
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useContext, Children, isValidElement,
|
|
1
|
+
import React, { useContext, Children, isValidElement, useEffect, useMemo, useState, createContext } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { createVersionedContext, createVersionedValueMap, getOrCreateGlobalSingleton } from '@backstage/version-bridge';
|
|
4
4
|
import ObservableImpl from 'zen-observable';
|
|
@@ -1402,7 +1402,7 @@ class PluginProtocolResolverFetchMiddleware {
|
|
|
1402
1402
|
base = `${baseUrl.protocol}//${authority}${baseUrl.host}${baseUrl.pathname}`;
|
|
1403
1403
|
}
|
|
1404
1404
|
const target = `${join(base, pathname)}${search}${hash}`;
|
|
1405
|
-
return next(target,
|
|
1405
|
+
return next(target, typeof input === "string" ? init : input);
|
|
1406
1406
|
};
|
|
1407
1407
|
}
|
|
1408
1408
|
}
|
|
@@ -1671,88 +1671,64 @@ const FeatureFlagged = (props) => {
|
|
|
1671
1671
|
};
|
|
1672
1672
|
attachComponentData(FeatureFlagged, "core.featureFlagged", true);
|
|
1673
1673
|
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1674
|
+
const MATCH_ALL_ROUTE = {
|
|
1675
|
+
caseSensitive: false,
|
|
1676
|
+
path: "/*",
|
|
1677
|
+
element: "match-all",
|
|
1678
|
+
routeRefs: /* @__PURE__ */ new Set()
|
|
1679
|
+
};
|
|
1680
|
+
const routingV1Collector = createCollector(() => ({
|
|
1681
|
+
paths: /* @__PURE__ */ new Map(),
|
|
1682
|
+
parents: /* @__PURE__ */ new Map(),
|
|
1683
|
+
objects: new Array()
|
|
1684
|
+
}), (acc, node, parent, ctx) => {
|
|
1685
|
+
var _a, _b, _c, _d, _e;
|
|
1686
1686
|
if ((parent == null ? void 0 : parent.props.element) === node) {
|
|
1687
|
-
return
|
|
1687
|
+
return ctx;
|
|
1688
1688
|
}
|
|
1689
|
+
let currentObj = ctx == null ? void 0 : ctx.obj;
|
|
1690
|
+
let currentParentRouteRef = ctx == null ? void 0 : ctx.routeRef;
|
|
1691
|
+
let sticky = ctx == null ? void 0 : ctx.sticky;
|
|
1692
|
+
const path = (_a = node.props) == null ? void 0 : _a.path;
|
|
1693
|
+
const parentChildren = (_b = currentObj == null ? void 0 : currentObj.children) != null ? _b : acc.objects;
|
|
1694
|
+
const caseSensitive = Boolean((_c = node.props) == null ? void 0 : _c.caseSensitive);
|
|
1695
|
+
let currentCtxPath = ctx == null ? void 0 : ctx.path;
|
|
1689
1696
|
if (getComponentData(node, "core.gatherMountPoints")) {
|
|
1690
|
-
const path = (_a = node.props) == null ? void 0 : _a.path;
|
|
1691
1697
|
if (!path) {
|
|
1692
1698
|
throw new Error("Mount point gatherer must have a path");
|
|
1693
1699
|
}
|
|
1694
1700
|
currentCtxPath = path;
|
|
1695
1701
|
}
|
|
1696
|
-
const
|
|
1702
|
+
const element = (_d = node.props) == null ? void 0 : _d.element;
|
|
1703
|
+
let routeRef = getComponentData(node, "core.mountPoint");
|
|
1704
|
+
if (!routeRef && isValidElement(element)) {
|
|
1705
|
+
routeRef = getComponentData(element, "core.mountPoint");
|
|
1706
|
+
}
|
|
1697
1707
|
if (routeRef) {
|
|
1698
|
-
let
|
|
1708
|
+
let routePath = path;
|
|
1699
1709
|
if (currentCtxPath) {
|
|
1700
|
-
if (
|
|
1710
|
+
if (routePath) {
|
|
1701
1711
|
currentCtxPath = void 0;
|
|
1702
1712
|
} else {
|
|
1703
|
-
|
|
1713
|
+
routePath = currentCtxPath;
|
|
1704
1714
|
}
|
|
1705
1715
|
}
|
|
1706
|
-
if (!
|
|
1716
|
+
if (!routePath) {
|
|
1707
1717
|
throw new Error("Mounted routable extension must have a path");
|
|
1708
1718
|
}
|
|
1709
|
-
acc.set(routeRef,
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
if ((parent == null ? void 0 : parent.props.element) === node) {
|
|
1716
|
-
return parentRouteRef;
|
|
1717
|
-
}
|
|
1718
|
-
let nextParent = parentRouteRef;
|
|
1719
|
-
const routeRef = getMountPoint(node);
|
|
1720
|
-
if (routeRef) {
|
|
1721
|
-
if (parentRouteRef && "sticky" in parentRouteRef) {
|
|
1722
|
-
acc.set(routeRef, parentRouteRef.sticky);
|
|
1723
|
-
if ((_a = node.props) == null ? void 0 : _a.path) {
|
|
1724
|
-
nextParent = routeRef;
|
|
1725
|
-
} else {
|
|
1726
|
-
nextParent = parentRouteRef;
|
|
1719
|
+
acc.paths.set(routeRef, routePath);
|
|
1720
|
+
if (currentParentRouteRef && sticky) {
|
|
1721
|
+
acc.parents.set(routeRef, currentParentRouteRef);
|
|
1722
|
+
if (path) {
|
|
1723
|
+
currentParentRouteRef = routeRef;
|
|
1724
|
+
sticky = false;
|
|
1727
1725
|
}
|
|
1728
1726
|
} else {
|
|
1729
|
-
acc.set(routeRef,
|
|
1730
|
-
|
|
1727
|
+
acc.parents.set(routeRef, currentParentRouteRef);
|
|
1728
|
+
currentParentRouteRef = routeRef;
|
|
1731
1729
|
}
|
|
1732
|
-
}
|
|
1733
|
-
if (getComponentData(node, "core.gatherMountPoints")) {
|
|
1734
|
-
return { sticky: nextParent };
|
|
1735
|
-
}
|
|
1736
|
-
return nextParent;
|
|
1737
|
-
});
|
|
1738
|
-
const MATCH_ALL_ROUTE = {
|
|
1739
|
-
caseSensitive: false,
|
|
1740
|
-
path: "/*",
|
|
1741
|
-
element: "match-all",
|
|
1742
|
-
routeRefs: /* @__PURE__ */ new Set()
|
|
1743
|
-
};
|
|
1744
|
-
const routeObjectCollector = createCollector(() => Array(), (acc, node, parent, parentObj) => {
|
|
1745
|
-
var _a, _b, _c;
|
|
1746
|
-
const parentChildren = (_a = parentObj == null ? void 0 : parentObj.children) != null ? _a : acc;
|
|
1747
|
-
if ((parent == null ? void 0 : parent.props.element) === node) {
|
|
1748
|
-
return parentObj;
|
|
1749
|
-
}
|
|
1750
|
-
const path = (_b = node.props) == null ? void 0 : _b.path;
|
|
1751
|
-
const caseSensitive = Boolean((_c = node.props) == null ? void 0 : _c.caseSensitive);
|
|
1752
|
-
const routeRef = getMountPoint(node);
|
|
1753
|
-
if (routeRef) {
|
|
1754
1730
|
if (path) {
|
|
1755
|
-
|
|
1731
|
+
currentObj = {
|
|
1756
1732
|
caseSensitive,
|
|
1757
1733
|
path,
|
|
1758
1734
|
element: "mounted",
|
|
@@ -1760,28 +1736,37 @@ const routeObjectCollector = createCollector(() => Array(), (acc, node, parent,
|
|
|
1760
1736
|
children: [MATCH_ALL_ROUTE],
|
|
1761
1737
|
plugin: getComponentData(node.props.element, "core.plugin")
|
|
1762
1738
|
};
|
|
1763
|
-
parentChildren.push(
|
|
1764
|
-
|
|
1739
|
+
parentChildren.push(currentObj);
|
|
1740
|
+
} else {
|
|
1741
|
+
currentObj == null ? void 0 : currentObj.routeRefs.add(routeRef);
|
|
1765
1742
|
}
|
|
1766
|
-
|
|
1743
|
+
}
|
|
1744
|
+
if (getComponentData(node, "core.gatherMountPoints")) {
|
|
1745
|
+
sticky = true;
|
|
1767
1746
|
}
|
|
1768
1747
|
const isGatherer = getComponentData(node, "core.gatherMountPoints");
|
|
1769
1748
|
if (isGatherer) {
|
|
1770
1749
|
if (!path) {
|
|
1771
1750
|
throw new Error("Mount point gatherer must have a path");
|
|
1772
1751
|
}
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1752
|
+
if (!routeRef) {
|
|
1753
|
+
currentObj = {
|
|
1754
|
+
caseSensitive,
|
|
1755
|
+
path,
|
|
1756
|
+
element: "gathered",
|
|
1757
|
+
routeRefs: /* @__PURE__ */ new Set(),
|
|
1758
|
+
children: [MATCH_ALL_ROUTE],
|
|
1759
|
+
plugin: (_e = ctx == null ? void 0 : ctx.obj) == null ? void 0 : _e.plugin
|
|
1760
|
+
};
|
|
1761
|
+
parentChildren.push(currentObj);
|
|
1762
|
+
}
|
|
1783
1763
|
}
|
|
1784
|
-
return
|
|
1764
|
+
return {
|
|
1765
|
+
obj: currentObj,
|
|
1766
|
+
path: currentCtxPath,
|
|
1767
|
+
routeRef: currentParentRouteRef,
|
|
1768
|
+
sticky
|
|
1769
|
+
};
|
|
1785
1770
|
});
|
|
1786
1771
|
const featureFlagCollector = createCollector(() => /* @__PURE__ */ new Set(), (acc, node) => {
|
|
1787
1772
|
if (node.type === FeatureFlagged) {
|
|
@@ -1964,17 +1949,10 @@ const TrackNavigation = ({
|
|
|
1964
1949
|
}, [analytics, pathname, search, hash]);
|
|
1965
1950
|
return null;
|
|
1966
1951
|
};
|
|
1967
|
-
const RouteTracker = ({
|
|
1952
|
+
const RouteTracker = ({
|
|
1953
|
+
routeObjects
|
|
1954
|
+
}) => {
|
|
1968
1955
|
const { pathname, search, hash } = useLocation();
|
|
1969
|
-
const { routeObjects } = useMemo(() => {
|
|
1970
|
-
return traverseElementTree({
|
|
1971
|
-
root: tree,
|
|
1972
|
-
discoverers: [childDiscoverer, routeElementDiscoverer],
|
|
1973
|
-
collectors: {
|
|
1974
|
-
routeObjects: routeObjectCollector
|
|
1975
|
-
}
|
|
1976
|
-
});
|
|
1977
|
-
}, [tree]);
|
|
1978
1956
|
return /* @__PURE__ */ React.createElement(AnalyticsContext, {
|
|
1979
1957
|
attributes: getExtensionContext(pathname, routeObjects)
|
|
1980
1958
|
}, /* @__PURE__ */ React.createElement(TrackNavigation, {
|
|
@@ -2239,6 +2217,7 @@ function resolveRouteBindings(bindRoutes) {
|
|
|
2239
2217
|
return result;
|
|
2240
2218
|
}
|
|
2241
2219
|
|
|
2220
|
+
const InternalAppContext = createContext({ routeObjects: [] });
|
|
2242
2221
|
function getBasePath(configApi) {
|
|
2243
2222
|
var _a;
|
|
2244
2223
|
let { pathname } = new URL((_a = configApi.getOptionalString("app.baseUrl")) != null ? _a : "/", "http://dummy.dev");
|
|
@@ -2313,20 +2292,12 @@ class AppManager {
|
|
|
2313
2292
|
let routesHaveBeenValidated = false;
|
|
2314
2293
|
const Provider = ({ children }) => {
|
|
2315
2294
|
const appThemeApi = useMemo(() => AppThemeSelector.createWithStorage(this.themes), []);
|
|
2316
|
-
const {
|
|
2317
|
-
routePaths,
|
|
2318
|
-
routeParents,
|
|
2319
|
-
routeObjects,
|
|
2320
|
-
featureFlags,
|
|
2321
|
-
routeBindings
|
|
2322
|
-
} = useMemo(() => {
|
|
2295
|
+
const { routing, featureFlags, routeBindings } = useMemo(() => {
|
|
2323
2296
|
const result = traverseElementTree({
|
|
2324
2297
|
root: children,
|
|
2325
2298
|
discoverers: [childDiscoverer, routeElementDiscoverer],
|
|
2326
2299
|
collectors: {
|
|
2327
|
-
|
|
2328
|
-
routeParents: routeParentCollector,
|
|
2329
|
-
routeObjects: routeObjectCollector,
|
|
2300
|
+
routing: routingV1Collector,
|
|
2330
2301
|
collectedPlugins: pluginCollector,
|
|
2331
2302
|
featureFlags: featureFlagCollector
|
|
2332
2303
|
}
|
|
@@ -2341,7 +2312,7 @@ class AppManager {
|
|
|
2341
2312
|
}, [children]);
|
|
2342
2313
|
if (!routesHaveBeenValidated) {
|
|
2343
2314
|
routesHaveBeenValidated = true;
|
|
2344
|
-
validateRouteParameters(
|
|
2315
|
+
validateRouteParameters(routing.paths, routing.parents);
|
|
2345
2316
|
validateRouteBindings(routeBindings, this.plugins);
|
|
2346
2317
|
}
|
|
2347
2318
|
const loadedConfig = useConfigLoader(this.configLoader, this.components, appThemeApi);
|
|
@@ -2386,12 +2357,14 @@ class AppManager {
|
|
|
2386
2357
|
}, /* @__PURE__ */ React.createElement(AppContextProvider, {
|
|
2387
2358
|
appContext
|
|
2388
2359
|
}, /* @__PURE__ */ React.createElement(ThemeProvider, null, /* @__PURE__ */ React.createElement(RoutingProvider, {
|
|
2389
|
-
routePaths,
|
|
2390
|
-
routeParents,
|
|
2391
|
-
routeObjects,
|
|
2360
|
+
routePaths: routing.paths,
|
|
2361
|
+
routeParents: routing.parents,
|
|
2362
|
+
routeObjects: routing.objects,
|
|
2392
2363
|
routeBindings,
|
|
2393
2364
|
basePath: getBasePath(loadedConfig.api)
|
|
2394
|
-
},
|
|
2365
|
+
}, /* @__PURE__ */ React.createElement(InternalAppContext.Provider, {
|
|
2366
|
+
value: { routeObjects: routing.objects }
|
|
2367
|
+
}, children)))));
|
|
2395
2368
|
};
|
|
2396
2369
|
return Provider;
|
|
2397
2370
|
}
|
|
@@ -2413,6 +2386,7 @@ class AppManager {
|
|
|
2413
2386
|
const AppRouter = ({ children }) => {
|
|
2414
2387
|
const configApi = useApi(configApiRef);
|
|
2415
2388
|
const mountPath = `${getBasePath(configApi)}/*`;
|
|
2389
|
+
const { routeObjects } = useContext(InternalAppContext);
|
|
2416
2390
|
if (!SignInPageComponent) {
|
|
2417
2391
|
this.appIdentityProxy.setTarget({
|
|
2418
2392
|
getUserId: () => "guest",
|
|
@@ -2435,14 +2409,14 @@ class AppManager {
|
|
|
2435
2409
|
}
|
|
2436
2410
|
});
|
|
2437
2411
|
return /* @__PURE__ */ React.createElement(RouterComponent, null, /* @__PURE__ */ React.createElement(RouteTracker, {
|
|
2438
|
-
|
|
2412
|
+
routeObjects
|
|
2439
2413
|
}), /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, {
|
|
2440
2414
|
path: mountPath,
|
|
2441
2415
|
element: /* @__PURE__ */ React.createElement(React.Fragment, null, children)
|
|
2442
2416
|
})));
|
|
2443
2417
|
}
|
|
2444
2418
|
return /* @__PURE__ */ React.createElement(RouterComponent, null, /* @__PURE__ */ React.createElement(RouteTracker, {
|
|
2445
|
-
|
|
2419
|
+
routeObjects
|
|
2446
2420
|
}), /* @__PURE__ */ React.createElement(SignInPageWrapper, {
|
|
2447
2421
|
component: SignInPageComponent
|
|
2448
2422
|
}, /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, {
|