import type { WorkflowType } from '@immich/sdk'; import { hostFunctions } from 'src/host-functions.js'; import type { WorkflowEventPayload, WorkflowResponse, WorkflowStepConfig, } from 'src/types.js'; type Property = { type: 'string' | 'boolean' | 'number'; array?: boolean; enum?: string[]; } & { type: 'object'; properties: { [K: string]: Property }; required?: string[]; }; type RequiredProperties< Properties extends { [K: string]: unknown }, Required extends string[] | undefined, RequiredKeys extends string = Required extends undefined ? never : NonNullable[number], > = { properties: Pick & Partial>; }; type GetConfigType = 'enum' extends keyof T ? NonNullable[number] : T['type'] extends 'boolean' ? boolean : T['type'] extends 'number' ? number : T['type'] extends 'string' ? string : T['type'] extends 'object' ? ConfigValue : never; type ConfigValue< T extends { properties: { [K: string]: Property }; required?: string[] }, Properties extends { [K: string]: Property } = T['properties'], > = T extends never ? never : RequiredProperties< { [K in keyof Properties]: Properties[K]['array'] extends true ? Array> : GetConfigType; }, 'required' extends keyof T ? T['required'] : undefined >['properties']; export const getWrapper = >() => < K extends T['methods'][number]['name'], L extends WorkflowType = (T['methods'][number] & { name: K; })['types'][number], TConfig = ConfigValue<(T['methods'][number] & { name: K })['schema']>, >( fn: ( payload: WorkflowEventPayload & { functions: ReturnType; }, ) => WorkflowResponse | undefined, ) => () => { const input = Host.inputString(); try { const payload = JSON.parse(input) as WorkflowEventPayload; const event = { ...payload, functions: hostFunctions(payload.workflow.authToken), }; const eventConfigBefore = JSON.stringify(event.config); console.debug( `Inputs: trigger=${event.trigger}, event=${event.type}, config=${eventConfigBefore}`, ); const response = fn(event) ?? {}; // if config changed, notify host const eventConfigAfter = JSON.stringify(event.config); if (!response.config && eventConfigBefore !== eventConfigAfter) { response.config = event.config as WorkflowStepConfig; } console.debug( `Outputs: workflow=${JSON.stringify(response.workflow)}, changes=${JSON.stringify(response.changes)}, data=${JSON.stringify(response.data)}, config=${JSON.stringify(response.config)}`, ); const output = JSON.stringify(response); Host.outputString(output); } catch (error: Error | any) { console.error(`Unhandled plugin exception: ${error.message || error}`); throw error; } };