@yangcurve/actions
Version:
Server Action wrapper inspired by trpc.
706 lines (698 loc) • 39.4 kB
TypeScript
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 };