frontend-plugin-api: more fixes for new extension io structure

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-07-27 11:10:53 +02:00
parent e2e84edf7b
commit 0d24c1fa3e
3 changed files with 46 additions and 36 deletions
@@ -80,15 +80,15 @@ export type ExtensionDataContainer<UExtensionData extends AnyExtensionDataRef> =
* @public
*/
export type ResolvedExtensionInput<
TExtensionData extends AnyExtensionDataMap | AnyExtensionDataRef,
> = [TExtensionData] extends [AnyExtensionDataRef]
TExtensionInput extends ExtensionInput<any, any>,
> = TExtensionInput['extensionData'] extends Array<AnyExtensionDataRef>
? {
node: AppNode;
} & ExtensionDataContainer<TExtensionData>
: TExtensionData extends AnyExtensionDataMap
} & ExtensionDataContainer<TExtensionInput['extensionData'][number]>
: TExtensionInput['extensionData'] extends AnyExtensionDataMap
? {
node: AppNode;
output: ExtensionDataValues<TExtensionData>;
output: ExtensionDataValues<TExtensionInput['extensionData']>;
}
: never;
@@ -97,15 +97,15 @@ export type ResolvedExtensionInput<
* @public
*/
export type ResolvedExtensionInputs<
TInputs extends { [name in string]: ExtensionInput<any, any> },
TInputs extends {
[name in string]: ExtensionInput<any, any> | LegacyExtensionInput<any, any>;
},
> = {
[InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']
? Array<Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>>
? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>>
: false extends TInputs[InputName]['config']['optional']
? Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>
: Expand<
ResolvedExtensionInput<TInputs[InputName]['extensionData']> | undefined
>;
? Expand<ResolvedExtensionInput<TInputs[InputName]>>
: Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>;
};
/**
@@ -57,13 +57,7 @@ describe('createExtensionBlueprint', () => {
name: 'my-extension',
namespace: undefined,
output: {
element: {
$$type: '@backstage/ExtensionDataRef',
config: {},
id: 'core.reactElement',
optional: expect.any(Function),
toString: expect.any(Function),
},
element: coreExtensionData.reactElement,
},
factory: expect.any(Function),
toString: expect.any(Function),
@@ -23,7 +23,7 @@ export interface ExtensionInput<
TConfig extends { singleton: boolean; optional: boolean },
> {
$$type: '@backstage/ExtensionInput';
extensionData: TExtensionData;
extensionData: Array<TExtensionData>;
config: TConfig;
}
@@ -76,7 +76,7 @@ export function createExtensionInput<
TExtensionDataMap extends AnyExtensionDataMap,
TConfig extends { singleton?: boolean; optional?: boolean },
>(
extensionData: TExtensionData,
extensionData: Array<TExtensionData> | TExtensionDataMap,
config?: TConfig,
):
| LegacyExtensionInput<
@@ -93,22 +93,24 @@ export function createExtensionInput<
optional: TConfig['optional'] extends true ? true : false;
}
> {
if (Array.isArray(extensionData)) {
const seen = new Set();
const duplicates = [];
for (const dataRef of extensionData) {
if (seen.has(dataRef.id)) {
duplicates.push(dataRef.id);
} else {
seen.add(dataRef.id);
if (process.env.NODE_ENV !== 'production') {
if (Array.isArray(extensionData)) {
const seen = new Set();
const duplicates = [];
for (const dataRef of extensionData) {
if (seen.has(dataRef.id)) {
duplicates.push(dataRef.id);
} else {
seen.add(dataRef.id);
}
}
if (duplicates.length > 0) {
throw new Error(
`ExtensionInput may not have duplicate data refs: '${duplicates.join(
"', '",
)}'`,
);
}
}
if (duplicates.length > 0) {
throw new Error(
`ExtensionInput may not have duplicate data refs: '${duplicates.join(
"', '",
)}'`,
);
}
}
return {
@@ -122,5 +124,19 @@ export function createExtensionInput<
? true
: false,
},
};
} as
| LegacyExtensionInput<
TExtensionDataMap,
{
singleton: TConfig['singleton'] extends true ? true : false;
optional: TConfig['optional'] extends true ? true : false;
}
>
| ExtensionInput<
TExtensionData,
{
singleton: TConfig['singleton'] extends true ? true : false;
optional: TConfig['optional'] extends true ? true : false;
}
>;
}