diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 0c89ff1567..84438d2f85 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -365,50 +365,6 @@ export function createExtension< namespace: string | undefined extends TNamespace ? undefined : TNamespace; name: string | undefined extends TName ? undefined : TName; } ->; -export function createExtension< - const TKind extends string | undefined, - const TNamespace extends string | undefined, - const TName extends string | undefined, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, - UFactoryOutput extends ExtensionDataValue, ->( - options: CreateExtensionOptions< - TKind, - TNamespace, - TName, - UOutput, - TInputs, - TConfigSchema, - UFactoryOutput - >, -): ExtensionDefinition< - string extends keyof TConfigSchema - ? {} - : { - [key in keyof TConfigSchema]: z.infer>; - }, - string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >, - UOutput, - TInputs, - { - kind: TKind; - namespace: TNamespace; - name: TName; - } > { const schemaDeclaration = options.config?.schema; const configSchema = @@ -447,76 +403,7 @@ export function createExtension< parts.push(`attachTo=${options.attachTo.id}@${options.attachTo.input}`); return `ExtensionDefinition{${parts.join(',')}}`; }, - override: < - TExtensionConfigSchema extends { - [key in string]: (zImpl: typeof z) => z.ZodType; - }, - UOverrideFactoryOutput extends ExtensionDataValue, - UNewOutput extends AnyExtensionDataRef, - TExtraInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - >(overrideOptions: { - attachTo?: { id: string; input: string }; - disabled?: boolean; - inputs?: TExtraInputs; - output?: Array; - config?: { - schema: TExtensionConfigSchema; - }; - factory( - originalFactory: (context?: { - config?: { - [key in keyof TConfigSchema]: z.infer< - ReturnType - >; - }; - inputs?: ResolveInputValueOverrides; - }) => ExtensionDataContainer, - context: { - node: AppNode; - config: { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; - } & { - [key in keyof TConfigSchema]: z.infer< - ReturnType - >; - }; - inputs: Expand>; - }, - ): Iterable; - }): ExtensionDefinition< - { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; - } & { - [key in keyof TConfigSchema]: z.infer>; - }, - z.input< - z.ZodObject< - { - [key in keyof TExtensionConfigSchema]: ReturnType< - TExtensionConfigSchema[key] - >; - } & { - [key in keyof TConfigSchema]: ReturnType; - } - > - >, - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, - TInputs & TExtraInputs, - { - kind: TKind; - namespace: TNamespace; - name: TName; - } - > => { + override(overrideOptions) { if (!Array.isArray(options.output)) { throw new Error( 'Cannot override an extension that is not declared using the new format with outputs as an array', @@ -531,12 +418,6 @@ export function createExtension< TConfigSchema, UFactoryOutput >; - const overrideNewConfigSchema = overrideOptions.config?.schema; - - const schema = { - ...newOptions.config?.schema, - ...overrideNewConfigSchema, - } as TConfigSchema & TExtensionConfigSchema; return createExtension({ kind: newOptions.kind, @@ -545,75 +426,74 @@ export function createExtension< attachTo: overrideOptions.attachTo ?? newOptions.attachTo, disabled: overrideOptions.disabled ?? newOptions.disabled, inputs: { ...overrideOptions.inputs, ...newOptions.inputs }, - output: overrideOptions.output ?? newOptions.output, - config: Object.keys(schema).length === 0 ? undefined : { schema }, + output: (overrideOptions.output ?? + newOptions.output) as AnyExtensionDataRef[], + config: + newOptions.config || overrideOptions.config + ? { + schema: { + ...newOptions.config?.schema, + ...overrideOptions.config?.schema, + }, + } + : undefined, factory: ({ node, config, inputs }) => { if (!overrideOptions.factory) { return newOptions.factory({ node, - config, - inputs: inputs as unknown as Expand< - ResolvedExtensionInputs - >, + config: config as any, + inputs: inputs as any, }); } const parentResult = overrideOptions.factory( - (innerContext?: { - config?: { - [key in keyof TConfigSchema]: z.infer< - ReturnType - >; - }; - inputs?: ResolveInputValueOverrides; - }): ExtensionDataContainer => { + (innerContext): ExtensionDataContainer => { return createExtensionDataContainer( newOptions.factory({ node, - config: innerContext?.config ?? config, + config: (innerContext?.config ?? config) as any, inputs: resolveInputOverrides( newOptions.inputs, inputs, innerContext?.inputs, - ) as any, // TODO: Might be able to improve this once legacy inputs are gone + ) as any, }) as Iterable, newOptions.output, ); }, { node, - config, - inputs, + config: config as any, + inputs: inputs as any, }, ); - const deduplicatedResult = new Map(); + const deduplicatedResult = new Map< + string, + ExtensionDataValue + >(); for (const item of parentResult) { deduplicatedResult.set(item.id, item); } - return deduplicatedResult.values() as Iterable; + return deduplicatedResult.values(); }, - } as CreateExtensionOptions); + }) as ExtensionDefinition; }, } as InternalExtensionDefinition< - string extends keyof TConfigSchema - ? {} - : { - [key in keyof TConfigSchema]: z.infer>; - }, - string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >, + { + [key in keyof TConfigSchema]: z.infer>; + }, + z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >, UOutput, TInputs, { - kind: TKind; - namespace: TNamespace; - name: TName; + kind: string | undefined extends TKind ? undefined : TKind; + namespace: string | undefined extends TNamespace ? undefined : TNamespace; + name: string | undefined extends TName ? undefined : TName; } >; } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index c27893489d..7cc1dcd678 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -17,7 +17,6 @@ import { AppNode } from '../apis'; import { Expand } from '../types'; import { - CreateExtensionOptions, ExtensionDefinition, ResolvedExtensionInputs, VerifyExtensionFactoryOutput, @@ -211,193 +210,6 @@ export interface ExtensionBlueprint< >; } -/** - * @internal - */ -class ExtensionBlueprintImpl< - TKind extends string, - TNamespace extends string | undefined, - TName extends string | undefined, - TParams, - 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 { [name in string]: AnyExtensionDataRef }, -> { - constructor( - private readonly options: CreateExtensionBlueprintOptions< - TKind, - TNamespace, - TName, - TParams, - UOutput, - TInputs, - TConfigSchema, - any, - TDataRefs - >, - ) { - this.dataRefs = options.dataRefs!; - } - - dataRefs: TDataRefs; - - public makeWithOverrides< - TExtensionConfigSchema extends { - [key in string]: (zImpl: typeof z) => z.ZodType; - }, - UFactoryOutput extends ExtensionDataValue, - UNewOutput extends AnyExtensionDataRef, - TExtraInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - TNewNamespace extends string | undefined = undefined, - TNewName extends string | undefined = undefined, - >(args: { - namespace?: TNewNamespace; - name?: TNewName; - attachTo?: { id: string; input: string }; - disabled?: boolean; - inputs?: TExtraInputs; - output?: Array; - config?: { - schema: TExtensionConfigSchema; - }; - factory( - originalFactory: ( - params: TParams, - context?: { - config?: { - [key in keyof TConfigSchema]: z.infer< - ReturnType - >; - }; - inputs?: ResolveInputValueOverrides; - }, - ) => ExtensionDataContainer, - context: { - node: AppNode; - config: { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; - } & { - [key in keyof TConfigSchema]: z.infer>; - }; - inputs: Expand>; - }, - ): Iterable; - }): ExtensionDefinition< - { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; - } & { - [key in keyof TConfigSchema]: z.infer>; - }, - z.input< - z.ZodObject< - { - [key in keyof TExtensionConfigSchema]: ReturnType< - TExtensionConfigSchema[key] - >; - } & { - [key in keyof TConfigSchema]: ReturnType; - } - > - > - > { - const schema = { - ...this.options.config?.schema, - ...args.config?.schema, - } as TConfigSchema & TExtensionConfigSchema; - - return createExtension({ - kind: this.options.kind, - namespace: args.namespace ?? this.options.namespace, - name: args.name ?? this.options.name, - attachTo: args.attachTo ?? this.options.attachTo, - disabled: args.disabled ?? this.options.disabled, - inputs: { ...args.inputs, ...this.options.inputs }, - output: args.output ?? this.options.output, - config: Object.keys(schema).length === 0 ? undefined : { schema }, - factory: ({ node, config, inputs }) => { - return args.factory( - ( - innerParams: TParams, - innerContext?: { - config?: { - [key in keyof TConfigSchema]: z.infer< - ReturnType - >; - }; - inputs?: ResolveInputValueOverrides; - }, - ): ExtensionDataContainer => { - return createExtensionDataContainer( - this.options.factory(innerParams, { - node, - config: innerContext?.config ?? config, - inputs: resolveInputOverrides( - this.options.inputs, - inputs, - innerContext?.inputs, - ) as any, // TODO: Might be able to improve this once legacy inputs are gone - }), - this.options.output, - ); - }, - { - node, - config, - inputs, - }, - ); - }, - } as CreateExtensionOptions); - } - - public make< - TNewNamespace extends string | undefined = undefined, - TNewName extends string | undefined = undefined, - >(args: { - namespace?: TNewNamespace; - name?: TNewName; - attachTo?: { id: string; input: string }; - disabled?: boolean; - params: TParams; - }): ExtensionDefinition< - { - [key in keyof TConfigSchema]: z.infer>; - }, - z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - > - > { - return createExtension({ - kind: this.options.kind, - namespace: args.namespace ?? this.options.namespace, - name: args.name ?? this.options.name, - attachTo: args.attachTo ?? this.options.attachTo, - disabled: args.disabled ?? this.options.disabled, - inputs: this.options.inputs, - output: this.options.output, - config: this.options.config, - factory: ctx => this.options.factory(args.params, ctx), - } as CreateExtensionOptions); - } -} - /** * A simpler replacement for wrapping up `createExtension` inside a kind or type. This allows for a cleaner API for creating * types and instances of those types. @@ -452,7 +264,68 @@ export function createExtensionBlueprint< >, TDataRefs > { - return new ExtensionBlueprintImpl(options) as ExtensionBlueprint< + return { + dataRefs: options.dataRefs, + make(args) { + return createExtension({ + kind: options.kind, + namespace: args.namespace ?? options.namespace, + name: args.name ?? options.name, + attachTo: args.attachTo ?? options.attachTo, + disabled: args.disabled ?? options.disabled, + inputs: options.inputs, + output: options.output as AnyExtensionDataRef[], + config: options.config, + factory: ctx => + options.factory(args.params, ctx) as Iterable< + ExtensionDataValue + >, + }); + }, + makeWithOverrides(args) { + return createExtension({ + kind: options.kind, + namespace: args.namespace ?? options.namespace, + name: args.name ?? options.name, + attachTo: args.attachTo ?? options.attachTo, + disabled: args.disabled ?? options.disabled, + inputs: { ...args.inputs, ...options.inputs }, + output: (args.output ?? options.output) as AnyExtensionDataRef[], + config: + options.config || args.config + ? { + schema: { + ...options.config?.schema, + ...args.config?.schema, + }, + } + : undefined, + factory: ({ node, config, inputs }) => { + return args.factory( + (innerParams, innerContext) => { + return createExtensionDataContainer( + options.factory(innerParams, { + node, + config: (innerContext?.config ?? config) as any, + inputs: resolveInputOverrides( + options.inputs, + inputs, + innerContext?.inputs, + ) as any, + }) as Iterable, + options.output, + ); + }, + { + node, + config: config as any, + inputs: inputs as any, + }, + ) as Iterable>; + }, + }) as ExtensionDefinition; + }, + } as ExtensionBlueprint< { kind: TKind; namespace: TNamespace; diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts index 3651eb3ee5..8d293fceb3 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts @@ -39,19 +39,6 @@ export function createExtensionInput< singleton: TConfig['singleton'] extends true ? true : false; optional: TConfig['optional'] extends true ? true : false; } ->; -export function createExtensionInput< - TExtensionData extends ExtensionDataRef, - TConfig extends { singleton?: boolean; optional?: boolean }, ->( - extensionData: Array, - config?: TConfig, -): ExtensionInput< - TExtensionData, - { - singleton: TConfig['singleton'] extends true ? true : false; - optional: TConfig['optional'] extends true ? true : false; - } > { if (process.env.NODE_ENV !== 'production') { if (Array.isArray(extensionData)) { @@ -85,7 +72,7 @@ export function createExtensionInput< : false, }, } as ExtensionInput< - TExtensionData, + UExtensionData, { singleton: TConfig['singleton'] extends true ? true : false; optional: TConfig['optional'] extends true ? true : false;