UNPKG

yup-server-action

Version:

Server actions powered by Yup

1 lines 5.73 kB
{"version":3,"sources":["../src/create-server-action.ts","../src/use-server-action.ts"],"sourcesContent":["import * as yup from \"yup\";\n\ntype MaybePromise<T> = T | Promise<T>;\ntype NoInput = undefined;\n\ntype ServerActionHandlerContext<TInput> = TInput extends NoInput\n ? {}\n : { input: TInput };\n\ntype ServerActionHandler<TInput, TResult> = (\n ctx: ServerActionHandlerContext<TInput>\n) => MaybePromise<TResult>;\n\n// ✅ Atualizado para incluir TResult\nexport type ServerAction<TInput, TResult = any> = {\n _inputType: TInput;\n _resultType: TResult; // Apenas para inferência, não será usado\n run: (rawInput: TInput extends undefined ? void : TInput) => Promise<TResult>;\n};\n\ntype ServerActionBuilderWithoutInput = {\n input<TNewInputSchema extends yup.ObjectSchema<Record<string, unknown>>>(\n schema: TNewInputSchema\n ): ServerActionBuilderWithInput<yup.InferType<TNewInputSchema>>;\n\n handle<TResult>(\n fn: ServerActionHandler<NoInput, TResult>\n ): ServerAction<undefined, TResult>;\n};\n\ntype ServerActionBuilderWithInput<TInput> = {\n handle<TResult>(\n fn: ServerActionHandler<TInput, TResult>\n ): ServerAction<TInput, TResult>;\n};\n\nfunction internalBuilder<TInput>(\n inputSchema?: yup.ObjectSchema<Record<string, unknown>>\n): TInput extends NoInput\n ? ServerActionBuilderWithoutInput\n : ServerActionBuilderWithInput<TInput> {\n const obj: any = {\n input<TNewInputSchema extends yup.ObjectSchema<Record<string, unknown>>>(\n schema: TNewInputSchema\n ) {\n return internalBuilder<yup.InferType<TNewInputSchema>>(schema);\n },\n\n handle<TResult>(\n fn: ServerActionHandler<any, TResult>\n ): ServerAction<any, TResult> {\n return {\n _inputType: undefined as any,\n _resultType: undefined as any,\n run: async (rawInput: unknown) => {\n const parsedInput = inputSchema\n ? await inputSchema.validate(rawInput, { abortEarly: false })\n : undefined;\n\n const ctx = inputSchema ? { input: parsedInput } : {};\n return fn(ctx);\n },\n };\n },\n };\n\n return obj;\n}\n\nexport function createServerAction(): ServerActionBuilderWithoutInput;\n\nexport function createServerAction<\n TSchema extends yup.ObjectSchema<Record<string, unknown>>\n>(schema: TSchema): ServerActionBuilderWithInput<yup.InferType<TSchema>>;\n\nexport function createServerAction(\n schema?: yup.ObjectSchema<Record<string, unknown>>\n) {\n return schema ? internalBuilder(schema) : internalBuilder<NoInput>();\n}\n","import { useState } from \"react\";\nimport type { ServerAction } from \"./create-server-action\";\n\ntype InferInput<T> = T extends ServerAction<infer Input, any> ? Input : never;\ntype InferResult<T> = T extends ServerAction<any, infer Result>\n ? Result\n : never;\n\ntype UseServerActionOptions<TAction extends ServerAction<any, any>> = {\n onSuccess?: (data: InferResult<TAction>) => void;\n onError?: (error: unknown) => void;\n};\n\ntype UseServerActionReturn<TAction extends ServerAction<any, any>> = {\n execute: InferInput<TAction> extends undefined\n ? () => Promise<void>\n : (input: InferInput<TAction>) => Promise<void>;\n isPending: boolean;\n isSuccess: boolean;\n isError: boolean;\n data: InferResult<TAction> | undefined;\n error: unknown | undefined;\n};\n\nexport function useServerAction<TAction extends ServerAction<any, any>>(\n action: TAction,\n options?: UseServerActionOptions<TAction>\n): UseServerActionReturn<TAction> {\n const [isPending, setIsPending] = useState(false);\n const [isSuccess, setIsSuccess] = useState(false);\n const [isError, setIsError] = useState(false);\n const [data, setData] = useState<InferResult<TAction> | undefined>(undefined);\n const [error, setError] = useState<unknown | undefined>(undefined);\n\n const execute = async (\n ...args: InferInput<TAction> extends undefined ? [] : [InferInput<TAction>]\n ): Promise<void> => {\n setIsPending(true);\n setIsSuccess(false);\n setIsError(false);\n\n try {\n const result = await action.run(...(args as [InferInput<TAction>]));\n options?.onSuccess?.(result);\n setIsSuccess(true);\n setData(result);\n } catch (error) {\n options?.onError?.(error);\n setIsError(true);\n setError(error);\n throw error;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n execute: execute as UseServerActionReturn<TAction>[\"execute\"],\n isPending,\n isSuccess,\n isError,\n data,\n error,\n };\n}\n"],"mappings":";AAoCA,SAAS,gBACP,aAGuC;AACvC,QAAM,MAAW;AAAA,IACf,MACE,QACA;AACA,aAAO,gBAAgD,MAAM;AAAA,IAC/D;AAAA,IAEA,OACE,IAC4B;AAC5B,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,KAAK,OAAO,aAAsB;AAChC,gBAAM,cAAc,cAChB,MAAM,YAAY,SAAS,UAAU,EAAE,YAAY,MAAM,CAAC,IAC1D;AAEJ,gBAAM,MAAM,cAAc,EAAE,OAAO,YAAY,IAAI,CAAC;AACpD,iBAAO,GAAG,GAAG;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAQO,SAAS,mBACd,QACA;AACA,SAAO,SAAS,gBAAgB,MAAM,IAAI,gBAAyB;AACrE;;;AC/EA,SAAS,gBAAgB;AAwBlB,SAAS,gBACd,QACA,SACgC;AAChC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,MAAM,OAAO,IAAI,SAA2C,MAAS;AAC5E,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA8B,MAAS;AAEjE,QAAM,UAAU,UACX,SACe;AAClB,iBAAa,IAAI;AACjB,iBAAa,KAAK;AAClB,eAAW,KAAK;AAEhB,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,IAAI,GAAI,IAA8B;AAClE,eAAS,YAAY,MAAM;AAC3B,mBAAa,IAAI;AACjB,cAAQ,MAAM;AAAA,IAChB,SAASA,QAAO;AACd,eAAS,UAAUA,MAAK;AACxB,iBAAW,IAAI;AACf,eAASA,MAAK;AACd,YAAMA;AAAA,IACR,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":["error"]}