frontend-plugin-api: add initial support for v2 extensions for blueprints
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -11,13 +11,9 @@ This allows the creation of extension instances with the following pattern:
|
||||
const EntityCardBlueprint = createExtensionBlueprint({
|
||||
kind: 'entity-card',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: {
|
||||
element: coreExtensionData.reactElement,
|
||||
},
|
||||
output: [coreExtensionData.reactElement],
|
||||
factory(params: { text: string }) {
|
||||
return {
|
||||
element: <h1>{params.text}</h1>,
|
||||
};
|
||||
return [coreExtensionData.reactElement(<h1>{params.text}</h1>)];
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -593,24 +593,38 @@ export function createExtension<
|
||||
// @public
|
||||
export function createExtensionBlueprint<
|
||||
TParams,
|
||||
TInputs extends AnyExtensionInputMap,
|
||||
TOutput extends AnyExtensionDataMap,
|
||||
UOutput extends AnyExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{
|
||||
optional: boolean;
|
||||
singleton: boolean;
|
||||
}
|
||||
>;
|
||||
},
|
||||
UExtraOutput extends AnyExtensionDataRef,
|
||||
TConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
},
|
||||
TDataRefs extends AnyExtensionDataMap = never,
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TDataRefs extends {
|
||||
[name in string]: AnyExtensionDataRef;
|
||||
} = never,
|
||||
>(
|
||||
options: CreateExtensionBlueprintOptions<
|
||||
TParams,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TOutput,
|
||||
TConfigSchema,
|
||||
UFactoryOutput,
|
||||
TDataRefs
|
||||
>,
|
||||
): ExtensionBlueprint<
|
||||
TParams,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TOutput,
|
||||
UExtraOutput,
|
||||
string extends keyof TConfigSchema
|
||||
? {}
|
||||
: {
|
||||
@@ -627,29 +641,38 @@ export function createExtensionBlueprint<
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface CreateExtensionBlueprintOptions<
|
||||
export type CreateExtensionBlueprintOptions<
|
||||
TParams,
|
||||
TInputs extends AnyExtensionInputMap,
|
||||
TOutput extends AnyExtensionDataMap,
|
||||
UOutput extends AnyExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{
|
||||
optional: boolean;
|
||||
singleton: boolean;
|
||||
}
|
||||
>;
|
||||
},
|
||||
TConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
},
|
||||
TDataRefs extends AnyExtensionDataMap,
|
||||
> {
|
||||
// (undocumented)
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TDataRefs extends {
|
||||
[name in string]: AnyExtensionDataRef;
|
||||
},
|
||||
> = {
|
||||
kind: string;
|
||||
namespace?: string;
|
||||
attachTo: {
|
||||
id: string;
|
||||
input: string;
|
||||
};
|
||||
// (undocumented)
|
||||
disabled?: boolean;
|
||||
inputs?: TInputs;
|
||||
output: Array<UOutput>;
|
||||
config?: {
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
// (undocumented)
|
||||
dataRefs?: TDataRefs;
|
||||
// (undocumented)
|
||||
disabled?: boolean;
|
||||
// (undocumented)
|
||||
factory(
|
||||
params: TParams,
|
||||
context: {
|
||||
@@ -659,16 +682,9 @@ export interface CreateExtensionBlueprintOptions<
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Expand<ExtensionDataValues<TOutput>>;
|
||||
// (undocumented)
|
||||
inputs?: TInputs;
|
||||
// (undocumented)
|
||||
kind: string;
|
||||
// (undocumented)
|
||||
namespace?: string;
|
||||
// (undocumented)
|
||||
output: TOutput;
|
||||
}
|
||||
): Iterable<UFactoryOutput>;
|
||||
dataRefs?: TDataRefs;
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export function createExtensionDataRef<TData>(
|
||||
@@ -769,22 +785,7 @@ export type CreateExtensionOptions<
|
||||
});
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}): Iterable<UFactoryOutput>;
|
||||
} & ((
|
||||
UOutput extends any
|
||||
? UOutput['config']['optional'] extends true
|
||||
? never
|
||||
: UOutput['id']
|
||||
: never
|
||||
) extends infer IRequiredOutputIds
|
||||
? [IRequiredOutputIds] extends [UFactoryOutput['id']]
|
||||
? {}
|
||||
: {
|
||||
'Error: The extension factory is missing the following outputs': Exclude<
|
||||
IRequiredOutputIds,
|
||||
UFactoryOutput['id']
|
||||
>;
|
||||
}
|
||||
: never);
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;
|
||||
|
||||
// @public (undocumented)
|
||||
export function createExtensionOverrides(
|
||||
@@ -1081,15 +1082,26 @@ export interface Extension<TConfig, TConfigInput = TConfig> {
|
||||
// @public (undocumented)
|
||||
export interface ExtensionBlueprint<
|
||||
TParams,
|
||||
TInputs extends AnyExtensionInputMap,
|
||||
TOutput extends AnyExtensionDataMap,
|
||||
UOutput extends AnyExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{
|
||||
optional: boolean;
|
||||
singleton: boolean;
|
||||
}
|
||||
>;
|
||||
},
|
||||
UExtraOutput extends AnyExtensionDataRef,
|
||||
TConfig extends {
|
||||
[key in string]: unknown;
|
||||
},
|
||||
TConfigInput extends {
|
||||
[key in string]: unknown;
|
||||
},
|
||||
TDataRefs extends AnyExtensionDataMap,
|
||||
TDataRefs extends {
|
||||
[name in string]: AnyExtensionDataRef;
|
||||
},
|
||||
> {
|
||||
// (undocumented)
|
||||
dataRefs: TDataRefs;
|
||||
@@ -1097,6 +1109,7 @@ export interface ExtensionBlueprint<
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
>(
|
||||
args: {
|
||||
namespace?: string;
|
||||
@@ -1107,7 +1120,7 @@ export interface ExtensionBlueprint<
|
||||
};
|
||||
disabled?: boolean;
|
||||
inputs?: TInputs;
|
||||
output?: TOutput;
|
||||
output?: Array<UExtraOutput>;
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema & {
|
||||
[KName in keyof TConfig]?: `Error: Config key '${KName &
|
||||
@@ -1115,7 +1128,7 @@ export interface ExtensionBlueprint<
|
||||
};
|
||||
};
|
||||
} & (
|
||||
| {
|
||||
| ({
|
||||
factory(
|
||||
originalFactory: (
|
||||
params: TParams,
|
||||
@@ -1123,7 +1136,7 @@ export interface ExtensionBlueprint<
|
||||
config?: TConfig;
|
||||
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
) => Expand<ExtensionDataValues<TOutput>>,
|
||||
) => Iterable<ExtensionDataRefToValue<UOutput>>,
|
||||
context: {
|
||||
node: AppNode;
|
||||
config: TConfig & {
|
||||
@@ -1133,8 +1146,11 @@ export interface ExtensionBlueprint<
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Expand<ExtensionDataValues<TOutput>>;
|
||||
}
|
||||
): Iterable<UFactoryOutput>;
|
||||
} & VerifyExtensionFactoryOutput<
|
||||
UOutput & UExtraOutput,
|
||||
UFactoryOutput
|
||||
>)
|
||||
| {
|
||||
params: TParams;
|
||||
}
|
||||
@@ -1196,6 +1212,12 @@ export type ExtensionDataRef<
|
||||
readonly config: TConfig;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export type ExtensionDataRefToValue<TDataRef extends AnyExtensionDataRef> =
|
||||
TDataRef extends ExtensionDataRef<infer IData, infer IId, any>
|
||||
? ExtensionDataValue<IData, IId>
|
||||
: never;
|
||||
|
||||
// @public (undocumented)
|
||||
export type ExtensionDataValue<TData, TId extends string> = {
|
||||
readonly $$type: '@backstage/ExtensionDataValue';
|
||||
@@ -1323,16 +1345,23 @@ export const IconBundleBlueprint: ExtensionBlueprint<
|
||||
[x: string]: IconComponent;
|
||||
};
|
||||
},
|
||||
AnyExtensionInputMap,
|
||||
ConfigurableExtensionDataRef<
|
||||
{
|
||||
[x: string]: IconComponent;
|
||||
},
|
||||
'core.icons',
|
||||
{}
|
||||
>,
|
||||
{
|
||||
icons: ConfigurableExtensionDataRef<
|
||||
[x: string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{
|
||||
[x: string]: IconComponent;
|
||||
},
|
||||
'core.icons',
|
||||
{}
|
||||
optional: boolean;
|
||||
singleton: boolean;
|
||||
}
|
||||
>;
|
||||
},
|
||||
AnyExtensionDataRef,
|
||||
{
|
||||
icons: string;
|
||||
test: string;
|
||||
|
||||
@@ -25,16 +25,16 @@ export const IconBundleBlueprint = createExtensionBlueprint({
|
||||
kind: 'icon-bundle',
|
||||
namespace: 'app',
|
||||
attachTo: { id: 'app', input: 'icons' },
|
||||
output: {
|
||||
icons: iconsDataRef,
|
||||
},
|
||||
output: [iconsDataRef],
|
||||
config: {
|
||||
schema: {
|
||||
icons: z => z.string().default('blob'),
|
||||
test: z => z.string(),
|
||||
},
|
||||
},
|
||||
factory: (params: { icons: { [key in string]: IconComponent } }) => params,
|
||||
factory: (params: { icons: { [key in string]: IconComponent } }) => [
|
||||
iconsDataRef(params.icons),
|
||||
],
|
||||
dataRefs: {
|
||||
icons: iconsDataRef,
|
||||
},
|
||||
|
||||
@@ -145,6 +145,27 @@ export interface LegacyCreateExtensionOptions<
|
||||
}): Expand<ExtensionDataValues<TOutput>>;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
export 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']]
|
||||
? {}
|
||||
: {
|
||||
'Error: The extension factory is missing the following outputs': Exclude<
|
||||
IRequiredOutputIds,
|
||||
UFactoryOutput['id']
|
||||
>;
|
||||
}
|
||||
: never;
|
||||
|
||||
/** @public */
|
||||
export type CreateExtensionOptions<
|
||||
UOutput extends AnyExtensionDataRef,
|
||||
@@ -183,22 +204,7 @@ export type CreateExtensionOptions<
|
||||
});
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}): Iterable<UFactoryOutput>;
|
||||
} & ((
|
||||
UOutput extends any
|
||||
? UOutput['config']['optional'] extends true
|
||||
? never
|
||||
: UOutput['id']
|
||||
: never
|
||||
) extends infer IRequiredOutputIds
|
||||
? [IRequiredOutputIds] extends [UFactoryOutput['id']]
|
||||
? {}
|
||||
: {
|
||||
'Error: The extension factory is missing the following outputs': Exclude<
|
||||
IRequiredOutputIds,
|
||||
UFactoryOutput['id']
|
||||
>;
|
||||
}
|
||||
: never);
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;
|
||||
|
||||
/** @public */
|
||||
export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> {
|
||||
|
||||
@@ -27,13 +27,9 @@ describe('createExtensionBlueprint', () => {
|
||||
const TestExtensionBlueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: {
|
||||
element: coreExtensionData.reactElement,
|
||||
},
|
||||
output: [coreExtensionData.reactElement],
|
||||
factory(params: { text: string }) {
|
||||
return {
|
||||
element: <h1>{params.text}</h1>,
|
||||
};
|
||||
return [coreExtensionData.reactElement(<h1>{params.text}</h1>)];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -56,12 +52,10 @@ describe('createExtensionBlueprint', () => {
|
||||
kind: 'test-extension',
|
||||
name: 'my-extension',
|
||||
namespace: undefined,
|
||||
output: {
|
||||
element: coreExtensionData.reactElement,
|
||||
},
|
||||
output: [coreExtensionData.reactElement],
|
||||
factory: expect.any(Function),
|
||||
toString: expect.any(Function),
|
||||
version: 'v1',
|
||||
version: 'v2',
|
||||
});
|
||||
|
||||
const { container } = createExtensionTester(extension).render();
|
||||
@@ -72,13 +66,9 @@ describe('createExtensionBlueprint', () => {
|
||||
const TestExtensionBlueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: {
|
||||
element: coreExtensionData.reactElement,
|
||||
},
|
||||
output: [coreExtensionData.reactElement],
|
||||
factory(params: { text: string }) {
|
||||
return {
|
||||
element: <h1>{params.text}</h1>,
|
||||
};
|
||||
return [coreExtensionData.reactElement(<h1>{params.text}</h1>)];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -103,16 +93,12 @@ describe('createExtensionBlueprint', () => {
|
||||
const TestExtensionBlueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: {
|
||||
element: coreExtensionData.reactElement,
|
||||
},
|
||||
output: [coreExtensionData.reactElement],
|
||||
dataRefs: {
|
||||
data: dataRef,
|
||||
},
|
||||
factory(params: { text: string }) {
|
||||
return {
|
||||
element: <h1>{params.text}</h1>,
|
||||
};
|
||||
return [coreExtensionData.reactElement(<h1>{params.text}</h1>)];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -125,9 +111,7 @@ describe('createExtensionBlueprint', () => {
|
||||
const TestExtensionBlueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: {
|
||||
element: coreExtensionData.reactElement,
|
||||
},
|
||||
output: [coreExtensionData.reactElement],
|
||||
config: {
|
||||
schema: {
|
||||
text: z => z.string(),
|
||||
@@ -142,9 +126,7 @@ describe('createExtensionBlueprint', () => {
|
||||
|
||||
expect(config.text).toBe('Hello, world!');
|
||||
|
||||
return {
|
||||
element: <h1>{config.text}</h1>,
|
||||
};
|
||||
return [coreExtensionData.reactElement(<h1>{config.text}</h1>)];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -188,18 +170,14 @@ describe('createExtensionBlueprint', () => {
|
||||
const TestExtensionBlueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: {
|
||||
element: coreExtensionData.reactElement,
|
||||
},
|
||||
output: [coreExtensionData.reactElement],
|
||||
config: {
|
||||
schema: {
|
||||
text: z => z.string(),
|
||||
},
|
||||
},
|
||||
factory(params: { text: string }) {
|
||||
return {
|
||||
element: <div>{params.text}</div>,
|
||||
};
|
||||
return [coreExtensionData.reactElement(<div>{params.text}</div>)];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -224,16 +202,12 @@ describe('createExtensionBlueprint', () => {
|
||||
const TestExtensionBlueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
attachTo: { id: 'test', input: 'default' },
|
||||
output: {
|
||||
element: coreExtensionData.reactElement,
|
||||
},
|
||||
output: [coreExtensionData.reactElement],
|
||||
factory(_, { config }) {
|
||||
// @ts-expect-error
|
||||
const b = config.something;
|
||||
|
||||
return {
|
||||
element: <div />,
|
||||
};
|
||||
return [coreExtensionData.reactElement(<div />)];
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -17,31 +17,42 @@
|
||||
import { AppNode } from '../apis';
|
||||
import { Expand } from '../types';
|
||||
import {
|
||||
AnyExtensionDataMap,
|
||||
AnyExtensionInputMap,
|
||||
ExtensionDataValues,
|
||||
CreateExtensionOptions,
|
||||
ExtensionDefinition,
|
||||
ResolvedExtensionInputs,
|
||||
VerifyExtensionFactoryOutput,
|
||||
createExtension,
|
||||
} from './createExtension';
|
||||
import { z } from 'zod';
|
||||
import { ExtensionInput } from './createExtensionInput';
|
||||
import {
|
||||
AnyExtensionDataRef,
|
||||
ExtensionDataRefToValue,
|
||||
ExtensionDataValue,
|
||||
} from './createExtensionDataRef';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface CreateExtensionBlueprintOptions<
|
||||
export type CreateExtensionBlueprintOptions<
|
||||
TParams,
|
||||
TInputs extends AnyExtensionInputMap,
|
||||
TOutput extends AnyExtensionDataMap,
|
||||
UOutput extends AnyExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{ optional: boolean; singleton: boolean }
|
||||
>;
|
||||
},
|
||||
TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },
|
||||
TDataRefs extends AnyExtensionDataMap,
|
||||
> {
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TDataRefs extends { [name in string]: AnyExtensionDataRef },
|
||||
> = {
|
||||
kind: string;
|
||||
namespace?: string;
|
||||
attachTo: { id: string; input: string };
|
||||
disabled?: boolean;
|
||||
inputs?: TInputs;
|
||||
output: TOutput;
|
||||
output: Array<UOutput>;
|
||||
config?: {
|
||||
schema: TConfigSchema;
|
||||
};
|
||||
@@ -54,21 +65,27 @@ export interface CreateExtensionBlueprintOptions<
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Expand<ExtensionDataValues<TOutput>>;
|
||||
): Iterable<UFactoryOutput>;
|
||||
|
||||
dataRefs?: TDataRefs;
|
||||
}
|
||||
} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ExtensionBlueprint<
|
||||
TParams,
|
||||
TInputs extends AnyExtensionInputMap,
|
||||
TOutput extends AnyExtensionDataMap,
|
||||
UOutput extends AnyExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{ optional: boolean; singleton: boolean }
|
||||
>;
|
||||
},
|
||||
UExtraOutput extends AnyExtensionDataRef,
|
||||
TConfig extends { [key in string]: unknown },
|
||||
TConfigInput extends { [key in string]: unknown },
|
||||
TDataRefs extends AnyExtensionDataMap,
|
||||
TDataRefs extends { [name in string]: AnyExtensionDataRef },
|
||||
> {
|
||||
dataRefs: TDataRefs;
|
||||
|
||||
@@ -82,6 +99,7 @@ export interface ExtensionBlueprint<
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
>(
|
||||
args: {
|
||||
namespace?: string;
|
||||
@@ -89,7 +107,7 @@ export interface ExtensionBlueprint<
|
||||
attachTo?: { id: string; input: string };
|
||||
disabled?: boolean;
|
||||
inputs?: TInputs;
|
||||
output?: TOutput;
|
||||
output?: Array<UExtraOutput>;
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema & {
|
||||
[KName in keyof TConfig]?: `Error: Config key '${KName &
|
||||
@@ -97,7 +115,7 @@ export interface ExtensionBlueprint<
|
||||
};
|
||||
};
|
||||
} & (
|
||||
| {
|
||||
| ({
|
||||
factory(
|
||||
originalFactory: (
|
||||
params: TParams,
|
||||
@@ -105,7 +123,7 @@ export interface ExtensionBlueprint<
|
||||
config?: TConfig;
|
||||
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
) => Expand<ExtensionDataValues<TOutput>>,
|
||||
) => Iterable<ExtensionDataRefToValue<UOutput>>,
|
||||
context: {
|
||||
node: AppNode;
|
||||
config: TConfig & {
|
||||
@@ -115,8 +133,11 @@ export interface ExtensionBlueprint<
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Expand<ExtensionDataValues<TOutput>>;
|
||||
}
|
||||
): Iterable<UFactoryOutput>;
|
||||
} & VerifyExtensionFactoryOutput<
|
||||
UOutput & UExtraOutput,
|
||||
UFactoryOutput
|
||||
>)
|
||||
| {
|
||||
params: TParams;
|
||||
}
|
||||
@@ -143,17 +164,24 @@ export interface ExtensionBlueprint<
|
||||
*/
|
||||
class ExtensionBlueprintImpl<
|
||||
TParams,
|
||||
TInputs extends AnyExtensionInputMap,
|
||||
TOutput extends AnyExtensionDataMap,
|
||||
UOutput extends AnyExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{ optional: boolean; singleton: boolean }
|
||||
>;
|
||||
},
|
||||
UExtraOutput extends AnyExtensionDataRef,
|
||||
TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },
|
||||
TDataRefs extends AnyExtensionDataMap,
|
||||
TDataRefs extends { [name in string]: AnyExtensionDataRef },
|
||||
> {
|
||||
constructor(
|
||||
private readonly options: CreateExtensionBlueprintOptions<
|
||||
TParams,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TOutput,
|
||||
TConfigSchema,
|
||||
any,
|
||||
TDataRefs
|
||||
>,
|
||||
) {
|
||||
@@ -166,13 +194,14 @@ class ExtensionBlueprintImpl<
|
||||
TExtensionConfigSchema extends {
|
||||
[key in string]: (zImpl: typeof z) => z.ZodType;
|
||||
},
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
>(args: {
|
||||
namespace?: string;
|
||||
name?: string;
|
||||
attachTo?: { id: string; input: string };
|
||||
disabled?: boolean;
|
||||
inputs?: TInputs;
|
||||
output?: TOutput;
|
||||
output?: Array<UExtraOutput>;
|
||||
params?: TParams;
|
||||
config?: {
|
||||
schema: TExtensionConfigSchema;
|
||||
@@ -188,7 +217,7 @@ class ExtensionBlueprintImpl<
|
||||
};
|
||||
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
) => Expand<ExtensionDataValues<TOutput>>,
|
||||
) => Iterable<ExtensionDataRefToValue<UOutput>>,
|
||||
context: {
|
||||
node: AppNode;
|
||||
config: {
|
||||
@@ -200,7 +229,7 @@ class ExtensionBlueprintImpl<
|
||||
};
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
): Expand<ExtensionDataValues<TOutput>>;
|
||||
): Iterable<UFactoryOutput>;
|
||||
}): ExtensionDefinition<
|
||||
{
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
@@ -232,7 +261,7 @@ class ExtensionBlueprintImpl<
|
||||
attachTo: args.attachTo ?? this.options.attachTo,
|
||||
disabled: args.disabled ?? this.options.disabled,
|
||||
inputs: args.inputs ?? this.options.inputs,
|
||||
output: args.output ?? this.options.output,
|
||||
output: [...(args.output ?? []), ...this.options.output],
|
||||
config: Object.keys(schema).length === 0 ? undefined : { schema },
|
||||
factory: ({ node, config, inputs }) => {
|
||||
if (args.factory) {
|
||||
@@ -247,12 +276,13 @@ class ExtensionBlueprintImpl<
|
||||
};
|
||||
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
},
|
||||
) =>
|
||||
this.options.factory(innerParams, {
|
||||
): Iterable<ExtensionDataRefToValue<UOutput>> => {
|
||||
return this.options.factory(innerParams, {
|
||||
node,
|
||||
config: innerContext?.config ?? config,
|
||||
inputs: innerContext?.inputs ?? inputs,
|
||||
}),
|
||||
});
|
||||
},
|
||||
{
|
||||
node,
|
||||
config,
|
||||
@@ -268,7 +298,30 @@ class ExtensionBlueprintImpl<
|
||||
}
|
||||
throw new Error('Either params or factory must be provided');
|
||||
},
|
||||
});
|
||||
} as CreateExtensionOptions<
|
||||
UOutput,
|
||||
TInputs,
|
||||
{
|
||||
[key in keyof TExtensionConfigSchema]: z.infer<
|
||||
ReturnType<TExtensionConfigSchema[key]>
|
||||
>;
|
||||
} & {
|
||||
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
||||
},
|
||||
z.input<
|
||||
z.ZodObject<
|
||||
{
|
||||
[key in keyof TExtensionConfigSchema]: ReturnType<
|
||||
TExtensionConfigSchema[key]
|
||||
>;
|
||||
} & {
|
||||
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
|
||||
}
|
||||
>
|
||||
>,
|
||||
TConfigSchema,
|
||||
UFactoryOutput
|
||||
>);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,22 +333,31 @@ class ExtensionBlueprintImpl<
|
||||
*/
|
||||
export function createExtensionBlueprint<
|
||||
TParams,
|
||||
TInputs extends AnyExtensionInputMap,
|
||||
TOutput extends AnyExtensionDataMap,
|
||||
UOutput extends AnyExtensionDataRef,
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{ optional: boolean; singleton: boolean }
|
||||
>;
|
||||
},
|
||||
UExtraOutput extends AnyExtensionDataRef,
|
||||
TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType },
|
||||
TDataRefs extends AnyExtensionDataMap = never,
|
||||
UFactoryOutput extends ExtensionDataValue<any, any>,
|
||||
TDataRefs extends { [name in string]: AnyExtensionDataRef } = never,
|
||||
>(
|
||||
options: CreateExtensionBlueprintOptions<
|
||||
TParams,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TOutput,
|
||||
TConfigSchema,
|
||||
UFactoryOutput,
|
||||
TDataRefs
|
||||
>,
|
||||
): ExtensionBlueprint<
|
||||
TParams,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TOutput,
|
||||
UExtraOutput,
|
||||
string extends keyof TConfigSchema
|
||||
? {}
|
||||
: { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>> },
|
||||
@@ -310,8 +372,9 @@ export function createExtensionBlueprint<
|
||||
> {
|
||||
return new ExtensionBlueprintImpl(options) as ExtensionBlueprint<
|
||||
TParams,
|
||||
UOutput,
|
||||
TInputs,
|
||||
TOutput,
|
||||
UExtraOutput,
|
||||
string extends keyof TConfigSchema
|
||||
? {}
|
||||
: {
|
||||
|
||||
@@ -33,6 +33,12 @@ export type ExtensionDataRef<
|
||||
readonly config: TConfig;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export type ExtensionDataRefToValue<TDataRef extends AnyExtensionDataRef> =
|
||||
TDataRef extends ExtensionDataRef<infer IData, infer IId, any>
|
||||
? ExtensionDataValue<IData, IId>
|
||||
: never;
|
||||
|
||||
/** @public */
|
||||
export type AnyExtensionDataRef = ExtensionDataRef<
|
||||
unknown,
|
||||
|
||||
@@ -36,6 +36,7 @@ export {
|
||||
createExtensionDataRef,
|
||||
type AnyExtensionDataRef,
|
||||
type ExtensionDataRef,
|
||||
type ExtensionDataRefToValue,
|
||||
type ExtensionDataValue,
|
||||
type ConfigurableExtensionDataRef,
|
||||
} from './createExtensionDataRef';
|
||||
|
||||
Reference in New Issue
Block a user