@backstage/frontend-plugin-api 0.3.0 → 0.4.0-next.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/dist/index.d.ts +323 -50
- package/dist/index.esm.js +253 -23
- package/dist/index.esm.js.map +1 -1
- package/package.json +8 -6
package/dist/index.esm.js
CHANGED
|
@@ -1,14 +1,189 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import React, { Component, Suspense, useEffect, lazy, useMemo } from 'react';
|
|
1
|
+
import { createVersionedContext, createVersionedValueMap, getOrCreateGlobalSingleton, useVersionedContext } from '@backstage/version-bridge';
|
|
2
|
+
import React, { useContext, useRef, Component, Suspense, useEffect, lazy, useMemo } from 'react';
|
|
3
|
+
import { createApiRef, useApi, AnalyticsContext as AnalyticsContext$1, useAnalytics as useAnalytics$1 } from '@backstage/core-plugin-api';
|
|
4
|
+
export { SessionState, alertApiRef, appThemeApiRef, atlassianAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, configApiRef, createApiFactory, createApiRef, discoveryApiRef, errorApiRef, featureFlagsApiRef, fetchApiRef, githubAuthApiRef, gitlabAuthApiRef, googleAuthApiRef, identityApiRef, microsoftAuthApiRef, oauthRequestApiRef, oktaAuthApiRef, oneloginAuthApiRef, storageApiRef, useApi, useApiHolder, withApis } from '@backstage/core-plugin-api';
|
|
3
5
|
import { Button } from '@material-ui/core';
|
|
4
6
|
import { ErrorPanel } from '@backstage/core-components';
|
|
5
|
-
import { getOrCreateGlobalSingleton, useVersionedContext } from '@backstage/version-bridge';
|
|
6
7
|
import { z } from 'zod';
|
|
7
8
|
import zodToJsonSchema from 'zod-to-json-schema';
|
|
8
9
|
import { useLocation, useParams } from 'react-router-dom';
|
|
9
10
|
|
|
11
|
+
const AnalyticsReactContext = createVersionedContext("analytics-context");
|
|
12
|
+
const useAnalyticsContext = () => {
|
|
13
|
+
const theContext = useContext(AnalyticsReactContext);
|
|
14
|
+
if (theContext === void 0) {
|
|
15
|
+
return {
|
|
16
|
+
pluginId: "root",
|
|
17
|
+
extensionId: "App"
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const theValue = theContext.atVersion(1);
|
|
21
|
+
if (theValue === void 0) {
|
|
22
|
+
throw new Error("No context found for version 1.");
|
|
23
|
+
}
|
|
24
|
+
return theValue;
|
|
25
|
+
};
|
|
26
|
+
const AnalyticsContext = (options) => {
|
|
27
|
+
const { attributes, children } = options;
|
|
28
|
+
const parentValues = useAnalyticsContext();
|
|
29
|
+
const combinedValue = {
|
|
30
|
+
...parentValues,
|
|
31
|
+
...attributes
|
|
32
|
+
};
|
|
33
|
+
const versionedCombinedValue = createVersionedValueMap({ 1: combinedValue });
|
|
34
|
+
return /* @__PURE__ */ React.createElement(AnalyticsReactContext.Provider, { value: versionedCombinedValue }, children);
|
|
35
|
+
};
|
|
36
|
+
|
|
10
37
|
const appTreeApiRef = createApiRef({ id: "core.app-tree" });
|
|
11
38
|
|
|
39
|
+
const componentsApiRef = createApiRef({
|
|
40
|
+
id: "core.components"
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const analyticsApiRef = createApiRef({
|
|
44
|
+
id: "core.analytics"
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const globalEvents = getOrCreateGlobalSingleton(
|
|
48
|
+
"core-plugin-api:analytics-tracker-events",
|
|
49
|
+
() => ({
|
|
50
|
+
mostRecentGatheredNavigation: void 0,
|
|
51
|
+
mostRecentRoutableExtensionRender: void 0,
|
|
52
|
+
beforeUnloadRegistered: false
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
const routableExtensionRenderedEvent$1 = "_ROUTABLE-EXTENSION-RENDERED";
|
|
56
|
+
class Tracker {
|
|
57
|
+
constructor(analyticsApi, context = {
|
|
58
|
+
pluginId: "root",
|
|
59
|
+
extensionId: "App"
|
|
60
|
+
}) {
|
|
61
|
+
this.analyticsApi = analyticsApi;
|
|
62
|
+
this.context = context;
|
|
63
|
+
if (!globalEvents.beforeUnloadRegistered) {
|
|
64
|
+
addEventListener(
|
|
65
|
+
"beforeunload",
|
|
66
|
+
() => {
|
|
67
|
+
if (globalEvents.mostRecentGatheredNavigation) {
|
|
68
|
+
this.analyticsApi.captureEvent({
|
|
69
|
+
...globalEvents.mostRecentGatheredNavigation,
|
|
70
|
+
...globalEvents.mostRecentRoutableExtensionRender
|
|
71
|
+
});
|
|
72
|
+
globalEvents.mostRecentGatheredNavigation = void 0;
|
|
73
|
+
globalEvents.mostRecentRoutableExtensionRender = void 0;
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{ once: true, passive: true }
|
|
77
|
+
);
|
|
78
|
+
globalEvents.beforeUnloadRegistered = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
setContext(context) {
|
|
82
|
+
this.context = context;
|
|
83
|
+
}
|
|
84
|
+
captureEvent(action, subject, {
|
|
85
|
+
value,
|
|
86
|
+
attributes
|
|
87
|
+
} = {}) {
|
|
88
|
+
const context = this.context;
|
|
89
|
+
if (action === routableExtensionRenderedEvent$1) {
|
|
90
|
+
if (globalEvents.mostRecentGatheredNavigation) {
|
|
91
|
+
globalEvents.mostRecentRoutableExtensionRender = {
|
|
92
|
+
context: {
|
|
93
|
+
...context,
|
|
94
|
+
extensionId: "App"
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (globalEvents.mostRecentGatheredNavigation) {
|
|
101
|
+
try {
|
|
102
|
+
this.analyticsApi.captureEvent({
|
|
103
|
+
...globalEvents.mostRecentGatheredNavigation,
|
|
104
|
+
...globalEvents.mostRecentRoutableExtensionRender
|
|
105
|
+
});
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.warn("Error during analytics event capture. %o", e);
|
|
108
|
+
}
|
|
109
|
+
globalEvents.mostRecentGatheredNavigation = void 0;
|
|
110
|
+
globalEvents.mostRecentRoutableExtensionRender = void 0;
|
|
111
|
+
}
|
|
112
|
+
if (action === "navigate" && context.pluginId === "root") {
|
|
113
|
+
globalEvents.mostRecentGatheredNavigation = {
|
|
114
|
+
action,
|
|
115
|
+
subject,
|
|
116
|
+
value,
|
|
117
|
+
attributes,
|
|
118
|
+
context
|
|
119
|
+
};
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
this.analyticsApi.captureEvent({
|
|
124
|
+
action,
|
|
125
|
+
subject,
|
|
126
|
+
value,
|
|
127
|
+
attributes,
|
|
128
|
+
context
|
|
129
|
+
});
|
|
130
|
+
} catch (e) {
|
|
131
|
+
console.warn("Error during analytics event capture. %o", e);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function useAnalyticsApi() {
|
|
137
|
+
try {
|
|
138
|
+
return useApi(analyticsApiRef);
|
|
139
|
+
} catch {
|
|
140
|
+
return { captureEvent: () => {
|
|
141
|
+
} };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function useAnalytics() {
|
|
145
|
+
const trackerRef = useRef(null);
|
|
146
|
+
const context = useAnalyticsContext();
|
|
147
|
+
const analyticsApi = useAnalyticsApi();
|
|
148
|
+
function getTracker() {
|
|
149
|
+
if (trackerRef.current === null) {
|
|
150
|
+
trackerRef.current = new Tracker(analyticsApi);
|
|
151
|
+
}
|
|
152
|
+
return trackerRef.current;
|
|
153
|
+
}
|
|
154
|
+
const tracker = getTracker();
|
|
155
|
+
tracker.setContext(context);
|
|
156
|
+
return tracker;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function createComponentRef(options) {
|
|
160
|
+
const { id } = options;
|
|
161
|
+
return {
|
|
162
|
+
id,
|
|
163
|
+
get T() {
|
|
164
|
+
throw new Error(`tried to read ComponentRef.T of ${id}`);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const coreProgressComponentRef = createComponentRef({
|
|
169
|
+
id: "core.components.progress"
|
|
170
|
+
});
|
|
171
|
+
const coreBootErrorPageComponentRef = createComponentRef({
|
|
172
|
+
id: "core.components.bootErrorPage"
|
|
173
|
+
});
|
|
174
|
+
const coreNotFoundErrorPageComponentRef = createComponentRef({
|
|
175
|
+
id: "core.components.notFoundErrorPage"
|
|
176
|
+
});
|
|
177
|
+
const coreErrorBoundaryFallbackComponentRef = createComponentRef({
|
|
178
|
+
id: "core.components.errorBoundaryFallback"
|
|
179
|
+
});
|
|
180
|
+
const coreComponentsRefs = {
|
|
181
|
+
progress: coreProgressComponentRef,
|
|
182
|
+
bootErrorPage: coreBootErrorPageComponentRef,
|
|
183
|
+
notFoundErrorPage: coreNotFoundErrorPageComponentRef,
|
|
184
|
+
errorBoundaryFallback: coreErrorBoundaryFallbackComponentRef
|
|
185
|
+
};
|
|
186
|
+
|
|
12
187
|
var __defProp$3 = Object.defineProperty;
|
|
13
188
|
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
189
|
var __publicField$3 = (obj, key, value) => {
|
|
@@ -51,13 +226,6 @@ class ErrorBoundary extends Component {
|
|
|
51
226
|
}
|
|
52
227
|
}
|
|
53
228
|
|
|
54
|
-
function ExtensionSuspense(props) {
|
|
55
|
-
const { children } = props;
|
|
56
|
-
const app = useApp();
|
|
57
|
-
const { Progress } = app.getComponents();
|
|
58
|
-
return /* @__PURE__ */ React.createElement(Suspense, { fallback: /* @__PURE__ */ React.createElement(Progress, null) }, children);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
229
|
getOrCreateGlobalSingleton(
|
|
62
230
|
"core-plugin-api:analytics-tracker-events",
|
|
63
231
|
() => ({
|
|
@@ -70,7 +238,7 @@ const routableExtensionRenderedEvent = "_ROUTABLE-EXTENSION-RENDERED";
|
|
|
70
238
|
|
|
71
239
|
const RouteTracker = (props) => {
|
|
72
240
|
const { disableTracking, children } = props;
|
|
73
|
-
const analytics = useAnalytics();
|
|
241
|
+
const analytics = useAnalytics$1();
|
|
74
242
|
useEffect(() => {
|
|
75
243
|
if (disableTracking)
|
|
76
244
|
return;
|
|
@@ -79,12 +247,13 @@ const RouteTracker = (props) => {
|
|
|
79
247
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
80
248
|
};
|
|
81
249
|
function ExtensionBoundary(props) {
|
|
82
|
-
|
|
250
|
+
var _a;
|
|
251
|
+
const { node, routable, children } = props;
|
|
83
252
|
const attributes = {
|
|
84
|
-
extension: id,
|
|
85
|
-
pluginId: source == null ? void 0 :
|
|
253
|
+
extension: node.spec.id,
|
|
254
|
+
pluginId: (_a = node.spec.source) == null ? void 0 : _a.id
|
|
86
255
|
};
|
|
87
|
-
return /* @__PURE__ */ React.createElement(
|
|
256
|
+
return /* @__PURE__ */ React.createElement(Suspense, { fallback: "Loading..." }, /* @__PURE__ */ React.createElement(ErrorBoundary, { plugin: node.spec.source }, /* @__PURE__ */ React.createElement(AnalyticsContext$1, { attributes }, /* @__PURE__ */ React.createElement(RouteTracker, { disableTracking: !routable }, children))));
|
|
88
257
|
}
|
|
89
258
|
|
|
90
259
|
function createExtensionDataRef(id) {
|
|
@@ -104,7 +273,9 @@ const coreExtensionData = {
|
|
|
104
273
|
apiFactory: createExtensionDataRef("core.api.factory"),
|
|
105
274
|
routeRef: createExtensionDataRef("core.routing.ref"),
|
|
106
275
|
navTarget: createExtensionDataRef("core.nav.target"),
|
|
107
|
-
theme: createExtensionDataRef("core.theme")
|
|
276
|
+
theme: createExtensionDataRef("core.theme"),
|
|
277
|
+
logoElements: createExtensionDataRef("core.logos"),
|
|
278
|
+
component: createExtensionDataRef("component.ref")
|
|
108
279
|
};
|
|
109
280
|
|
|
110
281
|
function createExtension(options) {
|
|
@@ -135,21 +306,25 @@ function createExtensionInput(extensionData, config) {
|
|
|
135
306
|
}
|
|
136
307
|
|
|
137
308
|
function createPlugin(options) {
|
|
138
|
-
var _a, _b, _c;
|
|
309
|
+
var _a, _b, _c, _d;
|
|
139
310
|
return {
|
|
140
|
-
|
|
311
|
+
$$type: "@backstage/BackstagePlugin",
|
|
312
|
+
version: "v1",
|
|
313
|
+
id: options.id,
|
|
141
314
|
routes: (_a = options.routes) != null ? _a : {},
|
|
142
315
|
externalRoutes: (_b = options.externalRoutes) != null ? _b : {},
|
|
143
316
|
extensions: (_c = options.extensions) != null ? _c : [],
|
|
144
|
-
|
|
317
|
+
featureFlags: (_d = options.featureFlags) != null ? _d : []
|
|
145
318
|
};
|
|
146
319
|
}
|
|
147
320
|
|
|
148
321
|
function createExtensionOverrides(options) {
|
|
322
|
+
var _a;
|
|
149
323
|
return {
|
|
150
324
|
$$type: "@backstage/ExtensionOverrides",
|
|
151
325
|
version: "v1",
|
|
152
|
-
extensions: options.extensions
|
|
326
|
+
extensions: options.extensions,
|
|
327
|
+
featureFlags: (_a = options.featureFlags) != null ? _a : []
|
|
153
328
|
};
|
|
154
329
|
}
|
|
155
330
|
|
|
@@ -219,14 +394,14 @@ function createPageExtension(options) {
|
|
|
219
394
|
path: coreExtensionData.routePath,
|
|
220
395
|
routeRef: coreExtensionData.routeRef.optional()
|
|
221
396
|
},
|
|
222
|
-
factory({ config, inputs,
|
|
397
|
+
factory({ config, inputs, node }) {
|
|
223
398
|
const ExtensionComponent = lazy(
|
|
224
399
|
() => options.loader({ config, inputs }).then((element) => ({ default: () => element }))
|
|
225
400
|
);
|
|
226
401
|
return {
|
|
227
402
|
path: config.path,
|
|
228
403
|
routeRef: options.routeRef,
|
|
229
|
-
element: /* @__PURE__ */ React.createElement(ExtensionBoundary, {
|
|
404
|
+
element: /* @__PURE__ */ React.createElement(ExtensionBoundary, { node, routable: true }, /* @__PURE__ */ React.createElement(ExtensionComponent, null))
|
|
230
405
|
};
|
|
231
406
|
}
|
|
232
407
|
});
|
|
@@ -255,6 +430,30 @@ function createNavItemExtension(options) {
|
|
|
255
430
|
});
|
|
256
431
|
}
|
|
257
432
|
|
|
433
|
+
const signInPageComponentDataRef = createExtensionDataRef("core.signInPage");
|
|
434
|
+
function createSignInPageExtension(options) {
|
|
435
|
+
var _a;
|
|
436
|
+
const { id } = options;
|
|
437
|
+
return createExtension({
|
|
438
|
+
id,
|
|
439
|
+
attachTo: (_a = options.attachTo) != null ? _a : { id: "core.router", input: "signInPage" },
|
|
440
|
+
configSchema: options.configSchema,
|
|
441
|
+
inputs: options.inputs,
|
|
442
|
+
disabled: options.disabled,
|
|
443
|
+
output: {
|
|
444
|
+
component: signInPageComponentDataRef
|
|
445
|
+
},
|
|
446
|
+
factory({ config, inputs, node }) {
|
|
447
|
+
const ExtensionComponent = lazy(
|
|
448
|
+
() => options.loader({ config, inputs }).then((component) => ({ default: component }))
|
|
449
|
+
);
|
|
450
|
+
return {
|
|
451
|
+
component: (props) => /* @__PURE__ */ React.createElement(ExtensionBoundary, { node, routable: true }, /* @__PURE__ */ React.createElement(ExtensionComponent, { ...props }))
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
|
|
258
457
|
function createThemeExtension(theme) {
|
|
259
458
|
return createExtension({
|
|
260
459
|
id: `themes.${theme.id}`,
|
|
@@ -266,6 +465,37 @@ function createThemeExtension(theme) {
|
|
|
266
465
|
});
|
|
267
466
|
}
|
|
268
467
|
|
|
468
|
+
function createComponentExtension(options) {
|
|
469
|
+
const id = options.ref.id;
|
|
470
|
+
return createExtension({
|
|
471
|
+
id,
|
|
472
|
+
attachTo: { id: "core", input: "components" },
|
|
473
|
+
inputs: options.inputs,
|
|
474
|
+
disabled: options.disabled,
|
|
475
|
+
configSchema: options.configSchema,
|
|
476
|
+
output: {
|
|
477
|
+
component: coreExtensionData.component
|
|
478
|
+
},
|
|
479
|
+
factory({ config, inputs, node }) {
|
|
480
|
+
let ExtensionComponent;
|
|
481
|
+
if ("sync" in options.component) {
|
|
482
|
+
ExtensionComponent = options.component.sync({ config, inputs });
|
|
483
|
+
} else {
|
|
484
|
+
const loader = options.component.lazy({ config, inputs });
|
|
485
|
+
ExtensionComponent = lazy(
|
|
486
|
+
() => loader.then((component) => ({ default: component }))
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
component: {
|
|
491
|
+
ref: options.ref,
|
|
492
|
+
impl: (props) => /* @__PURE__ */ React.createElement(ExtensionBoundary, { node }, /* @__PURE__ */ React.createElement(ExtensionComponent, { ...props }))
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
269
499
|
const MESSAGE_MARKER = "eHgtF5hmbrXyiEvo";
|
|
270
500
|
function describeParentCallSite(ErrorConstructor = Error) {
|
|
271
501
|
const { stack } = new ErrorConstructor(MESSAGE_MARKER);
|
|
@@ -504,5 +734,5 @@ function useRouteRefParams(_routeRef) {
|
|
|
504
734
|
return useParams();
|
|
505
735
|
}
|
|
506
736
|
|
|
507
|
-
export { ExtensionBoundary, appTreeApiRef, coreExtensionData, createApiExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSubRouteRef, createThemeExtension, useRouteRef, useRouteRefParams };
|
|
737
|
+
export { AnalyticsContext, ExtensionBoundary, analyticsApiRef, appTreeApiRef, componentsApiRef, coreComponentsRefs, coreExtensionData, createApiExtension, createComponentExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSignInPageExtension, createSubRouteRef, createThemeExtension, useAnalytics, useRouteRef, useRouteRefParams };
|
|
508
738
|
//# sourceMappingURL=index.esm.js.map
|