@backstage/frontend-plugin-api 0.6.4 → 0.6.5-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/analytics/AnalyticsContext.esm.js +31 -0
  3. package/dist/analytics/AnalyticsContext.esm.js.map +1 -0
  4. package/dist/analytics/Tracker.esm.js +93 -0
  5. package/dist/analytics/Tracker.esm.js.map +1 -0
  6. package/dist/analytics/useAnalytics.esm.js +38 -0
  7. package/dist/analytics/useAnalytics.esm.js.map +1 -0
  8. package/dist/apis/definitions/AnalyticsApi.esm.js +8 -0
  9. package/dist/apis/definitions/AnalyticsApi.esm.js.map +1 -0
  10. package/dist/apis/definitions/AppTreeApi.esm.js +6 -0
  11. package/dist/apis/definitions/AppTreeApi.esm.js.map +1 -0
  12. package/dist/apis/definitions/ComponentsApi.esm.js +12 -0
  13. package/dist/apis/definitions/ComponentsApi.esm.js.map +1 -0
  14. package/dist/apis/definitions/IconsApi.esm.js +8 -0
  15. package/dist/apis/definitions/IconsApi.esm.js.map +1 -0
  16. package/dist/apis/definitions/RouteResolutionApi.esm.js +8 -0
  17. package/dist/apis/definitions/RouteResolutionApi.esm.js.map +1 -0
  18. package/dist/components/ErrorBoundary.esm.js +38 -0
  19. package/dist/components/ErrorBoundary.esm.js.map +1 -0
  20. package/dist/components/ExtensionBoundary.esm.js +36 -0
  21. package/dist/components/ExtensionBoundary.esm.js.map +1 -0
  22. package/dist/components/coreComponentRefs.esm.js +19 -0
  23. package/dist/components/coreComponentRefs.esm.js.map +1 -0
  24. package/dist/components/createComponentRef.esm.js +12 -0
  25. package/dist/components/createComponentRef.esm.js.map +1 -0
  26. package/dist/core-plugin-api/src/analytics/Tracker.esm.js +14 -0
  27. package/dist/core-plugin-api/src/analytics/Tracker.esm.js.map +1 -0
  28. package/dist/extensions/createApiExtension.esm.js +31 -0
  29. package/dist/extensions/createApiExtension.esm.js.map +1 -0
  30. package/dist/extensions/createAppRootElementExtension.esm.js +26 -0
  31. package/dist/extensions/createAppRootElementExtension.esm.js.map +1 -0
  32. package/dist/extensions/createAppRootWrapperExtension.esm.js +35 -0
  33. package/dist/extensions/createAppRootWrapperExtension.esm.js.map +1 -0
  34. package/dist/extensions/createComponentExtension.esm.js +46 -0
  35. package/dist/extensions/createComponentExtension.esm.js.map +1 -0
  36. package/dist/extensions/createNavItemExtension.esm.js +34 -0
  37. package/dist/extensions/createNavItemExtension.esm.js.map +1 -0
  38. package/dist/extensions/createNavLogoExtension.esm.js +29 -0
  39. package/dist/extensions/createNavLogoExtension.esm.js.map +1 -0
  40. package/dist/extensions/createPageExtension.esm.js +39 -0
  41. package/dist/extensions/createPageExtension.esm.js.map +1 -0
  42. package/dist/extensions/createRouterExtension.esm.js +35 -0
  43. package/dist/extensions/createRouterExtension.esm.js.map +1 -0
  44. package/dist/extensions/createSignInPageExtension.esm.js +34 -0
  45. package/dist/extensions/createSignInPageExtension.esm.js.map +1 -0
  46. package/dist/extensions/createThemeExtension.esm.js +21 -0
  47. package/dist/extensions/createThemeExtension.esm.js.map +1 -0
  48. package/dist/extensions/createTranslationExtension.esm.js +21 -0
  49. package/dist/extensions/createTranslationExtension.esm.js.map +1 -0
  50. package/dist/index.esm.js +33 -969
  51. package/dist/index.esm.js.map +1 -1
  52. package/dist/routing/ExternalRouteRef.esm.js +32 -0
  53. package/dist/routing/ExternalRouteRef.esm.js.map +1 -0
  54. package/dist/routing/RouteRef.esm.js +86 -0
  55. package/dist/routing/RouteRef.esm.js.map +1 -0
  56. package/dist/routing/SubRouteRef.esm.js +86 -0
  57. package/dist/routing/SubRouteRef.esm.js.map +1 -0
  58. package/dist/routing/describeParentCallSite.esm.js +24 -0
  59. package/dist/routing/describeParentCallSite.esm.js.map +1 -0
  60. package/dist/routing/useRouteRef.esm.js +25 -0
  61. package/dist/routing/useRouteRef.esm.js.map +1 -0
  62. package/dist/routing/useRouteRefParams.esm.js +8 -0
  63. package/dist/routing/useRouteRefParams.esm.js.map +1 -0
  64. package/dist/schema/createSchemaFromZod.esm.js +34 -0
  65. package/dist/schema/createSchemaFromZod.esm.js.map +1 -0
  66. package/dist/wiring/coreExtensionData.esm.js +10 -0
  67. package/dist/wiring/coreExtensionData.esm.js.map +1 -0
  68. package/dist/wiring/createExtension.esm.js +52 -0
  69. package/dist/wiring/createExtension.esm.js.map +1 -0
  70. package/dist/wiring/createExtensionDataRef.esm.js +20 -0
  71. package/dist/wiring/createExtensionDataRef.esm.js.map +1 -0
  72. package/dist/wiring/createExtensionInput.esm.js +13 -0
  73. package/dist/wiring/createExtensionInput.esm.js.map +1 -0
  74. package/dist/wiring/createExtensionOverrides.esm.js +23 -0
  75. package/dist/wiring/createExtensionOverrides.esm.js.map +1 -0
  76. package/dist/wiring/createPlugin.esm.js +36 -0
  77. package/dist/wiring/createPlugin.esm.js.map +1 -0
  78. package/dist/wiring/resolveExtensionDefinition.esm.js +27 -0
  79. package/dist/wiring/resolveExtensionDefinition.esm.js.map +1 -0
  80. package/package.json +6 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @backstage/frontend-plugin-api
2
2
 
3
+ ## 0.6.5-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/core-components@0.14.5-next.0
9
+ - @backstage/core-plugin-api@1.9.2
10
+ - @backstage/types@1.1.1
11
+ - @backstage/version-bridge@1.0.8
12
+
3
13
  ## 0.6.4
4
14
 
5
15
  ### Patch Changes
@@ -0,0 +1,31 @@
1
+ import { createVersionedContext, createVersionedValueMap } from '@backstage/version-bridge';
2
+ import React, { useContext } from 'react';
3
+
4
+ const AnalyticsReactContext = createVersionedContext("analytics-context");
5
+ const useAnalyticsContext = () => {
6
+ const theContext = useContext(AnalyticsReactContext);
7
+ if (theContext === void 0) {
8
+ return {
9
+ pluginId: "app",
10
+ extensionId: "app"
11
+ };
12
+ }
13
+ const theValue = theContext.atVersion(1);
14
+ if (theValue === void 0) {
15
+ throw new Error("No context found for version 1.");
16
+ }
17
+ return theValue;
18
+ };
19
+ const AnalyticsContext = (options) => {
20
+ const { attributes, children } = options;
21
+ const parentValues = useAnalyticsContext();
22
+ const combinedValue = {
23
+ ...parentValues,
24
+ ...attributes
25
+ };
26
+ const versionedCombinedValue = createVersionedValueMap({ 1: combinedValue });
27
+ return /* @__PURE__ */ React.createElement(AnalyticsReactContext.Provider, { value: versionedCombinedValue }, children);
28
+ };
29
+
30
+ export { AnalyticsContext, useAnalyticsContext };
31
+ //# sourceMappingURL=AnalyticsContext.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsContext.esm.js","sources":["../../src/analytics/AnalyticsContext.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\nimport React, { ReactNode, useContext } from 'react';\nimport { AnalyticsContextValue } from './types';\n\nconst AnalyticsReactContext = createVersionedContext<{\n 1: AnalyticsContextValue;\n}>('analytics-context');\n\n/**\n * A \"private\" (to this package) hook that enables context inheritance and a\n * way to read Analytics Context values at event capture-time.\n *\n * @internal\n */\nexport const useAnalyticsContext = (): AnalyticsContextValue => {\n const theContext = useContext(AnalyticsReactContext);\n\n // Provide a default value if no value exists.\n if (theContext === undefined) {\n return {\n pluginId: 'app',\n extensionId: 'app',\n };\n }\n\n // This should probably never happen, but check for it.\n const theValue = theContext.atVersion(1);\n if (theValue === undefined) {\n throw new Error('No context found for version 1.');\n }\n\n return theValue;\n};\n\n/**\n * Provides components in the child react tree an Analytics Context, ensuring\n * all analytics events captured within the context have relevant attributes.\n *\n * @remarks\n *\n * Analytics contexts are additive, meaning the context ultimately emitted with\n * an event is the combination of all contexts in the parent tree.\n *\n * @public\n */\nexport const AnalyticsContext = (options: {\n attributes: Partial<AnalyticsContextValue>;\n children: ReactNode;\n}) => {\n const { attributes, children } = options;\n\n const parentValues = useAnalyticsContext();\n const combinedValue = {\n ...parentValues,\n ...attributes,\n };\n\n const versionedCombinedValue = createVersionedValueMap({ 1: combinedValue });\n return (\n <AnalyticsReactContext.Provider value={versionedCombinedValue}>\n {children}\n </AnalyticsReactContext.Provider>\n );\n};\n\n/**\n * Returns an HOC wrapping the provided component in an Analytics context with\n * the given values.\n *\n * @param Component - Component to be wrapped with analytics context attributes\n * @param values - Analytics context key/value pairs.\n * @internal\n */\nexport function withAnalyticsContext<TProps extends {}>(\n Component: React.ComponentType<TProps>,\n values: AnalyticsContextValue,\n) {\n const ComponentWithAnalyticsContext = (props: TProps) => {\n return (\n <AnalyticsContext attributes={values}>\n <Component {...props} />\n </AnalyticsContext>\n );\n };\n ComponentWithAnalyticsContext.displayName = `WithAnalyticsContext(${\n Component.displayName || Component.name || 'Component'\n })`;\n return ComponentWithAnalyticsContext;\n}\n"],"names":[],"mappings":";;;AAuBA,MAAM,qBAAA,GAAwB,uBAE3B,mBAAmB,CAAA,CAAA;AAQf,MAAM,sBAAsB,MAA6B;AAC9D,EAAM,MAAA,UAAA,GAAa,WAAW,qBAAqB,CAAA,CAAA;AAGnD,EAAA,IAAI,eAAe,KAAW,CAAA,EAAA;AAC5B,IAAO,OAAA;AAAA,MACL,QAAU,EAAA,KAAA;AAAA,MACV,WAAa,EAAA,KAAA;AAAA,KACf,CAAA;AAAA,GACF;AAGA,EAAM,MAAA,QAAA,GAAW,UAAW,CAAA,SAAA,CAAU,CAAC,CAAA,CAAA;AACvC,EAAA,IAAI,aAAa,KAAW,CAAA,EAAA;AAC1B,IAAM,MAAA,IAAI,MAAM,iCAAiC,CAAA,CAAA;AAAA,GACnD;AAEA,EAAO,OAAA,QAAA,CAAA;AACT,EAAA;AAaa,MAAA,gBAAA,GAAmB,CAAC,OAG3B,KAAA;AACJ,EAAM,MAAA,EAAE,UAAY,EAAA,QAAA,EAAa,GAAA,OAAA,CAAA;AAEjC,EAAA,MAAM,eAAe,mBAAoB,EAAA,CAAA;AACzC,EAAA,MAAM,aAAgB,GAAA;AAAA,IACpB,GAAG,YAAA;AAAA,IACH,GAAG,UAAA;AAAA,GACL,CAAA;AAEA,EAAA,MAAM,sBAAyB,GAAA,uBAAA,CAAwB,EAAE,CAAA,EAAG,eAAe,CAAA,CAAA;AAC3E,EAAA,2CACG,qBAAsB,CAAA,QAAA,EAAtB,EAA+B,KAAA,EAAO,0BACpC,QACH,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,93 @@
1
+ import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
2
+
3
+ const globalEvents = getOrCreateGlobalSingleton(
4
+ "core-plugin-api:analytics-tracker-events",
5
+ () => ({
6
+ mostRecentGatheredNavigation: void 0,
7
+ mostRecentRoutableExtensionRender: void 0,
8
+ beforeUnloadRegistered: false
9
+ })
10
+ );
11
+ const routableExtensionRenderedEvent = "_ROUTABLE-EXTENSION-RENDERED";
12
+ class Tracker {
13
+ constructor(analyticsApi, context = {
14
+ pluginId: "root",
15
+ extensionId: "App"
16
+ }) {
17
+ this.analyticsApi = analyticsApi;
18
+ this.context = context;
19
+ if (!globalEvents.beforeUnloadRegistered) {
20
+ addEventListener(
21
+ "beforeunload",
22
+ () => {
23
+ if (globalEvents.mostRecentGatheredNavigation) {
24
+ this.analyticsApi.captureEvent({
25
+ ...globalEvents.mostRecentGatheredNavigation,
26
+ ...globalEvents.mostRecentRoutableExtensionRender
27
+ });
28
+ globalEvents.mostRecentGatheredNavigation = void 0;
29
+ globalEvents.mostRecentRoutableExtensionRender = void 0;
30
+ }
31
+ },
32
+ { once: true, passive: true }
33
+ );
34
+ globalEvents.beforeUnloadRegistered = true;
35
+ }
36
+ }
37
+ setContext(context) {
38
+ this.context = context;
39
+ }
40
+ captureEvent(action, subject, {
41
+ value,
42
+ attributes
43
+ } = {}) {
44
+ const context = this.context;
45
+ if (action === routableExtensionRenderedEvent) {
46
+ if (globalEvents.mostRecentGatheredNavigation) {
47
+ globalEvents.mostRecentRoutableExtensionRender = {
48
+ context: {
49
+ ...context,
50
+ extensionId: "App"
51
+ }
52
+ };
53
+ }
54
+ return;
55
+ }
56
+ if (globalEvents.mostRecentGatheredNavigation) {
57
+ try {
58
+ this.analyticsApi.captureEvent({
59
+ ...globalEvents.mostRecentGatheredNavigation,
60
+ ...globalEvents.mostRecentRoutableExtensionRender
61
+ });
62
+ } catch (e) {
63
+ console.warn("Error during analytics event capture. %o", e);
64
+ }
65
+ globalEvents.mostRecentGatheredNavigation = void 0;
66
+ globalEvents.mostRecentRoutableExtensionRender = void 0;
67
+ }
68
+ if (action === "navigate" && context.pluginId === "root") {
69
+ globalEvents.mostRecentGatheredNavigation = {
70
+ action,
71
+ subject,
72
+ value,
73
+ attributes,
74
+ context
75
+ };
76
+ return;
77
+ }
78
+ try {
79
+ this.analyticsApi.captureEvent({
80
+ action,
81
+ subject,
82
+ value,
83
+ attributes,
84
+ context
85
+ });
86
+ } catch (e) {
87
+ console.warn("Error during analytics event capture. %o", e);
88
+ }
89
+ }
90
+ }
91
+
92
+ export { Tracker, routableExtensionRenderedEvent };
93
+ //# sourceMappingURL=Tracker.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tracker.esm.js","sources":["../../src/analytics/Tracker.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getOrCreateGlobalSingleton } from '@backstage/version-bridge';\nimport {\n AnalyticsApi,\n AnalyticsEventAttributes,\n AnalyticsTracker,\n} from '../apis';\nimport { AnalyticsContextValue } from './';\n\ntype TempGlobalEvents = {\n /**\n * Stores the most recent \"gathered\" mountpoint navigation.\n */\n mostRecentGatheredNavigation?: {\n action: string;\n subject: string;\n value?: number;\n attributes?: AnalyticsEventAttributes;\n context: AnalyticsContextValue;\n };\n /**\n * Stores the most recent routable extension render.\n */\n mostRecentRoutableExtensionRender?: {\n context: AnalyticsContextValue;\n };\n /**\n * Tracks whether or not a beforeunload event listener has already been\n * registered.\n */\n beforeUnloadRegistered: boolean;\n};\n\n/**\n * Temporary global store for select event data. Used to make `navigate` events\n * more accurate when gathered mountpoints are used.\n */\nconst globalEvents = getOrCreateGlobalSingleton<TempGlobalEvents>(\n 'core-plugin-api:analytics-tracker-events',\n () => ({\n mostRecentGatheredNavigation: undefined,\n mostRecentRoutableExtensionRender: undefined,\n beforeUnloadRegistered: false,\n }),\n);\n\n/**\n * Internal-only event representing when a routable extension is rendered.\n */\nexport const routableExtensionRenderedEvent = '_ROUTABLE-EXTENSION-RENDERED';\n\nexport class Tracker implements AnalyticsTracker {\n constructor(\n private readonly analyticsApi: AnalyticsApi,\n private context: AnalyticsContextValue = {\n pluginId: 'root',\n extensionId: 'App',\n },\n ) {\n // Only register a single beforeunload event across all trackers.\n if (!globalEvents.beforeUnloadRegistered) {\n // Before the page unloads, attempt to capture any deferred navigation\n // events that haven't yet been captured.\n addEventListener(\n 'beforeunload',\n () => {\n if (globalEvents.mostRecentGatheredNavigation) {\n this.analyticsApi.captureEvent({\n ...globalEvents.mostRecentGatheredNavigation,\n ...globalEvents.mostRecentRoutableExtensionRender,\n });\n globalEvents.mostRecentGatheredNavigation = undefined;\n globalEvents.mostRecentRoutableExtensionRender = undefined;\n }\n },\n { once: true, passive: true },\n );\n\n // Prevent duplicate handlers from being registered.\n globalEvents.beforeUnloadRegistered = true;\n }\n }\n\n setContext(context: AnalyticsContextValue) {\n this.context = context;\n }\n\n captureEvent(\n action: string,\n subject: string,\n {\n value,\n attributes,\n }: { value?: number; attributes?: AnalyticsEventAttributes } = {},\n ) {\n // Never pass internal \"_routeNodeType\" context value.\n const context = this.context;\n\n // Never fire the special \"_routable-extension-rendered\" internal event.\n if (action === routableExtensionRenderedEvent) {\n // But keep track of it if we're delaying a `navigate` event for a\n // a gathered route node type.\n if (globalEvents.mostRecentGatheredNavigation) {\n globalEvents.mostRecentRoutableExtensionRender = {\n context: {\n ...context,\n extensionId: 'App',\n },\n };\n }\n return;\n }\n\n // If we are about to fire a real event, and we have an un-fired gathered\n // mountpoint navigation on the global store, we need to fire the navigate\n // event first, so this real event happens accurately after the navigation.\n if (globalEvents.mostRecentGatheredNavigation) {\n try {\n this.analyticsApi.captureEvent({\n ...globalEvents.mostRecentGatheredNavigation,\n ...globalEvents.mostRecentRoutableExtensionRender,\n });\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('Error during analytics event capture. %o', e);\n }\n\n // Clear the global stores.\n globalEvents.mostRecentGatheredNavigation = undefined;\n globalEvents.mostRecentRoutableExtensionRender = undefined;\n }\n\n // Never directly fire a navigation event on a gathered route with default\n // contextual details.\n if (action === 'navigate' && context.pluginId === 'root') {\n // Instead, set it on the global store.\n globalEvents.mostRecentGatheredNavigation = {\n action,\n subject,\n value,\n attributes,\n context,\n };\n return;\n }\n\n try {\n this.analyticsApi.captureEvent({\n action,\n subject,\n value,\n attributes,\n context,\n });\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('Error during analytics event capture. %o', e);\n }\n }\n}\n"],"names":[],"mappings":";;AAoDA,MAAM,YAAe,GAAA,0BAAA;AAAA,EACnB,0CAAA;AAAA,EACA,OAAO;AAAA,IACL,4BAA8B,EAAA,KAAA,CAAA;AAAA,IAC9B,iCAAmC,EAAA,KAAA,CAAA;AAAA,IACnC,sBAAwB,EAAA,KAAA;AAAA,GAC1B,CAAA;AACF,CAAA,CAAA;AAKO,MAAM,8BAAiC,GAAA,+BAAA;AAEvC,MAAM,OAAoC,CAAA;AAAA,EAC/C,WAAA,CACmB,cACT,OAAiC,GAAA;AAAA,IACvC,QAAU,EAAA,MAAA;AAAA,IACV,WAAa,EAAA,KAAA;AAAA,GAEf,EAAA;AALiB,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA,CAAA;AACT,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA,CAAA;AAMR,IAAI,IAAA,CAAC,aAAa,sBAAwB,EAAA;AAGxC,MAAA,gBAAA;AAAA,QACE,cAAA;AAAA,QACA,MAAM;AACJ,UAAA,IAAI,aAAa,4BAA8B,EAAA;AAC7C,YAAA,IAAA,CAAK,aAAa,YAAa,CAAA;AAAA,cAC7B,GAAG,YAAa,CAAA,4BAAA;AAAA,cAChB,GAAG,YAAa,CAAA,iCAAA;AAAA,aACjB,CAAA,CAAA;AACD,YAAA,YAAA,CAAa,4BAA+B,GAAA,KAAA,CAAA,CAAA;AAC5C,YAAA,YAAA,CAAa,iCAAoC,GAAA,KAAA,CAAA,CAAA;AAAA,WACnD;AAAA,SACF;AAAA,QACA,EAAE,IAAA,EAAM,IAAM,EAAA,OAAA,EAAS,IAAK,EAAA;AAAA,OAC9B,CAAA;AAGA,MAAA,YAAA,CAAa,sBAAyB,GAAA,IAAA,CAAA;AAAA,KACxC;AAAA,GACF;AAAA,EAEA,WAAW,OAAgC,EAAA;AACzC,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA,CAAA;AAAA,GACjB;AAAA,EAEA,YAAA,CACE,QACA,OACA,EAAA;AAAA,IACE,KAAA;AAAA,IACA,UAAA;AAAA,GACF,GAA+D,EAC/D,EAAA;AAEA,IAAA,MAAM,UAAU,IAAK,CAAA,OAAA,CAAA;AAGrB,IAAA,IAAI,WAAW,8BAAgC,EAAA;AAG7C,MAAA,IAAI,aAAa,4BAA8B,EAAA;AAC7C,QAAA,YAAA,CAAa,iCAAoC,GAAA;AAAA,UAC/C,OAAS,EAAA;AAAA,YACP,GAAG,OAAA;AAAA,YACH,WAAa,EAAA,KAAA;AAAA,WACf;AAAA,SACF,CAAA;AAAA,OACF;AACA,MAAA,OAAA;AAAA,KACF;AAKA,IAAA,IAAI,aAAa,4BAA8B,EAAA;AAC7C,MAAI,IAAA;AACF,QAAA,IAAA,CAAK,aAAa,YAAa,CAAA;AAAA,UAC7B,GAAG,YAAa,CAAA,4BAAA;AAAA,UAChB,GAAG,YAAa,CAAA,iCAAA;AAAA,SACjB,CAAA,CAAA;AAAA,eACM,CAAG,EAAA;AAEV,QAAQ,OAAA,CAAA,IAAA,CAAK,4CAA4C,CAAC,CAAA,CAAA;AAAA,OAC5D;AAGA,MAAA,YAAA,CAAa,4BAA+B,GAAA,KAAA,CAAA,CAAA;AAC5C,MAAA,YAAA,CAAa,iCAAoC,GAAA,KAAA,CAAA,CAAA;AAAA,KACnD;AAIA,IAAA,IAAI,MAAW,KAAA,UAAA,IAAc,OAAQ,CAAA,QAAA,KAAa,MAAQ,EAAA;AAExD,MAAA,YAAA,CAAa,4BAA+B,GAAA;AAAA,QAC1C,MAAA;AAAA,QACA,OAAA;AAAA,QACA,KAAA;AAAA,QACA,UAAA;AAAA,QACA,OAAA;AAAA,OACF,CAAA;AACA,MAAA,OAAA;AAAA,KACF;AAEA,IAAI,IAAA;AACF,MAAA,IAAA,CAAK,aAAa,YAAa,CAAA;AAAA,QAC7B,MAAA;AAAA,QACA,OAAA;AAAA,QACA,KAAA;AAAA,QACA,UAAA;AAAA,QACA,OAAA;AAAA,OACD,CAAA,CAAA;AAAA,aACM,CAAG,EAAA;AAEV,MAAQ,OAAA,CAAA,IAAA,CAAK,4CAA4C,CAAC,CAAA,CAAA;AAAA,KAC5D;AAAA,GACF;AACF;;;;"}
@@ -0,0 +1,38 @@
1
+ import { useApi } from '@backstage/core-plugin-api';
2
+ import { useAnalyticsContext } from './AnalyticsContext.esm.js';
3
+ import '../apis/definitions/AppTreeApi.esm.js';
4
+ import '../apis/definitions/ComponentsApi.esm.js';
5
+ import '../apis/definitions/IconsApi.esm.js';
6
+ import '../apis/definitions/RouteResolutionApi.esm.js';
7
+ import { analyticsApiRef } from '../apis/definitions/AnalyticsApi.esm.js';
8
+ import { useRef } from 'react';
9
+ import { Tracker } from './Tracker.esm.js';
10
+
11
+ function useAnalyticsApi() {
12
+ try {
13
+ return useApi(analyticsApiRef);
14
+ } catch (error) {
15
+ if (error.name === "NotImplementedError") {
16
+ return { captureEvent: () => {
17
+ } };
18
+ }
19
+ throw error;
20
+ }
21
+ }
22
+ function useAnalytics() {
23
+ const trackerRef = useRef(null);
24
+ const context = useAnalyticsContext();
25
+ const analyticsApi = useAnalyticsApi();
26
+ function getTracker() {
27
+ if (trackerRef.current === null) {
28
+ trackerRef.current = new Tracker(analyticsApi);
29
+ }
30
+ return trackerRef.current;
31
+ }
32
+ const tracker = getTracker();
33
+ tracker.setContext(context);
34
+ return tracker;
35
+ }
36
+
37
+ export { useAnalytics };
38
+ //# sourceMappingURL=useAnalytics.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAnalytics.esm.js","sources":["../../src/analytics/useAnalytics.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useAnalyticsContext } from './AnalyticsContext';\nimport { analyticsApiRef, AnalyticsTracker, AnalyticsApi } from '../apis';\nimport { useRef } from 'react';\nimport { Tracker } from './Tracker';\n\nfunction useAnalyticsApi(): AnalyticsApi {\n try {\n return useApi(analyticsApiRef);\n } catch (error) {\n if (error.name === 'NotImplementedError') {\n return { captureEvent: () => {} };\n }\n throw error;\n }\n}\n\n/**\n * Gets a pre-configured analytics tracker.\n *\n * @public\n */\nexport function useAnalytics(): AnalyticsTracker {\n const trackerRef = useRef<Tracker | null>(null);\n const context = useAnalyticsContext();\n // Our goal is to make this API truly optional for any/all consuming code\n // (including tests). This hook runs last to ensure hook order is, as much as\n // possible, maintained.\n const analyticsApi = useAnalyticsApi();\n\n function getTracker(): Tracker {\n if (trackerRef.current === null) {\n trackerRef.current = new Tracker(analyticsApi);\n }\n return trackerRef.current;\n }\n\n const tracker = getTracker();\n // this is not ideal, but it allows to memoize the tracker\n // without explicitly set the context as dependency.\n tracker.setContext(context);\n\n return tracker;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAsBA,SAAS,eAAgC,GAAA;AACvC,EAAI,IAAA;AACF,IAAA,OAAO,OAAO,eAAe,CAAA,CAAA;AAAA,WACtB,KAAO,EAAA;AACd,IAAI,IAAA,KAAA,CAAM,SAAS,qBAAuB,EAAA;AACxC,MAAO,OAAA,EAAE,cAAc,MAAM;AAAA,OAAG,EAAA,CAAA;AAAA,KAClC;AACA,IAAM,MAAA,KAAA,CAAA;AAAA,GACR;AACF,CAAA;AAOO,SAAS,YAAiC,GAAA;AAC/C,EAAM,MAAA,UAAA,GAAa,OAAuB,IAAI,CAAA,CAAA;AAC9C,EAAA,MAAM,UAAU,mBAAoB,EAAA,CAAA;AAIpC,EAAA,MAAM,eAAe,eAAgB,EAAA,CAAA;AAErC,EAAA,SAAS,UAAsB,GAAA;AAC7B,IAAI,IAAA,UAAA,CAAW,YAAY,IAAM,EAAA;AAC/B,MAAW,UAAA,CAAA,OAAA,GAAU,IAAI,OAAA,CAAQ,YAAY,CAAA,CAAA;AAAA,KAC/C;AACA,IAAA,OAAO,UAAW,CAAA,OAAA,CAAA;AAAA,GACpB;AAEA,EAAA,MAAM,UAAU,UAAW,EAAA,CAAA;AAG3B,EAAA,OAAA,CAAQ,WAAW,OAAO,CAAA,CAAA;AAE1B,EAAO,OAAA,OAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,8 @@
1
+ import { createApiRef } from '@backstage/core-plugin-api';
2
+
3
+ const analyticsApiRef = createApiRef({
4
+ id: "core.analytics"
5
+ });
6
+
7
+ export { analyticsApiRef };
8
+ //# sourceMappingURL=AnalyticsApi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsApi.esm.js","sources":["../../../src/apis/definitions/AnalyticsApi.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ApiRef, createApiRef } from '@backstage/core-plugin-api';\nimport { AnalyticsContextValue } from '../../analytics/types';\n\n/**\n * Represents an event worth tracking in an analytics system that could inform\n * how users of a Backstage instance are using its features.\n *\n * @public\n */\nexport type AnalyticsEvent = {\n /**\n * A string that identifies the event being tracked by the type of action the\n * event represents. Be careful not to encode extra metadata in this string\n * that should instead be placed in the Analytics Context or attributes.\n * Examples include:\n *\n * - view\n * - click\n * - filter\n * - search\n * - hover\n * - scroll\n */\n action: string;\n\n /**\n * A string that uniquely identifies the object that the action is being\n * taken on. Examples include:\n *\n * - The path of the page viewed\n * - The url of the link clicked\n * - The value that was filtered by\n * - The text that was searched for\n */\n subject: string;\n\n /**\n * An optional numeric value relevant to the event that could be aggregated\n * by analytics tools. Examples include:\n *\n * - The index or position of the clicked element in an ordered list\n * - The percentage of an element that has been scrolled through\n * - The amount of time that has elapsed since a fixed point\n * - A satisfaction score on a fixed scale\n */\n value?: number;\n\n /**\n * Optional, additional attributes (representing dimensions or metrics)\n * specific to the event that could be forwarded on to analytics systems.\n */\n attributes?: AnalyticsEventAttributes;\n\n /**\n * Contextual metadata relating to where the event was captured and by whom.\n * This could include information about the route, plugin, or extension in\n * which an event was captured.\n */\n context: AnalyticsContextValue;\n};\n\n/**\n * A structure allowing other arbitrary metadata to be provided by analytics\n * event emitters.\n *\n * @public\n */\nexport type AnalyticsEventAttributes = {\n [attribute in string]: string | boolean | number;\n};\n\n/**\n * Represents a tracker with methods that can be called to track events in a\n * configured analytics service.\n *\n * @public\n */\nexport type AnalyticsTracker = {\n captureEvent: (\n action: string,\n subject: string,\n options?: {\n value?: number;\n attributes?: AnalyticsEventAttributes;\n },\n ) => void;\n};\n\n/**\n * The Analytics API is used to track user behavior in a Backstage instance.\n *\n * @remarks\n *\n * To instrument your App or Plugin, retrieve an analytics tracker using the\n * useAnalytics() hook. This will return a pre-configured AnalyticsTracker\n * with relevant methods for instrumentation.\n *\n * @public\n */\nexport type AnalyticsApi = {\n /**\n * Primary event handler responsible for compiling and forwarding events to\n * an analytics system.\n */\n captureEvent(event: AnalyticsEvent): void;\n};\n\n/**\n * The API reference of {@link AnalyticsApi}.\n *\n * @public\n */\nexport const analyticsApiRef: ApiRef<AnalyticsApi> = createApiRef({\n id: 'core.analytics',\n});\n"],"names":[],"mappings":";;AAgIO,MAAM,kBAAwC,YAAa,CAAA;AAAA,EAChE,EAAI,EAAA,gBAAA;AACN,CAAC;;;;"}
@@ -0,0 +1,6 @@
1
+ import { createApiRef } from '@backstage/core-plugin-api';
2
+
3
+ const appTreeApiRef = createApiRef({ id: "core.app-tree" });
4
+
5
+ export { appTreeApiRef };
6
+ //# sourceMappingURL=AppTreeApi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppTreeApi.esm.js","sources":["../../../src/apis/definitions/AppTreeApi.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createApiRef } from '@backstage/core-plugin-api';\nimport { BackstagePlugin, Extension, ExtensionDataRef } from '../../wiring';\n\n/**\n * The specification for this {@link AppNode} in the {@link AppTree}.\n *\n * @public\n * @remarks\n *\n * The specifications for a collection of app nodes is all the information needed\n * to build the tree and instantiate the nodes.\n */\nexport interface AppNodeSpec {\n readonly id: string;\n readonly attachTo: { id: string; input: string };\n readonly extension: Extension<unknown>;\n readonly disabled: boolean;\n readonly config?: unknown;\n readonly source?: BackstagePlugin;\n}\n\n/**\n * The connections from this {@link AppNode} to other nodes.\n *\n * @public\n * @remarks\n *\n * The app node edges are resolved based on the app node specs, regardless of whether\n * adjacent nodes are disabled or not. If no parent attachment is present or\n */\nexport interface AppNodeEdges {\n readonly attachedTo?: { node: AppNode; input: string };\n readonly attachments: ReadonlyMap<string, AppNode[]>;\n}\n\n/**\n * The instance of this {@link AppNode} in the {@link AppTree}.\n *\n * @public\n * @remarks\n *\n * The app node instance is created when the `factory` function of an extension is called.\n * Instances will only be present for nodes in the app that are connected to the root\n * node and not disabled\n */\nexport interface AppNodeInstance {\n /** Returns a sequence of all extension data refs that were output by this instance */\n getDataRefs(): Iterable<ExtensionDataRef<unknown>>;\n /** Get the output data for a single extension data ref */\n getData<T>(ref: ExtensionDataRef<T>): T | undefined;\n}\n\n/**\n * A node in the {@link AppTree}.\n *\n * @public\n */\nexport interface AppNode {\n /** The specification for how this node should be instantiated */\n readonly spec: AppNodeSpec;\n /** The edges from this node to other nodes in the app tree */\n readonly edges: AppNodeEdges;\n /** The instance of this node, if it was instantiated */\n readonly instance?: AppNodeInstance;\n}\n\n/**\n * The app tree containing all {@link AppNode}s of the app.\n *\n * @public\n */\nexport interface AppTree {\n /** The root node of the app */\n readonly root: AppNode;\n /** A map of all nodes in the app by ID, including orphaned or disabled nodes */\n readonly nodes: ReadonlyMap<string /* id */, AppNode>;\n /** A sequence of all nodes with a parent that is not reachable from the app root node */\n readonly orphans: Iterable<AppNode>;\n}\n\n/**\n * The API for interacting with the {@link AppTree}.\n *\n * @public\n */\nexport interface AppTreeApi {\n /**\n * Get the {@link AppTree} for the app.\n */\n getTree(): { tree: AppTree };\n}\n\n/**\n * The `ApiRef` of {@link AppTreeApi}.\n *\n * @public\n */\nexport const appTreeApiRef = createApiRef<AppTreeApi>({ id: 'core.app-tree' });\n"],"names":[],"mappings":";;AAiHO,MAAM,aAAgB,GAAA,YAAA,CAAyB,EAAE,EAAA,EAAI,iBAAiB;;;;"}
@@ -0,0 +1,12 @@
1
+ import { createApiRef, useApi } from '@backstage/core-plugin-api';
2
+
3
+ const componentsApiRef = createApiRef({
4
+ id: "core.components"
5
+ });
6
+ function useComponentRef(ref) {
7
+ const componentsApi = useApi(componentsApiRef);
8
+ return componentsApi.getComponent(ref);
9
+ }
10
+
11
+ export { componentsApiRef, useComponentRef };
12
+ //# sourceMappingURL=ComponentsApi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComponentsApi.esm.js","sources":["../../../src/apis/definitions/ComponentsApi.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentType } from 'react';\nimport { createApiRef, useApi } from '@backstage/core-plugin-api';\nimport { ComponentRef } from '../../components';\n\n/**\n * API for looking up components based on component refs.\n *\n * @public\n */\nexport interface ComponentsApi {\n // TODO: Should component refs also provide the default implementation so that we're guaranteed to get a component?\n getComponent<T extends {}>(ref: ComponentRef<T>): ComponentType<T>;\n}\n\n/**\n * The `ApiRef` of {@link ComponentsApi}.\n *\n * @public\n */\nexport const componentsApiRef = createApiRef<ComponentsApi>({\n id: 'core.components',\n});\n\n/**\n * @public\n * Returns the component associated with the given ref.\n */\nexport function useComponentRef<T extends {}>(\n ref: ComponentRef<T>,\n): ComponentType<T> {\n const componentsApi = useApi(componentsApiRef);\n return componentsApi.getComponent<T>(ref);\n}\n"],"names":[],"mappings":";;AAmCO,MAAM,mBAAmB,YAA4B,CAAA;AAAA,EAC1D,EAAI,EAAA,iBAAA;AACN,CAAC,EAAA;AAMM,SAAS,gBACd,GACkB,EAAA;AAClB,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA,CAAA;AAC7C,EAAO,OAAA,aAAA,CAAc,aAAgB,GAAG,CAAA,CAAA;AAC1C;;;;"}
@@ -0,0 +1,8 @@
1
+ import { createApiRef } from '@backstage/core-plugin-api';
2
+
3
+ const iconsApiRef = createApiRef({
4
+ id: "core.icons"
5
+ });
6
+
7
+ export { iconsApiRef };
8
+ //# sourceMappingURL=IconsApi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconsApi.esm.js","sources":["../../../src/apis/definitions/IconsApi.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createApiRef } from '@backstage/core-plugin-api';\nimport { IconComponent } from '../../icons';\n\n/**\n * API for accessing app icons.\n *\n * @public\n */\nexport interface IconsApi {\n getIcon(key: string): IconComponent | undefined;\n\n listIconKeys(): string[];\n}\n\n/**\n * The `ApiRef` of {@link IconsApi}.\n *\n * @public\n */\nexport const iconsApiRef = createApiRef<IconsApi>({\n id: 'core.icons',\n});\n"],"names":[],"mappings":";;AAmCO,MAAM,cAAc,YAAuB,CAAA;AAAA,EAChD,EAAI,EAAA,YAAA;AACN,CAAC;;;;"}
@@ -0,0 +1,8 @@
1
+ import { createApiRef } from '@backstage/core-plugin-api';
2
+
3
+ const routeResolutionApiRef = createApiRef({
4
+ id: "core.route-resolution"
5
+ });
6
+
7
+ export { routeResolutionApiRef };
8
+ //# sourceMappingURL=RouteResolutionApi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteResolutionApi.esm.js","sources":["../../../src/apis/definitions/RouteResolutionApi.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AnyRouteRefParams,\n RouteRef,\n SubRouteRef,\n ExternalRouteRef,\n} from '../../routing';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * TS magic for handling route parameters.\n *\n * @remarks\n *\n * The extra TS magic here is to require a single params argument if the RouteRef\n * had at least one param defined, but require 0 arguments if there are no params defined.\n * Without this we'd have to pass in empty object to all parameter-less RouteRefs\n * just to make TypeScript happy, or we would have to make the argument optional in\n * which case you might forget to pass it in when it is actually required.\n *\n * @public\n */\nexport type RouteFunc<TParams extends AnyRouteRefParams> = (\n ...[params]: TParams extends undefined\n ? readonly []\n : readonly [params: TParams]\n) => string;\n\n/**\n * @public\n */\nexport type RouteResolutionApiResolveOptions = {\n /**\n * An absolute path to use as a starting point when resolving the route.\n * If no path is provided the route will be resolved from the root of the app.\n */\n sourcePath?: string;\n};\n\n/**\n * @public\n */\nexport interface RouteResolutionApi {\n resolve<TParams extends AnyRouteRefParams>(\n anyRouteRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams, any>,\n options?: RouteResolutionApiResolveOptions,\n ): RouteFunc<TParams> | undefined;\n}\n\n/**\n * The `ApiRef` of {@link RouteResolutionApi}.\n *\n * @public\n */\nexport const routeResolutionApiRef = createApiRef<RouteResolutionApi>({\n id: 'core.route-resolution',\n});\n"],"names":[],"mappings":";;AAwEO,MAAM,wBAAwB,YAAiC,CAAA;AAAA,EACpE,EAAI,EAAA,uBAAA;AACN,CAAC;;;;"}
@@ -0,0 +1,38 @@
1
+ import React, { Component } from 'react';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
+ var __publicField = (obj, key, value) => {
6
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
+ return value;
8
+ };
9
+ class ErrorBoundary extends Component {
10
+ constructor() {
11
+ super(...arguments);
12
+ __publicField(this, "state", { error: void 0 });
13
+ __publicField(this, "handleErrorReset", () => {
14
+ this.setState({ error: void 0 });
15
+ });
16
+ }
17
+ static getDerivedStateFromError(error) {
18
+ return { error };
19
+ }
20
+ render() {
21
+ const { error } = this.state;
22
+ const { plugin, children, Fallback } = this.props;
23
+ if (error) {
24
+ return /* @__PURE__ */ React.createElement(
25
+ Fallback,
26
+ {
27
+ plugin,
28
+ error,
29
+ resetError: this.handleErrorReset
30
+ }
31
+ );
32
+ }
33
+ return children;
34
+ }
35
+ }
36
+
37
+ export { ErrorBoundary };
38
+ //# sourceMappingURL=ErrorBoundary.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorBoundary.esm.js","sources":["../../src/components/ErrorBoundary.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { Component, ComponentType, PropsWithChildren } from 'react';\nimport { BackstagePlugin } from '../wiring';\nimport { CoreErrorBoundaryFallbackProps } from '../types';\n\ntype ErrorBoundaryProps = PropsWithChildren<{\n plugin?: BackstagePlugin;\n Fallback: ComponentType<CoreErrorBoundaryFallbackProps>;\n}>;\ntype ErrorBoundaryState = { error?: Error };\n\n/** @internal */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n state: ErrorBoundaryState = { error: undefined };\n\n handleErrorReset = () => {\n this.setState({ error: undefined });\n };\n\n render() {\n const { error } = this.state;\n const { plugin, children, Fallback } = this.props;\n\n if (error) {\n return (\n <Fallback\n plugin={plugin}\n error={error}\n resetError={this.handleErrorReset}\n />\n );\n }\n\n return children;\n }\n}\n"],"names":[],"mappings":";;;;;;;;AA2BO,MAAM,sBAAsB,SAGjC,CAAA;AAAA,EAHK,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA,CAAA;AAQL,IAA4B,aAAA,CAAA,IAAA,EAAA,OAAA,EAAA,EAAE,OAAO,KAAU,CAAA,EAAA,CAAA,CAAA;AAE/C,IAAA,aAAA,CAAA,IAAA,EAAA,kBAAA,EAAmB,MAAM;AACvB,MAAA,IAAA,CAAK,QAAS,CAAA,EAAE,KAAO,EAAA,KAAA,CAAA,EAAW,CAAA,CAAA;AAAA,KACpC,CAAA,CAAA;AAAA,GAAA;AAAA,EARA,OAAO,yBAAyB,KAAc,EAAA;AAC5C,IAAA,OAAO,EAAE,KAAM,EAAA,CAAA;AAAA,GACjB;AAAA,EAQA,MAAS,GAAA;AACP,IAAM,MAAA,EAAE,KAAM,EAAA,GAAI,IAAK,CAAA,KAAA,CAAA;AACvB,IAAA,MAAM,EAAE,MAAA,EAAQ,QAAU,EAAA,QAAA,KAAa,IAAK,CAAA,KAAA,CAAA;AAE5C,IAAA,IAAI,KAAO,EAAA;AACT,MACE,uBAAA,KAAA,CAAA,aAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,KAAA;AAAA,UACA,YAAY,IAAK,CAAA,gBAAA;AAAA,SAAA;AAAA,OACnB,CAAA;AAAA,KAEJ;AAEA,IAAO,OAAA,QAAA,CAAA;AAAA,GACT;AACF;;;;"}
@@ -0,0 +1,36 @@
1
+ import React, { Suspense, useEffect } from 'react';
2
+ import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';
3
+ import { ErrorBoundary } from './ErrorBoundary.esm.js';
4
+ import { routableExtensionRenderedEvent } from '../core-plugin-api/src/analytics/Tracker.esm.js';
5
+ import '../apis/definitions/AppTreeApi.esm.js';
6
+ import { useComponentRef } from '../apis/definitions/ComponentsApi.esm.js';
7
+ import '../apis/definitions/IconsApi.esm.js';
8
+ import '../apis/definitions/RouteResolutionApi.esm.js';
9
+ import '../apis/definitions/AnalyticsApi.esm.js';
10
+ import { coreComponentRefs } from './coreComponentRefs.esm.js';
11
+
12
+ const RouteTracker = (props) => {
13
+ const { disableTracking, children } = props;
14
+ const analytics = useAnalytics();
15
+ useEffect(() => {
16
+ if (disableTracking)
17
+ return;
18
+ analytics.captureEvent(routableExtensionRenderedEvent, "");
19
+ }, [analytics, disableTracking]);
20
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
21
+ };
22
+ function ExtensionBoundary(props) {
23
+ var _a, _b;
24
+ const { node, routable, children } = props;
25
+ const plugin = node.spec.source;
26
+ const Progress = useComponentRef(coreComponentRefs.progress);
27
+ const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback);
28
+ const attributes = {
29
+ extensionId: node.spec.id,
30
+ pluginId: (_b = (_a = node.spec.source) == null ? void 0 : _a.id) != null ? _b : "app"
31
+ };
32
+ return /* @__PURE__ */ React.createElement(Suspense, { fallback: /* @__PURE__ */ React.createElement(Progress, null) }, /* @__PURE__ */ React.createElement(ErrorBoundary, { plugin, Fallback: fallback }, /* @__PURE__ */ React.createElement(AnalyticsContext, { attributes }, /* @__PURE__ */ React.createElement(RouteTracker, { disableTracking: !routable }, children))));
33
+ }
34
+
35
+ export { ExtensionBoundary };
36
+ //# sourceMappingURL=ExtensionBoundary.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExtensionBoundary.esm.js","sources":["../../src/components/ExtensionBoundary.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, {\n PropsWithChildren,\n ReactNode,\n Suspense,\n useEffect,\n} from 'react';\nimport { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';\nimport { ErrorBoundary } from './ErrorBoundary';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { routableExtensionRenderedEvent } from '../../../core-plugin-api/src/analytics/Tracker';\nimport { AppNode, useComponentRef } from '../apis';\nimport { coreComponentRefs } from './coreComponentRefs';\n\ntype RouteTrackerProps = PropsWithChildren<{\n disableTracking?: boolean;\n}>;\n\nconst RouteTracker = (props: RouteTrackerProps) => {\n const { disableTracking, children } = props;\n const analytics = useAnalytics();\n\n // This event, never exposed to end-users of the analytics API,\n // helps inform which extension metadata gets associated with a\n // navigation event when the route navigated to is a gathered\n // mountpoint.\n useEffect(() => {\n if (disableTracking) return;\n analytics.captureEvent(routableExtensionRenderedEvent, '');\n }, [analytics, disableTracking]);\n\n return <>{children}</>;\n};\n\n/** @public */\nexport interface ExtensionBoundaryProps {\n node: AppNode;\n routable?: boolean;\n children: ReactNode;\n}\n\n/** @public */\nexport function ExtensionBoundary(props: ExtensionBoundaryProps) {\n const { node, routable, children } = props;\n\n const plugin = node.spec.source;\n const Progress = useComponentRef(coreComponentRefs.progress);\n const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback);\n\n // Skipping \"routeRef\" attribute in the new system, the extension \"id\" should provide more insight\n const attributes = {\n extensionId: node.spec.id,\n pluginId: node.spec.source?.id ?? 'app',\n };\n\n return (\n <Suspense fallback={<Progress />}>\n <ErrorBoundary plugin={plugin} Fallback={fallback}>\n <AnalyticsContext attributes={attributes}>\n <RouteTracker disableTracking={!routable}>{children}</RouteTracker>\n </AnalyticsContext>\n </ErrorBoundary>\n </Suspense>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAiCA,MAAM,YAAA,GAAe,CAAC,KAA6B,KAAA;AACjD,EAAM,MAAA,EAAE,eAAiB,EAAA,QAAA,EAAa,GAAA,KAAA,CAAA;AACtC,EAAA,MAAM,YAAY,YAAa,EAAA,CAAA;AAM/B,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,eAAA;AAAiB,MAAA,OAAA;AACrB,IAAU,SAAA,CAAA,YAAA,CAAa,gCAAgC,EAAE,CAAA,CAAA;AAAA,GACxD,EAAA,CAAC,SAAW,EAAA,eAAe,CAAC,CAAA,CAAA;AAE/B,EAAA,iEAAU,QAAS,CAAA,CAAA;AACrB,CAAA,CAAA;AAUO,SAAS,kBAAkB,KAA+B,EAAA;AAzDjE,EAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AA0DE,EAAA,MAAM,EAAE,IAAA,EAAM,QAAU,EAAA,QAAA,EAAa,GAAA,KAAA,CAAA;AAErC,EAAM,MAAA,MAAA,GAAS,KAAK,IAAK,CAAA,MAAA,CAAA;AACzB,EAAM,MAAA,QAAA,GAAW,eAAgB,CAAA,iBAAA,CAAkB,QAAQ,CAAA,CAAA;AAC3D,EAAM,MAAA,QAAA,GAAW,eAAgB,CAAA,iBAAA,CAAkB,qBAAqB,CAAA,CAAA;AAGxE,EAAA,MAAM,UAAa,GAAA;AAAA,IACjB,WAAA,EAAa,KAAK,IAAK,CAAA,EAAA;AAAA,IACvB,WAAU,EAAK,GAAA,CAAA,EAAA,GAAA,IAAA,CAAA,IAAA,CAAK,MAAV,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAkB,OAAlB,IAAwB,GAAA,EAAA,GAAA,KAAA;AAAA,GACpC,CAAA;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,YAAS,QAAU,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAS,CAC5B,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,EAAA,MAAA,EAAgB,QAAU,EAAA,QAAA,EAAA,sCACtC,gBAAiB,EAAA,EAAA,UAAA,EAAA,sCACf,YAAa,EAAA,EAAA,eAAA,EAAiB,CAAC,QAAW,EAAA,EAAA,QAAS,CACtD,CACF,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,19 @@
1
+ import { createComponentRef } from './createComponentRef.esm.js';
2
+
3
+ const coreProgressComponentRef = createComponentRef({
4
+ id: "core.components.progress"
5
+ });
6
+ const coreNotFoundErrorPageComponentRef = createComponentRef({
7
+ id: "core.components.notFoundErrorPage"
8
+ });
9
+ const coreErrorBoundaryFallbackComponentRef = createComponentRef({
10
+ id: "core.components.errorBoundaryFallback"
11
+ });
12
+ const coreComponentRefs = {
13
+ progress: coreProgressComponentRef,
14
+ notFoundErrorPage: coreNotFoundErrorPageComponentRef,
15
+ errorBoundaryFallback: coreErrorBoundaryFallbackComponentRef
16
+ };
17
+
18
+ export { coreComponentRefs };
19
+ //# sourceMappingURL=coreComponentRefs.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coreComponentRefs.esm.js","sources":["../../src/components/coreComponentRefs.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CoreErrorBoundaryFallbackProps,\n CoreNotFoundErrorPageProps,\n CoreProgressProps,\n} from '../types';\nimport { createComponentRef } from './createComponentRef';\n\nconst coreProgressComponentRef = createComponentRef<CoreProgressProps>({\n id: 'core.components.progress',\n});\n\nconst coreNotFoundErrorPageComponentRef =\n createComponentRef<CoreNotFoundErrorPageProps>({\n id: 'core.components.notFoundErrorPage',\n });\n\nconst coreErrorBoundaryFallbackComponentRef =\n createComponentRef<CoreErrorBoundaryFallbackProps>({\n id: 'core.components.errorBoundaryFallback',\n });\n\n/** @public */\nexport const coreComponentRefs = {\n progress: coreProgressComponentRef,\n notFoundErrorPage: coreNotFoundErrorPageComponentRef,\n errorBoundaryFallback: coreErrorBoundaryFallbackComponentRef,\n};\n"],"names":[],"mappings":";;AAuBA,MAAM,2BAA2B,kBAAsC,CAAA;AAAA,EACrE,EAAI,EAAA,0BAAA;AACN,CAAC,CAAA,CAAA;AAED,MAAM,oCACJ,kBAA+C,CAAA;AAAA,EAC7C,EAAI,EAAA,mCAAA;AACN,CAAC,CAAA,CAAA;AAEH,MAAM,wCACJ,kBAAmD,CAAA;AAAA,EACjD,EAAI,EAAA,uCAAA;AACN,CAAC,CAAA,CAAA;AAGI,MAAM,iBAAoB,GAAA;AAAA,EAC/B,QAAU,EAAA,wBAAA;AAAA,EACV,iBAAmB,EAAA,iCAAA;AAAA,EACnB,qBAAuB,EAAA,qCAAA;AACzB;;;;"}
@@ -0,0 +1,12 @@
1
+ function createComponentRef(options) {
2
+ const { id } = options;
3
+ return {
4
+ id,
5
+ toString() {
6
+ return `ComponentRef{id=${id}}`;
7
+ }
8
+ };
9
+ }
10
+
11
+ export { createComponentRef };
12
+ //# sourceMappingURL=createComponentRef.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createComponentRef.esm.js","sources":["../../src/components/createComponentRef.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** @public */\nexport type ComponentRef<T extends {} = {}> = {\n id: string;\n T: T;\n};\n\n/** @public */\nexport function createComponentRef<T extends {} = {}>(options: {\n id: string;\n}): ComponentRef<T> {\n const { id } = options;\n return {\n id,\n toString() {\n return `ComponentRef{id=${id}}`;\n },\n } as ComponentRef<T>;\n}\n"],"names":[],"mappings":"AAuBO,SAAS,mBAAsC,OAElC,EAAA;AAClB,EAAM,MAAA,EAAE,IAAO,GAAA,OAAA,CAAA;AACf,EAAO,OAAA;AAAA,IACL,EAAA;AAAA,IACA,QAAW,GAAA;AACT,MAAA,OAAO,mBAAmB,EAAE,CAAA,CAAA,CAAA,CAAA;AAAA,KAC9B;AAAA,GACF,CAAA;AACF;;;;"}
@@ -0,0 +1,14 @@
1
+ import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
2
+
3
+ getOrCreateGlobalSingleton(
4
+ "core-plugin-api:analytics-tracker-events",
5
+ () => ({
6
+ mostRecentGatheredNavigation: void 0,
7
+ mostRecentRoutableExtensionRender: void 0,
8
+ beforeUnloadRegistered: false
9
+ })
10
+ );
11
+ const routableExtensionRenderedEvent = "_ROUTABLE-EXTENSION-RENDERED";
12
+
13
+ export { routableExtensionRenderedEvent };
14
+ //# sourceMappingURL=Tracker.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tracker.esm.js","sources":["../../../../../core-plugin-api/src/analytics/Tracker.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getOrCreateGlobalSingleton } from '@backstage/version-bridge';\nimport {\n AnalyticsApi,\n AnalyticsEventAttributes,\n AnalyticsTracker,\n} from '../apis';\nimport { AnalyticsContextValue } from './';\n\ntype TempGlobalEvents = {\n /**\n * Stores the most recent \"gathered\" mountpoint navigation.\n */\n mostRecentGatheredNavigation?: {\n action: string;\n subject: string;\n value?: number;\n attributes?: AnalyticsEventAttributes;\n context: AnalyticsContextValue;\n };\n /**\n * Stores the most recent routable extension render.\n */\n mostRecentRoutableExtensionRender?: {\n context: AnalyticsContextValue;\n };\n /**\n * Tracks whether or not a beforeunload event listener has already been\n * registered.\n */\n beforeUnloadRegistered: boolean;\n};\n\n/**\n * Temporary global store for select event data. Used to make `navigate` events\n * more accurate when gathered mountpoints are used.\n */\nconst globalEvents = getOrCreateGlobalSingleton<TempGlobalEvents>(\n 'core-plugin-api:analytics-tracker-events',\n () => ({\n mostRecentGatheredNavigation: undefined,\n mostRecentRoutableExtensionRender: undefined,\n beforeUnloadRegistered: false,\n }),\n);\n\n/**\n * Internal-only event representing when a routable extension is rendered.\n */\nexport const routableExtensionRenderedEvent = '_ROUTABLE-EXTENSION-RENDERED';\n\nexport class Tracker implements AnalyticsTracker {\n constructor(\n private readonly analyticsApi: AnalyticsApi,\n private context: AnalyticsContextValue = {\n routeRef: 'unknown',\n pluginId: 'root',\n extension: 'App',\n },\n ) {\n // Only register a single beforeunload event across all trackers.\n if (!globalEvents.beforeUnloadRegistered) {\n // Before the page unloads, attempt to capture any deferred navigation\n // events that haven't yet been captured.\n addEventListener(\n 'beforeunload',\n () => {\n if (globalEvents.mostRecentGatheredNavigation) {\n this.analyticsApi.captureEvent({\n ...globalEvents.mostRecentGatheredNavigation,\n ...globalEvents.mostRecentRoutableExtensionRender,\n });\n globalEvents.mostRecentGatheredNavigation = undefined;\n globalEvents.mostRecentRoutableExtensionRender = undefined;\n }\n },\n { once: true, passive: true },\n );\n\n // Prevent duplicate handlers from being registered.\n globalEvents.beforeUnloadRegistered = true;\n }\n }\n\n setContext(context: AnalyticsContextValue) {\n this.context = context;\n }\n\n captureEvent(\n action: string,\n subject: string,\n {\n value,\n attributes,\n }: { value?: number; attributes?: AnalyticsEventAttributes } = {},\n ) {\n // Never pass internal \"_routeNodeType\" context value.\n const { _routeNodeType, ...context } = this.context;\n\n // Never fire the special \"_routable-extension-rendered\" internal event.\n if (action === routableExtensionRenderedEvent) {\n // But keep track of it if we're delaying a `navigate` event for a\n // a gathered route node type.\n if (globalEvents.mostRecentGatheredNavigation) {\n globalEvents.mostRecentRoutableExtensionRender = {\n context: {\n ...context,\n extension: 'App',\n },\n };\n }\n return;\n }\n\n // If we are about to fire a real event, and we have an un-fired gathered\n // mountpoint navigation on the global store, we need to fire the navigate\n // event first, so this real event happens accurately after the navigation.\n if (globalEvents.mostRecentGatheredNavigation) {\n try {\n this.analyticsApi.captureEvent({\n ...globalEvents.mostRecentGatheredNavigation,\n ...globalEvents.mostRecentRoutableExtensionRender,\n });\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('Error during analytics event capture. %o', e);\n }\n\n // Clear the global stores.\n globalEvents.mostRecentGatheredNavigation = undefined;\n globalEvents.mostRecentRoutableExtensionRender = undefined;\n }\n\n // Never directly fire a navigation event on a gathered route with default\n // contextual details.\n if (\n action === 'navigate' &&\n _routeNodeType === 'gathered' &&\n context.pluginId === 'root'\n ) {\n // Instead, set it on the global store.\n globalEvents.mostRecentGatheredNavigation = {\n action,\n subject,\n value,\n attributes,\n context,\n };\n return;\n }\n\n try {\n this.analyticsApi.captureEvent({\n action,\n subject,\n value,\n attributes,\n context,\n });\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('Error during analytics event capture. %o', e);\n }\n }\n}\n"],"names":[],"mappings":";;AAoDqB,0BAAA;AAAA,EACnB,0CAAA;AAAA,EACA,OAAO;AAAA,IACL,4BAA8B,EAAA,KAAA,CAAA;AAAA,IAC9B,iCAAmC,EAAA,KAAA,CAAA;AAAA,IACnC,sBAAwB,EAAA,KAAA;AAAA,GAC1B,CAAA;AACF,EAAA;AAKO,MAAM,8BAAiC,GAAA;;;;"}
@@ -0,0 +1,31 @@
1
+ import { createExtensionDataRef } from '../wiring/createExtensionDataRef.esm.js';
2
+ import { createExtension } from '../wiring/createExtension.esm.js';
3
+
4
+ function createApiExtension(options) {
5
+ const { factory, configSchema, inputs: extensionInputs } = options;
6
+ const apiRef = "api" in options ? options.api : factory.api;
7
+ return createExtension({
8
+ kind: "api",
9
+ // Since ApiRef IDs use a global namespace we use the namespace here in order to override
10
+ // potential plugin IDs and always end up with the format `api:<api-ref-id>`
11
+ namespace: apiRef.id,
12
+ attachTo: { id: "app", input: "apis" },
13
+ inputs: extensionInputs,
14
+ configSchema,
15
+ output: {
16
+ api: createApiExtension.factoryDataRef
17
+ },
18
+ factory({ config, inputs }) {
19
+ if (typeof factory === "function") {
20
+ return { api: factory({ config, inputs }) };
21
+ }
22
+ return { api: factory };
23
+ }
24
+ });
25
+ }
26
+ ((createApiExtension2) => {
27
+ createApiExtension2.factoryDataRef = createExtensionDataRef("core.api.factory");
28
+ })(createApiExtension || (createApiExtension = {}));
29
+
30
+ export { createApiExtension };
31
+ //# sourceMappingURL=createApiExtension.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createApiExtension.esm.js","sources":["../../src/extensions/createApiExtension.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AnyApiFactory, AnyApiRef } from '@backstage/core-plugin-api';\nimport { PortableSchema } from '../schema';\nimport {\n ResolvedExtensionInputs,\n createExtension,\n createExtensionDataRef,\n} from '../wiring';\nimport { AnyExtensionInputMap } from '../wiring/createExtension';\nimport { Expand } from '../types';\n\n/** @public */\nexport function createApiExtension<\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(\n options: (\n | {\n api: AnyApiRef;\n factory: (options: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => AnyApiFactory;\n }\n | {\n factory: AnyApiFactory;\n }\n ) & {\n configSchema?: PortableSchema<TConfig>;\n inputs?: TInputs;\n },\n) {\n const { factory, configSchema, inputs: extensionInputs } = options;\n\n const apiRef =\n 'api' in options ? options.api : (factory as { api: AnyApiRef }).api;\n\n return createExtension({\n kind: 'api',\n // Since ApiRef IDs use a global namespace we use the namespace here in order to override\n // potential plugin IDs and always end up with the format `api:<api-ref-id>`\n namespace: apiRef.id,\n attachTo: { id: 'app', input: 'apis' },\n inputs: extensionInputs,\n configSchema,\n output: {\n api: createApiExtension.factoryDataRef,\n },\n factory({ config, inputs }) {\n if (typeof factory === 'function') {\n return { api: factory({ config, inputs }) };\n }\n return { api: factory };\n },\n });\n}\n\n/** @public */\nexport namespace createApiExtension {\n export const factoryDataRef =\n createExtensionDataRef<AnyApiFactory>('core.api.factory');\n}\n"],"names":["createApiExtension"],"mappings":";;;AA2BO,SAAS,mBAId,OAeA,EAAA;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,YAAc,EAAA,MAAA,EAAQ,iBAAoB,GAAA,OAAA,CAAA;AAE3D,EAAA,MAAM,MACJ,GAAA,KAAA,IAAS,OAAU,GAAA,OAAA,CAAQ,MAAO,OAA+B,CAAA,GAAA,CAAA;AAEnE,EAAA,OAAO,eAAgB,CAAA;AAAA,IACrB,IAAM,EAAA,KAAA;AAAA;AAAA;AAAA,IAGN,WAAW,MAAO,CAAA,EAAA;AAAA,IAClB,QAAU,EAAA,EAAE,EAAI,EAAA,KAAA,EAAO,OAAO,MAAO,EAAA;AAAA,IACrC,MAAQ,EAAA,eAAA;AAAA,IACR,YAAA;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,KAAK,kBAAmB,CAAA,cAAA;AAAA,KAC1B;AAAA,IACA,OAAQ,CAAA,EAAE,MAAQ,EAAA,MAAA,EAAU,EAAA;AAC1B,MAAI,IAAA,OAAO,YAAY,UAAY,EAAA;AACjC,QAAA,OAAO,EAAE,GAAK,EAAA,OAAA,CAAQ,EAAE,MAAQ,EAAA,MAAA,EAAQ,CAAE,EAAA,CAAA;AAAA,OAC5C;AACA,MAAO,OAAA,EAAE,KAAK,OAAQ,EAAA,CAAA;AAAA,KACxB;AAAA,GACD,CAAA,CAAA;AACH,CAAA;AAAA,CAGO,CAAUA,mBAAV,KAAA;AACE,EAAMA,mBAAAA,CAAA,cACX,GAAA,sBAAA,CAAsC,kBAAkB,CAAA,CAAA;AAAA,CAF3C,EAAA,kBAAA,KAAA,kBAAA,GAAA,EAAA,CAAA,CAAA;;;;"}
@@ -0,0 +1,26 @@
1
+ import { coreExtensionData } from '../wiring/coreExtensionData.esm.js';
2
+ import { createExtension } from '../wiring/createExtension.esm.js';
3
+
4
+ function createAppRootElementExtension(options) {
5
+ var _a;
6
+ return createExtension({
7
+ kind: "app-root-element",
8
+ namespace: options.namespace,
9
+ name: options.name,
10
+ attachTo: (_a = options.attachTo) != null ? _a : { id: "app/root", input: "elements" },
11
+ configSchema: options.configSchema,
12
+ disabled: options.disabled,
13
+ inputs: options.inputs,
14
+ output: {
15
+ element: coreExtensionData.reactElement
16
+ },
17
+ factory({ inputs, config }) {
18
+ return {
19
+ element: typeof options.element === "function" ? options.element({ inputs, config }) : options.element
20
+ };
21
+ }
22
+ });
23
+ }
24
+
25
+ export { createAppRootElementExtension };
26
+ //# sourceMappingURL=createAppRootElementExtension.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createAppRootElementExtension.esm.js","sources":["../../src/extensions/createAppRootElementExtension.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { JSX } from 'react';\nimport { PortableSchema } from '../schema/types';\nimport { Expand } from '../types';\nimport { coreExtensionData } from '../wiring/coreExtensionData';\nimport {\n AnyExtensionInputMap,\n ExtensionDefinition,\n ResolvedExtensionInputs,\n createExtension,\n} from '../wiring/createExtension';\n\n/**\n * Creates an extension that renders a React element at the app root, outside of\n * the app layout. This is useful for example for shared popups and similar.\n *\n * @public\n */\nexport function createAppRootElementExtension<\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(options: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n configSchema?: PortableSchema<TConfig>;\n disabled?: boolean;\n inputs?: TInputs;\n element:\n | JSX.Element\n | ((options: {\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n config: TConfig;\n }) => JSX.Element);\n}): ExtensionDefinition<TConfig> {\n return createExtension({\n kind: 'app-root-element',\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo ?? { id: 'app/root', input: 'elements' },\n configSchema: options.configSchema,\n disabled: options.disabled,\n inputs: options.inputs,\n output: {\n element: coreExtensionData.reactElement,\n },\n factory({ inputs, config }) {\n return {\n element:\n typeof options.element === 'function'\n ? options.element({ inputs, config })\n : options.element,\n };\n },\n });\n}\n"],"names":[],"mappings":";;;AAiCO,SAAS,8BAGd,OAa+B,EAAA;AAjDjC,EAAA,IAAA,EAAA,CAAA;AAkDE,EAAA,OAAO,eAAgB,CAAA;AAAA,IACrB,IAAM,EAAA,kBAAA;AAAA,IACN,WAAW,OAAQ,CAAA,SAAA;AAAA,IACnB,MAAM,OAAQ,CAAA,IAAA;AAAA,IACd,QAAA,EAAA,CAAU,aAAQ,QAAR,KAAA,IAAA,GAAA,EAAA,GAAoB,EAAE,EAAI,EAAA,UAAA,EAAY,OAAO,UAAW,EAAA;AAAA,IAClE,cAAc,OAAQ,CAAA,YAAA;AAAA,IACtB,UAAU,OAAQ,CAAA,QAAA;AAAA,IAClB,QAAQ,OAAQ,CAAA,MAAA;AAAA,IAChB,MAAQ,EAAA;AAAA,MACN,SAAS,iBAAkB,CAAA,YAAA;AAAA,KAC7B;AAAA,IACA,OAAQ,CAAA,EAAE,MAAQ,EAAA,MAAA,EAAU,EAAA;AAC1B,MAAO,OAAA;AAAA,QACL,OACE,EAAA,OAAO,OAAQ,CAAA,OAAA,KAAY,UACvB,GAAA,OAAA,CAAQ,OAAQ,CAAA,EAAE,MAAQ,EAAA,MAAA,EAAQ,CAAA,GAClC,OAAQ,CAAA,OAAA;AAAA,OAChB,CAAA;AAAA,KACF;AAAA,GACD,CAAA,CAAA;AACH;;;;"}
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { createExtension } from '../wiring/createExtension.esm.js';
3
+ import { createExtensionDataRef } from '../wiring/createExtensionDataRef.esm.js';
4
+
5
+ function createAppRootWrapperExtension(options) {
6
+ var _a;
7
+ return createExtension({
8
+ kind: "app-root-wrapper",
9
+ namespace: options.namespace,
10
+ name: options.name,
11
+ attachTo: (_a = options.attachTo) != null ? _a : { id: "app/root", input: "wrappers" },
12
+ configSchema: options.configSchema,
13
+ disabled: options.disabled,
14
+ inputs: options.inputs,
15
+ output: {
16
+ component: createAppRootWrapperExtension.componentDataRef
17
+ },
18
+ factory({ inputs, config }) {
19
+ const Component = (props) => {
20
+ return /* @__PURE__ */ React.createElement(options.Component, { inputs, config }, props.children);
21
+ };
22
+ return {
23
+ component: Component
24
+ };
25
+ }
26
+ });
27
+ }
28
+ ((createAppRootWrapperExtension2) => {
29
+ createAppRootWrapperExtension2.componentDataRef = createExtensionDataRef(
30
+ "app.root.wrapper"
31
+ );
32
+ })(createAppRootWrapperExtension || (createAppRootWrapperExtension = {}));
33
+
34
+ export { createAppRootWrapperExtension };
35
+ //# sourceMappingURL=createAppRootWrapperExtension.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createAppRootWrapperExtension.esm.js","sources":["../../src/extensions/createAppRootWrapperExtension.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ComponentType, PropsWithChildren } from 'react';\nimport { PortableSchema } from '../schema/types';\nimport {\n AnyExtensionInputMap,\n ExtensionDefinition,\n ResolvedExtensionInputs,\n createExtension,\n} from '../wiring/createExtension';\nimport { createExtensionDataRef } from '../wiring/createExtensionDataRef';\nimport { Expand } from '../types';\n\n/**\n * Creates an extension that renders a React wrapper at the app root, enclosing\n * the app layout. This is useful for example for adding global React contexts\n * and similar.\n *\n * @public\n */\nexport function createAppRootWrapperExtension<\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(options: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n configSchema?: PortableSchema<TConfig>;\n disabled?: boolean;\n inputs?: TInputs;\n Component: ComponentType<\n PropsWithChildren<{\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n config: TConfig;\n }>\n >;\n}): ExtensionDefinition<TConfig> {\n return createExtension({\n kind: 'app-root-wrapper',\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo ?? { id: 'app/root', input: 'wrappers' },\n configSchema: options.configSchema,\n disabled: options.disabled,\n inputs: options.inputs,\n output: {\n component: createAppRootWrapperExtension.componentDataRef,\n },\n factory({ inputs, config }) {\n const Component = (props: PropsWithChildren<{}>) => {\n return (\n <options.Component inputs={inputs} config={config}>\n {props.children}\n </options.Component>\n );\n };\n return {\n component: Component,\n };\n },\n });\n}\n\n/** @public */\nexport namespace createAppRootWrapperExtension {\n export const componentDataRef =\n createExtensionDataRef<ComponentType<PropsWithChildren<{}>>>(\n 'app.root.wrapper',\n );\n}\n"],"names":["createAppRootWrapperExtension"],"mappings":";;;;AAkCO,SAAS,8BAGd,OAa+B,EAAA;AAlDjC,EAAA,IAAA,EAAA,CAAA;AAmDE,EAAA,OAAO,eAAgB,CAAA;AAAA,IACrB,IAAM,EAAA,kBAAA;AAAA,IACN,WAAW,OAAQ,CAAA,SAAA;AAAA,IACnB,MAAM,OAAQ,CAAA,IAAA;AAAA,IACd,QAAA,EAAA,CAAU,aAAQ,QAAR,KAAA,IAAA,GAAA,EAAA,GAAoB,EAAE,EAAI,EAAA,UAAA,EAAY,OAAO,UAAW,EAAA;AAAA,IAClE,cAAc,OAAQ,CAAA,YAAA;AAAA,IACtB,UAAU,OAAQ,CAAA,QAAA;AAAA,IAClB,QAAQ,OAAQ,CAAA,MAAA;AAAA,IAChB,MAAQ,EAAA;AAAA,MACN,WAAW,6BAA8B,CAAA,gBAAA;AAAA,KAC3C;AAAA,IACA,OAAQ,CAAA,EAAE,MAAQ,EAAA,MAAA,EAAU,EAAA;AAC1B,MAAM,MAAA,SAAA,GAAY,CAAC,KAAiC,KAAA;AAClD,QAAA,2CACG,OAAQ,CAAA,SAAA,EAAR,EAAkB,MAAgB,EAAA,MAAA,EAAA,EAChC,MAAM,QACT,CAAA,CAAA;AAAA,OAEJ,CAAA;AACA,MAAO,OAAA;AAAA,QACL,SAAW,EAAA,SAAA;AAAA,OACb,CAAA;AAAA,KACF;AAAA,GACD,CAAA,CAAA;AACH,CAAA;AAAA,CAGO,CAAUA,8BAAV,KAAA;AACE,EAAMA,+BAAA,gBACX,GAAA,sBAAA;AAAA,IACE,kBAAA;AAAA,GACF,CAAA;AAAA,CAJa,EAAA,6BAAA,KAAA,6BAAA,GAAA,EAAA,CAAA,CAAA;;;;"}