UNPKG

@yangcurve/actions

Version:

Server Action wrapper inspired by trpc.

706 lines (698 loc) 39.4 kB
import { UseQueryOptions, QueryClient, UseQueryResult, UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; import * as zod from 'zod'; type ActionType = 'query' | 'mutation'; type Action<Info extends { type: ActionType; input: unknown; output: unknown; }> = (input: Info['input']) => Promise<Info['output']>; type Transformer = { stringify: (value: any) => any; parse: (value: any) => any; }; type ClientUtils<Actions extends Record<string, unknown>> = { [Key in keyof Actions]: Key extends string ? Actions[Key] extends Action<infer Info> ? Info['type'] extends 'query' ? { invalidate: (input?: Info['input']) => Promise<void>; } : { isMutating: () => number; } : Actions[Key] extends Record<string, unknown> ? ClientUtils<Actions[Key]> : never : never; } & { invalidate: () => Promise<void>; }; type ClientQueryAction<Info extends { input: unknown; output: unknown; }> = (input: Info['input'], options?: Omit<UseQueryOptions<Info['output']>, 'queryFn' | 'queryKey'>, queryClient?: QueryClient) => UseQueryResult<Info['output']>; type ClientMutationAction<Info extends { input: unknown; output: unknown; }> = (options?: Omit<UseMutationOptions<Info['output'], Error, Info['input']>, 'mutationFn' | 'mutationKey'>, queryClient?: QueryClient) => UseMutationResult<Info['output'], Error, Info['input']>; type ClientProxy<Actions extends Record<string, unknown>> = { [Key in keyof Actions]: Key extends string ? Actions[Key] extends Action<{ type: infer Type extends ActionType; input: infer Input; output: infer Output; }> ? Type extends 'query' ? { useQuery: ClientQueryAction<{ input: Input; output: Output; }>; } : { useMutation: ClientMutationAction<{ input: Input; output: Output; }>; } : Actions[Key] extends Record<string, unknown> ? ClientProxy<Actions[Key]> : never : never; }; type Caller<Actions extends Record<string, unknown>> = Actions & { __brand: 'Caller'; }; declare const initActions: ({ transformer }?: { transformer?: Transformer; }) => { createProcedure: <Context>({ createContext, }?: { createContext?: () => Context | Promise<Context>; }) => { use: <M extends (params: { ctx: Context; next: { (): Promise<{ __ctx: Context; __brand: "MiddlewareResult"; }>; <NewContext_1>(newCtx: NewContext_1): Promise<{ __ctx: NewContext_1; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: Context; __brand: "MiddlewareResult"; }>; <NewContext_1>(newCtx: NewContext_1): Promise<{ __ctx: NewContext_1; __brand: "MiddlewareResult"; }>; }>, NewContext = Awaited<ReturnType<M>>["__ctx"]>(middleware: M) => { use: <M_1 extends (params: { ctx: NewContext; next: { (): Promise<{ __ctx: NewContext; __brand: "MiddlewareResult"; }>; <NewContext_2>(newCtx: NewContext_2): Promise<{ __ctx: NewContext_2; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext; __brand: "MiddlewareResult"; }>; <NewContext_2>(newCtx: NewContext_2): Promise<{ __ctx: NewContext_2; __brand: "MiddlewareResult"; }>; }>, NewContext_1 = Awaited<ReturnType<M_1>>["__ctx"]>(middleware: M_1) => { use: <M_2 extends (params: { ctx: NewContext_1; next: { (): Promise<{ __ctx: NewContext_1; __brand: "MiddlewareResult"; }>; <NewContext_3>(newCtx: NewContext_3): Promise<{ __ctx: NewContext_3; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_1; __brand: "MiddlewareResult"; }>; <NewContext_3>(newCtx: NewContext_3): Promise<{ __ctx: NewContext_3; __brand: "MiddlewareResult"; }>; }>, NewContext_2 = Awaited<ReturnType<M_2>>["__ctx"]>(middleware: M_2) => { use: <M_3 extends (params: { ctx: NewContext_2; next: { (): Promise<{ __ctx: NewContext_2; __brand: "MiddlewareResult"; }>; <NewContext_4>(newCtx: NewContext_4): Promise<{ __ctx: NewContext_4; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_2; __brand: "MiddlewareResult"; }>; <NewContext_4>(newCtx: NewContext_4): Promise<{ __ctx: NewContext_4; __brand: "MiddlewareResult"; }>; }>, NewContext_3 = Awaited<ReturnType<M_3>>["__ctx"]>(middleware: M_3) => { use: <M_4 extends (params: { ctx: NewContext_3; next: { (): Promise<{ __ctx: NewContext_3; __brand: "MiddlewareResult"; }>; <NewContext_5>(newCtx: NewContext_5): Promise<{ __ctx: NewContext_5; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_3; __brand: "MiddlewareResult"; }>; <NewContext_5>(newCtx: NewContext_5): Promise<{ __ctx: NewContext_5; __brand: "MiddlewareResult"; }>; }>, NewContext_4 = Awaited<ReturnType<M_4>>["__ctx"]>(middleware: M_4) => { use: <M_5 extends (params: { ctx: NewContext_4; next: { (): Promise<{ __ctx: NewContext_4; __brand: "MiddlewareResult"; }>; <NewContext_6>(newCtx: NewContext_6): Promise<{ __ctx: NewContext_6; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_4; __brand: "MiddlewareResult"; }>; <NewContext_6>(newCtx: NewContext_6): Promise<{ __ctx: NewContext_6; __brand: "MiddlewareResult"; }>; }>, NewContext_5 = Awaited<ReturnType<M_5>>["__ctx"]>(middleware: M_5) => { use: <M_6 extends (params: { ctx: NewContext_5; next: { (): Promise<{ __ctx: NewContext_5; __brand: "MiddlewareResult"; }>; <NewContext_7>(newCtx: NewContext_7): Promise<{ __ctx: NewContext_7; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_5; __brand: "MiddlewareResult"; }>; <NewContext_7>(newCtx: NewContext_7): Promise<{ __ctx: NewContext_7; __brand: "MiddlewareResult"; }>; }>, NewContext_6 = Awaited<ReturnType<M_6>>["__ctx"]>(middleware: M_6) => { use: <M_7 extends (params: { ctx: NewContext_6; next: { (): Promise<{ __ctx: NewContext_6; __brand: "MiddlewareResult"; }>; <NewContext_8>(newCtx: NewContext_8): Promise<{ __ctx: NewContext_8; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_6; __brand: "MiddlewareResult"; }>; <NewContext_8>(newCtx: NewContext_8): Promise<{ __ctx: NewContext_8; __brand: "MiddlewareResult"; }>; }>, NewContext_7 = Awaited<ReturnType<M_7>>["__ctx"]>(middleware: M_7) => { use: <M_8 extends (params: { ctx: NewContext_7; next: { (): Promise<{ __ctx: NewContext_7; __brand: "MiddlewareResult"; }>; <NewContext_9>(newCtx: NewContext_9): Promise<{ __ctx: NewContext_9; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_7; __brand: "MiddlewareResult"; }>; <NewContext_9>(newCtx: NewContext_9): Promise<{ __ctx: NewContext_9; __brand: "MiddlewareResult"; }>; }>, NewContext_8 = Awaited<ReturnType<M_8>>["__ctx"]>(middleware: M_8) => { use: <M_9 extends (params: { ctx: NewContext_8; next: { (): Promise<{ __ctx: NewContext_8; __brand: "MiddlewareResult"; }>; <NewContext_10>(newCtx: NewContext_10): Promise<{ __ctx: NewContext_10; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_8; __brand: "MiddlewareResult"; }>; <NewContext_10>(newCtx: NewContext_10): Promise<{ __ctx: NewContext_10; __brand: "MiddlewareResult"; }>; }>, NewContext_9 = Awaited<ReturnType<M_9>>["__ctx"]>(middleware: M_9) => { use: <M_10 extends (params: { ctx: NewContext_9; next: { (): Promise<{ __ctx: NewContext_9; __brand: "MiddlewareResult"; }>; <NewContext_11>(newCtx: NewContext_11): Promise<{ __ctx: NewContext_11; __brand: "MiddlewareResult"; }>; }; }) => ReturnType<{ (): Promise<{ __ctx: NewContext_9; __brand: "MiddlewareResult"; }>; <NewContext_11>(newCtx: NewContext_11): Promise<{ __ctx: NewContext_11; __brand: "MiddlewareResult"; }>; }>, NewContext_10 = Awaited<ReturnType<M_10>>["__ctx"]>(middleware: M_10) => any; query: <Output>(resolver: (param: { ctx: NewContext_9; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_9; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_9; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_9; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext_8; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_8; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_8; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_8; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext_7; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_7; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_7; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_7; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext_6; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_6; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_6; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_6; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext_5; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_5; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_5; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_5; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext_4; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_4; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_4; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_4; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext_3; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_3; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_3; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_3; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext_2; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_2; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_2; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_2; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext_1; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_1; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext_1; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext_1; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: NewContext; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: NewContext; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: NewContext; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; query: <Output>(resolver: (param: { ctx: Context; input: void; }) => Output | Promise<Output>) => Action<{ type: "query"; input: void; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: Context; input: void; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: void; output: Output; }>; input: <Schema_1 extends zod.ZodType>(Schema: Schema_1) => { query: <Output>(resolver: (param: { ctx: Context; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "query"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; mutation: <Output>(resolver: (param: { ctx: Context; input: zod.TypeOf<Schema_1>; }) => Output | Promise<Output>) => Action<{ type: "mutation"; input: undefined extends zod.input<Schema_1> ? void | zod.input<Schema_1> : zod.input<Schema_1>; output: Output; }>; }; }; createCaller: <Actions extends Record<string, unknown>>(actions: Actions, path?: readonly string[]) => Caller<Actions>; createClientCaller: <Actions extends Record<string, unknown>>(actions: Caller<Actions>) => ClientProxy<Actions> & { useUtils: () => ClientUtils<Actions>; }; }; type InferActionInput<Actions extends Caller<Record<string, unknown>>> = Omit<{ [Key in keyof Actions]: Actions[Key] extends Action<infer Info> ? Info['input'] : Actions[Key] extends Record<string, unknown> ? InferActionInput<Actions[Key] & { __brand: 'Caller'; }> : never; }, '__brand'>; type InferActionOutput<Actions extends Caller<Record<string, unknown>>> = Omit<{ [Key in keyof Actions]: Actions[Key] extends Action<infer Info> ? Info['output'] : Actions[Key] extends Record<string, unknown> ? InferActionOutput<Actions[Key] & { __brand: 'Caller'; }> : never; }, '__brand'>; export { type InferActionInput, type InferActionOutput, initActions };