@backstage/frontend-plugin-api 0.10.4-next.1 → 0.11.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,13 +2,14 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, JSX as JSX$1, ComponentType, PropsWithChildren } from 'react';
4
4
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
5
- import { ApiHolder, ConfigApi, ApiRef, AnyApiFactory, IconComponent as IconComponent$1, SignInPageProps, AppTheme } from '@backstage/core-plugin-api';
5
+ import { ApiHolder, ConfigApi, ApiRef, ApiFactory, AnyApiFactory, IconComponent as IconComponent$2, SignInPageProps, AppTheme } from '@backstage/core-plugin-api';
6
6
  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, vmwareCloudAuthApiRef, withApis } from '@backstage/core-plugin-api';
7
7
  import { Expand, JsonObject } from '@backstage/types';
8
8
  import { z } from 'zod';
9
+ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
10
+ import { IconComponent as IconComponent$1, RouteRef as RouteRef$1 } from '@backstage/frontend-plugin-api';
9
11
  import { TranslationResource, TranslationMessages } from '@backstage/core-plugin-api/alpha';
10
12
  export { TranslationMessages, TranslationMessagesOptions, TranslationRef, TranslationRefOptions, TranslationResource, TranslationResourceOptions, createTranslationMessages, createTranslationRef, createTranslationResource, useTranslationRef } from '@backstage/core-plugin-api/alpha';
11
- import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
12
13
 
13
14
  /**
14
15
  * Common analytics context attributes.
@@ -350,6 +351,7 @@ interface Extension<TConfig, TConfigInput = TConfig> {
350
351
  type ResolveExtensionId<TExtension extends ExtensionDefinition, TNamespace extends string> = TExtension extends ExtensionDefinition<{
351
352
  kind: infer IKind extends string | undefined;
352
353
  name: infer IName extends string | undefined;
354
+ params: any;
353
355
  }> ? [string] extends [IKind | IName] ? never : (undefined extends IName ? TNamespace : `${TNamespace}/${IName}`) extends infer INamePart extends string ? IKind extends string ? `${IKind}:${INamePart}` : INamePart : never : never;
354
356
 
355
357
  type CompareChars<A extends string, B extends string> = [A, B] extends [
@@ -522,54 +524,106 @@ type ExtensionFactoryMiddleware = (originalFactory: (contextOverrides?: {
522
524
  type FrontendFeature = FrontendPlugin | FrontendModule;
523
525
 
524
526
  /**
525
- * Convert a single extension input into a matching resolved input.
527
+ * A function used to define a parameter mapping function in order to facilitate
528
+ * advanced parameter typing for extension blueprints.
529
+ *
530
+ * @remarks
531
+ *
532
+ * This function is primarily intended to enable the use of inferred type
533
+ * parameters for blueprint params, but it can also be used to transoform the
534
+ * params before they are handed ot the blueprint.
535
+ *
536
+ * The function must return an object created with
537
+ * {@link createExtensionBlueprintParams}.
538
+ *
526
539
  * @public
527
540
  */
528
- type ResolvedExtensionInput<TExtensionInput extends ExtensionInput<any, any>> = TExtensionInput['extensionData'] extends Array<AnyExtensionDataRef> ? {
529
- node: AppNode;
530
- } & ExtensionDataContainer<TExtensionInput['extensionData'][number]> : never;
541
+ type ExtensionBlueprintParamsDefiner<TParams extends object = object, TInput = any> = (params: TInput) => ExtensionBlueprintParams<TParams>;
531
542
  /**
532
- * Converts an extension input map into a matching collection of resolved inputs.
543
+ * An opaque type that represents a set of parameters to be passed to a blueprint.
544
+ *
545
+ * @remarks
546
+ *
547
+ * Created with {@link createExtensionBlueprintParams}.
548
+ *
533
549
  * @public
534
550
  */
535
- type ResolvedExtensionInputs<TInputs extends {
536
- [name in string]: ExtensionInput<any, any>;
537
- }> = {
538
- [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>> : false extends TInputs[InputName]['config']['optional'] ? Expand<ResolvedExtensionInput<TInputs[InputName]>> : Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>;
551
+ type ExtensionBlueprintParams<T extends object = object> = {
552
+ $$type: '@backstage/BlueprintParams';
553
+ T: T;
539
554
  };
540
- type ToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
541
- type PopUnion<U> = ToIntersection<U extends any ? () => U : never> extends () => infer R ? [rest: Exclude<U, R>, next: R] : undefined;
542
- /** @ignore */
543
- type JoinStringUnion<U, TDiv extends string = ', ', TResult extends string = ''> = PopUnion<U> extends [infer IRest extends string, infer INext extends string] ? TResult extends '' ? JoinStringUnion<IRest, TDiv, INext> : JoinStringUnion<IRest, TDiv, `${TResult}${TDiv}${INext}`> : TResult;
544
- /** @ignore */
545
- type VerifyExtensionFactoryOutput<UDeclaredOutput extends AnyExtensionDataRef, UFactoryOutput extends ExtensionDataValue<any, any>> = (UDeclaredOutput extends any ? UDeclaredOutput['config']['optional'] extends true ? never : UDeclaredOutput['id'] : never) extends infer IRequiredOutputIds ? [IRequiredOutputIds] extends [UFactoryOutput['id']] ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']] ? {} : `Error: The extension factory has undeclared output(s): ${JoinStringUnion<Exclude<UFactoryOutput['id'], UDeclaredOutput['id']>>}` : `Error: The extension factory is missing the following output(s): ${JoinStringUnion<Exclude<IRequiredOutputIds, UFactoryOutput['id']>>}` : never;
546
- /** @public */
547
- type ExtensionAttachToSpec = {
548
- id: string;
549
- input: string;
550
- } | Array<{
551
- id: string;
552
- input: string;
553
- }>;
554
- /** @public */
555
- type CreateExtensionOptions<TKind extends string | undefined, TName extends string | undefined, UOutput extends AnyExtensionDataRef, TInputs extends {
555
+ /**
556
+ * Wraps a plain blueprint parameter object in an opaque {@link ExtensionBlueprintParams} object.
557
+ *
558
+ * This is used in the definition of the `defineParams` option of {@link ExtensionBlueprint}.
559
+ *
560
+ * @public
561
+ * @param params - The plain blueprint parameter object to wrap.
562
+ * @returns The wrapped blueprint parameter object.
563
+ */
564
+ declare function createExtensionBlueprintParams<T extends object = object>(params: T): ExtensionBlueprintParams<T>;
565
+ /**
566
+ * @public
567
+ */
568
+ type CreateExtensionBlueprintOptions<TKind extends string, TName extends string | undefined, TParams extends object | ExtensionBlueprintParamsDefiner, UOutput extends AnyExtensionDataRef, TInputs extends {
556
569
  [inputName in string]: ExtensionInput<AnyExtensionDataRef, {
557
570
  optional: boolean;
558
571
  singleton: boolean;
559
572
  }>;
560
573
  }, TConfigSchema extends {
561
- [key: string]: (zImpl: typeof z) => z.ZodType;
562
- }, UFactoryOutput extends ExtensionDataValue<any, any>> = {
563
- kind?: TKind;
564
- name?: TName;
574
+ [key in string]: (zImpl: typeof z) => z.ZodType;
575
+ }, UFactoryOutput extends ExtensionDataValue<any, any>, TDataRefs extends {
576
+ [name in string]: AnyExtensionDataRef;
577
+ }> = {
578
+ kind: TKind;
565
579
  attachTo: ExtensionAttachToSpec;
566
580
  disabled?: boolean;
567
581
  inputs?: TInputs;
568
582
  output: Array<UOutput>;
583
+ name?: TName;
569
584
  config?: {
570
585
  schema: TConfigSchema;
571
586
  };
572
- factory(context: {
587
+ /**
588
+ * This option is used to further refine the blueprint params. When this
589
+ * option is used, the blueprint will require params to be passed in callback
590
+ * form. This function can both transform the params before they are handed to
591
+ * the blueprint factory, but importantly it also allows you to define
592
+ * inferred type parameters for your blueprint params.
593
+ *
594
+ * @example
595
+ * Blueprint definition with inferred type parameters:
596
+ * ```ts
597
+ * const ExampleBlueprint = createExtensionBlueprint({
598
+ * kind: 'example',
599
+ * attachTo: { id: 'example', input: 'example' },
600
+ * output: [exampleComponentDataRef, exampleFetcherDataRef],
601
+ * defineParams<T>(params: {
602
+ * component(props: ExampleProps<T>): JSX.Element | null
603
+ * fetcher(options: FetchOptions): Promise<FetchResult<T>>
604
+ * }) {
605
+ * return createExtensionBlueprintParams(params);
606
+ * },
607
+ * *factory(params) {
608
+ * yield exampleComponentDataRef(params.component)
609
+ * yield exampleFetcherDataRef(params.fetcher)
610
+ * },
611
+ * });
612
+ * ```
613
+ *
614
+ * @example
615
+ * Usage of the above example blueprint:
616
+ * ```ts
617
+ * const example = ExampleBlueprint.make({
618
+ * params: define => define({
619
+ * component: ...,
620
+ * fetcher: ...,
621
+ * }),
622
+ * });
623
+ * ```
624
+ */
625
+ defineParams?: TParams extends ExtensionBlueprintParamsDefiner ? TParams : 'The defineParams option must be a function if provided, see the docs for details';
626
+ factory(params: TParams extends ExtensionBlueprintParamsDefiner ? ReturnType<TParams>['T'] : TParams, context: {
573
627
  node: AppNode;
574
628
  apis: ApiHolder;
575
629
  config: {
@@ -577,11 +631,13 @@ type CreateExtensionOptions<TKind extends string | undefined, TName extends stri
577
631
  };
578
632
  inputs: Expand<ResolvedExtensionInputs<TInputs>>;
579
633
  }): Iterable<UFactoryOutput>;
634
+ dataRefs?: TDataRefs;
580
635
  } & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;
581
636
  /** @public */
582
- type ExtensionDefinitionParameters = {
583
- kind?: string;
637
+ type ExtensionBlueprintParameters = {
638
+ kind: string;
584
639
  name?: string;
640
+ params?: object | ExtensionBlueprintParamsDefiner;
585
641
  configInput?: {
586
642
  [K in string]: any;
587
643
  };
@@ -595,20 +651,53 @@ type ExtensionDefinitionParameters = {
595
651
  singleton: boolean;
596
652
  }>;
597
653
  };
598
- params?: object;
654
+ dataRefs?: {
655
+ [name in string]: AnyExtensionDataRef;
656
+ };
599
657
  };
600
- /** @public */
601
- type ExtensionDefinition<T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters> = {
602
- $$type: '@backstage/ExtensionDefinition';
603
- readonly T: T;
604
- override<TExtensionConfigSchema extends {
658
+ /** @ignore */
659
+ type ParamsFactory<TDefiner extends ExtensionBlueprintParamsDefiner> = (define: TDefiner) => ReturnType<TDefiner>;
660
+ /**
661
+ * Represents any form of params input that can be passed to a blueprint.
662
+ * This also includes the invalid form of passing a plain params object to a blueprint that uses a definition callback.
663
+ *
664
+ * @ignore
665
+ */
666
+ type AnyParamsInput$1<TParams extends object | ExtensionBlueprintParamsDefiner> = TParams extends ExtensionBlueprintParamsDefiner<infer IParams> ? IParams | ParamsFactory<TParams> : TParams | ParamsFactory<ExtensionBlueprintParamsDefiner<TParams, TParams>>;
667
+ /**
668
+ * @public
669
+ */
670
+ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionBlueprintParameters> {
671
+ dataRefs: T['dataRefs'];
672
+ make<TNewName extends string | undefined, TParamsInput extends AnyParamsInput$1<NonNullable<T['params']>>>(args: {
673
+ name?: TNewName;
674
+ attachTo?: ExtensionAttachToSpec;
675
+ disabled?: boolean;
676
+ params: TParamsInput extends ExtensionBlueprintParamsDefiner ? TParamsInput : T['params'] extends ExtensionBlueprintParamsDefiner ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `<blueprint>.make({ params: define => define(<params>) })`' : TParamsInput;
677
+ }): ExtensionDefinition<{
678
+ kind: T['kind'];
679
+ name: string | undefined extends TNewName ? T['name'] : TNewName;
680
+ config: T['config'];
681
+ configInput: T['configInput'];
682
+ output: T['output'];
683
+ inputs: T['inputs'];
684
+ params: T['params'];
685
+ }>;
686
+ /**
687
+ * Creates a new extension from the blueprint.
688
+ *
689
+ * You must either pass `params` directly, or define a `factory` that can
690
+ * optionally call the original factory with the same params.
691
+ */
692
+ makeWithOverrides<TNewName extends string | undefined, TExtensionConfigSchema extends {
605
693
  [key in string]: (zImpl: typeof z) => z.ZodType;
606
694
  }, UFactoryOutput extends ExtensionDataValue<any, any>, UNewOutput extends AnyExtensionDataRef, TExtraInputs extends {
607
695
  [inputName in string]: ExtensionInput<AnyExtensionDataRef, {
608
696
  optional: boolean;
609
697
  singleton: boolean;
610
698
  }>;
611
- }>(args: Expand<{
699
+ }>(args: {
700
+ name?: TNewName;
612
701
  attachTo?: ExtensionAttachToSpec;
613
702
  disabled?: boolean;
614
703
  inputs?: TExtraInputs & {
@@ -620,98 +709,110 @@ type ExtensionDefinition<T extends ExtensionDefinitionParameters = ExtensionDefi
620
709
  [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`;
621
710
  };
622
711
  };
623
- factory?(originalFactory: (context?: Expand<{
712
+ factory(originalFactory: <TParamsInput extends AnyParamsInput$1<NonNullable<T['params']>>>(params: TParamsInput extends ExtensionBlueprintParamsDefiner ? TParamsInput : T['params'] extends ExtensionBlueprintParamsDefiner ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(define => define(<params>))`' : TParamsInput, context?: {
624
713
  config?: T['config'];
625
714
  inputs?: ResolveInputValueOverrides<NonNullable<T['inputs']>>;
626
- } & ([T['params']] extends [never] ? {} : {
627
- params?: Partial<T['params']>;
628
- })>) => ExtensionDataContainer<NonNullable<T['output']>>, context: {
715
+ }) => ExtensionDataContainer<NonNullable<T['output']>>, context: {
629
716
  node: AppNode;
630
717
  apis: ApiHolder;
631
718
  config: T['config'] & {
632
719
  [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
633
720
  };
634
721
  inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
635
- }): Iterable<UFactoryOutput>;
636
- } & ([T['params']] extends [never] ? {} : {
637
- params?: Partial<T['params']>;
638
- })> & VerifyExtensionFactoryOutput<AnyExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>): ExtensionDefinition<{
639
- kind: T['kind'];
640
- name: T['name'];
641
- output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
642
- inputs: T['inputs'] & TExtraInputs;
643
- config: T['config'] & {
722
+ }): Iterable<UFactoryOutput> & VerifyExtensionFactoryOutput<AnyExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>;
723
+ }): ExtensionDefinition<{
724
+ config: (string extends keyof TExtensionConfigSchema ? {} : {
644
725
  [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
645
- };
646
- configInput: T['configInput'] & z.input<z.ZodObject<{
726
+ }) & T['config'];
727
+ configInput: (string extends keyof TExtensionConfigSchema ? {} : z.input<z.ZodObject<{
647
728
  [key in keyof TExtensionConfigSchema]: ReturnType<TExtensionConfigSchema[key]>;
648
- }>>;
729
+ }>>) & T['configInput'];
730
+ output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
731
+ inputs: T['inputs'] & TExtraInputs;
732
+ kind: T['kind'];
733
+ name: string | undefined extends TNewName ? T['name'] : TNewName;
734
+ params: T['params'];
649
735
  }>;
650
- };
651
- /** @public */
652
- declare function createExtension<UOutput extends AnyExtensionDataRef, TInputs extends {
736
+ }
737
+ /**
738
+ * A simpler replacement for wrapping up `createExtension` inside a kind or type. This allows for a cleaner API for creating
739
+ * types and instances of those types.
740
+ *
741
+ * @public
742
+ */
743
+ declare function createExtensionBlueprint<TParams extends object | ExtensionBlueprintParamsDefiner, UOutput extends AnyExtensionDataRef, TInputs extends {
653
744
  [inputName in string]: ExtensionInput<AnyExtensionDataRef, {
654
745
  optional: boolean;
655
746
  singleton: boolean;
656
747
  }>;
657
748
  }, TConfigSchema extends {
658
- [key: string]: (zImpl: typeof z) => z.ZodType;
659
- }, UFactoryOutput extends ExtensionDataValue<any, any>, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined>(options: CreateExtensionOptions<TKind, TName, UOutput, TInputs, TConfigSchema, UFactoryOutput>): ExtensionDefinition<{
749
+ [key in string]: (zImpl: typeof z) => z.ZodType;
750
+ }, UFactoryOutput extends ExtensionDataValue<any, any>, TKind extends string, TName extends string | undefined = undefined, TDataRefs extends {
751
+ [name in string]: AnyExtensionDataRef;
752
+ } = never>(options: CreateExtensionBlueprintOptions<TKind, TName, TParams, UOutput, TInputs, TConfigSchema, UFactoryOutput, TDataRefs>): ExtensionBlueprint<{
753
+ kind: TKind;
754
+ name: TName;
755
+ params: TParams;
756
+ output: UOutput;
757
+ inputs: string extends keyof TInputs ? {} : TInputs;
660
758
  config: string extends keyof TConfigSchema ? {} : {
661
759
  [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
662
760
  };
663
761
  configInput: string extends keyof TConfigSchema ? {} : z.input<z.ZodObject<{
664
762
  [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
665
763
  }>>;
666
- output: UOutput;
667
- inputs: TInputs;
668
- params: never;
669
- kind: string | undefined extends TKind ? undefined : TKind;
670
- name: string | undefined extends TName ? undefined : TName;
764
+ dataRefs: TDataRefs;
671
765
  }>;
672
766
 
673
- /** @public */
674
- interface CreateFrontendFeatureLoaderOptions {
675
- loader(deps: {
676
- config: ConfigApi;
677
- }): Iterable<FrontendFeature | FrontendFeatureLoader | Promise<{
678
- default: FrontendFeature | FrontendFeatureLoader;
679
- }>> | Promise<Iterable<FrontendFeature | FrontendFeatureLoader | Promise<{
680
- default: FrontendFeature | FrontendFeatureLoader;
681
- }>>> | AsyncIterable<FrontendFeature | FrontendFeatureLoader | {
682
- default: FrontendFeature | FrontendFeatureLoader;
683
- }>;
684
- }
685
- /** @public */
686
- interface FrontendFeatureLoader {
687
- readonly $$type: '@backstage/FrontendFeatureLoader';
688
- }
689
- /** @public */
690
- declare function createFrontendFeatureLoader(options: CreateFrontendFeatureLoaderOptions): FrontendFeatureLoader;
691
-
692
767
  /**
768
+ * Convert a single extension input into a matching resolved input.
769
+ * @public
770
+ */
771
+ type ResolvedExtensionInput<TExtensionInput extends ExtensionInput<any, any>> = TExtensionInput['extensionData'] extends Array<AnyExtensionDataRef> ? {
772
+ node: AppNode;
773
+ } & ExtensionDataContainer<TExtensionInput['extensionData'][number]> : never;
774
+ /**
775
+ * Converts an extension input map into a matching collection of resolved inputs.
693
776
  * @public
694
777
  */
695
- type CreateExtensionBlueprintOptions<TKind extends string, TName extends string | undefined, TParams, UOutput extends AnyExtensionDataRef, TInputs extends {
778
+ type ResolvedExtensionInputs<TInputs extends {
779
+ [name in string]: ExtensionInput<any, any>;
780
+ }> = {
781
+ [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>> : false extends TInputs[InputName]['config']['optional'] ? Expand<ResolvedExtensionInput<TInputs[InputName]>> : Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>;
782
+ };
783
+ type ToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
784
+ type PopUnion<U> = ToIntersection<U extends any ? () => U : never> extends () => infer R ? [rest: Exclude<U, R>, next: R] : undefined;
785
+ /** @ignore */
786
+ type JoinStringUnion<U, TDiv extends string = ', ', TResult extends string = ''> = PopUnion<U> extends [infer IRest extends string, infer INext extends string] ? TResult extends '' ? JoinStringUnion<IRest, TDiv, INext> : JoinStringUnion<IRest, TDiv, `${TResult}${TDiv}${INext}`> : TResult;
787
+ /** @ignore */
788
+ type VerifyExtensionFactoryOutput<UDeclaredOutput extends AnyExtensionDataRef, UFactoryOutput extends ExtensionDataValue<any, any>> = (UDeclaredOutput extends any ? UDeclaredOutput['config']['optional'] extends true ? never : UDeclaredOutput['id'] : never) extends infer IRequiredOutputIds ? [IRequiredOutputIds] extends [UFactoryOutput['id']] ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']] ? {} : `Error: The extension factory has undeclared output(s): ${JoinStringUnion<Exclude<UFactoryOutput['id'], UDeclaredOutput['id']>>}` : `Error: The extension factory is missing the following output(s): ${JoinStringUnion<Exclude<IRequiredOutputIds, UFactoryOutput['id']>>}` : never;
789
+ /** @public */
790
+ type ExtensionAttachToSpec = {
791
+ id: string;
792
+ input: string;
793
+ } | Array<{
794
+ id: string;
795
+ input: string;
796
+ }>;
797
+ /** @public */
798
+ type CreateExtensionOptions<TKind extends string | undefined, TName extends string | undefined, UOutput extends AnyExtensionDataRef, TInputs extends {
696
799
  [inputName in string]: ExtensionInput<AnyExtensionDataRef, {
697
800
  optional: boolean;
698
801
  singleton: boolean;
699
802
  }>;
700
803
  }, TConfigSchema extends {
701
- [key in string]: (zImpl: typeof z) => z.ZodType;
702
- }, UFactoryOutput extends ExtensionDataValue<any, any>, TDataRefs extends {
703
- [name in string]: AnyExtensionDataRef;
704
- }> = {
705
- kind: TKind;
804
+ [key: string]: (zImpl: typeof z) => z.ZodType;
805
+ }, UFactoryOutput extends ExtensionDataValue<any, any>> = {
806
+ kind?: TKind;
807
+ name?: TName;
706
808
  attachTo: ExtensionAttachToSpec;
707
809
  disabled?: boolean;
708
810
  inputs?: TInputs;
709
811
  output: Array<UOutput>;
710
- name?: TName;
711
812
  config?: {
712
813
  schema: TConfigSchema;
713
814
  };
714
- factory(params: TParams, context: {
815
+ factory(context: {
715
816
  node: AppNode;
716
817
  apis: ApiHolder;
717
818
  config: {
@@ -719,13 +820,11 @@ type CreateExtensionBlueprintOptions<TKind extends string, TName extends string
719
820
  };
720
821
  inputs: Expand<ResolvedExtensionInputs<TInputs>>;
721
822
  }): Iterable<UFactoryOutput>;
722
- dataRefs?: TDataRefs;
723
823
  } & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;
724
824
  /** @public */
725
- type ExtensionBlueprintParameters = {
726
- kind: string;
825
+ type ExtensionDefinitionParameters = {
826
+ kind?: string;
727
827
  name?: string;
728
- params?: object;
729
828
  configInput?: {
730
829
  [K in string]: any;
731
830
  };
@@ -739,44 +838,26 @@ type ExtensionBlueprintParameters = {
739
838
  singleton: boolean;
740
839
  }>;
741
840
  };
742
- dataRefs?: {
743
- [name in string]: AnyExtensionDataRef;
744
- };
841
+ params?: object | ExtensionBlueprintParamsDefiner;
745
842
  };
746
843
  /**
747
- * @public
844
+ * Same as the one in `createExtensionBlueprint`, but with `ParamsFactory` inlined.
845
+ * It can't be exported because it breaks API reports.
846
+ * @ignore
748
847
  */
749
- interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionBlueprintParameters> {
750
- dataRefs: T['dataRefs'];
751
- make<TNewName extends string | undefined>(args: {
752
- name?: TNewName;
753
- attachTo?: ExtensionAttachToSpec;
754
- disabled?: boolean;
755
- params: T['params'];
756
- }): ExtensionDefinition<{
757
- kind: T['kind'];
758
- name: string | undefined extends TNewName ? T['name'] : TNewName;
759
- config: T['config'];
760
- configInput: T['configInput'];
761
- output: T['output'];
762
- inputs: T['inputs'];
763
- params: T['params'];
764
- }>;
765
- /**
766
- * Creates a new extension from the blueprint.
767
- *
768
- * You must either pass `params` directly, or define a `factory` that can
769
- * optionally call the original factory with the same params.
770
- */
771
- makeWithOverrides<TNewName extends string | undefined, TExtensionConfigSchema extends {
848
+ type AnyParamsInput<TParams extends object | ExtensionBlueprintParamsDefiner> = TParams extends ExtensionBlueprintParamsDefiner<infer IParams> ? IParams | ((define: TParams) => ReturnType<TParams>) : TParams | ((define: ExtensionBlueprintParamsDefiner<TParams, TParams>) => ReturnType<ExtensionBlueprintParamsDefiner<TParams, TParams>>);
849
+ /** @public */
850
+ type ExtensionDefinition<T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters> = {
851
+ $$type: '@backstage/ExtensionDefinition';
852
+ readonly T: T;
853
+ override<TExtensionConfigSchema extends {
772
854
  [key in string]: (zImpl: typeof z) => z.ZodType;
773
855
  }, UFactoryOutput extends ExtensionDataValue<any, any>, UNewOutput extends AnyExtensionDataRef, TExtraInputs extends {
774
856
  [inputName in string]: ExtensionInput<AnyExtensionDataRef, {
775
857
  optional: boolean;
776
858
  singleton: boolean;
777
859
  }>;
778
- }>(args: {
779
- name?: TNewName;
860
+ }, TParamsInput extends AnyParamsInput<NonNullable<T['params']>>>(args: Expand<{
780
861
  attachTo?: ExtensionAttachToSpec;
781
862
  disabled?: boolean;
782
863
  inputs?: TExtraInputs & {
@@ -788,61 +869,75 @@ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionB
788
869
  [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`;
789
870
  };
790
871
  };
791
- factory(originalFactory: (params: T['params'], context?: {
872
+ factory?(originalFactory: <TFactoryParamsReturn extends AnyParamsInput<NonNullable<T['params']>>>(context?: Expand<{
792
873
  config?: T['config'];
793
874
  inputs?: ResolveInputValueOverrides<NonNullable<T['inputs']>>;
794
- }) => ExtensionDataContainer<NonNullable<T['output']>>, context: {
875
+ } & ([T['params']] extends [never] ? {} : {
876
+ params?: TFactoryParamsReturn extends ExtensionBlueprintParamsDefiner ? TFactoryParamsReturn : T['params'] extends ExtensionBlueprintParamsDefiner ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(define => define(<params>))`' : Partial<T['params']>;
877
+ })>) => ExtensionDataContainer<NonNullable<T['output']>>, context: {
795
878
  node: AppNode;
796
879
  apis: ApiHolder;
797
880
  config: T['config'] & {
798
881
  [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
799
882
  };
800
883
  inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
801
- }): Iterable<UFactoryOutput> & VerifyExtensionFactoryOutput<AnyExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>;
802
- }): ExtensionDefinition<{
803
- config: (string extends keyof TExtensionConfigSchema ? {} : {
804
- [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
805
- }) & T['config'];
806
- configInput: (string extends keyof TExtensionConfigSchema ? {} : z.input<z.ZodObject<{
807
- [key in keyof TExtensionConfigSchema]: ReturnType<TExtensionConfigSchema[key]>;
808
- }>>) & T['configInput'];
884
+ }): Iterable<UFactoryOutput>;
885
+ } & ([T['params']] extends [never] ? {} : {
886
+ params?: TParamsInput extends ExtensionBlueprintParamsDefiner ? TParamsInput : T['params'] extends ExtensionBlueprintParamsDefiner ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(define => define(<params>))`' : Partial<T['params']>;
887
+ })> & VerifyExtensionFactoryOutput<AnyExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>): ExtensionDefinition<{
888
+ kind: T['kind'];
889
+ name: T['name'];
809
890
  output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
810
891
  inputs: T['inputs'] & TExtraInputs;
811
- kind: T['kind'];
812
- name: string | undefined extends TNewName ? T['name'] : TNewName;
813
- params: T['params'];
892
+ config: T['config'] & {
893
+ [key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
894
+ };
895
+ configInput: T['configInput'] & z.input<z.ZodObject<{
896
+ [key in keyof TExtensionConfigSchema]: ReturnType<TExtensionConfigSchema[key]>;
897
+ }>>;
814
898
  }>;
815
- }
816
- /**
817
- * A simpler replacement for wrapping up `createExtension` inside a kind or type. This allows for a cleaner API for creating
818
- * types and instances of those types.
819
- *
820
- * @public
821
- */
822
- declare function createExtensionBlueprint<TParams extends object, UOutput extends AnyExtensionDataRef, TInputs extends {
899
+ };
900
+ /** @public */
901
+ declare function createExtension<UOutput extends AnyExtensionDataRef, TInputs extends {
823
902
  [inputName in string]: ExtensionInput<AnyExtensionDataRef, {
824
903
  optional: boolean;
825
904
  singleton: boolean;
826
905
  }>;
827
906
  }, TConfigSchema extends {
828
- [key in string]: (zImpl: typeof z) => z.ZodType;
829
- }, UFactoryOutput extends ExtensionDataValue<any, any>, TKind extends string, TName extends string | undefined = undefined, TDataRefs extends {
830
- [name in string]: AnyExtensionDataRef;
831
- } = never>(options: CreateExtensionBlueprintOptions<TKind, TName, TParams, UOutput, TInputs, TConfigSchema, UFactoryOutput, TDataRefs>): ExtensionBlueprint<{
832
- kind: TKind;
833
- name: TName;
834
- params: TParams;
835
- output: UOutput;
836
- inputs: string extends keyof TInputs ? {} : TInputs;
907
+ [key: string]: (zImpl: typeof z) => z.ZodType;
908
+ }, UFactoryOutput extends ExtensionDataValue<any, any>, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined>(options: CreateExtensionOptions<TKind, TName, UOutput, TInputs, TConfigSchema, UFactoryOutput>): ExtensionDefinition<{
837
909
  config: string extends keyof TConfigSchema ? {} : {
838
910
  [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
839
911
  };
840
912
  configInput: string extends keyof TConfigSchema ? {} : z.input<z.ZodObject<{
841
913
  [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
842
914
  }>>;
843
- dataRefs: TDataRefs;
915
+ output: UOutput;
916
+ inputs: TInputs;
917
+ params: never;
918
+ kind: string | undefined extends TKind ? undefined : TKind;
919
+ name: string | undefined extends TName ? undefined : TName;
844
920
  }>;
845
921
 
922
+ /** @public */
923
+ interface CreateFrontendFeatureLoaderOptions {
924
+ loader(deps: {
925
+ config: ConfigApi;
926
+ }): Iterable<FrontendFeature | FrontendFeatureLoader | Promise<{
927
+ default: FrontendFeature | FrontendFeatureLoader;
928
+ }>> | Promise<Iterable<FrontendFeature | FrontendFeatureLoader | Promise<{
929
+ default: FrontendFeature | FrontendFeatureLoader;
930
+ }>>> | AsyncIterable<FrontendFeature | FrontendFeatureLoader | {
931
+ default: FrontendFeature | FrontendFeatureLoader;
932
+ }>;
933
+ }
934
+ /** @public */
935
+ interface FrontendFeatureLoader {
936
+ readonly $$type: '@backstage/FrontendFeatureLoader';
937
+ }
938
+ /** @public */
939
+ declare function createFrontendFeatureLoader(options: CreateFrontendFeatureLoaderOptions): FrontendFeatureLoader;
940
+
846
941
  /**
847
942
  * The specification for this {@link AppNode} in the {@link AppTree}.
848
943
  *
@@ -1363,9 +1458,7 @@ declare function useAnalytics(): AnalyticsTracker;
1363
1458
  declare const ApiBlueprint: ExtensionBlueprint<{
1364
1459
  kind: "api";
1365
1460
  name: undefined;
1366
- params: {
1367
- factory: AnyApiFactory;
1368
- };
1461
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: ApiFactory<TApi, TImpl, TDeps>) => ExtensionBlueprintParams<AnyApiFactory>;
1369
1462
  output: ConfigurableExtensionDataRef<AnyApiFactory, "core.api.factory", {}>;
1370
1463
  inputs: {};
1371
1464
  config: {};
@@ -1441,59 +1534,80 @@ declare const IconBundleBlueprint: ExtensionBlueprint<{
1441
1534
  }>;
1442
1535
 
1443
1536
  /**
1444
- * Creates extensions that make up the items of the nav bar.
1537
+ * The props for the {@link NavContentComponent}.
1445
1538
  *
1446
1539
  * @public
1447
1540
  */
1448
- declare const NavItemBlueprint: ExtensionBlueprint<{
1449
- kind: "nav-item";
1541
+ interface NavContentComponentProps {
1542
+ /**
1543
+ * The nav items available to the component. These are all the items created
1544
+ * with the {@link NavItemBlueprint} in the app.
1545
+ *
1546
+ * In addition to the original properties from the nav items, these also
1547
+ * include a resolved route path as `to`, and duplicated `title` as `text` to
1548
+ * simplify rendering.
1549
+ */
1550
+ items: Array<{
1551
+ icon: IconComponent$1;
1552
+ title: string;
1553
+ routeRef: RouteRef$1<undefined>;
1554
+ to: string;
1555
+ text: string;
1556
+ }>;
1557
+ }
1558
+ /**
1559
+ * A component that renders the nav bar content, to be passed to the {@link NavContentBlueprint}.
1560
+ *
1561
+ * @public
1562
+ */
1563
+ type NavContentComponent = (props: NavContentComponentProps) => JSX.Element | null;
1564
+ /**
1565
+ * Creates an extension that replaces the entire nav bar with your own component.
1566
+ *
1567
+ * @public
1568
+ */
1569
+ declare const NavContentBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
1570
+ kind: "nav-content";
1450
1571
  name: undefined;
1451
1572
  params: {
1452
- title: string;
1453
- icon: IconComponent$1;
1454
- routeRef: RouteRef<undefined>;
1573
+ component: NavContentComponent;
1455
1574
  };
1456
- output: ConfigurableExtensionDataRef<{
1457
- title: string;
1458
- icon: IconComponent$1;
1459
- routeRef: RouteRef<undefined>;
1460
- }, "core.nav-item.target", {}>;
1575
+ output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<NavContentComponent, "core.nav-content.component", {}>;
1461
1576
  inputs: {};
1462
1577
  config: {};
1463
1578
  configInput: {};
1464
1579
  dataRefs: {
1465
- target: ConfigurableExtensionDataRef<{
1466
- title: string;
1467
- icon: IconComponent$1;
1468
- routeRef: RouteRef<undefined>;
1469
- }, "core.nav-item.target", {}>;
1580
+ component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<NavContentComponent, "core.nav-content.component", {}>;
1470
1581
  };
1471
1582
  }>;
1472
1583
 
1473
1584
  /**
1474
- * Creates an extension that replaces the logo in the nav bar with your own.
1585
+ * Creates extensions that make up the items of the nav bar.
1475
1586
  *
1476
1587
  * @public
1477
1588
  */
1478
- declare const NavLogoBlueprint: ExtensionBlueprint<{
1479
- kind: "nav-logo";
1589
+ declare const NavItemBlueprint: ExtensionBlueprint<{
1590
+ kind: "nav-item";
1480
1591
  name: undefined;
1481
1592
  params: {
1482
- logoIcon: JSX.Element;
1483
- logoFull: JSX.Element;
1593
+ title: string;
1594
+ icon: IconComponent$2;
1595
+ routeRef: RouteRef<undefined>;
1484
1596
  };
1485
1597
  output: ConfigurableExtensionDataRef<{
1486
- logoIcon?: JSX.Element;
1487
- logoFull?: JSX.Element;
1488
- }, "core.nav-logo.logo-elements", {}>;
1598
+ title: string;
1599
+ icon: IconComponent$2;
1600
+ routeRef: RouteRef<undefined>;
1601
+ }, "core.nav-item.target", {}>;
1489
1602
  inputs: {};
1490
1603
  config: {};
1491
1604
  configInput: {};
1492
1605
  dataRefs: {
1493
- logoElements: ConfigurableExtensionDataRef<{
1494
- logoIcon?: JSX.Element;
1495
- logoFull?: JSX.Element;
1496
- }, "core.nav-logo.logo-elements", {}>;
1606
+ target: ConfigurableExtensionDataRef<{
1607
+ title: string;
1608
+ icon: IconComponent$2;
1609
+ routeRef: RouteRef<undefined>;
1610
+ }, "core.nav-item.target", {}>;
1497
1611
  };
1498
1612
  }>;
1499
1613
 
@@ -1642,4 +1756,4 @@ declare namespace createComponentExtension {
1642
1756
  }, "core.component.component", {}>;
1643
1757
  }
1644
1758
 
1645
- export { type AnalyticsApi, AnalyticsContext, type AnalyticsContextValue, type AnalyticsEvent, type AnalyticsEventAttributes, type AnalyticsTracker, type AnyExtensionDataRef, type AnyExternalRoutes, type AnyRouteRefParams, type AnyRoutes, ApiBlueprint, type AppNode, type AppNodeEdges, type AppNodeInstance, type AppNodeSpec, AppRootElementBlueprint, AppRootWrapperBlueprint, type AppTree, type AppTreeApi, type CommonAnalyticsContext, type ComponentRef, type ComponentsApi, type ConfigurableExtensionDataRef, type CoreErrorBoundaryFallbackProps, type CoreNotFoundErrorPageProps, type CoreProgressProps, type CreateExtensionBlueprintOptions, type CreateExtensionOptions, type CreateFrontendFeatureLoaderOptions, type CreateFrontendModuleOptions, type DialogApi, type DialogApiDialog, type Extension, type ExtensionAttachToSpec, type ExtensionBlueprint, type ExtensionBlueprintParameters, ExtensionBoundary, type ExtensionBoundaryProps, type ExtensionDataContainer, type ExtensionDataRef, type ExtensionDataRefToValue, type ExtensionDataValue, type ExtensionDefinition, type ExtensionDefinitionParameters, type ExtensionFactoryMiddleware, type ExtensionInput, type ExternalRouteRef, type FeatureFlagConfig, type FrontendFeature, type FrontendFeatureLoader, type FrontendModule, type FrontendPlugin, type FrontendPluginInfo, type FrontendPluginInfoOptions, IconBundleBlueprint, type IconComponent, type IconsApi, NavItemBlueprint, NavLogoBlueprint, PageBlueprint, type PluginOptions, type PortableSchema, type ResolveInputValueOverrides, type ResolvedExtensionInput, type ResolvedExtensionInputs, type RouteFunc, type RouteRef, type RouteResolutionApi, type RouteResolutionApiResolveOptions, RouterBlueprint, SignInPageBlueprint, type SubRouteRef, ThemeBlueprint, TranslationBlueprint, analyticsApiRef, appTreeApiRef, componentsApiRef, coreComponentRefs, coreExtensionData, createComponentExtension, createComponentRef, createExtension, createExtensionBlueprint, createExtensionDataRef, createExtensionInput, createExternalRouteRef, createFrontendFeatureLoader, createFrontendModule, createFrontendPlugin, createRouteRef, createSubRouteRef, dialogApiRef, iconsApiRef, routeResolutionApiRef, useAnalytics, useAppNode, useComponentRef, useRouteRef, useRouteRefParams };
1759
+ export { type AnalyticsApi, AnalyticsContext, type AnalyticsContextValue, type AnalyticsEvent, type AnalyticsEventAttributes, type AnalyticsTracker, type AnyExtensionDataRef, type AnyExternalRoutes, type AnyRouteRefParams, type AnyRoutes, ApiBlueprint, type AppNode, type AppNodeEdges, type AppNodeInstance, type AppNodeSpec, AppRootElementBlueprint, AppRootWrapperBlueprint, type AppTree, type AppTreeApi, type CommonAnalyticsContext, type ComponentRef, type ComponentsApi, type ConfigurableExtensionDataRef, type CoreErrorBoundaryFallbackProps, type CoreNotFoundErrorPageProps, type CoreProgressProps, type CreateExtensionBlueprintOptions, type CreateExtensionOptions, type CreateFrontendFeatureLoaderOptions, type CreateFrontendModuleOptions, type DialogApi, type DialogApiDialog, type Extension, type ExtensionAttachToSpec, type ExtensionBlueprint, type ExtensionBlueprintParameters, type ExtensionBlueprintParams, type ExtensionBlueprintParamsDefiner, ExtensionBoundary, type ExtensionBoundaryProps, type ExtensionDataContainer, type ExtensionDataRef, type ExtensionDataRefToValue, type ExtensionDataValue, type ExtensionDefinition, type ExtensionDefinitionParameters, type ExtensionFactoryMiddleware, type ExtensionInput, type ExternalRouteRef, type FeatureFlagConfig, type FrontendFeature, type FrontendFeatureLoader, type FrontendModule, type FrontendPlugin, type FrontendPluginInfo, type FrontendPluginInfoOptions, IconBundleBlueprint, type IconComponent, type IconsApi, NavContentBlueprint, type NavContentComponent, type NavContentComponentProps, NavItemBlueprint, PageBlueprint, type PluginOptions, type PortableSchema, type ResolveInputValueOverrides, type ResolvedExtensionInput, type ResolvedExtensionInputs, type RouteFunc, type RouteRef, type RouteResolutionApi, type RouteResolutionApiResolveOptions, RouterBlueprint, SignInPageBlueprint, type SubRouteRef, ThemeBlueprint, TranslationBlueprint, analyticsApiRef, appTreeApiRef, componentsApiRef, coreComponentRefs, coreExtensionData, createComponentExtension, createComponentRef, createExtension, createExtensionBlueprint, createExtensionBlueprintParams, createExtensionDataRef, createExtensionInput, createExternalRouteRef, createFrontendFeatureLoader, createFrontendModule, createFrontendPlugin, createRouteRef, createSubRouteRef, dialogApiRef, iconsApiRef, routeResolutionApiRef, useAnalytics, useAppNode, useComponentRef, useRouteRef, useRouteRefParams };