frontend-plugin-api: add OverridableExtensionDefinition

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2025-09-20 23:09:02 +02:00
parent e5e79ce4e9
commit 7d87b4f6ad
6 changed files with 34 additions and 18 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-plugin-api': minor
---
Renamed `ExtensionDefinition` to `OverridableExtensionDefinition` and introduced a slimmer `ExtensionDefinition` type that does not include override methods. The overridable type is generally used as an output type, while plain `ExtensionDefinition`s are used for input. This reduces type conflicts across different of `@backstage/frontend-plugin-api`, improving long-term compatibility.
@@ -20,7 +20,7 @@ import {
ExtensionDefinitionAttachTo,
ExtensionDataValue,
ExtensionDataRef,
ExtensionDefinition,
OverridableExtensionDefinition,
ExtensionDefinitionParameters,
ExtensionInput,
PortableSchema,
@@ -29,7 +29,7 @@ import {
import { OpaqueType } from '@internal/opaque';
export const OpaqueExtensionDefinition = OpaqueType.create<{
public: ExtensionDefinition<ExtensionDefinitionParameters>;
public: OverridableExtensionDefinition<ExtensionDefinitionParameters>;
versions:
| {
readonly version: 'v1';
@@ -233,12 +233,17 @@ type AnyParamsInput<TParams extends object | ExtensionBlueprintDefineParams> =
) => ReturnType<ExtensionBlueprintDefineParams<TParams, TParams>>);
/** @public */
export type ExtensionDefinition<
T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters,
> = {
export interface ExtensionDefinition<
TParams extends ExtensionDefinitionParameters = ExtensionDefinitionParameters,
> {
$$type: '@backstage/ExtensionDefinition';
readonly T: T;
readonly T: TParams;
}
/** @public */
export interface OverridableExtensionDefinition<
T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters,
> extends ExtensionDefinition<T> {
/**
* References to the inputs of this extension, which can be used to attach child extensions.
*/
@@ -327,7 +332,7 @@ export type ExtensionDefinition<
: UNewOutput,
UFactoryOutput
>,
): ExtensionDefinition<{
): OverridableExtensionDefinition<{
kind: T['kind'];
name: T['name'];
output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
@@ -346,7 +351,7 @@ export type ExtensionDefinition<
}>
>;
}>;
};
}
/**
* @internal
@@ -425,7 +430,7 @@ export function createExtension<
UFactoryOutput,
UParentInputs
>,
): ExtensionDefinition<{
): OverridableExtensionDefinition<{
config: string extends keyof TConfigSchema
? {}
: {
@@ -638,7 +643,7 @@ export function createExtension<
return deduplicatedResult.values();
},
}) as ExtensionDefinition<any>;
}) as OverridableExtensionDefinition<any>;
},
});
}
@@ -19,7 +19,7 @@ import { Expand } from '@backstage/types';
import { OpaqueType } from '@internal/opaque';
import {
ExtensionDefinitionAttachTo,
ExtensionDefinition,
OverridableExtensionDefinition,
ResolvedExtensionInputs,
VerifyExtensionFactoryOutput,
createExtension,
@@ -226,7 +226,7 @@ export interface ExtensionBlueprint<
: T['params'] extends ExtensionBlueprintDefineParams
? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `<blueprint>.make({ params: defineParams => defineParams(<params>) })`'
: T['params'];
}): ExtensionDefinition<{
}): OverridableExtensionDefinition<{
kind: T['kind'];
name: string | undefined extends TName ? undefined : TName;
config: T['config'];
@@ -303,7 +303,7 @@ export interface ExtensionBlueprint<
: UNewOutput,
UFactoryOutput
>;
}): ExtensionDefinition<{
}): OverridableExtensionDefinition<{
config: (string extends keyof TExtensionConfigSchema
? {}
: {
@@ -514,7 +514,7 @@ export function createExtensionBlueprint<
unwrapParams(args.params, ctx, defineParams, options.kind),
ctx,
) as Iterable<ExtensionDataValue<any, any>>,
}) as ExtensionDefinition;
}) as OverridableExtensionDefinition;
},
makeWithOverrides(args) {
return createExtension({
@@ -572,7 +572,7 @@ export function createExtensionBlueprint<
},
) as Iterable<ExtensionDataValue<any, any>>;
},
}) as ExtensionDefinition;
}) as OverridableExtensionDefinition;
},
} as ExtensionBlueprint<{
kind: TKind;
@@ -18,7 +18,10 @@ import {
OpaqueExtensionDefinition,
OpaqueFrontendPlugin,
} from '@internal/frontend';
import { ExtensionDefinition } from './createExtension';
import {
ExtensionDefinition,
OverridableExtensionDefinition,
} from './createExtension';
import {
Extension,
resolveExtensionDefinition,
@@ -104,7 +107,9 @@ export interface OverridableFrontendPlugin<
[id in string]: ExtensionDefinition;
},
> extends FrontendPlugin<TRoutes, TExternalRoutes> {
getExtension<TId extends keyof TExtensionMap>(id: TId): TExtensionMap[TId];
getExtension<TId extends keyof TExtensionMap>(
id: TId,
): OverridableExtensionDefinition<TExtensionMap[TId]['T']>;
withOverrides(options: {
extensions: Array<ExtensionDefinition>;
@@ -15,12 +15,13 @@
*/
export { coreExtensionData } from './coreExtensionData';
export { createExtension } from './createExtension';
export {
createExtension,
type ExtensionDefinition,
type ExtensionDefinitionAttachTo,
type ExtensionDefinitionParameters,
type CreateExtensionOptions,
type OverridableExtensionDefinition,
type ResolvedExtensionInput,
type ResolvedExtensionInputs,
} from './createExtension';