@backstage/frontend-plugin-api 0.3.1-next.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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # @backstage/frontend-plugin-api
2
2
 
3
+ ## 0.4.0-next.1
4
+
5
+ ### Minor Changes
6
+
7
+ - a5a04739e1: The extension `factory` function now longer receives `id` or `source`, but instead now provides the extension's `AppNode` as `node`. The `ExtensionBoundary` component has also been updated to receive a `node` prop rather than `id` and `source`.
8
+
9
+ ### Patch Changes
10
+
11
+ - 5eb6b8a7bc: Added the nav logo extension for customization of sidebar logo
12
+ - 1f12fb762c: Create factories for overriding default core components extensions.
13
+ - 59709286b3: Add feature flags to plugins and extension overrides.
14
+ - e539735435: Added `createSignInPageExtension`.
15
+ - f27ee7d937: Migrate analytics api and context files.
16
+ - Updated dependencies
17
+ - @backstage/core-components@0.13.9-next.1
18
+ - @backstage/core-plugin-api@1.8.1-next.1
19
+ - @backstage/config@1.1.1
20
+ - @backstage/types@1.1.1
21
+ - @backstage/version-bridge@1.0.7
22
+
3
23
  ## 0.3.1-next.0
4
24
 
5
25
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,11 +1,54 @@
1
1
  /// <reference types="react" />
2
+ import React, { ReactNode, ComponentType, PropsWithChildren, JSX as JSX$1 } from 'react';
2
3
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
- import { IconComponent as IconComponent$1, AnyApiFactory, AppTheme, AnyApiRef } from '@backstage/core-plugin-api';
4
+ import { BackstagePlugin as BackstagePlugin$1, IconComponent as IconComponent$1, AnyApiFactory, AppTheme, ApiRef, AnyApiRef, SignInPageProps } from '@backstage/core-plugin-api';
4
5
  export { AlertApi, AlertMessage, AnyApiFactory, AnyApiRef, ApiFactory, ApiHolder, ApiRef, ApiRefConfig, AppTheme, AppThemeApi, AuthProviderInfo, AuthRequestOptions, BackstageIdentityApi, BackstageIdentityResponse, BackstageUserIdentity, ConfigApi, DiscoveryApi, ErrorApi, ErrorApiError, ErrorApiErrorContext, FeatureFlag, FeatureFlagState, FeatureFlagsApi, FeatureFlagsSaveOptions, FetchApi, IdentityApi, OAuthApi, OAuthRequestApi, OAuthRequester, OAuthRequesterOptions, OAuthScope, OpenIdConnectApi, PendingOAuthRequest, ProfileInfo, ProfileInfoApi, SessionApi, SessionState, StorageApi, StorageValueSnapshot, TypesToApiRefs, 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';
5
6
  import { JsonObject } from '@backstage/types';
6
- import React, { JSX as JSX$1, ReactNode, ComponentType } from 'react';
7
7
  import { z, ZodSchema, ZodTypeDef } from 'zod';
8
8
 
9
+ /**
10
+ * Common analytics context attributes.
11
+ *
12
+ * @public
13
+ */
14
+ type CommonAnalyticsContext = {
15
+ /**
16
+ * The nearest known parent plugin where the event was captured.
17
+ */
18
+ pluginId: string;
19
+ /**
20
+ * The nearest known parent extension where the event was captured.
21
+ */
22
+ /**
23
+ * The nearest known parent extension where the event was captured.
24
+ */
25
+ extensionId: string;
26
+ };
27
+ /**
28
+ * Analytics context envelope.
29
+ *
30
+ * @public
31
+ */
32
+ type AnalyticsContextValue = CommonAnalyticsContext & {
33
+ [param in string]: string | boolean | number | undefined;
34
+ };
35
+
36
+ /**
37
+ * Provides components in the child react tree an Analytics Context, ensuring
38
+ * all analytics events captured within the context have relevant attributes.
39
+ *
40
+ * @remarks
41
+ *
42
+ * Analytics contexts are additive, meaning the context ultimately emitted with
43
+ * an event is the combination of all contexts in the parent tree.
44
+ *
45
+ * @public
46
+ */
47
+ declare const AnalyticsContext: (options: {
48
+ attributes: Partial<AnalyticsContextValue>;
49
+ children: ReactNode;
50
+ }) => React.JSX.Element;
51
+
9
52
  /**
10
53
  * Catch-all type for route params.
11
54
  *
@@ -217,6 +260,51 @@ interface ConfigurableExtensionDataRef<TData, TConfig extends {
217
260
  /** @public */
218
261
  declare function createExtensionDataRef<TData>(id: string): ConfigurableExtensionDataRef<TData>;
219
262
 
263
+ /**
264
+ * Utility type to expand type aliases into their equivalent type.
265
+ * @ignore
266
+ */
267
+ type Expand<T> = T extends infer O ? {
268
+ [K in keyof O]: O[K];
269
+ } : never;
270
+ /** @public */
271
+ type CoreProgressComponent = ComponentType<PropsWithChildren<{}>>;
272
+ /** @public */
273
+ type CoreBootErrorPageComponent = ComponentType<PropsWithChildren<{
274
+ step: 'load-config' | 'load-chunk';
275
+ error: Error;
276
+ }>>;
277
+ /** @public */
278
+ type CoreNotFoundErrorPageComponent = ComponentType<PropsWithChildren<{}>>;
279
+ /** @public */
280
+ type CoreErrorBoundaryFallbackComponent = ComponentType<PropsWithChildren<{
281
+ plugin?: BackstagePlugin$1;
282
+ error: Error;
283
+ resetError: () => void;
284
+ }>>;
285
+
286
+ /** @public */
287
+ type ComponentRef<T> = {
288
+ id: string;
289
+ T: T;
290
+ };
291
+ /** @public */
292
+ declare const coreComponentsRefs: {
293
+ progress: ComponentRef<CoreProgressComponent>;
294
+ bootErrorPage: ComponentRef<CoreBootErrorPageComponent>;
295
+ notFoundErrorPage: ComponentRef<CoreNotFoundErrorPageComponent>;
296
+ errorBoundaryFallback: ComponentRef<CoreErrorBoundaryFallbackComponent>;
297
+ };
298
+
299
+ /** @public */
300
+ interface ExtensionBoundaryProps {
301
+ node: AppNode;
302
+ routable?: boolean;
303
+ children: ReactNode;
304
+ }
305
+ /** @public */
306
+ declare function ExtensionBoundary(props: ExtensionBoundaryProps): React.JSX.Element;
307
+
220
308
  /** @public */
221
309
  type NavTarget = {
222
310
  title: string;
@@ -224,6 +312,11 @@ type NavTarget = {
224
312
  routeRef: RouteRef<undefined>;
225
313
  };
226
314
  /** @public */
315
+ type LogoElements = {
316
+ logoIcon?: JSX$1.Element;
317
+ logoFull?: JSX$1.Element;
318
+ };
319
+ /** @public */
227
320
  declare const coreExtensionData: {
228
321
  reactElement: ConfigurableExtensionDataRef<JSX$1.Element, {}>;
229
322
  routePath: ConfigurableExtensionDataRef<string, {}>;
@@ -231,6 +324,11 @@ declare const coreExtensionData: {
231
324
  routeRef: ConfigurableExtensionDataRef<RouteRef<AnyRouteRefParams>, {}>;
232
325
  navTarget: ConfigurableExtensionDataRef<NavTarget, {}>;
233
326
  theme: ConfigurableExtensionDataRef<AppTheme, {}>;
327
+ logoElements: ConfigurableExtensionDataRef<LogoElements, {}>;
328
+ component: ConfigurableExtensionDataRef<{
329
+ ref: ComponentRef<ComponentType<any>>;
330
+ impl: ComponentType<any>;
331
+ }, {}>;
234
332
  };
235
333
 
236
334
  /** @public */
@@ -242,14 +340,6 @@ type PortableSchema<TOutput> = {
242
340
  /** @public */
243
341
  declare function createSchemaFromZod<TOutput, TInput>(schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>): PortableSchema<TOutput>;
244
342
 
245
- /**
246
- * Utility type to expand type aliases into their equivalent type.
247
- * @ignore
248
- */
249
- type Expand<T> = T extends infer O ? {
250
- [K in keyof O]: O[K];
251
- } : never;
252
-
253
343
  /** @public */
254
344
  interface ExtensionInput<TExtensionData extends AnyExtensionDataMap, TConfig extends {
255
345
  singleton: boolean;
@@ -268,32 +358,6 @@ declare function createExtensionInput<TExtensionData extends AnyExtensionDataMap
268
358
  optional: TConfig['optional'] extends true ? true : false;
269
359
  }>;
270
360
 
271
- /** @public */
272
- type AnyRoutes = {
273
- [name in string]: RouteRef;
274
- };
275
- /** @public */
276
- type AnyExternalRoutes = {
277
- [name in string]: ExternalRouteRef;
278
- };
279
- /** @public */
280
- interface PluginOptions<Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes> {
281
- id: string;
282
- routes?: Routes;
283
- externalRoutes?: ExternalRoutes;
284
- extensions?: Extension<unknown>[];
285
- }
286
- /** @public */
287
- interface BackstagePlugin<Routes extends AnyRoutes = AnyRoutes, ExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes> {
288
- $$type: '@backstage/BackstagePlugin';
289
- id: string;
290
- extensions: Extension<unknown>[];
291
- routes: Routes;
292
- externalRoutes: ExternalRoutes;
293
- }
294
- /** @public */
295
- declare function createPlugin<Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}>(options: PluginOptions<Routes, ExternalRoutes>): BackstagePlugin<Routes, ExternalRoutes>;
296
-
297
361
  /** @public */
298
362
  type AnyExtensionDataMap = {
299
363
  [name in string]: ExtensionDataRef<unknown, {
@@ -341,7 +405,7 @@ interface CreateExtensionOptions<TOutput extends AnyExtensionDataMap, TInputs ex
341
405
  output: TOutput;
342
406
  configSchema?: PortableSchema<TConfig>;
343
407
  factory(options: {
344
- source?: BackstagePlugin;
408
+ node: AppNode;
345
409
  config: TConfig;
346
410
  inputs: Expand<ExtensionInputValues<TInputs>>;
347
411
  }): Expand<ExtensionDataValues<TOutput>>;
@@ -359,7 +423,7 @@ interface Extension<TConfig> {
359
423
  output: AnyExtensionDataMap;
360
424
  configSchema?: PortableSchema<TConfig>;
361
425
  factory(options: {
362
- source?: BackstagePlugin;
426
+ node: AppNode;
363
427
  config: TConfig;
364
428
  inputs: Record<string, undefined | Record<string, unknown> | Array<Record<string, unknown>>>;
365
429
  }): ExtensionDataValues<any>;
@@ -367,13 +431,50 @@ interface Extension<TConfig> {
367
431
  /** @public */
368
432
  declare function createExtension<TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig = never>(options: CreateExtensionOptions<TOutput, TInputs, TConfig>): Extension<TConfig>;
369
433
 
434
+ /**
435
+ * Feature flag configuration.
436
+ *
437
+ * @public
438
+ */
439
+ type FeatureFlagConfig = {
440
+ /** Feature flag name */
441
+ name: string;
442
+ };
443
+
444
+ /** @public */
445
+ type AnyRoutes = {
446
+ [name in string]: RouteRef;
447
+ };
448
+ /** @public */
449
+ type AnyExternalRoutes = {
450
+ [name in string]: ExternalRouteRef;
451
+ };
452
+ /** @public */
453
+ interface PluginOptions<Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes> {
454
+ id: string;
455
+ routes?: Routes;
456
+ externalRoutes?: ExternalRoutes;
457
+ extensions?: Extension<unknown>[];
458
+ featureFlags?: FeatureFlagConfig[];
459
+ }
460
+ /** @public */
461
+ interface BackstagePlugin<Routes extends AnyRoutes = AnyRoutes, ExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes> {
462
+ readonly $$type: '@backstage/BackstagePlugin';
463
+ readonly id: string;
464
+ readonly routes: Routes;
465
+ readonly externalRoutes: ExternalRoutes;
466
+ }
467
+ /** @public */
468
+ declare function createPlugin<Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}>(options: PluginOptions<Routes, ExternalRoutes>): BackstagePlugin<Routes, ExternalRoutes>;
469
+
370
470
  /** @public */
371
471
  interface ExtensionOverridesOptions {
372
472
  extensions: Extension<unknown>[];
473
+ featureFlags?: FeatureFlagConfig[];
373
474
  }
374
475
  /** @public */
375
476
  interface ExtensionOverrides {
376
- $$type: '@backstage/ExtensionOverrides';
477
+ readonly $$type: '@backstage/ExtensionOverrides';
377
478
  }
378
479
  /** @public */
379
480
  declare function createExtensionOverrides(options: ExtensionOverridesOptions): ExtensionOverrides;
@@ -476,15 +577,126 @@ interface AppTreeApi {
476
577
  */
477
578
  declare const appTreeApiRef: _backstage_core_plugin_api.ApiRef<AppTreeApi>;
478
579
 
479
- /** @public */
480
- interface ExtensionBoundaryProps {
481
- id: string;
482
- source?: BackstagePlugin;
483
- routable?: boolean;
484
- children: ReactNode;
580
+ /**
581
+ * API for looking up components based on component refs.
582
+ *
583
+ * @public
584
+ */
585
+ interface ComponentsApi {
586
+ getComponent<T>(ref: ComponentRef<T>): T;
485
587
  }
486
- /** @public */
487
- declare function ExtensionBoundary(props: ExtensionBoundaryProps): React.JSX.Element;
588
+ /**
589
+ * The `ApiRef` of {@link ComponentsApi}.
590
+ *
591
+ * @public
592
+ */
593
+ declare const componentsApiRef: _backstage_core_plugin_api.ApiRef<ComponentsApi>;
594
+
595
+ /**
596
+ * Represents an event worth tracking in an analytics system that could inform
597
+ * how users of a Backstage instance are using its features.
598
+ *
599
+ * @public
600
+ */
601
+ type AnalyticsEvent = {
602
+ /**
603
+ * A string that identifies the event being tracked by the type of action the
604
+ * event represents. Be careful not to encode extra metadata in this string
605
+ * that should instead be placed in the Analytics Context or attributes.
606
+ * Examples include:
607
+ *
608
+ * - view
609
+ * - click
610
+ * - filter
611
+ * - search
612
+ * - hover
613
+ * - scroll
614
+ */
615
+ action: string;
616
+ /**
617
+ * A string that uniquely identifies the object that the action is being
618
+ * taken on. Examples include:
619
+ *
620
+ * - The path of the page viewed
621
+ * - The url of the link clicked
622
+ * - The value that was filtered by
623
+ * - The text that was searched for
624
+ */
625
+ subject: string;
626
+ /**
627
+ * An optional numeric value relevant to the event that could be aggregated
628
+ * by analytics tools. Examples include:
629
+ *
630
+ * - The index or position of the clicked element in an ordered list
631
+ * - The percentage of an element that has been scrolled through
632
+ * - The amount of time that has elapsed since a fixed point
633
+ * - A satisfaction score on a fixed scale
634
+ */
635
+ value?: number;
636
+ /**
637
+ * Optional, additional attributes (representing dimensions or metrics)
638
+ * specific to the event that could be forwarded on to analytics systems.
639
+ */
640
+ attributes?: AnalyticsEventAttributes;
641
+ /**
642
+ * Contextual metadata relating to where the event was captured and by whom.
643
+ * This could include information about the route, plugin, or extension in
644
+ * which an event was captured.
645
+ */
646
+ context: AnalyticsContextValue;
647
+ };
648
+ /**
649
+ * A structure allowing other arbitrary metadata to be provided by analytics
650
+ * event emitters.
651
+ *
652
+ * @public
653
+ */
654
+ type AnalyticsEventAttributes = {
655
+ [attribute in string]: string | boolean | number;
656
+ };
657
+ /**
658
+ * Represents a tracker with methods that can be called to track events in a
659
+ * configured analytics service.
660
+ *
661
+ * @public
662
+ */
663
+ type AnalyticsTracker = {
664
+ captureEvent: (action: string, subject: string, options?: {
665
+ value?: number;
666
+ attributes?: AnalyticsEventAttributes;
667
+ }) => void;
668
+ };
669
+ /**
670
+ * The Analytics API is used to track user behavior in a Backstage instance.
671
+ *
672
+ * @remarks
673
+ *
674
+ * To instrument your App or Plugin, retrieve an analytics tracker using the
675
+ * useAnalytics() hook. This will return a pre-configured AnalyticsTracker
676
+ * with relevant methods for instrumentation.
677
+ *
678
+ * @public
679
+ */
680
+ type AnalyticsApi = {
681
+ /**
682
+ * Primary event handler responsible for compiling and forwarding events to
683
+ * an analytics system.
684
+ */
685
+ captureEvent(event: AnalyticsEvent): void;
686
+ };
687
+ /**
688
+ * The API reference of {@link AnalyticsApi}.
689
+ *
690
+ * @public
691
+ */
692
+ declare const analyticsApiRef: ApiRef<AnalyticsApi>;
693
+
694
+ /**
695
+ * Gets a pre-configured analytics tracker.
696
+ *
697
+ * @public
698
+ */
699
+ declare function useAnalytics(): AnalyticsTracker;
488
700
 
489
701
  /** @public */
490
702
  declare function createApiExtension<TConfig extends {}, TInputs extends AnyExtensionInputMap>(options: ({
@@ -539,9 +751,47 @@ declare function createNavItemExtension(options: {
539
751
  title: string;
540
752
  }>;
541
753
 
754
+ /**
755
+ *
756
+ * @public
757
+ */
758
+ declare function createSignInPageExtension<TConfig extends {}, TInputs extends AnyExtensionInputMap>(options: {
759
+ id: string;
760
+ attachTo?: {
761
+ id: string;
762
+ input: string;
763
+ };
764
+ configSchema?: PortableSchema<TConfig>;
765
+ disabled?: boolean;
766
+ inputs?: TInputs;
767
+ loader: (options: {
768
+ config: TConfig;
769
+ inputs: Expand<ExtensionInputValues<TInputs>>;
770
+ }) => Promise<ComponentType<SignInPageProps>>;
771
+ }): Extension<TConfig>;
772
+
542
773
  /** @public */
543
774
  declare function createThemeExtension(theme: AppTheme): Extension<never>;
544
775
 
776
+ /** @public */
777
+ declare function createComponentExtension<TRef extends ComponentRef<any>, TConfig extends {}, TInputs extends AnyExtensionInputMap>(options: {
778
+ ref: TRef;
779
+ disabled?: boolean;
780
+ inputs?: TInputs;
781
+ configSchema?: PortableSchema<TConfig>;
782
+ component: {
783
+ lazy: (values: {
784
+ config: TConfig;
785
+ inputs: Expand<ExtensionInputValues<TInputs>>;
786
+ }) => Promise<TRef['T']>;
787
+ } | {
788
+ sync: (values: {
789
+ config: TConfig;
790
+ inputs: Expand<ExtensionInputValues<TInputs>>;
791
+ }) => TRef['T'];
792
+ };
793
+ }): Extension<TConfig>;
794
+
545
795
  /**
546
796
  * IconComponent is the common icon type used throughout Backstage when
547
797
  * working with and rendering generic icons, including the app system icons.
@@ -564,4 +814,4 @@ type IconComponent = ComponentType<{
564
814
  fontSize?: 'medium' | 'large' | 'small' | 'inherit';
565
815
  }>;
566
816
 
567
- export { AnyExtensionDataMap, AnyExtensionInputMap, AnyExternalRoutes, AnyRouteRefParams, AnyRoutes, AppNode, AppNodeEdges, AppNodeInstance, AppNodeSpec, AppTree, AppTreeApi, BackstagePlugin, ConfigurableExtensionDataRef, CreateExtensionOptions, Extension, ExtensionBoundary, ExtensionBoundaryProps, ExtensionDataRef, ExtensionDataValues, ExtensionInput, ExtensionInputValues, ExtensionOverrides, ExtensionOverridesOptions, ExternalRouteRef, IconComponent, NavTarget, PluginOptions, PortableSchema, RouteFunc, RouteRef, SubRouteRef, appTreeApiRef, coreExtensionData, createApiExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSubRouteRef, createThemeExtension, useRouteRef, useRouteRefParams };
817
+ export { AnalyticsApi, AnalyticsContext, AnalyticsContextValue, AnalyticsEvent, AnalyticsEventAttributes, AnalyticsTracker, AnyExtensionDataMap, AnyExtensionInputMap, AnyExternalRoutes, AnyRouteRefParams, AnyRoutes, AppNode, AppNodeEdges, AppNodeInstance, AppNodeSpec, AppTree, AppTreeApi, BackstagePlugin, CommonAnalyticsContext, ComponentRef, ComponentsApi, ConfigurableExtensionDataRef, CoreBootErrorPageComponent, CoreErrorBoundaryFallbackComponent, CoreNotFoundErrorPageComponent, CoreProgressComponent, CreateExtensionOptions, Extension, ExtensionBoundary, ExtensionBoundaryProps, ExtensionDataRef, ExtensionDataValues, ExtensionInput, ExtensionInputValues, ExtensionOverrides, ExtensionOverridesOptions, ExternalRouteRef, FeatureFlagConfig, IconComponent, LogoElements, NavTarget, PluginOptions, PortableSchema, RouteFunc, RouteRef, SubRouteRef, analyticsApiRef, appTreeApiRef, componentsApiRef, coreComponentsRefs, coreExtensionData, createApiExtension, createComponentExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSignInPageExtension, createSubRouteRef, createThemeExtension, useAnalytics, useRouteRef, useRouteRefParams };
package/dist/index.esm.js CHANGED
@@ -1,15 +1,189 @@
1
- import { createApiRef, useApp, AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';
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';
2
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
- import React, { Component, Suspense, useEffect, lazy, useMemo } from 'react';
4
5
  import { Button } from '@material-ui/core';
5
6
  import { ErrorPanel } from '@backstage/core-components';
6
- import { getOrCreateGlobalSingleton, useVersionedContext } from '@backstage/version-bridge';
7
7
  import { z } from 'zod';
8
8
  import zodToJsonSchema from 'zod-to-json-schema';
9
9
  import { useLocation, useParams } from 'react-router-dom';
10
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
+
11
37
  const appTreeApiRef = createApiRef({ id: "core.app-tree" });
12
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
+
13
187
  var __defProp$3 = Object.defineProperty;
14
188
  var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
15
189
  var __publicField$3 = (obj, key, value) => {
@@ -52,13 +226,6 @@ class ErrorBoundary extends Component {
52
226
  }
53
227
  }
54
228
 
55
- function ExtensionSuspense(props) {
56
- const { children } = props;
57
- const app = useApp();
58
- const { Progress } = app.getComponents();
59
- return /* @__PURE__ */ React.createElement(Suspense, { fallback: /* @__PURE__ */ React.createElement(Progress, null) }, children);
60
- }
61
-
62
229
  getOrCreateGlobalSingleton(
63
230
  "core-plugin-api:analytics-tracker-events",
64
231
  () => ({
@@ -71,7 +238,7 @@ const routableExtensionRenderedEvent = "_ROUTABLE-EXTENSION-RENDERED";
71
238
 
72
239
  const RouteTracker = (props) => {
73
240
  const { disableTracking, children } = props;
74
- const analytics = useAnalytics();
241
+ const analytics = useAnalytics$1();
75
242
  useEffect(() => {
76
243
  if (disableTracking)
77
244
  return;
@@ -80,12 +247,13 @@ const RouteTracker = (props) => {
80
247
  return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
81
248
  };
82
249
  function ExtensionBoundary(props) {
83
- const { id, source, routable, children } = props;
250
+ var _a;
251
+ const { node, routable, children } = props;
84
252
  const attributes = {
85
- extension: id,
86
- pluginId: source == null ? void 0 : source.id
253
+ extension: node.spec.id,
254
+ pluginId: (_a = node.spec.source) == null ? void 0 : _a.id
87
255
  };
88
- return /* @__PURE__ */ React.createElement(ExtensionSuspense, null, /* @__PURE__ */ React.createElement(ErrorBoundary, { plugin: source }, /* @__PURE__ */ React.createElement(AnalyticsContext, { attributes }, /* @__PURE__ */ React.createElement(RouteTracker, { disableTracking: !routable }, children))));
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))));
89
257
  }
90
258
 
91
259
  function createExtensionDataRef(id) {
@@ -105,7 +273,9 @@ const coreExtensionData = {
105
273
  apiFactory: createExtensionDataRef("core.api.factory"),
106
274
  routeRef: createExtensionDataRef("core.routing.ref"),
107
275
  navTarget: createExtensionDataRef("core.nav.target"),
108
- theme: createExtensionDataRef("core.theme")
276
+ theme: createExtensionDataRef("core.theme"),
277
+ logoElements: createExtensionDataRef("core.logos"),
278
+ component: createExtensionDataRef("component.ref")
109
279
  };
110
280
 
111
281
  function createExtension(options) {
@@ -136,21 +306,25 @@ function createExtensionInput(extensionData, config) {
136
306
  }
137
307
 
138
308
  function createPlugin(options) {
139
- var _a, _b, _c;
309
+ var _a, _b, _c, _d;
140
310
  return {
141
- ...options,
311
+ $$type: "@backstage/BackstagePlugin",
312
+ version: "v1",
313
+ id: options.id,
142
314
  routes: (_a = options.routes) != null ? _a : {},
143
315
  externalRoutes: (_b = options.externalRoutes) != null ? _b : {},
144
316
  extensions: (_c = options.extensions) != null ? _c : [],
145
- $$type: "@backstage/BackstagePlugin"
317
+ featureFlags: (_d = options.featureFlags) != null ? _d : []
146
318
  };
147
319
  }
148
320
 
149
321
  function createExtensionOverrides(options) {
322
+ var _a;
150
323
  return {
151
324
  $$type: "@backstage/ExtensionOverrides",
152
325
  version: "v1",
153
- extensions: options.extensions
326
+ extensions: options.extensions,
327
+ featureFlags: (_a = options.featureFlags) != null ? _a : []
154
328
  };
155
329
  }
156
330
 
@@ -220,14 +394,14 @@ function createPageExtension(options) {
220
394
  path: coreExtensionData.routePath,
221
395
  routeRef: coreExtensionData.routeRef.optional()
222
396
  },
223
- factory({ config, inputs, source }) {
397
+ factory({ config, inputs, node }) {
224
398
  const ExtensionComponent = lazy(
225
399
  () => options.loader({ config, inputs }).then((element) => ({ default: () => element }))
226
400
  );
227
401
  return {
228
402
  path: config.path,
229
403
  routeRef: options.routeRef,
230
- element: /* @__PURE__ */ React.createElement(ExtensionBoundary, { id, source, routable: true }, /* @__PURE__ */ React.createElement(ExtensionComponent, null))
404
+ element: /* @__PURE__ */ React.createElement(ExtensionBoundary, { node, routable: true }, /* @__PURE__ */ React.createElement(ExtensionComponent, null))
231
405
  };
232
406
  }
233
407
  });
@@ -256,6 +430,30 @@ function createNavItemExtension(options) {
256
430
  });
257
431
  }
258
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
+
259
457
  function createThemeExtension(theme) {
260
458
  return createExtension({
261
459
  id: `themes.${theme.id}`,
@@ -267,6 +465,37 @@ function createThemeExtension(theme) {
267
465
  });
268
466
  }
269
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
+
270
499
  const MESSAGE_MARKER = "eHgtF5hmbrXyiEvo";
271
500
  function describeParentCallSite(ErrorConstructor = Error) {
272
501
  const { stack } = new ErrorConstructor(MESSAGE_MARKER);
@@ -505,5 +734,5 @@ function useRouteRefParams(_routeRef) {
505
734
  return useParams();
506
735
  }
507
736
 
508
- 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 };
509
738
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/apis/definitions/AppTreeApi.ts","../src/components/ErrorBoundary.tsx","../src/components/ExtensionSuspense.tsx","../../core-plugin-api/src/analytics/Tracker.ts","../src/components/ExtensionBoundary.tsx","../src/wiring/createExtensionDataRef.ts","../src/wiring/coreExtensionData.ts","../src/wiring/createExtension.ts","../src/wiring/createExtensionInput.ts","../src/wiring/createPlugin.ts","../src/wiring/createExtensionOverrides.ts","../src/extensions/createApiExtension.ts","../src/schema/createSchemaFromZod.ts","../src/extensions/createPageExtension.tsx","../src/extensions/createNavItemExtension.tsx","../src/extensions/createThemeExtension.ts","../src/routing/describeParentCallSite.ts","../src/routing/RouteRef.ts","../src/routing/SubRouteRef.ts","../src/routing/ExternalRouteRef.ts","../src/routing/useRouteRef.tsx","../src/routing/useRouteRefParams.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","/*\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, PropsWithChildren } from 'react';\n// TODO: Dependency on MUI should be removed from core packages\nimport { Button } from '@material-ui/core';\nimport { ErrorPanel } from '@backstage/core-components';\nimport { BackstagePlugin } from '../wiring';\n\ntype DefaultErrorBoundaryFallbackProps = PropsWithChildren<{\n plugin?: BackstagePlugin;\n error: Error;\n resetError: () => void;\n}>;\n\nconst DefaultErrorBoundaryFallback = ({\n plugin,\n error,\n resetError,\n}: DefaultErrorBoundaryFallbackProps) => {\n const title = `Error in ${plugin?.id}`;\n\n return (\n <ErrorPanel title={title} error={error} defaultExpanded>\n <Button variant=\"outlined\" onClick={resetError}>\n Retry\n </Button>\n </ErrorPanel>\n );\n};\n\ntype ErrorBoundaryProps = PropsWithChildren<{ plugin?: BackstagePlugin }>;\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 } = this.props;\n\n if (error) {\n // TODO: use a configurable error boundary fallback\n return (\n <DefaultErrorBoundaryFallback\n plugin={plugin}\n error={error}\n resetError={this.handleErrorReset}\n />\n );\n }\n\n return children;\n }\n}\n","/*\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, { ReactNode, Suspense } from 'react';\nimport { useApp } from '@backstage/core-plugin-api';\n\n/** @public */\nexport interface ExtensionSuspenseProps {\n children: ReactNode;\n}\n\n/** @public */\nexport function ExtensionSuspense(props: ExtensionSuspenseProps) {\n const { children } = props;\n\n const app = useApp();\n const { Progress } = app.getComponents();\n\n return <Suspense fallback={<Progress />}>{children}</Suspense>;\n}\n","/*\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","/*\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, { PropsWithChildren, ReactNode, useEffect } from 'react';\nimport { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';\nimport { BackstagePlugin } from '../wiring';\nimport { ErrorBoundary } from './ErrorBoundary';\nimport { ExtensionSuspense } from './ExtensionSuspense';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { routableExtensionRenderedEvent } from '../../../core-plugin-api/src/analytics/Tracker';\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 id: string;\n source?: BackstagePlugin;\n routable?: boolean;\n children: ReactNode;\n}\n\n/** @public */\nexport function ExtensionBoundary(props: ExtensionBoundaryProps) {\n const { id, source, routable, children } = props;\n\n // Skipping \"routeRef\" attribute in the new system, the extension \"id\" should provide more insight\n const attributes = {\n extension: id,\n pluginId: source?.id,\n };\n\n return (\n <ExtensionSuspense>\n <ErrorBoundary plugin={source}>\n <AnalyticsContext attributes={attributes}>\n <RouteTracker disableTracking={!routable}>{children}</RouteTracker>\n </AnalyticsContext>\n </ErrorBoundary>\n </ExtensionSuspense>\n );\n}\n","/*\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 ExtensionDataRef<\n TData,\n TConfig extends { optional?: true } = {},\n> = {\n id: string;\n T: TData;\n config: TConfig;\n $$type: '@backstage/ExtensionDataRef';\n};\n\n/** @public */\nexport interface ConfigurableExtensionDataRef<\n TData,\n TConfig extends { optional?: true } = {},\n> extends ExtensionDataRef<TData, TConfig> {\n optional(): ConfigurableExtensionDataRef<TData, TData & { optional: true }>;\n}\n\n// TODO: change to options object with ID.\n/** @public */\nexport function createExtensionDataRef<TData>(\n id: string,\n): ConfigurableExtensionDataRef<TData> {\n return {\n id,\n $$type: '@backstage/ExtensionDataRef',\n config: {},\n optional() {\n return { ...this, config: { ...this.config, optional: true } };\n },\n } as ConfigurableExtensionDataRef<TData>;\n}\n","/*\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 {\n AnyApiFactory,\n AppTheme,\n IconComponent,\n} from '@backstage/core-plugin-api';\nimport { createExtensionDataRef } from './createExtensionDataRef';\nimport { RouteRef } from '../routing';\n\n/** @public */\nexport type NavTarget = {\n title: string;\n icon: IconComponent;\n routeRef: RouteRef<undefined>;\n};\n\n/** @public */\nexport const coreExtensionData = {\n reactElement: createExtensionDataRef<JSX.Element>('core.reactElement'),\n routePath: createExtensionDataRef<string>('core.routing.path'),\n apiFactory: createExtensionDataRef<AnyApiFactory>('core.api.factory'),\n routeRef: createExtensionDataRef<RouteRef>('core.routing.ref'),\n navTarget: createExtensionDataRef<NavTarget>('core.nav.target'),\n theme: createExtensionDataRef<AppTheme>('core.theme'),\n};\n","/*\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 { PortableSchema } from '../schema';\nimport { Expand } from '../types';\nimport { ExtensionDataRef } from './createExtensionDataRef';\nimport { ExtensionInput } from './createExtensionInput';\nimport { BackstagePlugin } from './createPlugin';\n\n/** @public */\nexport type AnyExtensionDataMap = {\n [name in string]: ExtensionDataRef<unknown, { optional?: true }>;\n};\n\n/** @public */\nexport type AnyExtensionInputMap = {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataMap,\n { optional: boolean; singleton: boolean }\n >;\n};\n\n/**\n * Converts an extension data map into the matching concrete data values type.\n * @public\n */\nexport type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = {\n [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends {\n optional: true;\n }\n ? never\n : DataName]: TExtensionData[DataName]['T'];\n} & {\n [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends {\n optional: true;\n }\n ? DataName\n : never]?: TExtensionData[DataName]['T'];\n};\n\n/**\n * Converts an extension input map into the matching concrete input values type.\n * @public\n */\nexport type ExtensionInputValues<\n TInputs extends { [name in string]: ExtensionInput<any, any> },\n> = {\n [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']\n ? Array<Expand<ExtensionDataValues<TInputs[InputName]['extensionData']>>>\n : false extends TInputs[InputName]['config']['optional']\n ? Expand<ExtensionDataValues<TInputs[InputName]['extensionData']>>\n : Expand<\n ExtensionDataValues<TInputs[InputName]['extensionData']> | undefined\n >;\n};\n\n/** @public */\nexport interface CreateExtensionOptions<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig,\n> {\n id: string;\n attachTo: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output: TOutput;\n configSchema?: PortableSchema<TConfig>;\n factory(options: {\n source?: BackstagePlugin;\n config: TConfig;\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }): Expand<ExtensionDataValues<TOutput>>;\n}\n\n/** @public */\nexport interface Extension<TConfig> {\n $$type: '@backstage/Extension';\n id: string;\n attachTo: { id: string; input: string };\n disabled: boolean;\n inputs: AnyExtensionInputMap;\n output: AnyExtensionDataMap;\n configSchema?: PortableSchema<TConfig>;\n factory(options: {\n source?: BackstagePlugin;\n config: TConfig;\n inputs: Record<\n string,\n undefined | Record<string, unknown> | Array<Record<string, unknown>>\n >;\n }): ExtensionDataValues<any>;\n}\n\n/** @public */\nexport function createExtension<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig = never,\n>(\n options: CreateExtensionOptions<TOutput, TInputs, TConfig>,\n): Extension<TConfig> {\n return {\n ...options,\n disabled: options.disabled ?? false,\n $$type: '@backstage/Extension',\n inputs: options.inputs ?? {},\n factory({ inputs, ...rest }) {\n // TODO: Simplify this, but TS wouldn't infer the input type for some reason\n return options.factory({\n inputs: inputs as Expand<ExtensionInputValues<TInputs>>,\n ...rest,\n });\n },\n };\n}\n","/*\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 { AnyExtensionDataMap } from './createExtension';\n\n/** @public */\nexport interface ExtensionInput<\n TExtensionData extends AnyExtensionDataMap,\n TConfig extends { singleton: boolean; optional: boolean },\n> {\n $$type: '@backstage/ExtensionInput';\n extensionData: TExtensionData;\n config: TConfig;\n}\n\n/** @public */\nexport function createExtensionInput<\n TExtensionData extends AnyExtensionDataMap,\n TConfig extends { singleton?: boolean; optional?: boolean },\n>(\n extensionData: TExtensionData,\n config?: TConfig,\n): ExtensionInput<\n TExtensionData,\n {\n singleton: TConfig['singleton'] extends true ? true : false;\n optional: TConfig['optional'] extends true ? true : false;\n }\n> {\n return {\n $$type: '@backstage/ExtensionInput',\n extensionData,\n config: {\n singleton: Boolean(config?.singleton) as TConfig['singleton'] extends true\n ? true\n : false,\n optional: Boolean(config?.optional) as TConfig['optional'] extends true\n ? true\n : false,\n },\n };\n}\n","/*\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 { Extension } from './createExtension';\nimport { ExternalRouteRef, RouteRef } from '../routing';\n\n/** @public */\nexport type AnyRoutes = { [name in string]: RouteRef };\n\n/** @public */\nexport type AnyExternalRoutes = { [name in string]: ExternalRouteRef };\n\n/** @public */\nexport interface PluginOptions<\n Routes extends AnyRoutes,\n ExternalRoutes extends AnyExternalRoutes,\n> {\n id: string;\n routes?: Routes;\n externalRoutes?: ExternalRoutes;\n extensions?: Extension<unknown>[];\n}\n\n/** @public */\nexport interface BackstagePlugin<\n Routes extends AnyRoutes = AnyRoutes,\n ExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes,\n> {\n $$type: '@backstage/BackstagePlugin';\n id: string;\n extensions: Extension<unknown>[];\n routes: Routes;\n externalRoutes: ExternalRoutes;\n}\n\n/** @public */\nexport function createPlugin<\n Routes extends AnyRoutes = {},\n ExternalRoutes extends AnyExternalRoutes = {},\n>(\n options: PluginOptions<Routes, ExternalRoutes>,\n): BackstagePlugin<Routes, ExternalRoutes> {\n return {\n ...options,\n routes: options.routes ?? ({} as Routes),\n externalRoutes: options.externalRoutes ?? ({} as ExternalRoutes),\n extensions: options.extensions ?? [],\n $$type: '@backstage/BackstagePlugin',\n };\n}\n","/*\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 { Extension } from './createExtension';\n\n/** @public */\nexport interface ExtensionOverridesOptions {\n extensions: Extension<unknown>[];\n}\n\n/** @public */\nexport interface ExtensionOverrides {\n $$type: '@backstage/ExtensionOverrides';\n}\n\n/** @internal */\nexport interface InternalExtensionOverrides extends ExtensionOverrides {\n version: string;\n extensions: Extension<unknown>[];\n}\n\n/** @public */\nexport function createExtensionOverrides(\n options: ExtensionOverridesOptions,\n): ExtensionOverrides {\n return {\n $$type: '@backstage/ExtensionOverrides',\n version: 'v1',\n extensions: options.extensions,\n } as InternalExtensionOverrides;\n}\n\n/** @internal */\nexport function toInternalExtensionOverrides(\n overrides: ExtensionOverrides,\n): InternalExtensionOverrides {\n const internal = overrides as InternalExtensionOverrides;\n if (internal.$$type !== '@backstage/ExtensionOverrides') {\n throw new Error(\n `Invalid translation resource, bad type '${internal.$$type}'`,\n );\n }\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid translation resource, bad version '${internal.version}'`,\n );\n }\n return internal;\n}\n","/*\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 ExtensionInputValues,\n createExtension,\n coreExtensionData,\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<ExtensionInputValues<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 id: `apis.${apiRef.id}`,\n attachTo: { id: 'core', input: 'apis' },\n inputs: extensionInputs,\n configSchema,\n output: {\n api: coreExtensionData.apiFactory,\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 * 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 { JsonObject } from '@backstage/types';\nimport { z, ZodSchema, ZodTypeDef } from 'zod';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { PortableSchema } from './types';\n\n/** @public */\nexport function createSchemaFromZod<TOutput, TInput>(\n schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>,\n): PortableSchema<TOutput> {\n const schema = schemaCreator(z);\n return {\n // TODO: Types allow z.array etc here but it will break stuff\n parse: input => {\n const result = schema.safeParse(input);\n if (result.success) {\n return result.data;\n }\n\n throw new Error(result.error.issues.map(formatIssue).join('; '));\n },\n // TODO: Verify why we are not compatible with the latest zodToJsonSchema.\n schema: zodToJsonSchema(schema) as JsonObject,\n };\n}\n\nfunction formatIssue(issue: z.ZodIssue): string {\n if (issue.code === 'invalid_union') {\n return formatIssue(issue.unionErrors[0].issues[0]);\n }\n let message = issue.message;\n if (message === 'Required') {\n message = `Missing required value`;\n }\n if (issue.path.length) {\n message += ` at '${issue.path.join('.')}'`;\n }\n return message;\n}\n","/*\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, { lazy } from 'react';\nimport { ExtensionBoundary } from '../components';\nimport { createSchemaFromZod, PortableSchema } from '../schema';\nimport {\n coreExtensionData,\n createExtension,\n Extension,\n ExtensionInputValues,\n AnyExtensionInputMap,\n} from '../wiring';\nimport { RouteRef } from '../routing';\nimport { Expand } from '../types';\n\n/**\n * Helper for creating extensions for a routable React page component.\n *\n * @public\n */\nexport function createPageExtension<\n TConfig extends { path: string },\n TInputs extends AnyExtensionInputMap,\n>(\n options: (\n | {\n defaultPath: string;\n }\n | {\n configSchema: PortableSchema<TConfig>;\n }\n ) & {\n id: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n routeRef?: RouteRef;\n loader: (options: {\n config: TConfig;\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => Promise<JSX.Element>;\n },\n): Extension<TConfig> {\n const { id } = options;\n\n const configSchema =\n 'configSchema' in options\n ? options.configSchema\n : (createSchemaFromZod(z =>\n z.object({ path: z.string().default(options.defaultPath) }),\n ) as PortableSchema<TConfig>);\n\n return createExtension({\n id,\n attachTo: options.attachTo ?? { id: 'core.routes', input: 'routes' },\n configSchema,\n inputs: options.inputs,\n disabled: options.disabled,\n output: {\n element: coreExtensionData.reactElement,\n path: coreExtensionData.routePath,\n routeRef: coreExtensionData.routeRef.optional(),\n },\n factory({ config, inputs, source }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ config, inputs })\n .then(element => ({ default: () => element })),\n );\n\n return {\n path: config.path,\n routeRef: options.routeRef,\n element: (\n <ExtensionBoundary id={id} source={source} routable>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n };\n },\n });\n}\n","/*\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 { IconComponent } from '@backstage/core-plugin-api';\nimport { createSchemaFromZod } from '../schema/createSchemaFromZod';\nimport { coreExtensionData, createExtension } from '../wiring';\nimport { RouteRef } from '../routing';\n\n/**\n * Helper for creating extensions for a nav item.\n * @public\n */\nexport function createNavItemExtension(options: {\n id: string;\n routeRef: RouteRef<undefined>;\n title: string;\n icon: IconComponent;\n}) {\n const { id, routeRef, title, icon } = options;\n return createExtension({\n id,\n attachTo: { id: 'core.nav', input: 'items' },\n configSchema: createSchemaFromZod(z =>\n z.object({\n title: z.string().default(title),\n }),\n ),\n output: {\n navTarget: coreExtensionData.navTarget,\n },\n factory: ({ config }) => ({\n navTarget: {\n title: config.title,\n icon,\n routeRef,\n },\n }),\n });\n}\n","/*\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 { createExtension, coreExtensionData } from '../wiring';\nimport { AppTheme } from '@backstage/core-plugin-api';\n\n/** @public */\nexport function createThemeExtension(theme: AppTheme) {\n return createExtension({\n id: `themes.${theme.id}`,\n attachTo: { id: 'core', input: 'themes' },\n output: {\n theme: coreExtensionData.theme,\n },\n factory: () => ({ theme }),\n });\n}\n","/*\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\nconst MESSAGE_MARKER = 'eHgtF5hmbrXyiEvo';\n\n/**\n * Internal helper that describes the location of the parent caller.\n * @internal\n */\nexport function describeParentCallSite(\n ErrorConstructor: { new (message: string): Error } = Error,\n): string {\n const { stack } = new ErrorConstructor(MESSAGE_MARKER);\n if (!stack) {\n return '<unknown>';\n }\n\n // Safari and Firefox don't include the error itself in the stack\n const startIndex = stack.includes(MESSAGE_MARKER)\n ? stack.indexOf('\\n') + 1\n : 0;\n const secondEntryStart =\n stack.indexOf('\\n', stack.indexOf('\\n', startIndex) + 1) + 1;\n const secondEntryEnd = stack.indexOf('\\n', secondEntryStart);\n\n const line = stack.substring(secondEntryStart, secondEntryEnd).trim();\n if (!line) {\n return 'unknown';\n }\n\n // Below we try to extract the location for different browsers.\n // Since RouteRefs are declared at the top-level of modules the caller name isn't interesting.\n\n // Chrome\n if (line.includes('(')) {\n return line.substring(line.indexOf('(') + 1, line.indexOf(')'));\n }\n\n // Safari & Firefox\n if (line.includes('@')) {\n return line.substring(line.indexOf('@') + 1);\n }\n\n // Give up\n return line;\n}\n","/*\n * Copyright 2020 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 { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Absolute route reference.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface RouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> {\n readonly $$type: '@backstage/RouteRef';\n readonly T: TParams;\n}\n\n/** @internal */\nexport interface InternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> extends RouteRef<TParams> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n>(resource: RouteRef<TParams>): InternalRouteRef<TParams> {\n const r = resource as InternalRouteRef<TParams>;\n if (r.$$type !== '@backstage/RouteRef') {\n throw new Error(`Invalid RouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isRouteRef(opaque: { $$type: string }): opaque is RouteRef {\n return opaque.$$type === '@backstage/RouteRef';\n}\n\n/** @internal */\nexport class RouteRefImpl implements InternalRouteRef {\n readonly $$type = '@backstage/RouteRef';\n readonly version = 'v1';\n declare readonly T: never;\n\n #id?: string;\n #params: string[];\n #creationSite: string;\n\n constructor(readonly params: string[] = [], creationSite: string) {\n this.#params = params;\n this.#creationSite = creationSite;\n }\n\n getParams(): string[] {\n return this.#params;\n }\n\n getDescription(): string {\n if (this.#id) {\n return this.#id;\n }\n return `created at '${this.#creationSite}'`;\n }\n\n get #name() {\n return this.$$type.slice('@backstage/'.length);\n }\n\n setId(id: string): void {\n if (!id) {\n throw new Error(`${this.#name} id must be a non-empty string`);\n }\n if (this.#id) {\n throw new Error(\n `${this.#name} was referenced twice as both '${this.#id}' and '${id}'`,\n );\n }\n this.#id = id;\n }\n\n toString(): string {\n return `${this.#name}{${this.getDescription()}}`;\n }\n}\n\n/**\n * Create a {@link RouteRef} from a route descriptor.\n *\n * @param config - Description of the route reference to be created.\n * @public\n */\nexport function createRouteRef<\n // Params is the type that we care about and the one to be embedded in the route ref.\n // For example, given the params ['name', 'kind'], Params will be {name: string, kind: string}\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TParamKeys extends string = string,\n>(config?: {\n /** A list of parameter names that the path that this route ref is bound to must contain */\n readonly params: string extends TParamKeys ? (keyof TParams)[] : TParamKeys[];\n}): RouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string }\n> {\n return new RouteRefImpl(\n config?.params as string[] | undefined,\n describeParentCallSite(),\n ) as RouteRef<any>;\n}\n","/*\n * Copyright 2020 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 { RouteRef, toInternalRouteRef } from './RouteRef';\nimport { AnyRouteRefParams } from './types';\n\n// Should match the pattern in react-router\nconst PARAM_PATTERN = /^\\w+$/;\n\n/**\n * Descriptor of a route relative to an absolute {@link RouteRef}.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface SubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> {\n readonly $$type: '@backstage/SubRouteRef';\n\n readonly T: TParams;\n\n readonly path: string;\n}\n\n/** @internal */\nexport interface InternalSubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> extends SubRouteRef<TParams> {\n readonly version: 'v1';\n\n getParams(): string[];\n getParent(): RouteRef;\n getDescription(): string;\n}\n\n/** @internal */\nexport function toInternalSubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n>(resource: SubRouteRef<TParams>): InternalSubRouteRef<TParams> {\n const r = resource as InternalSubRouteRef<TParams>;\n if (r.$$type !== '@backstage/SubRouteRef') {\n throw new Error(`Invalid SubRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isSubRouteRef(opaque: {\n $$type: string;\n}): opaque is SubRouteRef {\n return opaque.$$type === '@backstage/SubRouteRef';\n}\n\n/** @internal */\nexport class SubRouteRefImpl<TParams extends AnyRouteRefParams>\n implements SubRouteRef<TParams>\n{\n readonly $$type = '@backstage/SubRouteRef';\n readonly version = 'v1';\n declare readonly T: never;\n\n #params: string[];\n #parent: RouteRef;\n\n constructor(readonly path: string, params: string[], parent: RouteRef) {\n this.#params = params;\n this.#parent = parent;\n }\n\n getParams(): string[] {\n return this.#params;\n }\n\n getParent(): RouteRef {\n return this.#parent;\n }\n\n getDescription(): string {\n const parent = toInternalRouteRef(this.#parent);\n return `at ${this.path} with parent ${parent.getDescription()}`;\n }\n\n toString(): string {\n return `SubRouteRef{${this.getDescription()}}`;\n }\n}\n\n/**\n * Used in {@link PathParams} type declaration.\n * @ignore\n */\ntype ParamPart<S extends string> = S extends `:${infer Param}` ? Param : never;\n\n/**\n * Used in {@link PathParams} type declaration.\n * @ignore\n */\ntype ParamNames<S extends string> = S extends `${infer Part}/${infer Rest}`\n ? ParamPart<Part> | ParamNames<Rest>\n : ParamPart<S>;\n/**\n * This utility type helps us infer a Param object type from a string path\n * For example, `/foo/:bar/:baz` inferred to `{ bar: string, baz: string }`\n * @ignore\n */\ntype PathParams<S extends string> = { [name in ParamNames<S>]: string };\n\n/**\n * Merges a param object type with an optional params type into a params object.\n * @ignore\n */\ntype MergeParams<\n P1 extends { [param in string]: string },\n P2 extends AnyRouteRefParams,\n> = (P1[keyof P1] extends never ? {} : P1) & (P2 extends undefined ? {} : P2);\n\n/**\n * Convert empty params to undefined.\n * @ignore\n */\ntype TrimEmptyParams<Params extends { [param in string]: string }> =\n keyof Params extends never ? undefined : Params;\n\n/**\n * Creates a SubRouteRef type given the desired parameters and parent route parameters.\n * The parameters types are merged together while ensuring that there is no overlap between the two.\n *\n * @ignore\n */\ntype MakeSubRouteRef<\n Params extends { [param in string]: string },\n ParentParams extends AnyRouteRefParams,\n> = keyof Params & keyof ParentParams extends never\n ? SubRouteRef<TrimEmptyParams<MergeParams<Params, ParentParams>>>\n : never;\n\n/**\n * Create a {@link SubRouteRef} from a route descriptor.\n *\n * @param config - Description of the route reference to be created.\n * @public\n */\nexport function createSubRouteRef<\n Path extends string,\n ParentParams extends AnyRouteRefParams = never,\n>(config: {\n path: Path;\n parent: RouteRef<ParentParams>;\n}): MakeSubRouteRef<PathParams<Path>, ParentParams> {\n const { path, parent } = config;\n type Params = PathParams<Path>;\n\n const internalParent = toInternalRouteRef(parent);\n const parentParams = internalParent.getParams();\n\n // Collect runtime parameters from the path, e.g. ['bar', 'baz'] from '/foo/:bar/:baz'\n const pathParams = path\n .split('/')\n .filter(p => p.startsWith(':'))\n .map(p => p.substring(1));\n const params = [...parentParams, ...pathParams];\n\n if (parentParams.some(p => pathParams.includes(p as string))) {\n throw new Error(\n 'SubRouteRef may not have params that overlap with its parent',\n );\n }\n if (!path.startsWith('/')) {\n throw new Error(`SubRouteRef path must start with '/', got '${path}'`);\n }\n if (path.endsWith('/')) {\n throw new Error(`SubRouteRef path must not end with '/', got '${path}'`);\n }\n for (const param of pathParams) {\n if (!PARAM_PATTERN.test(param)) {\n throw new Error(`SubRouteRef path has invalid param, got '${param}'`);\n }\n }\n\n // We ensure that the type of the return type is sane here\n const subRouteRef = new SubRouteRefImpl(\n path,\n params as string[],\n parent,\n ) as SubRouteRef<TrimEmptyParams<MergeParams<Params, ParentParams>>>;\n\n // But skip type checking of the return value itself, because the conditional\n // type checking of the parent parameter overlap is tricky to express.\n return subRouteRef as any;\n}\n","/*\n * Copyright 2020 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 { RouteRefImpl } from './RouteRef';\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface ExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n> {\n readonly $$type: '@backstage/ExternalRouteRef';\n readonly T: TParams;\n readonly optional: TOptional;\n}\n\n/** @internal */\nexport interface InternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n> extends ExternalRouteRef<TParams, TOptional> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n>(\n resource: ExternalRouteRef<TParams, TOptional>,\n): InternalExternalRouteRef<TParams, TOptional> {\n const r = resource as InternalExternalRouteRef<TParams, TOptional>;\n if (r.$$type !== '@backstage/ExternalRouteRef') {\n throw new Error(`Invalid ExternalRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isExternalRouteRef(opaque: {\n $$type: string;\n}): opaque is ExternalRouteRef {\n return opaque.$$type === '@backstage/ExternalRouteRef';\n}\n\n/** @internal */\nclass ExternalRouteRefImpl\n extends RouteRefImpl\n implements InternalExternalRouteRef\n{\n readonly $$type = '@backstage/ExternalRouteRef' as any;\n\n constructor(\n readonly optional: boolean,\n readonly params: string[] = [],\n creationSite: string,\n ) {\n super(params, creationSite);\n }\n}\n\n/**\n * Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @param options - Description of the route reference to be created.\n * @public\n */\nexport function createExternalRouteRef<\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TOptional extends boolean = false,\n TParamKeys extends string = string,\n>(options?: {\n /**\n * The parameters that will be provided to the external route reference.\n */\n readonly params?: string extends TParamKeys\n ? (keyof TParams)[]\n : TParamKeys[];\n\n /**\n * Whether or not this route is optional, defaults to false.\n *\n * Optional external routes are not required to be bound in the app, and\n * if they aren't, `useExternalRouteRef` will return `undefined`.\n */\n optional?: TOptional;\n}): ExternalRouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string },\n TOptional\n> {\n return new ExternalRouteRefImpl(\n Boolean(options?.optional),\n options?.params as string[] | undefined,\n describeParentCallSite(),\n ) as ExternalRouteRef<any, any>;\n}\n","/*\n * Copyright 2020 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 { useMemo } from 'react';\nimport { matchRoutes, useLocation } from 'react-router-dom';\nimport { useVersionedContext } from '@backstage/version-bridge';\nimport { AnyRouteRefParams } from './types';\nimport { RouteRef } from './RouteRef';\nimport { SubRouteRef } from './SubRouteRef';\nimport { ExternalRouteRef } from './ExternalRouteRef';\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 * @internal\n */\nexport interface RouteResolver {\n resolve<TParams extends AnyRouteRefParams>(\n anyRouteRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams, any>,\n sourceLocation: Parameters<typeof matchRoutes>[1],\n ): RouteFunc<TParams> | undefined;\n}\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<\n TOptional extends boolean,\n TParams extends AnyRouteRefParams,\n>(\n routeRef: ExternalRouteRef<TParams, TOptional>,\n): TParams extends true ? RouteFunc<TParams> | undefined : RouteFunc<TParams>;\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<TParams extends AnyRouteRefParams>(\n routeRef: RouteRef<TParams> | SubRouteRef<TParams>,\n): RouteFunc<TParams>;\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<TParams extends AnyRouteRefParams>(\n routeRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams, any>,\n): RouteFunc<TParams> | undefined {\n const { pathname } = useLocation();\n const versionedContext = useVersionedContext<{ 1: RouteResolver }>(\n 'routing-context',\n );\n if (!versionedContext) {\n throw new Error('Routing context is not available');\n }\n\n const resolver = versionedContext.atVersion(1);\n const routeFunc = useMemo(\n () => resolver && resolver.resolve(routeRef, { pathname }),\n [resolver, routeRef, pathname],\n );\n\n if (!versionedContext) {\n throw new Error('useRouteRef used outside of routing context');\n }\n if (!resolver) {\n throw new Error('RoutingContext v1 not available');\n }\n\n const isOptional = 'optional' in routeRef && routeRef.optional;\n if (!routeFunc && !isOptional) {\n throw new Error(`No path for ${routeRef}`);\n }\n\n return routeFunc;\n}\n","/*\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 { useParams } from 'react-router-dom';\nimport { AnyRouteRefParams } from './types';\nimport { RouteRef } from './RouteRef';\nimport { SubRouteRef } from './SubRouteRef';\n\n/**\n * React hook for retrieving dynamic params from the current URL.\n * @param _routeRef - Ref of the current route.\n * @public\n */\nexport function useRouteRefParams<Params extends AnyRouteRefParams>(\n _routeRef: RouteRef<Params> | SubRouteRef<Params>,\n): Params {\n return useParams() as Params;\n}\n"],"names":["__publicField","_params","__privateAdd","__privateSet","__privateGet"],"mappings":";;;;;;;;;;AAiHO,MAAM,aAAgB,GAAA,YAAA,CAAyB,EAAE,EAAA,EAAI,iBAAiB;;;;;;;;ACrF7E,MAAM,+BAA+B,CAAC;AAAA,EACpC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AACF,CAAyC,KAAA;AACvC,EAAM,MAAA,KAAA,GAAQ,CAAY,SAAA,EAAA,MAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAQ,EAAE,CAAA,CAAA,CAAA;AAEpC,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,KAAc,EAAA,KAAA,EAAc,eAAe,EAAA,IAAA,EAAA,kBACpD,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAO,OAAQ,EAAA,UAAA,EAAW,OAAS,EAAA,UAAA,EAAA,EAAY,OAEhD,CACF,CAAA,CAAA;AAEJ,CAAA,CAAA;AAMO,MAAM,sBAAsB,SAGjC,CAAA;AAAA,EAHK,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA,CAAA;AAQL,IAA4BA,eAAA,CAAA,IAAA,EAAA,OAAA,EAAA,EAAE,OAAO,KAAU,CAAA,EAAA,CAAA,CAAA;AAE/C,IAAAA,eAAA,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,QAAS,EAAA,GAAI,IAAK,CAAA,KAAA,CAAA;AAElC,IAAA,IAAI,KAAO,EAAA;AAET,MACE,uBAAA,KAAA,CAAA,aAAA;AAAA,QAAC,4BAAA;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;;ACtDO,SAAS,kBAAkB,KAA+B,EAAA;AAC/D,EAAM,MAAA,EAAE,UAAa,GAAA,KAAA,CAAA;AAErB,EAAA,MAAM,MAAM,MAAO,EAAA,CAAA;AACnB,EAAA,MAAM,EAAE,QAAA,EAAa,GAAA,GAAA,CAAI,aAAc,EAAA,CAAA;AAEvC,EAAA,2CAAQ,QAAS,EAAA,EAAA,QAAA,kBAAW,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,IAAS,KAAK,QAAS,CAAA,CAAA;AACrD;;ACoBqB,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,8BAAA;;ACpC9C,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;AAWO,SAAS,kBAAkB,KAA+B,EAAA;AAC/D,EAAA,MAAM,EAAE,EAAA,EAAI,MAAQ,EAAA,QAAA,EAAU,UAAa,GAAA,KAAA,CAAA;AAG3C,EAAA,MAAM,UAAa,GAAA;AAAA,IACjB,SAAW,EAAA,EAAA;AAAA,IACX,UAAU,MAAQ,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAA,EAAA;AAAA,GACpB,CAAA;AAEA,EAAA,2CACG,iBACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,EAAA,MAAA,EAAQ,0BACpB,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA,EAAiB,UAChB,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,gBAAa,eAAiB,EAAA,CAAC,YAAW,QAAS,CACtD,CACF,CACF,CAAA,CAAA;AAEJ;;AClCO,SAAS,uBACd,EACqC,EAAA;AACrC,EAAO,OAAA;AAAA,IACL,EAAA;AAAA,IACA,MAAQ,EAAA,6BAAA;AAAA,IACR,QAAQ,EAAC;AAAA,IACT,QAAW,GAAA;AACT,MAAO,OAAA,EAAE,GAAG,IAAA,EAAM,MAAQ,EAAA,EAAE,GAAG,IAAK,CAAA,MAAA,EAAQ,QAAU,EAAA,IAAA,EAAO,EAAA,CAAA;AAAA,KAC/D;AAAA,GACF,CAAA;AACF;;ACfO,MAAM,iBAAoB,GAAA;AAAA,EAC/B,YAAA,EAAc,uBAAoC,mBAAmB,CAAA;AAAA,EACrE,SAAA,EAAW,uBAA+B,mBAAmB,CAAA;AAAA,EAC7D,UAAA,EAAY,uBAAsC,kBAAkB,CAAA;AAAA,EACpE,QAAA,EAAU,uBAAiC,kBAAkB,CAAA;AAAA,EAC7D,SAAA,EAAW,uBAAkC,iBAAiB,CAAA;AAAA,EAC9D,KAAA,EAAO,uBAAiC,YAAY,CAAA;AACtD;;ACoEO,SAAS,gBAKd,OACoB,EAAA;AAlHtB,EAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAmHE,EAAO,OAAA;AAAA,IACL,GAAG,OAAA;AAAA,IACH,QAAA,EAAA,CAAU,EAAQ,GAAA,OAAA,CAAA,QAAA,KAAR,IAAoB,GAAA,EAAA,GAAA,KAAA;AAAA,IAC9B,MAAQ,EAAA,sBAAA;AAAA,IACR,MAAQ,EAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,MAAR,KAAA,IAAA,GAAA,EAAA,GAAkB,EAAC;AAAA,IAC3B,OAAQ,CAAA,EAAE,MAAQ,EAAA,GAAG,MAAQ,EAAA;AAE3B,MAAA,OAAO,QAAQ,OAAQ,CAAA;AAAA,QACrB,MAAA;AAAA,QACA,GAAG,IAAA;AAAA,OACJ,CAAA,CAAA;AAAA,KACH;AAAA,GACF,CAAA;AACF;;ACnGgB,SAAA,oBAAA,CAId,eACA,MAOA,EAAA;AACA,EAAO,OAAA;AAAA,IACL,MAAQ,EAAA,2BAAA;AAAA,IACR,aAAA;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,SAAA,EAAW,OAAQ,CAAA,MAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAQ,SAAS,CAAA;AAAA,MAGpC,QAAA,EAAU,OAAQ,CAAA,MAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAQ,QAAQ,CAAA;AAAA,KAGpC;AAAA,GACF,CAAA;AACF;;ACLO,SAAS,aAId,OACyC,EAAA;AAtD3C,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA;AAuDE,EAAO,OAAA;AAAA,IACL,GAAG,OAAA;AAAA,IACH,MAAQ,EAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,MAAR,KAAA,IAAA,GAAA,EAAA,GAAmB,EAAC;AAAA,IAC5B,cAAgB,EAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,cAAR,KAAA,IAAA,GAAA,EAAA,GAA2B,EAAC;AAAA,IAC5C,UAAY,EAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,UAAR,KAAA,IAAA,GAAA,EAAA,GAAsB,EAAC;AAAA,IACnC,MAAQ,EAAA,4BAAA;AAAA,GACV,CAAA;AACF;;AC3BO,SAAS,yBACd,OACoB,EAAA;AACpB,EAAO,OAAA;AAAA,IACL,MAAQ,EAAA,+BAAA;AAAA,IACR,OAAS,EAAA,IAAA;AAAA,IACT,YAAY,OAAQ,CAAA,UAAA;AAAA,GACtB,CAAA;AACF;;AChBO,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,EAAA,EAAI,CAAQ,KAAA,EAAA,MAAA,CAAO,EAAE,CAAA,CAAA;AAAA,IACrB,QAAU,EAAA,EAAE,EAAI,EAAA,MAAA,EAAQ,OAAO,MAAO,EAAA;AAAA,IACtC,MAAQ,EAAA,eAAA;AAAA,IACR,YAAA;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,KAAK,iBAAkB,CAAA,UAAA;AAAA,KACzB;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;;AC7CO,SAAS,oBACd,aACyB,EAAA;AACzB,EAAM,MAAA,MAAA,GAAS,cAAc,CAAC,CAAA,CAAA;AAC9B,EAAO,OAAA;AAAA;AAAA,IAEL,OAAO,CAAS,KAAA,KAAA;AACd,MAAM,MAAA,MAAA,GAAS,MAAO,CAAA,SAAA,CAAU,KAAK,CAAA,CAAA;AACrC,MAAA,IAAI,OAAO,OAAS,EAAA;AAClB,QAAA,OAAO,MAAO,CAAA,IAAA,CAAA;AAAA,OAChB;AAEA,MAAM,MAAA,IAAI,KAAM,CAAA,MAAA,CAAO,KAAM,CAAA,MAAA,CAAO,IAAI,WAAW,CAAA,CAAE,IAAK,CAAA,IAAI,CAAC,CAAA,CAAA;AAAA,KACjE;AAAA;AAAA,IAEA,MAAA,EAAQ,gBAAgB,MAAM,CAAA;AAAA,GAChC,CAAA;AACF,CAAA;AAEA,SAAS,YAAY,KAA2B,EAAA;AAC9C,EAAI,IAAA,KAAA,CAAM,SAAS,eAAiB,EAAA;AAClC,IAAA,OAAO,YAAY,KAAM,CAAA,WAAA,CAAY,CAAC,CAAE,CAAA,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA;AAAA,GACnD;AACA,EAAA,IAAI,UAAU,KAAM,CAAA,OAAA,CAAA;AACpB,EAAA,IAAI,YAAY,UAAY,EAAA;AAC1B,IAAU,OAAA,GAAA,CAAA,sBAAA,CAAA,CAAA;AAAA,GACZ;AACA,EAAI,IAAA,KAAA,CAAM,KAAK,MAAQ,EAAA;AACrB,IAAA,OAAA,IAAW,CAAQ,KAAA,EAAA,KAAA,CAAM,IAAK,CAAA,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA,CAAA;AAAA,GACzC;AACA,EAAO,OAAA,OAAA,CAAA;AACT;;ACnBO,SAAS,oBAId,OAkBoB,EAAA;AAxDtB,EAAA,IAAA,EAAA,CAAA;AAyDE,EAAM,MAAA,EAAE,IAAO,GAAA,OAAA,CAAA;AAEf,EAAA,MAAM,YACJ,GAAA,cAAA,IAAkB,OACd,GAAA,OAAA,CAAQ,YACP,GAAA,mBAAA;AAAA,IAAoB,CACnB,CAAA,KAAA,CAAA,CAAE,MAAO,CAAA,EAAE,IAAM,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,CAAA,OAAA,CAAQ,WAAW,CAAA,EAAG,CAAA;AAAA,GAC5D,CAAA;AAEN,EAAA,OAAO,eAAgB,CAAA;AAAA,IACrB,EAAA;AAAA,IACA,QAAA,EAAA,CAAU,aAAQ,QAAR,KAAA,IAAA,GAAA,EAAA,GAAoB,EAAE,EAAI,EAAA,aAAA,EAAe,OAAO,QAAS,EAAA;AAAA,IACnE,YAAA;AAAA,IACA,QAAQ,OAAQ,CAAA,MAAA;AAAA,IAChB,UAAU,OAAQ,CAAA,QAAA;AAAA,IAClB,MAAQ,EAAA;AAAA,MACN,SAAS,iBAAkB,CAAA,YAAA;AAAA,MAC3B,MAAM,iBAAkB,CAAA,SAAA;AAAA,MACxB,QAAA,EAAU,iBAAkB,CAAA,QAAA,CAAS,QAAS,EAAA;AAAA,KAChD;AAAA,IACA,OAAQ,CAAA,EAAE,MAAQ,EAAA,MAAA,EAAQ,QAAU,EAAA;AAClC,MAAA,MAAM,kBAAqB,GAAA,IAAA;AAAA,QAAK,MAC9B,OAAA,CACG,MAAO,CAAA,EAAE,QAAQ,MAAO,EAAC,CACzB,CAAA,IAAA,CAAK,CAAY,OAAA,MAAA,EAAE,OAAS,EAAA,MAAM,SAAU,CAAA,CAAA;AAAA,OACjD,CAAA;AAEA,MAAO,OAAA;AAAA,QACL,MAAM,MAAO,CAAA,IAAA;AAAA,QACb,UAAU,OAAQ,CAAA,QAAA;AAAA,QAClB,OAAA,sCACG,iBAAkB,EAAA,EAAA,EAAA,EAAQ,QAAgB,QAAQ,EAAA,IAAA,EAAA,kBAChD,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA,IAAmB,CACtB,CAAA;AAAA,OAEJ,CAAA;AAAA,KACF;AAAA,GACD,CAAA,CAAA;AACH;;ACtEO,SAAS,uBAAuB,OAKpC,EAAA;AACD,EAAA,MAAM,EAAE,EAAA,EAAI,QAAU,EAAA,KAAA,EAAO,MAAS,GAAA,OAAA,CAAA;AACtC,EAAA,OAAO,eAAgB,CAAA;AAAA,IACrB,EAAA;AAAA,IACA,QAAU,EAAA,EAAE,EAAI,EAAA,UAAA,EAAY,OAAO,OAAQ,EAAA;AAAA,IAC3C,YAAc,EAAA,mBAAA;AAAA,MAAoB,CAAA,CAAA,KAChC,EAAE,MAAO,CAAA;AAAA,QACP,KAAO,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAQ,KAAK,CAAA;AAAA,OAChC,CAAA;AAAA,KACH;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,WAAW,iBAAkB,CAAA,SAAA;AAAA,KAC/B;AAAA,IACA,OAAS,EAAA,CAAC,EAAE,MAAA,EAAc,MAAA;AAAA,MACxB,SAAW,EAAA;AAAA,QACT,OAAO,MAAO,CAAA,KAAA;AAAA,QACd,IAAA;AAAA,QACA,QAAA;AAAA,OACF;AAAA,KACF,CAAA;AAAA,GACD,CAAA,CAAA;AACH;;AC/BO,SAAS,qBAAqB,KAAiB,EAAA;AACpD,EAAA,OAAO,eAAgB,CAAA;AAAA,IACrB,EAAA,EAAI,CAAU,OAAA,EAAA,KAAA,CAAM,EAAE,CAAA,CAAA;AAAA,IACtB,QAAU,EAAA,EAAE,EAAI,EAAA,MAAA,EAAQ,OAAO,QAAS,EAAA;AAAA,IACxC,MAAQ,EAAA;AAAA,MACN,OAAO,iBAAkB,CAAA,KAAA;AAAA,KAC3B;AAAA,IACA,OAAA,EAAS,OAAO,EAAE,KAAM,EAAA,CAAA;AAAA,GACzB,CAAA,CAAA;AACH;;ACbA,MAAM,cAAiB,GAAA,kBAAA,CAAA;AAMP,SAAA,sBAAA,CACd,mBAAqD,KAC7C,EAAA;AACR,EAAA,MAAM,EAAE,KAAA,EAAU,GAAA,IAAI,iBAAiB,cAAc,CAAA,CAAA;AACrD,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAO,OAAA,WAAA,CAAA;AAAA,GACT;AAGA,EAAM,MAAA,UAAA,GAAa,MAAM,QAAS,CAAA,cAAc,IAC5C,KAAM,CAAA,OAAA,CAAQ,IAAI,CAAA,GAAI,CACtB,GAAA,CAAA,CAAA;AACJ,EAAM,MAAA,gBAAA,GACJ,KAAM,CAAA,OAAA,CAAQ,IAAM,EAAA,KAAA,CAAM,QAAQ,IAAM,EAAA,UAAU,CAAI,GAAA,CAAC,CAAI,GAAA,CAAA,CAAA;AAC7D,EAAA,MAAM,cAAiB,GAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,EAAM,gBAAgB,CAAA,CAAA;AAE3D,EAAA,MAAM,OAAO,KAAM,CAAA,SAAA,CAAU,gBAAkB,EAAA,cAAc,EAAE,IAAK,EAAA,CAAA;AACpE,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAO,OAAA,SAAA,CAAA;AAAA,GACT;AAMA,EAAI,IAAA,IAAA,CAAK,QAAS,CAAA,GAAG,CAAG,EAAA;AACtB,IAAO,OAAA,IAAA,CAAK,SAAU,CAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAG,EAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,CAAC,CAAA,CAAA;AAAA,GAChE;AAGA,EAAI,IAAA,IAAA,CAAK,QAAS,CAAA,GAAG,CAAG,EAAA;AACtB,IAAA,OAAO,KAAK,SAAU,CAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAC,CAAA,CAAA;AAAA,GAC7C;AAGA,EAAO,OAAA,IAAA,CAAA;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;AC1DA,IAAA,GAAA,EAAAC,SAAA,EAAA,aAAA,EAAA,KAAA,EAAA,QAAA,CAAA;AA+CO,SAAS,mBAEd,QAAwD,EAAA;AACxD,EAAA,MAAM,CAAI,GAAA,QAAA,CAAA;AACV,EAAI,IAAA,CAAA,CAAE,WAAW,qBAAuB,EAAA;AACtC,IAAA,MAAM,IAAI,KAAA,CAAM,CAA+B,4BAAA,EAAA,CAAA,CAAE,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,GAC5D;AAEA,EAAO,OAAA,CAAA,CAAA;AACT,CAAA;AAQO,MAAM,YAAyC,CAAA;AAAA,EASpD,WAAqB,CAAA,MAAA,GAAmB,EAAC,EAAG,YAAsB,EAAA;AAA7C,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AAgBrB,IAAIC,cAAA,CAAA,IAAA,EAAA,KAAA,CAAA,CAAA;AAxBJ,IAAAF,eAAA,CAAA,IAAA,EAAS,QAAS,EAAA,qBAAA,CAAA,CAAA;AAClB,IAAAA,eAAA,CAAA,IAAA,EAAS,SAAU,EAAA,IAAA,CAAA,CAAA;AAGnB,IAAAE,cAAA,CAAA,IAAA,EAAA,GAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AACA,IAAAA,cAAA,CAAA,IAAA,EAAAD,SAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AACA,IAAAC,cAAA,CAAA,IAAA,EAAA,aAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAGE,IAAAC,cAAA,CAAA,IAAA,EAAKF,SAAU,EAAA,MAAA,CAAA,CAAA;AACf,IAAAE,cAAA,CAAA,IAAA,EAAK,aAAgB,EAAA,YAAA,CAAA,CAAA;AAAA,GACvB;AAAA,EAEA,SAAsB,GAAA;AACpB,IAAA,OAAOC,cAAK,CAAA,IAAA,EAAAH,SAAA,CAAA,CAAA;AAAA,GACd;AAAA,EAEA,cAAyB,GAAA;AACvB,IAAA,IAAIG,qBAAK,GAAK,CAAA,EAAA;AACZ,MAAA,OAAOA,cAAK,CAAA,IAAA,EAAA,GAAA,CAAA,CAAA;AAAA,KACd;AACA,IAAO,OAAA,CAAA,YAAA,EAAeA,qBAAK,aAAa,CAAA,CAAA,CAAA,CAAA,CAAA;AAAA,GAC1C;AAAA,EAMA,MAAM,EAAkB,EAAA;AACtB,IAAA,IAAI,CAAC,EAAI,EAAA;AACP,MAAA,MAAM,IAAI,KAAA,CAAM,CAAG,EAAAA,cAAA,CAAA,IAAA,EAAK,gBAAK,CAAgC,8BAAA,CAAA,CAAA,CAAA;AAAA,KAC/D;AACA,IAAA,IAAIA,qBAAK,GAAK,CAAA,EAAA;AACZ,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,GAAGA,cAAK,CAAA,IAAA,EAAA,KAAA,EAAA,QAAA,CAAK,kCAAkCA,cAAK,CAAA,IAAA,EAAA,GAAA,CAAG,UAAU,EAAE,CAAA,CAAA,CAAA;AAAA,OACrE,CAAA;AAAA,KACF;AACA,IAAAD,cAAA,CAAA,IAAA,EAAK,GAAM,EAAA,EAAA,CAAA,CAAA;AAAA,GACb;AAAA,EAEA,QAAmB,GAAA;AACjB,IAAA,OAAO,GAAGC,cAAK,CAAA,IAAA,EAAA,KAAA,EAAA,QAAA,CAAK,CAAI,CAAA,EAAA,IAAA,CAAK,gBAAgB,CAAA,CAAA,CAAA,CAAA;AAAA,GAC/C;AACF,CAAA;AAvCE,GAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACAH,SAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACA,aAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAkBI,KAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAAA,QAAA,GAAK,WAAG;AACV,EAAA,OAAO,IAAK,CAAA,MAAA,CAAO,KAAM,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AAC/C,CAAA,CAAA;AAyBK,SAAS,eAKd,MASA,EAAA;AACA,EAAA,OAAO,IAAI,YAAA;AAAA,IACT,MAAQ,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAA,MAAA;AAAA,IACR,sBAAuB,EAAA;AAAA,GACzB,CAAA;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;ACvIA,IAAA,OAAA,EAAA,OAAA,CAAA;AAoBA,MAAM,aAAgB,GAAA,OAAA,CAAA;AAoDf,MAAM,eAEb,CAAA;AAAA,EAQE,WAAA,CAAqB,IAAc,EAAA,MAAA,EAAkB,MAAkB,EAAA;AAAlD,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA,CAAA;AAPrB,IAAAD,eAAA,CAAA,IAAA,EAAS,QAAS,EAAA,wBAAA,CAAA,CAAA;AAClB,IAAAA,eAAA,CAAA,IAAA,EAAS,SAAU,EAAA,IAAA,CAAA,CAAA;AAGnB,IAAA,YAAA,CAAA,IAAA,EAAA,OAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AACA,IAAA,YAAA,CAAA,IAAA,EAAA,OAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAGE,IAAA,YAAA,CAAA,IAAA,EAAK,OAAU,EAAA,MAAA,CAAA,CAAA;AACf,IAAA,YAAA,CAAA,IAAA,EAAK,OAAU,EAAA,MAAA,CAAA,CAAA;AAAA,GACjB;AAAA,EAEA,SAAsB,GAAA;AACpB,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,OAAA,CAAA,CAAA;AAAA,GACd;AAAA,EAEA,SAAsB,GAAA;AACpB,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,OAAA,CAAA,CAAA;AAAA,GACd;AAAA,EAEA,cAAyB,GAAA;AACvB,IAAM,MAAA,MAAA,GAAS,kBAAmB,CAAA,YAAA,CAAA,IAAA,EAAK,OAAO,CAAA,CAAA,CAAA;AAC9C,IAAA,OAAO,MAAM,IAAK,CAAA,IAAI,CAAgB,aAAA,EAAA,MAAA,CAAO,gBAAgB,CAAA,CAAA,CAAA;AAAA,GAC/D;AAAA,EAEA,QAAmB,GAAA;AACjB,IAAO,OAAA,CAAA,YAAA,EAAe,IAAK,CAAA,cAAA,EAAgB,CAAA,CAAA,CAAA,CAAA;AAAA,GAC7C;AACF,CAAA;AAxBE,OAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACA,OAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAgFK,SAAS,kBAGd,MAGkD,EAAA;AAClD,EAAM,MAAA,EAAE,IAAM,EAAA,MAAA,EAAW,GAAA,MAAA,CAAA;AAGzB,EAAM,MAAA,cAAA,GAAiB,mBAAmB,MAAM,CAAA,CAAA;AAChD,EAAM,MAAA,YAAA,GAAe,eAAe,SAAU,EAAA,CAAA;AAG9C,EAAA,MAAM,aAAa,IAChB,CAAA,KAAA,CAAM,GAAG,CAAA,CACT,OAAO,CAAK,CAAA,KAAA,CAAA,CAAE,UAAW,CAAA,GAAG,CAAC,CAC7B,CAAA,GAAA,CAAI,OAAK,CAAE,CAAA,SAAA,CAAU,CAAC,CAAC,CAAA,CAAA;AAC1B,EAAA,MAAM,MAAS,GAAA,CAAC,GAAG,YAAA,EAAc,GAAG,UAAU,CAAA,CAAA;AAE9C,EAAA,IAAI,aAAa,IAAK,CAAA,CAAA,CAAA,KAAK,WAAW,QAAS,CAAA,CAAW,CAAC,CAAG,EAAA;AAC5D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,8DAAA;AAAA,KACF,CAAA;AAAA,GACF;AACA,EAAA,IAAI,CAAC,IAAA,CAAK,UAAW,CAAA,GAAG,CAAG,EAAA;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAA8C,2CAAA,EAAA,IAAI,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,GACvE;AACA,EAAI,IAAA,IAAA,CAAK,QAAS,CAAA,GAAG,CAAG,EAAA;AACtB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAgD,6CAAA,EAAA,IAAI,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,GACzE;AACA,EAAA,KAAA,MAAW,SAAS,UAAY,EAAA;AAC9B,IAAA,IAAI,CAAC,aAAA,CAAc,IAAK,CAAA,KAAK,CAAG,EAAA;AAC9B,MAAA,MAAM,IAAI,KAAA,CAAM,CAA4C,yCAAA,EAAA,KAAK,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,KACtE;AAAA,GACF;AAGA,EAAA,MAAM,cAAc,IAAI,eAAA;AAAA,IACtB,IAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,GACF,CAAA;AAIA,EAAO,OAAA,WAAA,CAAA;AACT;;;;;;;;ACtIA,MAAM,6BACI,YAEV,CAAA;AAAA,EAGE,WACW,CAAA,QAAA,EACA,MAAmB,GAAA,IAC5B,YACA,EAAA;AACA,IAAA,KAAA,CAAM,QAAQ,YAAY,CAAA,CAAA;AAJjB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA,CAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AAJX,IAAA,aAAA,CAAA,IAAA,EAAS,QAAS,EAAA,6BAAA,CAAA,CAAA;AAAA,GAQlB;AACF,CAAA;AAYO,SAAS,uBAId,OAsBA,EAAA;AACA,EAAA,OAAO,IAAI,oBAAA;AAAA,IACT,OAAA,CAAQ,mCAAS,QAAQ,CAAA;AAAA,IACzB,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,MAAA;AAAA,IACT,sBAAuB,EAAA;AAAA,GACzB,CAAA;AACF;;AC9BO,SAAS,YACd,QAIgC,EAAA;AAChC,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,WAAY,EAAA,CAAA;AACjC,EAAA,MAAM,gBAAmB,GAAA,mBAAA;AAAA,IACvB,iBAAA;AAAA,GACF,CAAA;AACA,EAAA,IAAI,CAAC,gBAAkB,EAAA;AACrB,IAAM,MAAA,IAAI,MAAM,kCAAkC,CAAA,CAAA;AAAA,GACpD;AAEA,EAAM,MAAA,QAAA,GAAW,gBAAiB,CAAA,SAAA,CAAU,CAAC,CAAA,CAAA;AAC7C,EAAA,MAAM,SAAY,GAAA,OAAA;AAAA,IAChB,MAAM,QAAY,IAAA,QAAA,CAAS,QAAQ,QAAU,EAAA,EAAE,UAAU,CAAA;AAAA,IACzD,CAAC,QAAU,EAAA,QAAA,EAAU,QAAQ,CAAA;AAAA,GAC/B,CAAA;AAEA,EAAA,IAAI,CAAC,gBAAkB,EAAA;AACrB,IAAM,MAAA,IAAI,MAAM,6CAA6C,CAAA,CAAA;AAAA,GAC/D;AACA,EAAA,IAAI,CAAC,QAAU,EAAA;AACb,IAAM,MAAA,IAAI,MAAM,iCAAiC,CAAA,CAAA;AAAA,GACnD;AAEA,EAAM,MAAA,UAAA,GAAa,UAAc,IAAA,QAAA,IAAY,QAAS,CAAA,QAAA,CAAA;AACtD,EAAI,IAAA,CAAC,SAAa,IAAA,CAAC,UAAY,EAAA;AAC7B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAe,YAAA,EAAA,QAAQ,CAAE,CAAA,CAAA,CAAA;AAAA,GAC3C;AAEA,EAAO,OAAA,SAAA,CAAA;AACT;;AC3GO,SAAS,kBACd,SACQ,EAAA;AACR,EAAA,OAAO,SAAU,EAAA,CAAA;AACnB;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/analytics/AnalyticsContext.tsx","../src/apis/definitions/AppTreeApi.ts","../src/apis/definitions/ComponentsApi.ts","../src/apis/definitions/AnalyticsApi.ts","../src/analytics/Tracker.ts","../src/analytics/useAnalytics.tsx","../src/components/ComponentRef.tsx","../src/components/ErrorBoundary.tsx","../../core-plugin-api/src/analytics/Tracker.ts","../src/components/ExtensionBoundary.tsx","../src/wiring/createExtensionDataRef.ts","../src/wiring/coreExtensionData.ts","../src/wiring/createExtension.ts","../src/wiring/createExtensionInput.ts","../src/wiring/createPlugin.ts","../src/wiring/createExtensionOverrides.ts","../src/extensions/createApiExtension.ts","../src/schema/createSchemaFromZod.ts","../src/extensions/createPageExtension.tsx","../src/extensions/createNavItemExtension.tsx","../src/extensions/createSignInPageExtension.tsx","../src/extensions/createThemeExtension.ts","../src/extensions/createComponentExtension.tsx","../src/routing/describeParentCallSite.ts","../src/routing/RouteRef.ts","../src/routing/SubRouteRef.ts","../src/routing/ExternalRouteRef.ts","../src/routing/useRouteRef.tsx","../src/routing/useRouteRefParams.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 {\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: 'root',\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","/*\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","/*\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 { 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>(ref: ComponentRef<T>): 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 * 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","/*\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","/*\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 {\n return { captureEvent: () => {} };\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","/*\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 CoreBootErrorPageComponent,\n CoreErrorBoundaryFallbackComponent,\n CoreNotFoundErrorPageComponent,\n CoreProgressComponent,\n} from '../types';\n\n/** @public */\nexport type ComponentRef<T> = {\n id: string;\n T: T;\n};\n\n/** @public */\nexport function createComponentRef<T>(options: {\n id: string;\n}): ComponentRef<T> {\n const { id } = options;\n return {\n id,\n get T(): T {\n throw new Error(`tried to read ComponentRef.T of ${id}`);\n },\n };\n}\n\nconst coreProgressComponentRef = createComponentRef<CoreProgressComponent>({\n id: 'core.components.progress',\n});\n\nconst coreBootErrorPageComponentRef =\n createComponentRef<CoreBootErrorPageComponent>({\n id: 'core.components.bootErrorPage',\n });\n\nconst coreNotFoundErrorPageComponentRef =\n createComponentRef<CoreNotFoundErrorPageComponent>({\n id: 'core.components.notFoundErrorPage',\n });\n\nconst coreErrorBoundaryFallbackComponentRef =\n createComponentRef<CoreErrorBoundaryFallbackComponent>({\n id: 'core.components.errorBoundaryFallback',\n });\n\n/** @public */\nexport const coreComponentsRefs = {\n progress: coreProgressComponentRef,\n bootErrorPage: coreBootErrorPageComponentRef,\n notFoundErrorPage: coreNotFoundErrorPageComponentRef,\n errorBoundaryFallback: coreErrorBoundaryFallbackComponentRef,\n};\n","/*\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, PropsWithChildren } from 'react';\n// TODO: Dependency on MUI should be removed from core packages\nimport { Button } from '@material-ui/core';\nimport { ErrorPanel } from '@backstage/core-components';\nimport { BackstagePlugin } from '../wiring';\n\ntype DefaultErrorBoundaryFallbackProps = PropsWithChildren<{\n plugin?: BackstagePlugin;\n error: Error;\n resetError: () => void;\n}>;\n\nconst DefaultErrorBoundaryFallback = ({\n plugin,\n error,\n resetError,\n}: DefaultErrorBoundaryFallbackProps) => {\n const title = `Error in ${plugin?.id}`;\n\n return (\n <ErrorPanel title={title} error={error} defaultExpanded>\n <Button variant=\"outlined\" onClick={resetError}>\n Retry\n </Button>\n </ErrorPanel>\n );\n};\n\ntype ErrorBoundaryProps = PropsWithChildren<{ plugin?: BackstagePlugin }>;\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 } = this.props;\n\n if (error) {\n // TODO: use a configurable error boundary fallback\n return (\n <DefaultErrorBoundaryFallback\n plugin={plugin}\n error={error}\n resetError={this.handleErrorReset}\n />\n );\n }\n\n return children;\n }\n}\n","/*\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","/*\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 } from '../apis';\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 // Skipping \"routeRef\" attribute in the new system, the extension \"id\" should provide more insight\n const attributes = {\n extension: node.spec.id,\n pluginId: node.spec.source?.id,\n };\n\n return (\n <Suspense fallback=\"Loading...\">\n <ErrorBoundary plugin={node.spec.source}>\n <AnalyticsContext attributes={attributes}>\n <RouteTracker disableTracking={!routable}>{children}</RouteTracker>\n </AnalyticsContext>\n </ErrorBoundary>\n </Suspense>\n );\n}\n","/*\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 ExtensionDataRef<\n TData,\n TConfig extends { optional?: true } = {},\n> = {\n id: string;\n T: TData;\n config: TConfig;\n $$type: '@backstage/ExtensionDataRef';\n};\n\n/** @public */\nexport interface ConfigurableExtensionDataRef<\n TData,\n TConfig extends { optional?: true } = {},\n> extends ExtensionDataRef<TData, TConfig> {\n optional(): ConfigurableExtensionDataRef<TData, TData & { optional: true }>;\n}\n\n// TODO: change to options object with ID.\n/** @public */\nexport function createExtensionDataRef<TData>(\n id: string,\n): ConfigurableExtensionDataRef<TData> {\n return {\n id,\n $$type: '@backstage/ExtensionDataRef',\n config: {},\n optional() {\n return { ...this, config: { ...this.config, optional: true } };\n },\n } as ConfigurableExtensionDataRef<TData>;\n}\n","/*\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, JSX } from 'react';\nimport {\n AnyApiFactory,\n AppTheme,\n IconComponent,\n} from '@backstage/core-plugin-api';\nimport { RouteRef } from '../routing';\nimport { ComponentRef } from '../components';\nimport { createExtensionDataRef } from './createExtensionDataRef';\n\n/** @public */\nexport type NavTarget = {\n title: string;\n icon: IconComponent;\n routeRef: RouteRef<undefined>;\n};\n\n/** @public */\nexport type LogoElements = {\n logoIcon?: JSX.Element;\n logoFull?: JSX.Element;\n};\n\n/** @public */\nexport const coreExtensionData = {\n reactElement: createExtensionDataRef<JSX.Element>('core.reactElement'),\n routePath: createExtensionDataRef<string>('core.routing.path'),\n apiFactory: createExtensionDataRef<AnyApiFactory>('core.api.factory'),\n routeRef: createExtensionDataRef<RouteRef>('core.routing.ref'),\n navTarget: createExtensionDataRef<NavTarget>('core.nav.target'),\n theme: createExtensionDataRef<AppTheme>('core.theme'),\n logoElements: createExtensionDataRef<LogoElements>('core.logos'),\n component: createExtensionDataRef<{\n ref: ComponentRef<ComponentType<any>>;\n impl: ComponentType<any>;\n }>('component.ref'),\n};\n","/*\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 { AppNode } from '../apis';\nimport { PortableSchema } from '../schema';\nimport { Expand } from '../types';\nimport { ExtensionDataRef } from './createExtensionDataRef';\nimport { ExtensionInput } from './createExtensionInput';\n\n/** @public */\nexport type AnyExtensionDataMap = {\n [name in string]: ExtensionDataRef<unknown, { optional?: true }>;\n};\n\n/** @public */\nexport type AnyExtensionInputMap = {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataMap,\n { optional: boolean; singleton: boolean }\n >;\n};\n\n/**\n * Converts an extension data map into the matching concrete data values type.\n * @public\n */\nexport type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = {\n [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends {\n optional: true;\n }\n ? never\n : DataName]: TExtensionData[DataName]['T'];\n} & {\n [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends {\n optional: true;\n }\n ? DataName\n : never]?: TExtensionData[DataName]['T'];\n};\n\n/**\n * Converts an extension input map into the matching concrete input values type.\n * @public\n */\nexport type ExtensionInputValues<\n TInputs extends { [name in string]: ExtensionInput<any, any> },\n> = {\n [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']\n ? Array<Expand<ExtensionDataValues<TInputs[InputName]['extensionData']>>>\n : false extends TInputs[InputName]['config']['optional']\n ? Expand<ExtensionDataValues<TInputs[InputName]['extensionData']>>\n : Expand<\n ExtensionDataValues<TInputs[InputName]['extensionData']> | undefined\n >;\n};\n\n/** @public */\nexport interface CreateExtensionOptions<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig,\n> {\n id: string;\n attachTo: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n output: TOutput;\n configSchema?: PortableSchema<TConfig>;\n factory(options: {\n node: AppNode;\n config: TConfig;\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }): Expand<ExtensionDataValues<TOutput>>;\n}\n\n/** @public */\nexport interface Extension<TConfig> {\n $$type: '@backstage/Extension';\n id: string;\n attachTo: { id: string; input: string };\n disabled: boolean;\n inputs: AnyExtensionInputMap;\n output: AnyExtensionDataMap;\n configSchema?: PortableSchema<TConfig>;\n factory(options: {\n node: AppNode;\n config: TConfig;\n inputs: Record<\n string,\n undefined | Record<string, unknown> | Array<Record<string, unknown>>\n >;\n }): ExtensionDataValues<any>;\n}\n\n/** @public */\nexport function createExtension<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig = never,\n>(\n options: CreateExtensionOptions<TOutput, TInputs, TConfig>,\n): Extension<TConfig> {\n return {\n ...options,\n disabled: options.disabled ?? false,\n $$type: '@backstage/Extension',\n inputs: options.inputs ?? {},\n factory({ inputs, ...rest }) {\n // TODO: Simplify this, but TS wouldn't infer the input type for some reason\n return options.factory({\n inputs: inputs as Expand<ExtensionInputValues<TInputs>>,\n ...rest,\n });\n },\n };\n}\n","/*\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 { AnyExtensionDataMap } from './createExtension';\n\n/** @public */\nexport interface ExtensionInput<\n TExtensionData extends AnyExtensionDataMap,\n TConfig extends { singleton: boolean; optional: boolean },\n> {\n $$type: '@backstage/ExtensionInput';\n extensionData: TExtensionData;\n config: TConfig;\n}\n\n/** @public */\nexport function createExtensionInput<\n TExtensionData extends AnyExtensionDataMap,\n TConfig extends { singleton?: boolean; optional?: boolean },\n>(\n extensionData: TExtensionData,\n config?: TConfig,\n): ExtensionInput<\n TExtensionData,\n {\n singleton: TConfig['singleton'] extends true ? true : false;\n optional: TConfig['optional'] extends true ? true : false;\n }\n> {\n return {\n $$type: '@backstage/ExtensionInput',\n extensionData,\n config: {\n singleton: Boolean(config?.singleton) as TConfig['singleton'] extends true\n ? true\n : false,\n optional: Boolean(config?.optional) as TConfig['optional'] extends true\n ? true\n : false,\n },\n };\n}\n","/*\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 { Extension } from './createExtension';\nimport { ExternalRouteRef, RouteRef } from '../routing';\nimport { FeatureFlagConfig } from './types';\n\n/** @public */\nexport type AnyRoutes = { [name in string]: RouteRef };\n\n/** @public */\nexport type AnyExternalRoutes = { [name in string]: ExternalRouteRef };\n\n/** @public */\nexport interface PluginOptions<\n Routes extends AnyRoutes,\n ExternalRoutes extends AnyExternalRoutes,\n> {\n id: string;\n routes?: Routes;\n externalRoutes?: ExternalRoutes;\n extensions?: Extension<unknown>[];\n featureFlags?: FeatureFlagConfig[];\n}\n\n/** @public */\nexport interface BackstagePlugin<\n Routes extends AnyRoutes = AnyRoutes,\n ExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes,\n> {\n readonly $$type: '@backstage/BackstagePlugin';\n readonly id: string;\n readonly routes: Routes;\n readonly externalRoutes: ExternalRoutes;\n}\n\n/** @public */\nexport interface InternalBackstagePlugin<\n Routes extends AnyRoutes = AnyRoutes,\n ExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes,\n> extends BackstagePlugin<Routes, ExternalRoutes> {\n readonly version: 'v1';\n readonly extensions: Extension<unknown>[];\n readonly featureFlags: FeatureFlagConfig[];\n}\n\n/** @public */\nexport function createPlugin<\n Routes extends AnyRoutes = {},\n ExternalRoutes extends AnyExternalRoutes = {},\n>(\n options: PluginOptions<Routes, ExternalRoutes>,\n): BackstagePlugin<Routes, ExternalRoutes> {\n return {\n $$type: '@backstage/BackstagePlugin',\n version: 'v1',\n id: options.id,\n routes: options.routes ?? ({} as Routes),\n externalRoutes: options.externalRoutes ?? ({} as ExternalRoutes),\n extensions: options.extensions ?? [],\n featureFlags: options.featureFlags ?? [],\n } as InternalBackstagePlugin<Routes, ExternalRoutes>;\n}\n\n/** @internal */\nexport function toInternalBackstagePlugin(\n plugin: BackstagePlugin,\n): InternalBackstagePlugin {\n const internal = plugin as InternalBackstagePlugin;\n if (internal.$$type !== '@backstage/BackstagePlugin') {\n throw new Error(`Invalid plugin instance, bad type '${internal.$$type}'`);\n }\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid plugin instance, bad version '${internal.version}'`,\n );\n }\n return internal;\n}\n","/*\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 { Extension } from './createExtension';\nimport { FeatureFlagConfig } from './types';\n\n/** @public */\nexport interface ExtensionOverridesOptions {\n extensions: Extension<unknown>[];\n featureFlags?: FeatureFlagConfig[];\n}\n\n/** @public */\nexport interface ExtensionOverrides {\n readonly $$type: '@backstage/ExtensionOverrides';\n}\n\n/** @internal */\nexport interface InternalExtensionOverrides extends ExtensionOverrides {\n readonly version: 'v1';\n readonly extensions: Extension<unknown>[];\n readonly featureFlags: FeatureFlagConfig[];\n}\n\n/** @public */\nexport function createExtensionOverrides(\n options: ExtensionOverridesOptions,\n): ExtensionOverrides {\n return {\n $$type: '@backstage/ExtensionOverrides',\n version: 'v1',\n extensions: options.extensions,\n featureFlags: options.featureFlags ?? [],\n } as InternalExtensionOverrides;\n}\n\n/** @internal */\nexport function toInternalExtensionOverrides(\n overrides: ExtensionOverrides,\n): InternalExtensionOverrides {\n const internal = overrides as InternalExtensionOverrides;\n if (internal.$$type !== '@backstage/ExtensionOverrides') {\n throw new Error(\n `Invalid extension overrides instance, bad type '${internal.$$type}'`,\n );\n }\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid extension overrides instance, bad version '${internal.version}'`,\n );\n }\n return internal;\n}\n","/*\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 ExtensionInputValues,\n createExtension,\n coreExtensionData,\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<ExtensionInputValues<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 id: `apis.${apiRef.id}`,\n attachTo: { id: 'core', input: 'apis' },\n inputs: extensionInputs,\n configSchema,\n output: {\n api: coreExtensionData.apiFactory,\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 * 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 { JsonObject } from '@backstage/types';\nimport { z, ZodSchema, ZodTypeDef } from 'zod';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { PortableSchema } from './types';\n\n/** @public */\nexport function createSchemaFromZod<TOutput, TInput>(\n schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>,\n): PortableSchema<TOutput> {\n const schema = schemaCreator(z);\n return {\n // TODO: Types allow z.array etc here but it will break stuff\n parse: input => {\n const result = schema.safeParse(input);\n if (result.success) {\n return result.data;\n }\n\n throw new Error(result.error.issues.map(formatIssue).join('; '));\n },\n // TODO: Verify why we are not compatible with the latest zodToJsonSchema.\n schema: zodToJsonSchema(schema) as JsonObject,\n };\n}\n\nfunction formatIssue(issue: z.ZodIssue): string {\n if (issue.code === 'invalid_union') {\n return formatIssue(issue.unionErrors[0].issues[0]);\n }\n let message = issue.message;\n if (message === 'Required') {\n message = `Missing required value`;\n }\n if (issue.path.length) {\n message += ` at '${issue.path.join('.')}'`;\n }\n return message;\n}\n","/*\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, { lazy } from 'react';\nimport { ExtensionBoundary } from '../components';\nimport { createSchemaFromZod, PortableSchema } from '../schema';\nimport {\n coreExtensionData,\n createExtension,\n Extension,\n ExtensionInputValues,\n AnyExtensionInputMap,\n} from '../wiring';\nimport { RouteRef } from '../routing';\nimport { Expand } from '../types';\n\n/**\n * Helper for creating extensions for a routable React page component.\n *\n * @public\n */\nexport function createPageExtension<\n TConfig extends { path: string },\n TInputs extends AnyExtensionInputMap,\n>(\n options: (\n | {\n defaultPath: string;\n }\n | {\n configSchema: PortableSchema<TConfig>;\n }\n ) & {\n id: string;\n attachTo?: { id: string; input: string };\n disabled?: boolean;\n inputs?: TInputs;\n routeRef?: RouteRef;\n loader: (options: {\n config: TConfig;\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => Promise<JSX.Element>;\n },\n): Extension<TConfig> {\n const { id } = options;\n\n const configSchema =\n 'configSchema' in options\n ? options.configSchema\n : (createSchemaFromZod(z =>\n z.object({ path: z.string().default(options.defaultPath) }),\n ) as PortableSchema<TConfig>);\n\n return createExtension({\n id,\n attachTo: options.attachTo ?? { id: 'core.routes', input: 'routes' },\n configSchema,\n inputs: options.inputs,\n disabled: options.disabled,\n output: {\n element: coreExtensionData.reactElement,\n path: coreExtensionData.routePath,\n routeRef: coreExtensionData.routeRef.optional(),\n },\n factory({ config, inputs, node }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ config, inputs })\n .then(element => ({ default: () => element })),\n );\n\n return {\n path: config.path,\n routeRef: options.routeRef,\n element: (\n <ExtensionBoundary node={node} routable>\n <ExtensionComponent />\n </ExtensionBoundary>\n ),\n };\n },\n });\n}\n","/*\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 { IconComponent } from '@backstage/core-plugin-api';\nimport { createSchemaFromZod } from '../schema/createSchemaFromZod';\nimport { coreExtensionData, createExtension } from '../wiring';\nimport { RouteRef } from '../routing';\n\n/**\n * Helper for creating extensions for a nav item.\n * @public\n */\nexport function createNavItemExtension(options: {\n id: string;\n routeRef: RouteRef<undefined>;\n title: string;\n icon: IconComponent;\n}) {\n const { id, routeRef, title, icon } = options;\n return createExtension({\n id,\n attachTo: { id: 'core.nav', input: 'items' },\n configSchema: createSchemaFromZod(z =>\n z.object({\n title: z.string().default(title),\n }),\n ),\n output: {\n navTarget: coreExtensionData.navTarget,\n },\n factory: ({ config }) => ({\n navTarget: {\n title: config.title,\n icon,\n routeRef,\n },\n }),\n });\n}\n","/*\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, lazy } from 'react';\nimport { ExtensionBoundary } from '../components';\nimport { PortableSchema } from '../schema';\nimport {\n createExtension,\n Extension,\n ExtensionInputValues,\n AnyExtensionInputMap,\n createExtensionDataRef,\n} from '../wiring';\nimport { Expand } from '../types';\nimport { SignInPageProps } from '@backstage/core-plugin-api';\n\n/** @internal */\nexport const signInPageComponentDataRef =\n createExtensionDataRef<ComponentType<SignInPageProps>>('core.signInPage');\n\n/**\n *\n * @public\n */\nexport function createSignInPageExtension<\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(options: {\n id: string;\n attachTo?: { id: string; input: string };\n configSchema?: PortableSchema<TConfig>;\n disabled?: boolean;\n inputs?: TInputs;\n loader: (options: {\n config: TConfig;\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => Promise<ComponentType<SignInPageProps>>;\n}): Extension<TConfig> {\n const { id } = options;\n\n return createExtension({\n id,\n attachTo: options.attachTo ?? { id: 'core.router', input: 'signInPage' },\n configSchema: options.configSchema,\n inputs: options.inputs,\n disabled: options.disabled,\n output: {\n component: signInPageComponentDataRef,\n },\n factory({ config, inputs, node }) {\n const ExtensionComponent = lazy(() =>\n options\n .loader({ config, inputs })\n .then(component => ({ default: component })),\n );\n\n return {\n component: props => (\n <ExtensionBoundary node={node} routable>\n <ExtensionComponent {...props} />\n </ExtensionBoundary>\n ),\n };\n },\n });\n}\n","/*\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 { createExtension, coreExtensionData } from '../wiring';\nimport { AppTheme } from '@backstage/core-plugin-api';\n\n/** @public */\nexport function createThemeExtension(theme: AppTheme) {\n return createExtension({\n id: `themes.${theme.id}`,\n attachTo: { id: 'core', input: 'themes' },\n output: {\n theme: coreExtensionData.theme,\n },\n factory: () => ({ theme }),\n });\n}\n","/*\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, { lazy } from 'react';\nimport {\n AnyExtensionInputMap,\n ExtensionInputValues,\n coreExtensionData,\n createExtension,\n} from '../wiring';\nimport { Expand } from '../types';\nimport { PortableSchema } from '../schema';\nimport { ExtensionBoundary, ComponentRef } from '../components';\n\n/** @public */\nexport function createComponentExtension<\n TRef extends ComponentRef<any>,\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(options: {\n ref: TRef;\n disabled?: boolean;\n inputs?: TInputs;\n configSchema?: PortableSchema<TConfig>;\n component:\n | {\n lazy: (values: {\n config: TConfig;\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => Promise<TRef['T']>;\n }\n | {\n sync: (values: {\n config: TConfig;\n inputs: Expand<ExtensionInputValues<TInputs>>;\n }) => TRef['T'];\n };\n}) {\n const id = options.ref.id;\n return createExtension({\n id,\n attachTo: { id: 'core', input: 'components' },\n inputs: options.inputs,\n disabled: options.disabled,\n configSchema: options.configSchema,\n output: {\n component: coreExtensionData.component,\n },\n factory({ config, inputs, node }) {\n let ExtensionComponent: TRef['T'];\n\n if ('sync' in options.component) {\n ExtensionComponent = options.component.sync({ config, inputs });\n } else {\n const loader = options.component.lazy({ config, inputs });\n ExtensionComponent = lazy(() =>\n loader.then(component => ({ default: component })),\n );\n }\n\n return {\n component: {\n ref: options.ref,\n impl: props => (\n <ExtensionBoundary node={node}>\n <ExtensionComponent {...props} />\n </ExtensionBoundary>\n ),\n },\n };\n },\n });\n}\n","/*\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\nconst MESSAGE_MARKER = 'eHgtF5hmbrXyiEvo';\n\n/**\n * Internal helper that describes the location of the parent caller.\n * @internal\n */\nexport function describeParentCallSite(\n ErrorConstructor: { new (message: string): Error } = Error,\n): string {\n const { stack } = new ErrorConstructor(MESSAGE_MARKER);\n if (!stack) {\n return '<unknown>';\n }\n\n // Safari and Firefox don't include the error itself in the stack\n const startIndex = stack.includes(MESSAGE_MARKER)\n ? stack.indexOf('\\n') + 1\n : 0;\n const secondEntryStart =\n stack.indexOf('\\n', stack.indexOf('\\n', startIndex) + 1) + 1;\n const secondEntryEnd = stack.indexOf('\\n', secondEntryStart);\n\n const line = stack.substring(secondEntryStart, secondEntryEnd).trim();\n if (!line) {\n return 'unknown';\n }\n\n // Below we try to extract the location for different browsers.\n // Since RouteRefs are declared at the top-level of modules the caller name isn't interesting.\n\n // Chrome\n if (line.includes('(')) {\n return line.substring(line.indexOf('(') + 1, line.indexOf(')'));\n }\n\n // Safari & Firefox\n if (line.includes('@')) {\n return line.substring(line.indexOf('@') + 1);\n }\n\n // Give up\n return line;\n}\n","/*\n * Copyright 2020 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 { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Absolute route reference.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface RouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> {\n readonly $$type: '@backstage/RouteRef';\n readonly T: TParams;\n}\n\n/** @internal */\nexport interface InternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> extends RouteRef<TParams> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n>(resource: RouteRef<TParams>): InternalRouteRef<TParams> {\n const r = resource as InternalRouteRef<TParams>;\n if (r.$$type !== '@backstage/RouteRef') {\n throw new Error(`Invalid RouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isRouteRef(opaque: { $$type: string }): opaque is RouteRef {\n return opaque.$$type === '@backstage/RouteRef';\n}\n\n/** @internal */\nexport class RouteRefImpl implements InternalRouteRef {\n readonly $$type = '@backstage/RouteRef';\n readonly version = 'v1';\n declare readonly T: never;\n\n #id?: string;\n #params: string[];\n #creationSite: string;\n\n constructor(readonly params: string[] = [], creationSite: string) {\n this.#params = params;\n this.#creationSite = creationSite;\n }\n\n getParams(): string[] {\n return this.#params;\n }\n\n getDescription(): string {\n if (this.#id) {\n return this.#id;\n }\n return `created at '${this.#creationSite}'`;\n }\n\n get #name() {\n return this.$$type.slice('@backstage/'.length);\n }\n\n setId(id: string): void {\n if (!id) {\n throw new Error(`${this.#name} id must be a non-empty string`);\n }\n if (this.#id) {\n throw new Error(\n `${this.#name} was referenced twice as both '${this.#id}' and '${id}'`,\n );\n }\n this.#id = id;\n }\n\n toString(): string {\n return `${this.#name}{${this.getDescription()}}`;\n }\n}\n\n/**\n * Create a {@link RouteRef} from a route descriptor.\n *\n * @param config - Description of the route reference to be created.\n * @public\n */\nexport function createRouteRef<\n // Params is the type that we care about and the one to be embedded in the route ref.\n // For example, given the params ['name', 'kind'], Params will be {name: string, kind: string}\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TParamKeys extends string = string,\n>(config?: {\n /** A list of parameter names that the path that this route ref is bound to must contain */\n readonly params: string extends TParamKeys ? (keyof TParams)[] : TParamKeys[];\n}): RouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string }\n> {\n return new RouteRefImpl(\n config?.params as string[] | undefined,\n describeParentCallSite(),\n ) as RouteRef<any>;\n}\n","/*\n * Copyright 2020 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 { RouteRef, toInternalRouteRef } from './RouteRef';\nimport { AnyRouteRefParams } from './types';\n\n// Should match the pattern in react-router\nconst PARAM_PATTERN = /^\\w+$/;\n\n/**\n * Descriptor of a route relative to an absolute {@link RouteRef}.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface SubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> {\n readonly $$type: '@backstage/SubRouteRef';\n\n readonly T: TParams;\n\n readonly path: string;\n}\n\n/** @internal */\nexport interface InternalSubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> extends SubRouteRef<TParams> {\n readonly version: 'v1';\n\n getParams(): string[];\n getParent(): RouteRef;\n getDescription(): string;\n}\n\n/** @internal */\nexport function toInternalSubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n>(resource: SubRouteRef<TParams>): InternalSubRouteRef<TParams> {\n const r = resource as InternalSubRouteRef<TParams>;\n if (r.$$type !== '@backstage/SubRouteRef') {\n throw new Error(`Invalid SubRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isSubRouteRef(opaque: {\n $$type: string;\n}): opaque is SubRouteRef {\n return opaque.$$type === '@backstage/SubRouteRef';\n}\n\n/** @internal */\nexport class SubRouteRefImpl<TParams extends AnyRouteRefParams>\n implements SubRouteRef<TParams>\n{\n readonly $$type = '@backstage/SubRouteRef';\n readonly version = 'v1';\n declare readonly T: never;\n\n #params: string[];\n #parent: RouteRef;\n\n constructor(readonly path: string, params: string[], parent: RouteRef) {\n this.#params = params;\n this.#parent = parent;\n }\n\n getParams(): string[] {\n return this.#params;\n }\n\n getParent(): RouteRef {\n return this.#parent;\n }\n\n getDescription(): string {\n const parent = toInternalRouteRef(this.#parent);\n return `at ${this.path} with parent ${parent.getDescription()}`;\n }\n\n toString(): string {\n return `SubRouteRef{${this.getDescription()}}`;\n }\n}\n\n/**\n * Used in {@link PathParams} type declaration.\n * @ignore\n */\ntype ParamPart<S extends string> = S extends `:${infer Param}` ? Param : never;\n\n/**\n * Used in {@link PathParams} type declaration.\n * @ignore\n */\ntype ParamNames<S extends string> = S extends `${infer Part}/${infer Rest}`\n ? ParamPart<Part> | ParamNames<Rest>\n : ParamPart<S>;\n/**\n * This utility type helps us infer a Param object type from a string path\n * For example, `/foo/:bar/:baz` inferred to `{ bar: string, baz: string }`\n * @ignore\n */\ntype PathParams<S extends string> = { [name in ParamNames<S>]: string };\n\n/**\n * Merges a param object type with an optional params type into a params object.\n * @ignore\n */\ntype MergeParams<\n P1 extends { [param in string]: string },\n P2 extends AnyRouteRefParams,\n> = (P1[keyof P1] extends never ? {} : P1) & (P2 extends undefined ? {} : P2);\n\n/**\n * Convert empty params to undefined.\n * @ignore\n */\ntype TrimEmptyParams<Params extends { [param in string]: string }> =\n keyof Params extends never ? undefined : Params;\n\n/**\n * Creates a SubRouteRef type given the desired parameters and parent route parameters.\n * The parameters types are merged together while ensuring that there is no overlap between the two.\n *\n * @ignore\n */\ntype MakeSubRouteRef<\n Params extends { [param in string]: string },\n ParentParams extends AnyRouteRefParams,\n> = keyof Params & keyof ParentParams extends never\n ? SubRouteRef<TrimEmptyParams<MergeParams<Params, ParentParams>>>\n : never;\n\n/**\n * Create a {@link SubRouteRef} from a route descriptor.\n *\n * @param config - Description of the route reference to be created.\n * @public\n */\nexport function createSubRouteRef<\n Path extends string,\n ParentParams extends AnyRouteRefParams = never,\n>(config: {\n path: Path;\n parent: RouteRef<ParentParams>;\n}): MakeSubRouteRef<PathParams<Path>, ParentParams> {\n const { path, parent } = config;\n type Params = PathParams<Path>;\n\n const internalParent = toInternalRouteRef(parent);\n const parentParams = internalParent.getParams();\n\n // Collect runtime parameters from the path, e.g. ['bar', 'baz'] from '/foo/:bar/:baz'\n const pathParams = path\n .split('/')\n .filter(p => p.startsWith(':'))\n .map(p => p.substring(1));\n const params = [...parentParams, ...pathParams];\n\n if (parentParams.some(p => pathParams.includes(p as string))) {\n throw new Error(\n 'SubRouteRef may not have params that overlap with its parent',\n );\n }\n if (!path.startsWith('/')) {\n throw new Error(`SubRouteRef path must start with '/', got '${path}'`);\n }\n if (path.endsWith('/')) {\n throw new Error(`SubRouteRef path must not end with '/', got '${path}'`);\n }\n for (const param of pathParams) {\n if (!PARAM_PATTERN.test(param)) {\n throw new Error(`SubRouteRef path has invalid param, got '${param}'`);\n }\n }\n\n // We ensure that the type of the return type is sane here\n const subRouteRef = new SubRouteRefImpl(\n path,\n params as string[],\n parent,\n ) as SubRouteRef<TrimEmptyParams<MergeParams<Params, ParentParams>>>;\n\n // But skip type checking of the return value itself, because the conditional\n // type checking of the parent parameter overlap is tricky to express.\n return subRouteRef as any;\n}\n","/*\n * Copyright 2020 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 { RouteRefImpl } from './RouteRef';\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface ExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n> {\n readonly $$type: '@backstage/ExternalRouteRef';\n readonly T: TParams;\n readonly optional: TOptional;\n}\n\n/** @internal */\nexport interface InternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n> extends ExternalRouteRef<TParams, TOptional> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n>(\n resource: ExternalRouteRef<TParams, TOptional>,\n): InternalExternalRouteRef<TParams, TOptional> {\n const r = resource as InternalExternalRouteRef<TParams, TOptional>;\n if (r.$$type !== '@backstage/ExternalRouteRef') {\n throw new Error(`Invalid ExternalRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isExternalRouteRef(opaque: {\n $$type: string;\n}): opaque is ExternalRouteRef {\n return opaque.$$type === '@backstage/ExternalRouteRef';\n}\n\n/** @internal */\nclass ExternalRouteRefImpl\n extends RouteRefImpl\n implements InternalExternalRouteRef\n{\n readonly $$type = '@backstage/ExternalRouteRef' as any;\n\n constructor(\n readonly optional: boolean,\n readonly params: string[] = [],\n creationSite: string,\n ) {\n super(params, creationSite);\n }\n}\n\n/**\n * Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @param options - Description of the route reference to be created.\n * @public\n */\nexport function createExternalRouteRef<\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TOptional extends boolean = false,\n TParamKeys extends string = string,\n>(options?: {\n /**\n * The parameters that will be provided to the external route reference.\n */\n readonly params?: string extends TParamKeys\n ? (keyof TParams)[]\n : TParamKeys[];\n\n /**\n * Whether or not this route is optional, defaults to false.\n *\n * Optional external routes are not required to be bound in the app, and\n * if they aren't, `useExternalRouteRef` will return `undefined`.\n */\n optional?: TOptional;\n}): ExternalRouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string },\n TOptional\n> {\n return new ExternalRouteRefImpl(\n Boolean(options?.optional),\n options?.params as string[] | undefined,\n describeParentCallSite(),\n ) as ExternalRouteRef<any, any>;\n}\n","/*\n * Copyright 2020 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 { useMemo } from 'react';\nimport { matchRoutes, useLocation } from 'react-router-dom';\nimport { useVersionedContext } from '@backstage/version-bridge';\nimport { AnyRouteRefParams } from './types';\nimport { RouteRef } from './RouteRef';\nimport { SubRouteRef } from './SubRouteRef';\nimport { ExternalRouteRef } from './ExternalRouteRef';\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 * @internal\n */\nexport interface RouteResolver {\n resolve<TParams extends AnyRouteRefParams>(\n anyRouteRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams, any>,\n sourceLocation: Parameters<typeof matchRoutes>[1],\n ): RouteFunc<TParams> | undefined;\n}\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<\n TOptional extends boolean,\n TParams extends AnyRouteRefParams,\n>(\n routeRef: ExternalRouteRef<TParams, TOptional>,\n): TParams extends true ? RouteFunc<TParams> | undefined : RouteFunc<TParams>;\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<TParams extends AnyRouteRefParams>(\n routeRef: RouteRef<TParams> | SubRouteRef<TParams>,\n): RouteFunc<TParams>;\n\n/**\n * React hook for constructing URLs to routes.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}\n *\n * @param routeRef - The ref to route that should be converted to URL.\n * @returns A function that will in turn return the concrete URL of the `routeRef`.\n * @public\n */\nexport function useRouteRef<TParams extends AnyRouteRefParams>(\n routeRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams, any>,\n): RouteFunc<TParams> | undefined {\n const { pathname } = useLocation();\n const versionedContext = useVersionedContext<{ 1: RouteResolver }>(\n 'routing-context',\n );\n if (!versionedContext) {\n throw new Error('Routing context is not available');\n }\n\n const resolver = versionedContext.atVersion(1);\n const routeFunc = useMemo(\n () => resolver && resolver.resolve(routeRef, { pathname }),\n [resolver, routeRef, pathname],\n );\n\n if (!versionedContext) {\n throw new Error('useRouteRef used outside of routing context');\n }\n if (!resolver) {\n throw new Error('RoutingContext v1 not available');\n }\n\n const isOptional = 'optional' in routeRef && routeRef.optional;\n if (!routeFunc && !isOptional) {\n throw new Error(`No path for ${routeRef}`);\n }\n\n return routeFunc;\n}\n","/*\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 { useParams } from 'react-router-dom';\nimport { AnyRouteRefParams } from './types';\nimport { RouteRef } from './RouteRef';\nimport { SubRouteRef } from './SubRouteRef';\n\n/**\n * React hook for retrieving dynamic params from the current URL.\n * @param _routeRef - Ref of the current route.\n * @public\n */\nexport function useRouteRefParams<Params extends AnyRouteRefParams>(\n _routeRef: RouteRef<Params> | SubRouteRef<Params>,\n): Params {\n return useParams() as Params;\n}\n"],"names":["routableExtensionRenderedEvent","__publicField","useAnalytics","AnalyticsContext","_params","__privateAdd","__privateSet","__privateGet"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/frontend-plugin-api",
3
- "version": "0.3.1-next.0",
3
+ "version": "0.4.0-next.1",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -23,10 +23,10 @@
23
23
  "postpack": "backstage-cli package postpack"
24
24
  },
25
25
  "devDependencies": {
26
- "@backstage/cli": "^0.24.1-next.0",
27
- "@backstage/frontend-app-api": "^0.3.1-next.0",
28
- "@backstage/frontend-test-utils": "^0.1.0-next.0",
29
- "@backstage/test-utils": "^1.4.6-next.0",
26
+ "@backstage/cli": "^0.25.0-next.1",
27
+ "@backstage/frontend-app-api": "^0.4.0-next.1",
28
+ "@backstage/frontend-test-utils": "^0.1.0-next.1",
29
+ "@backstage/test-utils": "^1.4.6-next.1",
30
30
  "@testing-library/jest-dom": "^6.0.0",
31
31
  "@testing-library/react": "^14.0.0",
32
32
  "history": "^5.3.0"
@@ -40,8 +40,8 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@backstage/config": "^1.1.1",
43
- "@backstage/core-components": "^0.13.9-next.0",
44
- "@backstage/core-plugin-api": "^1.8.1-next.0",
43
+ "@backstage/core-components": "^0.13.9-next.1",
44
+ "@backstage/core-plugin-api": "^1.8.1-next.1",
45
45
  "@backstage/types": "^1.1.1",
46
46
  "@backstage/version-bridge": "^1.0.7",
47
47
  "@material-ui/core": "^4.12.4",