UNPKG

safe-actions-state

Version:

A lightweight, type-safe utility for Next.js server & client actions with built-in authentication and RBAC(role based access control) checks, Zod validation, auto retries if server action fails, and real-time toast feedback out of the box. Just write your

69 lines (63 loc) 2.17 kB
import { z } from 'zod'; import * as react from 'react'; type FieldErrors<T> = { [K in keyof T]?: string[]; }; type ActionState<TInput, TOutput> = { fieldErrors?: FieldErrors<TInput>; error?: string; data?: TOutput; } | void; type SessionObject = { authenticated: boolean; role?: string; }; type PublicAction = { isPrivate: false; }; type PrivateAction = { isPrivate: true; }; type RoleBasedAction = { isPrivate: true; allowedRoles: string[]; }; type ActionType = PublicAction | PrivateAction | RoleBasedAction; type ActionWithInputs<TInput, TOutput> = { withInputs: true; handler: (validatedData: TInput) => Promise<ActionState<TInput, TOutput>>; schema: z.Schema<TInput>; }; type ActionWithoutInputs<TOutput> = { withInputs: false; handler: () => Promise<ActionState<undefined, TOutput>>; }; type Action<TInput, TOutput> = ActionWithInputs<TInput, TOutput> | ActionWithoutInputs<TOutput>; type SafeActionProps<TInput, TOutput> = { action: Action<TInput, TOutput>; actionType: ActionType; }; declare const createSafeAction: <TInput, TOutput>({ action, actionType, }: SafeActionProps<TInput, TOutput>) => (data: TInput) => Promise<ActionState<TInput, TOutput>>; type SafeActionType<TInput, TOutput> = (data: TInput) => Promise<ActionState<TInput, TOutput>>; type UseActionOptions<TOutput> = { retries?: number; onStart?: () => void; onSuccess?: (data?: TOutput) => void; onError?: (error: string) => void; onComplete?: () => void; toastMessages?: { loading: string; success: string; }; }; declare const useSafeAction: <TInput, TOutput>(serverAction: SafeActionType<TInput, TOutput>, options?: UseActionOptions<TOutput>) => { clientAction: (input: TInput) => Promise<void>; abortAction: () => void | undefined; error: string | undefined; data: TOutput | undefined; isPending: boolean; fieldErrors: FieldErrors<TInput> | undefined; setFieldErrors: react.Dispatch<react.SetStateAction<FieldErrors<TInput> | undefined>>; }; export { createSafeAction, useSafeAction }; export type { SafeActionType, SessionObject, UseActionOptions };