import z, { ZodObject, ZodRawShape } from "zod"; export class Action { constructor(readonly state: TActionState) {} /** * Input object required by the action to fulfill its function. * * @param input - Schema defining the input requirements of the action. */ input(input: TInput): Action & { input: ZodObject }> { return new Action({ ...this.state, input: z.object(input) as any }); } /** * Output object defining the result shape of the action. * * @param output - Schema defining the result shape. */ output(output: TOutput): Action & { output: ZodObject }> { return new Action({ ...this.state, output: z.object(output) as any }); } /** * Add handler method to the action. * * @param handle - Handler method. */ handle>( handle: THandleFn, ): Action & { handle: THandleFn }> { return new Action({ ...this.state, handle }); } } /* |-------------------------------------------------------------------------------- | Factory |-------------------------------------------------------------------------------- */ export const action: { make(name: string): Action; } = { make(name: string) { return new Action({ name }); }, }; /* |-------------------------------------------------------------------------------- | Types |-------------------------------------------------------------------------------- */ type ActionState = { name: string; input?: ZodObject; output?: ZodObject; handle?: ActionHandlerFn; }; type ActionHandlerFn = TInput extends ZodObject ? (input: z.infer) => TOutput extends ZodObject ? Promise> : Promise : () => TOutput extends ZodObject ? Promise> : Promise;