@backstage/frontend-plugin-api 0.4.0-next.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/dist/index.d.ts +112 -97
- package/dist/index.esm.js +80 -30
- package/dist/index.esm.js.map +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @backstage/frontend-plugin-api
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- af7bc3e: Switched all core extensions to instead use the namespace `'app'`.
|
|
8
|
+
- 5cdf2b3: Changed `Extension` and `ExtensionDefinition` to use opaque types.
|
|
9
|
+
- 8f5d6c1: Extension inputs are now wrapped into an additional object when passed to the extension factory, with the previous values being available at the `output` property. The `ExtensionInputValues` type has also been replaced by `ResolvedExtensionInputs`.
|
|
10
|
+
- 8837a96: **BREAKING**: This version changes how extensions are created and how their IDs are determined. The `createExtension` function now accepts `kind`, `namespace` and `name` instead of `id`. All of the new options are optional, and are used to construct the final extension ID. By convention extension creators should set the `kind` to match their own name, for example `createNavItemExtension` sets the kind `nav-item`.
|
|
11
|
+
|
|
12
|
+
The `createExtension` function as well as all extension creators now also return an `ExtensionDefinition` rather than an `Extension`, which in turn needs to be passed to `createPlugin` or `createExtensionOverrides` to be used.
|
|
13
|
+
|
|
14
|
+
- f9ef632: Moved several extension data references from `coreExtensionData` to their respective extension creators.
|
|
15
|
+
- a5a0473: 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`.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- a379243: Add the `FrontendFeature` type, which is the union of `BackstagePlugin` and `ExtensionOverrides`
|
|
20
|
+
- b7adf24: Update alpha component ref type to be more specific than any, delete boot page component and use new plugin type for error boundary component extensions.
|
|
21
|
+
- 5eb6b8a: Added the nav logo extension for customization of sidebar logo
|
|
22
|
+
- 1f12fb7: Create factories for overriding default core components extensions.
|
|
23
|
+
- 5970928: Add feature flags to plugins and extension overrides.
|
|
24
|
+
- e539735: Added `createSignInPageExtension`.
|
|
25
|
+
- 73246ec: Added translation APIs as well as `createTranslationExtension`.
|
|
26
|
+
- cb4197a: Forward ` node`` instead of `extensionId` to resolved extension inputs.
|
|
27
|
+
- f27ee7d: Migrate analytics api and context files.
|
|
28
|
+
- 0cbb03b: Fixing regular expression ReDoS with zod packages. Upgrading to latest. ref: https://security.snyk.io/vuln/SNYK-JS-ZOD-5925617
|
|
29
|
+
- f1183b7: Renamed the `component` option of `createComponentExtension` to `loader`.
|
|
30
|
+
- Updated dependencies
|
|
31
|
+
- @backstage/core-plugin-api@1.8.1
|
|
32
|
+
- @backstage/core-components@0.13.9
|
|
33
|
+
- @backstage/config@1.1.1
|
|
34
|
+
- @backstage/types@1.1.1
|
|
35
|
+
- @backstage/version-bridge@1.0.7
|
|
36
|
+
|
|
3
37
|
## 0.4.0-next.3
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import React, { ReactNode, JSX as JSX$1, ComponentType } from 'react';
|
|
3
3
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
4
|
-
import { IconComponent as IconComponent$1,
|
|
4
|
+
import { ApiRef, AnyApiRef, AnyApiFactory, IconComponent as IconComponent$1, SignInPageProps, AppTheme } from '@backstage/core-plugin-api';
|
|
5
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';
|
|
6
6
|
import { JsonObject } from '@backstage/types';
|
|
7
7
|
import { TranslationResource, TranslationMessages } from '@backstage/core-plugin-api/alpha';
|
|
@@ -262,6 +262,22 @@ interface ConfigurableExtensionDataRef<TData, TConfig extends {
|
|
|
262
262
|
/** @public */
|
|
263
263
|
declare function createExtensionDataRef<TData>(id: string): ConfigurableExtensionDataRef<TData>;
|
|
264
264
|
|
|
265
|
+
/** @public */
|
|
266
|
+
declare const coreExtensionData: {
|
|
267
|
+
reactElement: ConfigurableExtensionDataRef<JSX$1.Element, {}>;
|
|
268
|
+
routePath: ConfigurableExtensionDataRef<string, {}>;
|
|
269
|
+
routeRef: ConfigurableExtensionDataRef<RouteRef<AnyRouteRefParams>, {}>;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
/** @public */
|
|
273
|
+
type PortableSchema<TOutput> = {
|
|
274
|
+
parse: (input: unknown) => TOutput;
|
|
275
|
+
schema: JsonObject;
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/** @public */
|
|
279
|
+
declare function createSchemaFromZod<TOutput, TInput>(schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>): PortableSchema<TOutput>;
|
|
280
|
+
|
|
265
281
|
/**
|
|
266
282
|
* Utility type to expand type aliases into their equivalent type.
|
|
267
283
|
* @ignore
|
|
@@ -282,62 +298,6 @@ type CoreErrorBoundaryFallbackProps = {
|
|
|
282
298
|
resetError: () => void;
|
|
283
299
|
};
|
|
284
300
|
|
|
285
|
-
/** @public */
|
|
286
|
-
type ComponentRef<T extends {} = {}> = {
|
|
287
|
-
id: string;
|
|
288
|
-
T: T;
|
|
289
|
-
};
|
|
290
|
-
/** @public */
|
|
291
|
-
declare const coreComponentRefs: {
|
|
292
|
-
progress: ComponentRef<CoreProgressProps>;
|
|
293
|
-
notFoundErrorPage: ComponentRef<CoreNotFoundErrorPageProps>;
|
|
294
|
-
errorBoundaryFallback: ComponentRef<CoreErrorBoundaryFallbackProps>;
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
/** @public */
|
|
298
|
-
interface ExtensionBoundaryProps {
|
|
299
|
-
node: AppNode;
|
|
300
|
-
routable?: boolean;
|
|
301
|
-
children: ReactNode;
|
|
302
|
-
}
|
|
303
|
-
/** @public */
|
|
304
|
-
declare function ExtensionBoundary(props: ExtensionBoundaryProps): React.JSX.Element;
|
|
305
|
-
|
|
306
|
-
/** @public */
|
|
307
|
-
type NavTarget = {
|
|
308
|
-
title: string;
|
|
309
|
-
icon: IconComponent$1;
|
|
310
|
-
routeRef: RouteRef<undefined>;
|
|
311
|
-
};
|
|
312
|
-
/** @public */
|
|
313
|
-
type LogoElements = {
|
|
314
|
-
logoIcon?: JSX$1.Element;
|
|
315
|
-
logoFull?: JSX$1.Element;
|
|
316
|
-
};
|
|
317
|
-
/** @public */
|
|
318
|
-
declare const coreExtensionData: {
|
|
319
|
-
reactElement: ConfigurableExtensionDataRef<JSX$1.Element, {}>;
|
|
320
|
-
routePath: ConfigurableExtensionDataRef<string, {}>;
|
|
321
|
-
apiFactory: ConfigurableExtensionDataRef<AnyApiFactory, {}>;
|
|
322
|
-
routeRef: ConfigurableExtensionDataRef<RouteRef<AnyRouteRefParams>, {}>;
|
|
323
|
-
navTarget: ConfigurableExtensionDataRef<NavTarget, {}>;
|
|
324
|
-
theme: ConfigurableExtensionDataRef<AppTheme, {}>;
|
|
325
|
-
logoElements: ConfigurableExtensionDataRef<LogoElements, {}>;
|
|
326
|
-
component: ConfigurableExtensionDataRef<{
|
|
327
|
-
ref: ComponentRef;
|
|
328
|
-
impl: ComponentType;
|
|
329
|
-
}, {}>;
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
/** @public */
|
|
333
|
-
type PortableSchema<TOutput> = {
|
|
334
|
-
parse: (input: unknown) => TOutput;
|
|
335
|
-
schema: JsonObject;
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
/** @public */
|
|
339
|
-
declare function createSchemaFromZod<TOutput, TInput>(schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>): PortableSchema<TOutput>;
|
|
340
|
-
|
|
341
301
|
/** @public */
|
|
342
302
|
interface ExtensionInput<TExtensionData extends AnyExtensionDataMap, TConfig extends {
|
|
343
303
|
singleton: boolean;
|
|
@@ -421,43 +381,30 @@ interface CreateExtensionOptions<TOutput extends AnyExtensionDataMap, TInputs ex
|
|
|
421
381
|
/** @public */
|
|
422
382
|
interface ExtensionDefinition<TConfig> {
|
|
423
383
|
$$type: '@backstage/ExtensionDefinition';
|
|
424
|
-
kind?: string;
|
|
425
|
-
namespace?: string;
|
|
426
|
-
name?: string;
|
|
427
|
-
attachTo: {
|
|
384
|
+
readonly kind?: string;
|
|
385
|
+
readonly namespace?: string;
|
|
386
|
+
readonly name?: string;
|
|
387
|
+
readonly attachTo: {
|
|
428
388
|
id: string;
|
|
429
389
|
input: string;
|
|
430
390
|
};
|
|
431
|
-
disabled: boolean;
|
|
432
|
-
|
|
433
|
-
output: AnyExtensionDataMap;
|
|
434
|
-
configSchema?: PortableSchema<TConfig>;
|
|
435
|
-
factory(options: {
|
|
436
|
-
node: AppNode;
|
|
437
|
-
config: TConfig;
|
|
438
|
-
inputs: ResolvedExtensionInputs<any>;
|
|
439
|
-
}): ExtensionDataValues<any>;
|
|
391
|
+
readonly disabled: boolean;
|
|
392
|
+
readonly configSchema?: PortableSchema<TConfig>;
|
|
440
393
|
}
|
|
394
|
+
/** @public */
|
|
395
|
+
declare function createExtension<TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig = never>(options: CreateExtensionOptions<TOutput, TInputs, TConfig>): ExtensionDefinition<TConfig>;
|
|
396
|
+
|
|
441
397
|
/** @public */
|
|
442
398
|
interface Extension<TConfig> {
|
|
443
399
|
$$type: '@backstage/Extension';
|
|
444
|
-
id: string;
|
|
445
|
-
attachTo: {
|
|
400
|
+
readonly id: string;
|
|
401
|
+
readonly attachTo: {
|
|
446
402
|
id: string;
|
|
447
403
|
input: string;
|
|
448
404
|
};
|
|
449
|
-
disabled: boolean;
|
|
450
|
-
|
|
451
|
-
output: AnyExtensionDataMap;
|
|
452
|
-
configSchema?: PortableSchema<TConfig>;
|
|
453
|
-
factory(options: {
|
|
454
|
-
node: AppNode;
|
|
455
|
-
config: TConfig;
|
|
456
|
-
inputs: ResolvedExtensionInputs<any>;
|
|
457
|
-
}): ExtensionDataValues<any>;
|
|
405
|
+
readonly disabled: boolean;
|
|
406
|
+
readonly configSchema?: PortableSchema<TConfig>;
|
|
458
407
|
}
|
|
459
|
-
/** @public */
|
|
460
|
-
declare function createExtension<TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig = never>(options: CreateExtensionOptions<TOutput, TInputs, TConfig>): ExtensionDefinition<TConfig>;
|
|
461
408
|
|
|
462
409
|
/**
|
|
463
410
|
* Feature flag configuration.
|
|
@@ -468,7 +415,6 @@ type FeatureFlagConfig = {
|
|
|
468
415
|
/** Feature flag name */
|
|
469
416
|
name: string;
|
|
470
417
|
};
|
|
471
|
-
|
|
472
418
|
/** @public */
|
|
473
419
|
type AnyRoutes = {
|
|
474
420
|
[name in string]: RouteRef;
|
|
@@ -477,6 +423,20 @@ type AnyRoutes = {
|
|
|
477
423
|
type AnyExternalRoutes = {
|
|
478
424
|
[name in string]: ExternalRouteRef;
|
|
479
425
|
};
|
|
426
|
+
/** @public */
|
|
427
|
+
interface BackstagePlugin<Routes extends AnyRoutes = AnyRoutes, ExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes> {
|
|
428
|
+
readonly $$type: '@backstage/BackstagePlugin';
|
|
429
|
+
readonly id: string;
|
|
430
|
+
readonly routes: Routes;
|
|
431
|
+
readonly externalRoutes: ExternalRoutes;
|
|
432
|
+
}
|
|
433
|
+
/** @public */
|
|
434
|
+
interface ExtensionOverrides {
|
|
435
|
+
readonly $$type: '@backstage/ExtensionOverrides';
|
|
436
|
+
}
|
|
437
|
+
/** @public */
|
|
438
|
+
type FrontendFeature = BackstagePlugin | ExtensionOverrides;
|
|
439
|
+
|
|
480
440
|
/** @public */
|
|
481
441
|
interface PluginOptions<Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes> {
|
|
482
442
|
id: string;
|
|
@@ -486,13 +446,6 @@ interface PluginOptions<Routes extends AnyRoutes, ExternalRoutes extends AnyExte
|
|
|
486
446
|
featureFlags?: FeatureFlagConfig[];
|
|
487
447
|
}
|
|
488
448
|
/** @public */
|
|
489
|
-
interface BackstagePlugin<Routes extends AnyRoutes = AnyRoutes, ExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes> {
|
|
490
|
-
readonly $$type: '@backstage/BackstagePlugin';
|
|
491
|
-
readonly id: string;
|
|
492
|
-
readonly routes: Routes;
|
|
493
|
-
readonly externalRoutes: ExternalRoutes;
|
|
494
|
-
}
|
|
495
|
-
/** @public */
|
|
496
449
|
declare function createPlugin<Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}>(options: PluginOptions<Routes, ExternalRoutes>): BackstagePlugin<Routes, ExternalRoutes>;
|
|
497
450
|
|
|
498
451
|
/** @public */
|
|
@@ -501,10 +454,6 @@ interface ExtensionOverridesOptions {
|
|
|
501
454
|
featureFlags?: FeatureFlagConfig[];
|
|
502
455
|
}
|
|
503
456
|
/** @public */
|
|
504
|
-
interface ExtensionOverrides {
|
|
505
|
-
readonly $$type: '@backstage/ExtensionOverrides';
|
|
506
|
-
}
|
|
507
|
-
/** @public */
|
|
508
457
|
declare function createExtensionOverrides(options: ExtensionOverridesOptions): ExtensionOverrides;
|
|
509
458
|
|
|
510
459
|
/**
|
|
@@ -605,6 +554,27 @@ interface AppTreeApi {
|
|
|
605
554
|
*/
|
|
606
555
|
declare const appTreeApiRef: _backstage_core_plugin_api.ApiRef<AppTreeApi>;
|
|
607
556
|
|
|
557
|
+
/** @public */
|
|
558
|
+
type ComponentRef<T extends {} = {}> = {
|
|
559
|
+
id: string;
|
|
560
|
+
T: T;
|
|
561
|
+
};
|
|
562
|
+
/** @public */
|
|
563
|
+
declare const coreComponentRefs: {
|
|
564
|
+
progress: ComponentRef<CoreProgressProps>;
|
|
565
|
+
notFoundErrorPage: ComponentRef<CoreNotFoundErrorPageProps>;
|
|
566
|
+
errorBoundaryFallback: ComponentRef<CoreErrorBoundaryFallbackProps>;
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
/** @public */
|
|
570
|
+
interface ExtensionBoundaryProps {
|
|
571
|
+
node: AppNode;
|
|
572
|
+
routable?: boolean;
|
|
573
|
+
children: ReactNode;
|
|
574
|
+
}
|
|
575
|
+
/** @public */
|
|
576
|
+
declare function ExtensionBoundary(props: ExtensionBoundaryProps): React.JSX.Element;
|
|
577
|
+
|
|
608
578
|
/**
|
|
609
579
|
* API for looking up components based on component refs.
|
|
610
580
|
*
|
|
@@ -744,6 +714,10 @@ declare function createApiExtension<TConfig extends {}, TInputs extends AnyExten
|
|
|
744
714
|
configSchema?: PortableSchema<TConfig>;
|
|
745
715
|
inputs?: TInputs;
|
|
746
716
|
}): ExtensionDefinition<TConfig>;
|
|
717
|
+
/** @public */
|
|
718
|
+
declare namespace createApiExtension {
|
|
719
|
+
const factoryDataRef: ConfigurableExtensionDataRef<AnyApiFactory, {}>;
|
|
720
|
+
}
|
|
747
721
|
|
|
748
722
|
/**
|
|
749
723
|
* Helper for creating extensions for a routable React page component.
|
|
@@ -785,6 +759,32 @@ declare function createNavItemExtension(options: {
|
|
|
785
759
|
}): ExtensionDefinition<{
|
|
786
760
|
title: string;
|
|
787
761
|
}>;
|
|
762
|
+
/** @public */
|
|
763
|
+
declare namespace createNavItemExtension {
|
|
764
|
+
const targetDataRef: ConfigurableExtensionDataRef<{
|
|
765
|
+
title: string;
|
|
766
|
+
icon: IconComponent$1;
|
|
767
|
+
routeRef: RouteRef<undefined>;
|
|
768
|
+
}, {}>;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Helper for creating extensions for a nav logos.
|
|
773
|
+
* @public
|
|
774
|
+
*/
|
|
775
|
+
declare function createNavLogoExtension(options: {
|
|
776
|
+
name?: string;
|
|
777
|
+
namespace?: string;
|
|
778
|
+
logoIcon: JSX.Element;
|
|
779
|
+
logoFull: JSX.Element;
|
|
780
|
+
}): ExtensionDefinition<never>;
|
|
781
|
+
/** @public */
|
|
782
|
+
declare namespace createNavLogoExtension {
|
|
783
|
+
const logoElementsDataRef: ConfigurableExtensionDataRef<{
|
|
784
|
+
logoIcon?: JSX.Element | undefined;
|
|
785
|
+
logoFull?: JSX.Element | undefined;
|
|
786
|
+
}, {}>;
|
|
787
|
+
}
|
|
788
788
|
|
|
789
789
|
/**
|
|
790
790
|
*
|
|
@@ -805,9 +805,17 @@ declare function createSignInPageExtension<TConfig extends {}, TInputs extends A
|
|
|
805
805
|
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
|
806
806
|
}) => Promise<ComponentType<SignInPageProps>>;
|
|
807
807
|
}): ExtensionDefinition<TConfig>;
|
|
808
|
+
/** @public */
|
|
809
|
+
declare namespace createSignInPageExtension {
|
|
810
|
+
const componentDataRef: ConfigurableExtensionDataRef<React.ComponentType<SignInPageProps>, {}>;
|
|
811
|
+
}
|
|
808
812
|
|
|
809
813
|
/** @public */
|
|
810
814
|
declare function createThemeExtension(theme: AppTheme): ExtensionDefinition<never>;
|
|
815
|
+
/** @public */
|
|
816
|
+
declare namespace createThemeExtension {
|
|
817
|
+
const themeDataRef: ConfigurableExtensionDataRef<AppTheme, {}>;
|
|
818
|
+
}
|
|
811
819
|
|
|
812
820
|
/** @public */
|
|
813
821
|
declare function createComponentExtension<TProps extends {}, TConfig extends {}, TInputs extends AnyExtensionInputMap>(options: {
|
|
@@ -816,7 +824,7 @@ declare function createComponentExtension<TProps extends {}, TConfig extends {},
|
|
|
816
824
|
disabled?: boolean;
|
|
817
825
|
inputs?: TInputs;
|
|
818
826
|
configSchema?: PortableSchema<TConfig>;
|
|
819
|
-
|
|
827
|
+
loader: {
|
|
820
828
|
lazy: (values: {
|
|
821
829
|
config: TConfig;
|
|
822
830
|
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
|
@@ -828,6 +836,13 @@ declare function createComponentExtension<TProps extends {}, TConfig extends {},
|
|
|
828
836
|
}) => ComponentType<TProps>;
|
|
829
837
|
};
|
|
830
838
|
}): ExtensionDefinition<TConfig>;
|
|
839
|
+
/** @public */
|
|
840
|
+
declare namespace createComponentExtension {
|
|
841
|
+
const componentDataRef: ConfigurableExtensionDataRef<{
|
|
842
|
+
ref: ComponentRef;
|
|
843
|
+
impl: ComponentType;
|
|
844
|
+
}, {}>;
|
|
845
|
+
}
|
|
831
846
|
|
|
832
847
|
/** @public */
|
|
833
848
|
declare function createTranslationExtension(options: {
|
|
@@ -863,4 +878,4 @@ type IconComponent = ComponentType<{
|
|
|
863
878
|
fontSize?: 'medium' | 'large' | 'small' | 'inherit';
|
|
864
879
|
}>;
|
|
865
880
|
|
|
866
|
-
export { AnalyticsApi, AnalyticsContext, AnalyticsContextValue, AnalyticsEvent, AnalyticsEventAttributes, AnalyticsTracker, AnyExtensionDataMap, AnyExtensionInputMap, AnyExternalRoutes, AnyRouteRefParams, AnyRoutes, AppNode, AppNodeEdges, AppNodeInstance, AppNodeSpec, AppTree, AppTreeApi, BackstagePlugin, CommonAnalyticsContext, ComponentRef, ComponentsApi, ConfigurableExtensionDataRef, CoreErrorBoundaryFallbackProps, CoreNotFoundErrorPageProps, CoreProgressProps, CreateExtensionOptions, Extension, ExtensionBoundary, ExtensionBoundaryProps, ExtensionDataRef, ExtensionDataValues, ExtensionDefinition, ExtensionInput, ExtensionOverrides, ExtensionOverridesOptions, ExternalRouteRef, FeatureFlagConfig,
|
|
881
|
+
export { AnalyticsApi, AnalyticsContext, AnalyticsContextValue, AnalyticsEvent, AnalyticsEventAttributes, AnalyticsTracker, AnyExtensionDataMap, AnyExtensionInputMap, AnyExternalRoutes, AnyRouteRefParams, AnyRoutes, AppNode, AppNodeEdges, AppNodeInstance, AppNodeSpec, AppTree, AppTreeApi, BackstagePlugin, CommonAnalyticsContext, ComponentRef, ComponentsApi, ConfigurableExtensionDataRef, CoreErrorBoundaryFallbackProps, CoreNotFoundErrorPageProps, CoreProgressProps, CreateExtensionOptions, Extension, ExtensionBoundary, ExtensionBoundaryProps, ExtensionDataRef, ExtensionDataValues, ExtensionDefinition, ExtensionInput, ExtensionOverrides, ExtensionOverridesOptions, ExternalRouteRef, FeatureFlagConfig, FrontendFeature, IconComponent, PluginOptions, PortableSchema, ResolvedExtensionInput, ResolvedExtensionInputs, RouteFunc, RouteRef, SubRouteRef, analyticsApiRef, appTreeApiRef, componentsApiRef, coreComponentRefs, coreExtensionData, createApiExtension, createComponentExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createNavLogoExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSignInPageExtension, createSubRouteRef, createThemeExtension, createTranslationExtension, useAnalytics, useComponentRef, useRouteRef, useRouteRefParams };
|
package/dist/index.esm.js
CHANGED
|
@@ -261,18 +261,28 @@ function createExtensionDataRef(id) {
|
|
|
261
261
|
const coreExtensionData = {
|
|
262
262
|
reactElement: createExtensionDataRef("core.reactElement"),
|
|
263
263
|
routePath: createExtensionDataRef("core.routing.path"),
|
|
264
|
-
|
|
265
|
-
routeRef: createExtensionDataRef("core.routing.ref"),
|
|
266
|
-
navTarget: createExtensionDataRef("core.nav.target"),
|
|
267
|
-
theme: createExtensionDataRef("core.theme"),
|
|
268
|
-
logoElements: createExtensionDataRef("core.logos"),
|
|
269
|
-
component: createExtensionDataRef("core.component")
|
|
264
|
+
routeRef: createExtensionDataRef("core.routing.ref")
|
|
270
265
|
};
|
|
271
266
|
|
|
267
|
+
function toInternalExtensionDefinition(overrides) {
|
|
268
|
+
const internal = overrides;
|
|
269
|
+
if (internal.$$type !== "@backstage/ExtensionDefinition") {
|
|
270
|
+
throw new Error(
|
|
271
|
+
`Invalid extension definition instance, bad type '${internal.$$type}'`
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
if (internal.version !== "v1") {
|
|
275
|
+
throw new Error(
|
|
276
|
+
`Invalid extension definition instance, bad version '${internal.version}'`
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
return internal;
|
|
280
|
+
}
|
|
272
281
|
function createExtension(options) {
|
|
273
282
|
var _a, _b;
|
|
274
283
|
return {
|
|
275
284
|
$$type: "@backstage/ExtensionDefinition",
|
|
285
|
+
version: "v1",
|
|
276
286
|
kind: options.kind,
|
|
277
287
|
namespace: options.namespace,
|
|
278
288
|
name: options.name,
|
|
@@ -303,8 +313,9 @@ function createExtensionInput(extensionData, config) {
|
|
|
303
313
|
|
|
304
314
|
function resolveExtensionDefinition(definition, context) {
|
|
305
315
|
var _a;
|
|
306
|
-
const
|
|
307
|
-
const
|
|
316
|
+
const internalDefinition = toInternalExtensionDefinition(definition);
|
|
317
|
+
const { name, kind, namespace: _, ...rest } = internalDefinition;
|
|
318
|
+
const namespace = (_a = internalDefinition.namespace) != null ? _a : context == null ? void 0 : context.namespace;
|
|
308
319
|
const namePart = name && namespace ? `${namespace}/${name}` : namespace || name;
|
|
309
320
|
if (!namePart) {
|
|
310
321
|
throw new Error(
|
|
@@ -313,8 +324,9 @@ function resolveExtensionDefinition(definition, context) {
|
|
|
313
324
|
}
|
|
314
325
|
return {
|
|
315
326
|
...rest,
|
|
316
|
-
|
|
317
|
-
|
|
327
|
+
$$type: "@backstage/Extension",
|
|
328
|
+
version: "v1",
|
|
329
|
+
id: kind ? `${kind}:${namePart}` : namePart
|
|
318
330
|
};
|
|
319
331
|
}
|
|
320
332
|
|
|
@@ -365,11 +377,11 @@ function createApiExtension(options) {
|
|
|
365
377
|
// Since ApiRef IDs use a global namespace we use the namespace here in order to override
|
|
366
378
|
// potential plugin IDs and always end up with the format `api:<api-ref-id>`
|
|
367
379
|
namespace: apiRef.id,
|
|
368
|
-
attachTo: { id: "
|
|
380
|
+
attachTo: { id: "app", input: "apis" },
|
|
369
381
|
inputs: extensionInputs,
|
|
370
382
|
configSchema,
|
|
371
383
|
output: {
|
|
372
|
-
api:
|
|
384
|
+
api: createApiExtension.factoryDataRef
|
|
373
385
|
},
|
|
374
386
|
factory({ config, inputs }) {
|
|
375
387
|
if (typeof factory === "function") {
|
|
@@ -379,6 +391,9 @@ function createApiExtension(options) {
|
|
|
379
391
|
}
|
|
380
392
|
});
|
|
381
393
|
}
|
|
394
|
+
((createApiExtension2) => {
|
|
395
|
+
createApiExtension2.factoryDataRef = createExtensionDataRef("core.api.factory");
|
|
396
|
+
})(createApiExtension || (createApiExtension = {}));
|
|
382
397
|
|
|
383
398
|
function createSchemaFromZod(schemaCreator) {
|
|
384
399
|
const schema = schemaCreator(z);
|
|
@@ -418,7 +433,7 @@ function createPageExtension(options) {
|
|
|
418
433
|
kind: "page",
|
|
419
434
|
namespace: options.namespace,
|
|
420
435
|
name: options.name,
|
|
421
|
-
attachTo: (_a = options.attachTo) != null ? _a : { id: "
|
|
436
|
+
attachTo: (_a = options.attachTo) != null ? _a : { id: "app/routes", input: "routes" },
|
|
422
437
|
configSchema,
|
|
423
438
|
inputs: options.inputs,
|
|
424
439
|
disabled: options.disabled,
|
|
@@ -446,14 +461,14 @@ function createNavItemExtension(options) {
|
|
|
446
461
|
namespace,
|
|
447
462
|
name,
|
|
448
463
|
kind: "nav-item",
|
|
449
|
-
attachTo: { id: "
|
|
464
|
+
attachTo: { id: "app/nav", input: "items" },
|
|
450
465
|
configSchema: createSchemaFromZod(
|
|
451
466
|
(z) => z.object({
|
|
452
467
|
title: z.string().default(title)
|
|
453
468
|
})
|
|
454
469
|
),
|
|
455
470
|
output: {
|
|
456
|
-
navTarget:
|
|
471
|
+
navTarget: createNavItemExtension.targetDataRef
|
|
457
472
|
},
|
|
458
473
|
factory: ({ config }) => ({
|
|
459
474
|
navTarget: {
|
|
@@ -464,20 +479,46 @@ function createNavItemExtension(options) {
|
|
|
464
479
|
})
|
|
465
480
|
});
|
|
466
481
|
}
|
|
482
|
+
((createNavItemExtension2) => {
|
|
483
|
+
createNavItemExtension2.targetDataRef = createExtensionDataRef("core.nav-item.target");
|
|
484
|
+
})(createNavItemExtension || (createNavItemExtension = {}));
|
|
485
|
+
|
|
486
|
+
function createNavLogoExtension(options) {
|
|
487
|
+
const { logoIcon, logoFull } = options;
|
|
488
|
+
return createExtension({
|
|
489
|
+
kind: "nav-logo",
|
|
490
|
+
name: options == null ? void 0 : options.name,
|
|
491
|
+
namespace: options == null ? void 0 : options.namespace,
|
|
492
|
+
attachTo: { id: "app/nav", input: "logos" },
|
|
493
|
+
output: {
|
|
494
|
+
logos: createNavLogoExtension.logoElementsDataRef
|
|
495
|
+
},
|
|
496
|
+
factory: () => {
|
|
497
|
+
return {
|
|
498
|
+
logos: {
|
|
499
|
+
logoIcon,
|
|
500
|
+
logoFull
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
((createNavLogoExtension2) => {
|
|
507
|
+
createNavLogoExtension2.logoElementsDataRef = createExtensionDataRef("core.nav-logo.logo-elements");
|
|
508
|
+
})(createNavLogoExtension || (createNavLogoExtension = {}));
|
|
467
509
|
|
|
468
|
-
const signInPageComponentDataRef = createExtensionDataRef("core.signInPage");
|
|
469
510
|
function createSignInPageExtension(options) {
|
|
470
511
|
var _a;
|
|
471
512
|
return createExtension({
|
|
472
513
|
kind: "sign-in-page",
|
|
473
514
|
namespace: options == null ? void 0 : options.namespace,
|
|
474
515
|
name: options == null ? void 0 : options.name,
|
|
475
|
-
attachTo: (_a = options.attachTo) != null ? _a : { id: "
|
|
516
|
+
attachTo: (_a = options.attachTo) != null ? _a : { id: "app/router", input: "signInPage" },
|
|
476
517
|
configSchema: options.configSchema,
|
|
477
518
|
inputs: options.inputs,
|
|
478
519
|
disabled: options.disabled,
|
|
479
520
|
output: {
|
|
480
|
-
component:
|
|
521
|
+
component: createSignInPageExtension.componentDataRef
|
|
481
522
|
},
|
|
482
523
|
factory({ config, inputs, node }) {
|
|
483
524
|
const ExtensionComponent = lazy(
|
|
@@ -489,41 +530,47 @@ function createSignInPageExtension(options) {
|
|
|
489
530
|
}
|
|
490
531
|
});
|
|
491
532
|
}
|
|
533
|
+
((createSignInPageExtension2) => {
|
|
534
|
+
createSignInPageExtension2.componentDataRef = createExtensionDataRef("core.sign-in-page.component");
|
|
535
|
+
})(createSignInPageExtension || (createSignInPageExtension = {}));
|
|
492
536
|
|
|
493
537
|
function createThemeExtension(theme) {
|
|
494
538
|
return createExtension({
|
|
495
539
|
kind: "theme",
|
|
496
540
|
namespace: "app",
|
|
497
541
|
name: theme.id,
|
|
498
|
-
attachTo: { id: "
|
|
542
|
+
attachTo: { id: "app", input: "themes" },
|
|
499
543
|
output: {
|
|
500
|
-
theme:
|
|
544
|
+
theme: createThemeExtension.themeDataRef
|
|
501
545
|
},
|
|
502
546
|
factory: () => ({ theme })
|
|
503
547
|
});
|
|
504
548
|
}
|
|
549
|
+
((createThemeExtension2) => {
|
|
550
|
+
createThemeExtension2.themeDataRef = createExtensionDataRef("core.theme.theme");
|
|
551
|
+
})(createThemeExtension || (createThemeExtension = {}));
|
|
505
552
|
|
|
506
553
|
function createComponentExtension(options) {
|
|
507
554
|
return createExtension({
|
|
508
555
|
kind: "component",
|
|
509
556
|
namespace: options.ref.id,
|
|
510
557
|
name: options.name,
|
|
511
|
-
attachTo: { id: "
|
|
558
|
+
attachTo: { id: "app", input: "components" },
|
|
512
559
|
inputs: options.inputs,
|
|
513
560
|
disabled: options.disabled,
|
|
514
561
|
configSchema: options.configSchema,
|
|
515
562
|
output: {
|
|
516
|
-
component:
|
|
563
|
+
component: createComponentExtension.componentDataRef
|
|
517
564
|
},
|
|
518
565
|
factory({ config, inputs, node }) {
|
|
519
566
|
let ExtensionComponent;
|
|
520
|
-
if ("sync" in options.
|
|
521
|
-
ExtensionComponent = options.
|
|
567
|
+
if ("sync" in options.loader) {
|
|
568
|
+
ExtensionComponent = options.loader.sync({ config, inputs });
|
|
522
569
|
} else {
|
|
523
|
-
const lazyLoader = options.
|
|
570
|
+
const lazyLoader = options.loader.lazy;
|
|
524
571
|
ExtensionComponent = lazy(
|
|
525
|
-
() => lazyLoader({ config, inputs }).then((
|
|
526
|
-
default:
|
|
572
|
+
() => lazyLoader({ config, inputs }).then((Component) => ({
|
|
573
|
+
default: Component
|
|
527
574
|
}))
|
|
528
575
|
);
|
|
529
576
|
}
|
|
@@ -536,13 +583,16 @@ function createComponentExtension(options) {
|
|
|
536
583
|
}
|
|
537
584
|
});
|
|
538
585
|
}
|
|
586
|
+
((createComponentExtension2) => {
|
|
587
|
+
createComponentExtension2.componentDataRef = createExtensionDataRef("core.component.component");
|
|
588
|
+
})(createComponentExtension || (createComponentExtension = {}));
|
|
539
589
|
|
|
540
590
|
function createTranslationExtension(options) {
|
|
541
591
|
return createExtension({
|
|
542
592
|
kind: "translation",
|
|
543
593
|
namespace: options.resource.id,
|
|
544
594
|
name: options.name,
|
|
545
|
-
attachTo: { id: "
|
|
595
|
+
attachTo: { id: "app", input: "translations" },
|
|
546
596
|
output: {
|
|
547
597
|
resource: createTranslationExtension.translationDataRef
|
|
548
598
|
},
|
|
@@ -550,7 +600,7 @@ function createTranslationExtension(options) {
|
|
|
550
600
|
});
|
|
551
601
|
}
|
|
552
602
|
((createTranslationExtension2) => {
|
|
553
|
-
createTranslationExtension2.translationDataRef = createExtensionDataRef("core.
|
|
603
|
+
createTranslationExtension2.translationDataRef = createExtensionDataRef("core.translation.translation");
|
|
554
604
|
})(createTranslationExtension || (createTranslationExtension = {}));
|
|
555
605
|
|
|
556
606
|
const MESSAGE_MARKER = "eHgtF5hmbrXyiEvo";
|
|
@@ -791,5 +841,5 @@ function useRouteRefParams(_routeRef) {
|
|
|
791
841
|
return useParams();
|
|
792
842
|
}
|
|
793
843
|
|
|
794
|
-
export { AnalyticsContext, ExtensionBoundary, analyticsApiRef, appTreeApiRef, componentsApiRef, coreComponentRefs, coreExtensionData, createApiExtension, createComponentExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSignInPageExtension, createSubRouteRef, createThemeExtension, createTranslationExtension, useAnalytics, useComponentRef, useRouteRef, useRouteRefParams };
|
|
844
|
+
export { AnalyticsContext, ExtensionBoundary, analyticsApiRef, appTreeApiRef, componentsApiRef, coreComponentRefs, coreExtensionData, createApiExtension, createComponentExtension, createExtension, createExtensionDataRef, createExtensionInput, createExtensionOverrides, createExternalRouteRef, createNavItemExtension, createNavLogoExtension, createPageExtension, createPlugin, createRouteRef, createSchemaFromZod, createSignInPageExtension, createSubRouteRef, createThemeExtension, createTranslationExtension, useAnalytics, useComponentRef, useRouteRef, useRouteRefParams };
|
|
795
845
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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/resolveExtensionDefinition.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/extensions/createTranslationExtension.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 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 { ComponentType } from 'react';\nimport { createApiRef, useApi } from '@backstage/core-plugin-api';\nimport { ComponentRef } from '../../components';\n\n/**\n * API for looking up components based on component refs.\n *\n * @public\n */\nexport interface ComponentsApi {\n // TODO: Should component refs also provide the default implementation so that we're guaranteed to get a component?\n getComponent<T extends {}>(ref: ComponentRef<T>): ComponentType<T>;\n}\n\n/**\n * The `ApiRef` of {@link ComponentsApi}.\n *\n * @public\n */\nexport const componentsApiRef = createApiRef<ComponentsApi>({\n id: 'core.components',\n});\n\n/**\n * @public\n * Returns the component associated with the given ref.\n */\nexport function useComponentRef<T extends {}>(\n ref: ComponentRef<T>,\n): ComponentType<T> {\n const componentsApi = useApi(componentsApiRef);\n return componentsApi.getComponent<T>(ref);\n}\n","/*\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 CoreErrorBoundaryFallbackProps,\n CoreNotFoundErrorPageProps,\n CoreProgressProps,\n} from '../types';\n\n/** @public */\nexport type ComponentRef<T extends {} = {}> = {\n id: string;\n T: T;\n};\n\n/** @public */\nexport function createComponentRef<T extends {} = {}>(options: {\n id: string;\n}): ComponentRef<T> {\n const { id } = options;\n return {\n id,\n } as ComponentRef<T>;\n}\n\nconst coreProgressComponentRef = createComponentRef<CoreProgressProps>({\n id: 'core.components.progress',\n});\n\nconst coreNotFoundErrorPageComponentRef =\n createComponentRef<CoreNotFoundErrorPageProps>({\n id: 'core.components.notFoundErrorPage',\n });\n\nconst coreErrorBoundaryFallbackComponentRef =\n createComponentRef<CoreErrorBoundaryFallbackProps>({\n id: 'core.components.errorBoundaryFallback',\n });\n\n/** @public */\nexport const coreComponentRefs = {\n progress: coreProgressComponentRef,\n notFoundErrorPage: coreNotFoundErrorPageComponentRef,\n errorBoundaryFallback: coreErrorBoundaryFallbackComponentRef,\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { Component, ComponentType, PropsWithChildren } from 'react';\nimport { BackstagePlugin } from '../wiring';\nimport { CoreErrorBoundaryFallbackProps } from '../types';\n\ntype ErrorBoundaryProps = PropsWithChildren<{\n plugin?: BackstagePlugin;\n Fallback: ComponentType<CoreErrorBoundaryFallbackProps>;\n}>;\ntype ErrorBoundaryState = { error?: Error };\n\n/** @internal */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n state: ErrorBoundaryState = { error: undefined };\n\n handleErrorReset = () => {\n this.setState({ error: undefined });\n };\n\n render() {\n const { error } = this.state;\n const { plugin, children, Fallback } = this.props;\n\n if (error) {\n return (\n <Fallback\n plugin={plugin}\n error={error}\n resetError={this.handleErrorReset}\n />\n );\n }\n\n return children;\n }\n}\n","/*\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, useComponentRef } from '../apis';\nimport { coreComponentRefs } from './ComponentRef';\n\ntype RouteTrackerProps = PropsWithChildren<{\n disableTracking?: boolean;\n}>;\n\nconst RouteTracker = (props: RouteTrackerProps) => {\n const { disableTracking, children } = props;\n const analytics = useAnalytics();\n\n // This event, never exposed to end-users of the analytics API,\n // helps inform which extension metadata gets associated with a\n // navigation event when the route navigated to is a gathered\n // mountpoint.\n useEffect(() => {\n if (disableTracking) return;\n analytics.captureEvent(routableExtensionRenderedEvent, '');\n }, [analytics, disableTracking]);\n\n return <>{children}</>;\n};\n\n/** @public */\nexport interface ExtensionBoundaryProps {\n node: AppNode;\n routable?: boolean;\n children: ReactNode;\n}\n\n/** @public */\nexport function ExtensionBoundary(props: ExtensionBoundaryProps) {\n const { node, routable, children } = props;\n\n const plugin = node.spec.source;\n const Progress = useComponentRef(coreComponentRefs.progress);\n const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback);\n\n // Skipping \"routeRef\" attribute in the new system, the extension \"id\" should provide more insight\n const attributes = {\n extensionId: node.spec.id,\n pluginId: node.spec.source?.id,\n };\n\n return (\n <Suspense fallback={<Progress />}>\n <ErrorBoundary plugin={plugin} Fallback={fallback}>\n <AnalyticsContext attributes={attributes}>\n <RouteTracker disableTracking={!routable}>{children}</RouteTracker>\n </AnalyticsContext>\n </ErrorBoundary>\n </Suspense>\n );\n}\n","/*\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;\n impl: ComponentType;\n }>('core.component'),\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 * Convert a single extension input into a matching resolved input.\n * @public\n */\nexport type ResolvedExtensionInput<TExtensionData extends AnyExtensionDataMap> =\n {\n node: AppNode;\n output: ExtensionDataValues<TExtensionData>;\n };\n\n/**\n * Converts an extension input map into a matching collection of resolved inputs.\n * @public\n */\nexport type ResolvedExtensionInputs<\n TInputs extends { [name in string]: ExtensionInput<any, any> },\n> = {\n [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']\n ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>>\n : false extends TInputs[InputName]['config']['optional']\n ? Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>\n : Expand<\n ResolvedExtensionInput<TInputs[InputName]['extensionData']> | undefined\n >;\n};\n\n/** @public */\nexport interface CreateExtensionOptions<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig,\n> {\n kind?: string;\n namespace?: string;\n name?: 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<ResolvedExtensionInputs<TInputs>>;\n }): Expand<ExtensionDataValues<TOutput>>;\n}\n\n/** @public */\nexport interface ExtensionDefinition<TConfig> {\n $$type: '@backstage/ExtensionDefinition';\n kind?: string;\n namespace?: string;\n name?: 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: ResolvedExtensionInputs<any>;\n }): ExtensionDataValues<any>;\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: ResolvedExtensionInputs<any>;\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): ExtensionDefinition<TConfig> {\n return {\n $$type: '@backstage/ExtensionDefinition',\n kind: options.kind,\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo,\n disabled: options.disabled ?? false,\n inputs: options.inputs ?? {},\n output: options.output,\n configSchema: options.configSchema,\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<ResolvedExtensionInputs<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, ExtensionDefinition } from './createExtension';\n\n/** @internal */\nexport function resolveExtensionDefinition<TConfig>(\n definition: ExtensionDefinition<TConfig>,\n context?: { namespace?: string },\n): Extension<TConfig> {\n const { name, kind, namespace: _, ...rest } = definition;\n const namespace = definition.namespace ?? context?.namespace;\n\n const namePart =\n name && namespace ? `${namespace}/${name}` : namespace || name;\n if (!namePart) {\n throw new Error(\n `Extension must declare an explicit namespace or name as it could not be resolved from context, kind=${kind} namespace=${namespace} name=${name}`,\n );\n }\n\n return {\n ...rest,\n id: kind ? `${kind}:${namePart}` : namePart,\n $$type: '@backstage/Extension',\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, ExtensionDefinition } from './createExtension';\nimport { ExternalRouteRef, RouteRef } from '../routing';\nimport { FeatureFlagConfig } from './types';\nimport { resolveExtensionDefinition } from './resolveExtensionDefinition';\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?: ExtensionDefinition<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 const extensions = (options.extensions ?? []).map(def =>\n resolveExtensionDefinition(def, { namespace: options.id }),\n );\n\n const extensionIds = extensions.map(e => e.id);\n if (extensionIds.length !== new Set(extensionIds).size) {\n const duplicates = Array.from(\n new Set(\n extensionIds.filter((id, index) => extensionIds.indexOf(id) !== index),\n ),\n );\n // TODO(Rugvip): This could provide some more information about the kind + name of the extensions\n throw new Error(\n `Plugin '${options.id}' provided duplicate extensions: ${duplicates.join(\n ', ',\n )}`,\n );\n }\n\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 featureFlags: options.featureFlags ?? [],\n extensions,\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, ExtensionDefinition } from './createExtension';\nimport { resolveExtensionDefinition } from './resolveExtensionDefinition';\nimport { FeatureFlagConfig } from './types';\n\n/** @public */\nexport interface ExtensionOverridesOptions {\n extensions: ExtensionDefinition<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.map(def => resolveExtensionDefinition(def)),\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 ResolvedExtensionInputs,\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<ResolvedExtensionInputs<TInputs>>;\n }) => AnyApiFactory;\n }\n | {\n factory: AnyApiFactory;\n }\n ) & {\n configSchema?: PortableSchema<TConfig>;\n inputs?: TInputs;\n },\n) {\n const { factory, configSchema, inputs: extensionInputs } = options;\n\n const apiRef =\n 'api' in options ? options.api : (factory as { api: AnyApiRef }).api;\n\n return createExtension({\n kind: 'api',\n // Since ApiRef IDs use a global namespace we use the namespace here in order to override\n // potential plugin IDs and always end up with the format `api:<api-ref-id>`\n namespace: apiRef.id,\n attachTo: { id: '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 ResolvedExtensionInputs,\n AnyExtensionInputMap,\n} from '../wiring';\nimport { RouteRef } from '../routing';\nimport { Expand } from '../types';\nimport { ExtensionDefinition } from '../wiring/createExtension';\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 namespace?: string;\n name?: 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<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<JSX.Element>;\n },\n): ExtensionDefinition<TConfig> {\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 kind: 'page',\n namespace: options.namespace,\n name: options.name,\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 namespace?: string;\n name?: string;\n routeRef: RouteRef<undefined>;\n title: string;\n icon: IconComponent;\n}) {\n const { routeRef, title, icon, namespace, name } = options;\n return createExtension({\n namespace,\n name,\n kind: 'nav-item',\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 ResolvedExtensionInputs,\n AnyExtensionInputMap,\n createExtensionDataRef,\n ExtensionDefinition,\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 namespace?: string;\n name?: 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<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<ComponentType<SignInPageProps>>;\n}): ExtensionDefinition<TConfig> {\n return createExtension({\n kind: 'sign-in-page',\n namespace: options?.namespace,\n name: options?.name,\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 kind: 'theme',\n namespace: 'app',\n name: 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, ComponentType } from 'react';\nimport {\n AnyExtensionInputMap,\n ResolvedExtensionInputs,\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 TProps extends {},\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(options: {\n ref: ComponentRef<TProps>;\n name?: string;\n disabled?: boolean;\n inputs?: TInputs;\n configSchema?: PortableSchema<TConfig>;\n component:\n | {\n lazy: (values: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<ComponentType<TProps>>;\n }\n | {\n sync: (values: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => ComponentType<TProps>;\n };\n}) {\n return createExtension({\n kind: 'component',\n namespace: options.ref.id,\n name: options.name,\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: ComponentType<TProps>;\n\n if ('sync' in options.component) {\n ExtensionComponent = options.component.sync({ config, inputs });\n } else {\n const lazyLoader = options.component.lazy;\n ExtensionComponent = lazy(() =>\n lazyLoader({ config, inputs }).then(component => ({\n default: component,\n })),\n ) as unknown as ComponentType<TProps>;\n }\n\n return {\n component: {\n ref: options.ref,\n impl: props => (\n <ExtensionBoundary node={node}>\n <ExtensionComponent {...(props as TProps)} />\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\nimport { TranslationMessages, TranslationResource } from '../translation';\nimport { createExtension, createExtensionDataRef } from '../wiring';\n\n/** @public */\nexport function createTranslationExtension(options: {\n name?: string;\n resource: TranslationResource | TranslationMessages;\n}) {\n return createExtension({\n kind: 'translation',\n namespace: options.resource.id,\n name: options.name,\n attachTo: { id: 'core', input: 'translations' },\n output: {\n resource: createTranslationExtension.translationDataRef,\n },\n factory: () => ({ resource: options.resource }),\n });\n}\n\n/** @public */\nexport namespace createTranslationExtension {\n export const translationDataRef = createExtensionDataRef<\n TranslationResource | TranslationMessages\n >('core.translationResource');\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","createTranslationExtension","_params","__privateAdd","__privateSet","__privateGet"],"mappings":"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"}
|
|
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/resolveExtensionDefinition.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/createNavLogoExtension.tsx","../src/extensions/createSignInPageExtension.tsx","../src/extensions/createThemeExtension.ts","../src/extensions/createComponentExtension.tsx","../src/extensions/createTranslationExtension.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 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 { ComponentType } from 'react';\nimport { createApiRef, useApi } from '@backstage/core-plugin-api';\nimport { ComponentRef } from '../../components';\n\n/**\n * API for looking up components based on component refs.\n *\n * @public\n */\nexport interface ComponentsApi {\n // TODO: Should component refs also provide the default implementation so that we're guaranteed to get a component?\n getComponent<T extends {}>(ref: ComponentRef<T>): ComponentType<T>;\n}\n\n/**\n * The `ApiRef` of {@link ComponentsApi}.\n *\n * @public\n */\nexport const componentsApiRef = createApiRef<ComponentsApi>({\n id: 'core.components',\n});\n\n/**\n * @public\n * Returns the component associated with the given ref.\n */\nexport function useComponentRef<T extends {}>(\n ref: ComponentRef<T>,\n): ComponentType<T> {\n const componentsApi = useApi(componentsApiRef);\n return componentsApi.getComponent<T>(ref);\n}\n","/*\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 CoreErrorBoundaryFallbackProps,\n CoreNotFoundErrorPageProps,\n CoreProgressProps,\n} from '../types';\n\n/** @public */\nexport type ComponentRef<T extends {} = {}> = {\n id: string;\n T: T;\n};\n\n/** @public */\nexport function createComponentRef<T extends {} = {}>(options: {\n id: string;\n}): ComponentRef<T> {\n const { id } = options;\n return {\n id,\n } as ComponentRef<T>;\n}\n\nconst coreProgressComponentRef = createComponentRef<CoreProgressProps>({\n id: 'core.components.progress',\n});\n\nconst coreNotFoundErrorPageComponentRef =\n createComponentRef<CoreNotFoundErrorPageProps>({\n id: 'core.components.notFoundErrorPage',\n });\n\nconst coreErrorBoundaryFallbackComponentRef =\n createComponentRef<CoreErrorBoundaryFallbackProps>({\n id: 'core.components.errorBoundaryFallback',\n });\n\n/** @public */\nexport const coreComponentRefs = {\n progress: coreProgressComponentRef,\n notFoundErrorPage: coreNotFoundErrorPageComponentRef,\n errorBoundaryFallback: coreErrorBoundaryFallbackComponentRef,\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { Component, ComponentType, PropsWithChildren } from 'react';\nimport { BackstagePlugin } from '../wiring';\nimport { CoreErrorBoundaryFallbackProps } from '../types';\n\ntype ErrorBoundaryProps = PropsWithChildren<{\n plugin?: BackstagePlugin;\n Fallback: ComponentType<CoreErrorBoundaryFallbackProps>;\n}>;\ntype ErrorBoundaryState = { error?: Error };\n\n/** @internal */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n state: ErrorBoundaryState = { error: undefined };\n\n handleErrorReset = () => {\n this.setState({ error: undefined });\n };\n\n render() {\n const { error } = this.state;\n const { plugin, children, Fallback } = this.props;\n\n if (error) {\n return (\n <Fallback\n plugin={plugin}\n error={error}\n resetError={this.handleErrorReset}\n />\n );\n }\n\n return children;\n }\n}\n","/*\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, useComponentRef } from '../apis';\nimport { coreComponentRefs } from './ComponentRef';\n\ntype RouteTrackerProps = PropsWithChildren<{\n disableTracking?: boolean;\n}>;\n\nconst RouteTracker = (props: RouteTrackerProps) => {\n const { disableTracking, children } = props;\n const analytics = useAnalytics();\n\n // This event, never exposed to end-users of the analytics API,\n // helps inform which extension metadata gets associated with a\n // navigation event when the route navigated to is a gathered\n // mountpoint.\n useEffect(() => {\n if (disableTracking) return;\n analytics.captureEvent(routableExtensionRenderedEvent, '');\n }, [analytics, disableTracking]);\n\n return <>{children}</>;\n};\n\n/** @public */\nexport interface ExtensionBoundaryProps {\n node: AppNode;\n routable?: boolean;\n children: ReactNode;\n}\n\n/** @public */\nexport function ExtensionBoundary(props: ExtensionBoundaryProps) {\n const { node, routable, children } = props;\n\n const plugin = node.spec.source;\n const Progress = useComponentRef(coreComponentRefs.progress);\n const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback);\n\n // Skipping \"routeRef\" attribute in the new system, the extension \"id\" should provide more insight\n const attributes = {\n extensionId: node.spec.id,\n pluginId: node.spec.source?.id,\n };\n\n return (\n <Suspense fallback={<Progress />}>\n <ErrorBoundary plugin={plugin} Fallback={fallback}>\n <AnalyticsContext attributes={attributes}>\n <RouteTracker disableTracking={!routable}>{children}</RouteTracker>\n </AnalyticsContext>\n </ErrorBoundary>\n </Suspense>\n );\n}\n","/*\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 { RouteRef } from '../routing';\nimport { createExtensionDataRef } from './createExtensionDataRef';\n\n/** @public */\nexport const coreExtensionData = {\n reactElement: createExtensionDataRef<JSX.Element>('core.reactElement'),\n routePath: createExtensionDataRef<string>('core.routing.path'),\n routeRef: createExtensionDataRef<RouteRef>('core.routing.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 * Convert a single extension input into a matching resolved input.\n * @public\n */\nexport type ResolvedExtensionInput<TExtensionData extends AnyExtensionDataMap> =\n {\n node: AppNode;\n output: ExtensionDataValues<TExtensionData>;\n };\n\n/**\n * Converts an extension input map into a matching collection of resolved inputs.\n * @public\n */\nexport type ResolvedExtensionInputs<\n TInputs extends { [name in string]: ExtensionInput<any, any> },\n> = {\n [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']\n ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>>\n : false extends TInputs[InputName]['config']['optional']\n ? Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>\n : Expand<\n ResolvedExtensionInput<TInputs[InputName]['extensionData']> | undefined\n >;\n};\n\n/** @public */\nexport interface CreateExtensionOptions<\n TOutput extends AnyExtensionDataMap,\n TInputs extends AnyExtensionInputMap,\n TConfig,\n> {\n kind?: string;\n namespace?: string;\n name?: 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<ResolvedExtensionInputs<TInputs>>;\n }): Expand<ExtensionDataValues<TOutput>>;\n}\n\n/** @public */\nexport interface ExtensionDefinition<TConfig> {\n $$type: '@backstage/ExtensionDefinition';\n readonly kind?: string;\n readonly namespace?: string;\n readonly name?: string;\n readonly attachTo: { id: string; input: string };\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<TConfig>;\n}\n\n/** @internal */\nexport interface InternalExtensionDefinition<TConfig>\n extends ExtensionDefinition<TConfig> {\n readonly version: 'v1';\n readonly inputs: AnyExtensionInputMap;\n readonly output: AnyExtensionDataMap;\n factory(options: {\n node: AppNode;\n config: TConfig;\n inputs: ResolvedExtensionInputs<any>;\n }): ExtensionDataValues<any>;\n}\n\n/** @internal */\nexport function toInternalExtensionDefinition<TConfig>(\n overrides: ExtensionDefinition<TConfig>,\n): InternalExtensionDefinition<TConfig> {\n const internal = overrides as InternalExtensionDefinition<TConfig>;\n if (internal.$$type !== '@backstage/ExtensionDefinition') {\n throw new Error(\n `Invalid extension definition instance, bad type '${internal.$$type}'`,\n );\n }\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid extension definition instance, bad version '${internal.version}'`,\n );\n }\n return internal;\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): ExtensionDefinition<TConfig> {\n return {\n $$type: '@backstage/ExtensionDefinition',\n version: 'v1',\n kind: options.kind,\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo,\n disabled: options.disabled ?? false,\n inputs: options.inputs ?? {},\n output: options.output,\n configSchema: options.configSchema,\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<ResolvedExtensionInputs<TInputs>>,\n ...rest,\n });\n },\n } as InternalExtensionDefinition<TConfig>;\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 { AppNode } from '../apis';\nimport {\n AnyExtensionDataMap,\n AnyExtensionInputMap,\n ExtensionDataValues,\n ExtensionDefinition,\n ResolvedExtensionInputs,\n toInternalExtensionDefinition,\n} from './createExtension';\nimport { PortableSchema } from '../schema';\n\n/** @public */\nexport interface Extension<TConfig> {\n $$type: '@backstage/Extension';\n readonly id: string;\n readonly attachTo: { id: string; input: string };\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<TConfig>;\n}\n\n/** @internal */\nexport interface InternalExtension<TConfig> extends Extension<TConfig> {\n readonly version: 'v1';\n readonly inputs: AnyExtensionInputMap;\n readonly output: AnyExtensionDataMap;\n factory(options: {\n node: AppNode;\n config: TConfig;\n inputs: ResolvedExtensionInputs<any>;\n }): ExtensionDataValues<any>;\n}\n\n/** @internal */\nexport function toInternalExtension<TConfig>(\n overrides: Extension<TConfig>,\n): InternalExtension<TConfig> {\n const internal = overrides as InternalExtension<TConfig>;\n if (internal.$$type !== '@backstage/Extension') {\n throw new Error(\n `Invalid extension instance, bad type '${internal.$$type}'`,\n );\n }\n if (internal.version !== 'v1') {\n throw new Error(\n `Invalid extension instance, bad version '${internal.version}'`,\n );\n }\n return internal;\n}\n\n/** @internal */\nexport function resolveExtensionDefinition<TConfig>(\n definition: ExtensionDefinition<TConfig>,\n context?: { namespace?: string },\n): Extension<TConfig> {\n const internalDefinition = toInternalExtensionDefinition(definition);\n const { name, kind, namespace: _, ...rest } = internalDefinition;\n const namespace = internalDefinition.namespace ?? context?.namespace;\n\n const namePart =\n name && namespace ? `${namespace}/${name}` : namespace || name;\n if (!namePart) {\n throw new Error(\n `Extension must declare an explicit namespace or name as it could not be resolved from context, kind=${kind} namespace=${namespace} name=${name}`,\n );\n }\n\n return {\n ...rest,\n $$type: '@backstage/Extension',\n version: 'v1',\n id: kind ? `${kind}:${namePart}` : namePart,\n } as InternalExtension<TConfig>;\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 { ExtensionDefinition } from './createExtension';\nimport {\n Extension,\n resolveExtensionDefinition,\n} from './resolveExtensionDefinition';\nimport {\n AnyExternalRoutes,\n AnyRoutes,\n BackstagePlugin,\n FeatureFlagConfig,\n} from './types';\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?: ExtensionDefinition<unknown>[];\n featureFlags?: FeatureFlagConfig[];\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 const extensions = (options.extensions ?? []).map(def =>\n resolveExtensionDefinition(def, { namespace: options.id }),\n );\n\n const extensionIds = extensions.map(e => e.id);\n if (extensionIds.length !== new Set(extensionIds).size) {\n const duplicates = Array.from(\n new Set(\n extensionIds.filter((id, index) => extensionIds.indexOf(id) !== index),\n ),\n );\n // TODO(Rugvip): This could provide some more information about the kind + name of the extensions\n throw new Error(\n `Plugin '${options.id}' provided duplicate extensions: ${duplicates.join(\n ', ',\n )}`,\n );\n }\n\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 featureFlags: options.featureFlags ?? [],\n extensions,\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 { ExtensionDefinition } from './createExtension';\nimport {\n Extension,\n resolveExtensionDefinition,\n} from './resolveExtensionDefinition';\nimport { ExtensionOverrides, FeatureFlagConfig } from './types';\n\n/** @public */\nexport interface ExtensionOverridesOptions {\n extensions: ExtensionDefinition<unknown>[];\n featureFlags?: FeatureFlagConfig[];\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.map(def => resolveExtensionDefinition(def)),\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 ResolvedExtensionInputs,\n createExtension,\n createExtensionDataRef,\n} from '../wiring';\nimport { AnyExtensionInputMap } from '../wiring/createExtension';\nimport { Expand } from '../types';\n\n/** @public */\nexport function createApiExtension<\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(\n options: (\n | {\n api: AnyApiRef;\n factory: (options: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => AnyApiFactory;\n }\n | {\n factory: AnyApiFactory;\n }\n ) & {\n configSchema?: PortableSchema<TConfig>;\n inputs?: TInputs;\n },\n) {\n const { factory, configSchema, inputs: extensionInputs } = options;\n\n const apiRef =\n 'api' in options ? options.api : (factory as { api: AnyApiRef }).api;\n\n return createExtension({\n kind: 'api',\n // Since ApiRef IDs use a global namespace we use the namespace here in order to override\n // potential plugin IDs and always end up with the format `api:<api-ref-id>`\n namespace: apiRef.id,\n attachTo: { id: 'app', input: 'apis' },\n inputs: extensionInputs,\n configSchema,\n output: {\n api: createApiExtension.factoryDataRef,\n },\n factory({ config, inputs }) {\n if (typeof factory === 'function') {\n return { api: factory({ config, inputs }) };\n }\n return { api: factory };\n },\n });\n}\n\n/** @public */\nexport namespace createApiExtension {\n export const factoryDataRef =\n createExtensionDataRef<AnyApiFactory>('core.api.factory');\n}\n","/*\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 ResolvedExtensionInputs,\n AnyExtensionInputMap,\n} from '../wiring';\nimport { RouteRef } from '../routing';\nimport { Expand } from '../types';\nimport { ExtensionDefinition } from '../wiring/createExtension';\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 namespace?: string;\n name?: 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<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<JSX.Element>;\n },\n): ExtensionDefinition<TConfig> {\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 kind: 'page',\n namespace: options.namespace,\n name: options.name,\n attachTo: options.attachTo ?? { id: 'app/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 { createExtension, createExtensionDataRef } 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 namespace?: string;\n name?: string;\n routeRef: RouteRef<undefined>;\n title: string;\n icon: IconComponent;\n}) {\n const { routeRef, title, icon, namespace, name } = options;\n return createExtension({\n namespace,\n name,\n kind: 'nav-item',\n attachTo: { id: 'app/nav', input: 'items' },\n configSchema: createSchemaFromZod(z =>\n z.object({\n title: z.string().default(title),\n }),\n ),\n output: {\n navTarget: createNavItemExtension.targetDataRef,\n },\n factory: ({ config }) => ({\n navTarget: {\n title: config.title,\n icon,\n routeRef,\n },\n }),\n });\n}\n\n/** @public */\nexport namespace createNavItemExtension {\n // TODO(Rugvip): Should this be broken apart into separate refs? title/icon/routeRef\n export const targetDataRef = createExtensionDataRef<{\n title: string;\n icon: IconComponent;\n routeRef: RouteRef<undefined>;\n }>('core.nav-item.target');\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, createExtensionDataRef } from '../wiring';\n\n/**\n * Helper for creating extensions for a nav logos.\n * @public\n */\nexport function createNavLogoExtension(options: {\n name?: string;\n namespace?: string;\n logoIcon: JSX.Element;\n logoFull: JSX.Element;\n}) {\n const { logoIcon, logoFull } = options;\n return createExtension({\n kind: 'nav-logo',\n name: options?.name,\n namespace: options?.namespace,\n attachTo: { id: 'app/nav', input: 'logos' },\n output: {\n logos: createNavLogoExtension.logoElementsDataRef,\n },\n factory: () => {\n return {\n logos: {\n logoIcon,\n logoFull,\n },\n };\n },\n });\n}\n\n/** @public */\nexport namespace createNavLogoExtension {\n export const logoElementsDataRef = createExtensionDataRef<{\n logoIcon?: JSX.Element;\n logoFull?: JSX.Element;\n }>('core.nav-logo.logo-elements');\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 ResolvedExtensionInputs,\n AnyExtensionInputMap,\n createExtensionDataRef,\n ExtensionDefinition,\n} from '../wiring';\nimport { Expand } from '../types';\nimport { SignInPageProps } from '@backstage/core-plugin-api';\n\n/**\n *\n * @public\n */\nexport function createSignInPageExtension<\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(options: {\n namespace?: string;\n name?: string;\n attachTo?: { id: string; input: string };\n configSchema?: PortableSchema<TConfig>;\n disabled?: boolean;\n inputs?: TInputs;\n loader: (options: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<ComponentType<SignInPageProps>>;\n}): ExtensionDefinition<TConfig> {\n return createExtension({\n kind: 'sign-in-page',\n namespace: options?.namespace,\n name: options?.name,\n attachTo: options.attachTo ?? { id: 'app/router', input: 'signInPage' },\n configSchema: options.configSchema,\n inputs: options.inputs,\n disabled: options.disabled,\n output: {\n component: createSignInPageExtension.componentDataRef,\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/** @public */\nexport namespace createSignInPageExtension {\n export const componentDataRef = createExtensionDataRef<\n ComponentType<SignInPageProps>\n >('core.sign-in-page.component');\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, createExtensionDataRef } from '../wiring';\nimport { AppTheme } from '@backstage/core-plugin-api';\n\n/** @public */\nexport function createThemeExtension(theme: AppTheme) {\n return createExtension({\n kind: 'theme',\n namespace: 'app',\n name: theme.id,\n attachTo: { id: 'app', input: 'themes' },\n output: {\n theme: createThemeExtension.themeDataRef,\n },\n factory: () => ({ theme }),\n });\n}\n\n/** @public */\nexport namespace createThemeExtension {\n export const themeDataRef =\n createExtensionDataRef<AppTheme>('core.theme.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 React, { lazy, ComponentType } from 'react';\nimport {\n AnyExtensionInputMap,\n ResolvedExtensionInputs,\n createExtension,\n createExtensionDataRef,\n} from '../wiring';\nimport { Expand } from '../types';\nimport { PortableSchema } from '../schema';\nimport { ExtensionBoundary, ComponentRef } from '../components';\n\n/** @public */\nexport function createComponentExtension<\n TProps extends {},\n TConfig extends {},\n TInputs extends AnyExtensionInputMap,\n>(options: {\n ref: ComponentRef<TProps>;\n name?: string;\n disabled?: boolean;\n inputs?: TInputs;\n configSchema?: PortableSchema<TConfig>;\n loader:\n | {\n lazy: (values: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => Promise<ComponentType<TProps>>;\n }\n | {\n sync: (values: {\n config: TConfig;\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }) => ComponentType<TProps>;\n };\n}) {\n return createExtension({\n kind: 'component',\n namespace: options.ref.id,\n name: options.name,\n attachTo: { id: 'app', input: 'components' },\n inputs: options.inputs,\n disabled: options.disabled,\n configSchema: options.configSchema,\n output: {\n component: createComponentExtension.componentDataRef,\n },\n factory({ config, inputs, node }) {\n let ExtensionComponent: ComponentType<TProps>;\n\n if ('sync' in options.loader) {\n ExtensionComponent = options.loader.sync({ config, inputs });\n } else {\n const lazyLoader = options.loader.lazy;\n ExtensionComponent = lazy(() =>\n lazyLoader({ config, inputs }).then(Component => ({\n default: Component,\n })),\n ) as unknown as ComponentType<TProps>;\n }\n\n return {\n component: {\n ref: options.ref,\n impl: props => (\n <ExtensionBoundary node={node}>\n <ExtensionComponent {...(props as TProps)} />\n </ExtensionBoundary>\n ),\n },\n };\n },\n });\n}\n\n/** @public */\nexport namespace createComponentExtension {\n export const componentDataRef = createExtensionDataRef<{\n ref: ComponentRef;\n impl: ComponentType;\n }>('core.component.component');\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 { TranslationMessages, TranslationResource } from '../translation';\nimport { createExtension, createExtensionDataRef } from '../wiring';\n\n/** @public */\nexport function createTranslationExtension(options: {\n name?: string;\n resource: TranslationResource | TranslationMessages;\n}) {\n return createExtension({\n kind: 'translation',\n namespace: options.resource.id,\n name: options.name,\n attachTo: { id: 'app', input: 'translations' },\n output: {\n resource: createTranslationExtension.translationDataRef,\n },\n factory: () => ({ resource: options.resource }),\n });\n}\n\n/** @public */\nexport namespace createTranslationExtension {\n export const translationDataRef = createExtensionDataRef<\n TranslationResource | TranslationMessages\n >('core.translation.translation');\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","createApiExtension","createNavItemExtension","createNavLogoExtension","createSignInPageExtension","createThemeExtension","createComponentExtension","createTranslationExtension","_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.4.0
|
|
3
|
+
"version": "0.4.0",
|
|
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.25.0
|
|
27
|
-
"@backstage/frontend-app-api": "^0.4.0
|
|
28
|
-
"@backstage/frontend-test-utils": "^0.1.0
|
|
29
|
-
"@backstage/test-utils": "^1.4.6
|
|
26
|
+
"@backstage/cli": "^0.25.0",
|
|
27
|
+
"@backstage/frontend-app-api": "^0.4.0",
|
|
28
|
+
"@backstage/frontend-test-utils": "^0.1.0",
|
|
29
|
+
"@backstage/test-utils": "^1.4.6",
|
|
30
30
|
"@testing-library/jest-dom": "^6.0.0",
|
|
31
31
|
"@testing-library/react": "^14.0.0",
|
|
32
32
|
"history": "^5.3.0"
|
|
@@ -40,14 +40,14 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@backstage/config": "^1.1.1",
|
|
43
|
-
"@backstage/core-components": "^0.13.9
|
|
44
|
-
"@backstage/core-plugin-api": "^1.8.1
|
|
43
|
+
"@backstage/core-components": "^0.13.9",
|
|
44
|
+
"@backstage/core-plugin-api": "^1.8.1",
|
|
45
45
|
"@backstage/types": "^1.1.1",
|
|
46
46
|
"@backstage/version-bridge": "^1.0.7",
|
|
47
47
|
"@material-ui/core": "^4.12.4",
|
|
48
48
|
"@types/react": "^16.13.1 || ^17.0.0",
|
|
49
49
|
"lodash": "^4.17.21",
|
|
50
|
-
"zod": "^3.
|
|
50
|
+
"zod": "^3.22.4",
|
|
51
51
|
"zod-to-json-schema": "^3.21.4"
|
|
52
52
|
},
|
|
53
53
|
"module": "./dist/index.esm.js"
|