frontend-plugin-api: make ExtensionInput type parameters optional

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2025-11-03 22:36:53 +01:00
parent fc2f7e5b1a
commit 878c25146c
16 changed files with 74 additions and 200 deletions
@@ -44,13 +44,12 @@ export const ctxParamsSymbol = Symbol('params');
* Convert a single extension input into a matching resolved input.
* @public
*/
export type ResolvedExtensionInput<
TExtensionInput extends ExtensionInput<any, any>,
> = TExtensionInput['extensionData'] extends Array<ExtensionDataRef>
? {
node: AppNode;
} & ExtensionDataContainer<TExtensionInput['extensionData'][number]>
: never;
export type ResolvedExtensionInput<TExtensionInput extends ExtensionInput> =
TExtensionInput['extensionData'] extends Array<ExtensionDataRef>
? {
node: AppNode;
} & ExtensionDataContainer<TExtensionInput['extensionData'][number]>
: never;
/**
* Converts an extension input map into a matching collection of resolved inputs.
@@ -58,7 +57,7 @@ export type ResolvedExtensionInput<
*/
export type ResolvedExtensionInputs<
TInputs extends {
[name in string]: ExtensionInput<any, any>;
[name in string]: ExtensionInput;
},
> = {
[InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']
@@ -123,12 +122,7 @@ export type CreateExtensionOptions<
TKind extends string | undefined,
TName extends string | undefined,
UOutput extends ExtensionDataRef,
TInputs extends {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
TInputs extends { [inputName in string]: ExtensionInput },
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
UFactoryOutput extends ExtensionDataValue<any, any>,
> = {
@@ -158,12 +152,7 @@ export type ExtensionDefinitionParameters = {
configInput?: { [K in string]: any };
config?: { [K in string]: any };
output?: ExtensionDataRef;
inputs?: {
[KName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
};
inputs?: { [KName in string]: ExtensionInput };
params?: object | ExtensionBlueprintDefineParams;
};
@@ -194,12 +183,7 @@ export type ExtensionDefinition<
},
UFactoryOutput extends ExtensionDataValue<any, any>,
UNewOutput extends ExtensionDataRef,
TExtraInputs extends {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
TExtraInputs extends { [inputName in string]: ExtensionInput },
TParamsInput extends AnyParamsInput<NonNullable<T['params']>>,
>(
args: Expand<
@@ -323,12 +307,7 @@ export type ExtensionDefinition<
*/
export function createExtension<
UOutput extends ExtensionDataRef,
TInputs extends {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
TInputs extends { [inputName in string]: ExtensionInput },
TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },
UFactoryOutput extends ExtensionDataValue<any, any>,
const TKind extends string | undefined = undefined,
@@ -103,12 +103,7 @@ export type CreateExtensionBlueprintOptions<
TKind extends string,
TParams extends object | ExtensionBlueprintDefineParams,
UOutput extends ExtensionDataRef,
TInputs extends {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
TInputs extends { [inputName in string]: ExtensionInput },
TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },
UFactoryOutput extends ExtensionDataValue<any, any>,
TDataRefs extends { [name in string]: ExtensionDataRef },
@@ -186,12 +181,7 @@ export type ExtensionBlueprintParameters = {
configInput?: { [K in string]: any };
config?: { [K in string]: any };
output?: ExtensionDataRef;
inputs?: {
[KName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
};
inputs?: { [KName in string]: ExtensionInput };
dataRefs?: { [name in string]: ExtensionDataRef };
};
@@ -254,12 +244,7 @@ export interface ExtensionBlueprint<
},
UFactoryOutput extends ExtensionDataValue<any, any>,
UNewOutput extends ExtensionDataRef,
TExtraInputs extends {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
TExtraInputs extends { [inputName in string]: ExtensionInput },
>(args: {
name?: TName;
attachTo?: ExtensionAttachToSpec;
@@ -455,12 +440,7 @@ function unwrapParams<TParams extends object>(
export function createExtensionBlueprint<
TParams extends object | ExtensionBlueprintDefineParams,
UOutput extends ExtensionDataRef,
TInputs extends {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
TInputs extends { [inputName in string]: ExtensionInput },
TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },
UFactoryOutput extends ExtensionDataValue<any, any>,
TKind extends string,
@@ -18,8 +18,15 @@ import { ExtensionDataRef } from './createExtensionDataRef';
/** @public */
export interface ExtensionInput<
UExtensionData extends ExtensionDataRef<unknown, string, { optional?: true }>,
TConfig extends { singleton: boolean; optional: boolean },
UExtensionData extends ExtensionDataRef<
unknown,
string,
{ optional?: true }
> = ExtensionDataRef,
TConfig extends { singleton: boolean; optional: boolean } = {
singleton: boolean;
optional: boolean;
},
> {
$$type: '@backstage/ExtensionInput';
extensionData: Array<UExtensionData>;
@@ -68,22 +68,14 @@ export type InternalExtension<TConfig, TConfigInput> = Extension<
}
| {
readonly version: 'v2';
readonly inputs: {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
};
readonly inputs: { [inputName in string]: ExtensionInput };
readonly output: Array<ExtensionDataRef>;
factory(options: {
apis: ApiHolder;
node: AppNode;
config: TConfig;
inputs: ResolvedExtensionInputs<{
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
[inputName in string]: ExtensionInput;
}>;
}): Iterable<ExtensionDataValue<any, any>>;
}
@@ -19,7 +19,6 @@ import { Expand } from '@backstage/types';
import { ResolvedExtensionInput } from './createExtension';
import { createExtensionDataContainer } from '@internal/frontend';
import {
ExtensionDataRef,
ExtensionDataRefToValue,
ExtensionDataValue,
} from './createExtensionDataRef';
@@ -28,16 +27,8 @@ import { ExtensionDataContainer } from './types';
/** @ignore */
export type ResolvedInputValueOverrides<
TInputs extends {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
} = {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
TInputs extends { [inputName in string]: ExtensionInput } = {
[inputName in string]: ExtensionInput;
},
> = Expand<
{
@@ -90,12 +81,7 @@ function expectItem<T>(value: T | T[]): T {
/** @internal */
export function resolveInputOverrides(
declaredInputs?: {
[inputName in string]: ExtensionInput<
ExtensionDataRef,
{ optional: boolean; singleton: boolean }
>;
},
declaredInputs?: { [inputName in string]: ExtensionInput },
inputs?: {
[KName in string]?:
| ({ node: AppNode } & ExtensionDataContainer<any>)