UNPKG

next-safe-action

Version:

Type safe and validated Server Actions in your Next.js project.

280 lines (279 loc) 13.6 kB
import { B as InferInputOrDefault, C as SafeActionResult, H as StandardSchemaV1, R as MaybePromise, S as SafeActionFn, T as SafeStateActionFn, b as NormalizeActionResult, v as NavigationKind, z as Prettify } from "./index.types-35LqR3EA.mjs"; //#region src/hooks.types.d.ts /** * Hook options: configuration + lifecycle callbacks. * * When `throwOnNavigation` is `true`, `onNavigation` and `onSettled` callbacks are not available * because the render-phase throw prevents React from committing effects. This is a fundamental * constraint of React's rendering model: when a component throws during render, the commit phase * (where effects run) is never reached. * * Use server-side action callbacks for guaranteed navigation side effects. */ type HookBaseOptions<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data> = ({ throwOnNavigation?: false; } & HookCallbacks<ServerError, Schema, ShapedErrors, Data>) | ({ throwOnNavigation: true; } & Omit<HookCallbacks<ServerError, Schema, ShapedErrors, Data>, "onNavigation" | "onSettled">); /** * Type of hooks callbacks. These are executed when action is in a specific state. */ type HookCallbacks<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data> = { onExecute?: (args: { input: InferInputOrDefault<Schema, undefined>; }) => MaybePromise<unknown>; onSuccess?: (args: { data: Data; input: InferInputOrDefault<Schema, undefined>; }) => MaybePromise<unknown>; onError?: (args: { error: Prettify<Omit<SafeActionResult<ServerError, Schema, ShapedErrors, Data>, "data">> & { thrownError?: Error; }; input: InferInputOrDefault<Schema, undefined>; }) => MaybePromise<unknown>; onNavigation?: (args: { input: InferInputOrDefault<Schema, undefined>; navigationKind: NavigationKind; }) => MaybePromise<unknown>; onSettled?: (args: { result: Prettify<NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>>; input: InferInputOrDefault<Schema, undefined>; navigationKind?: NavigationKind; }) => MaybePromise<unknown>; }; /** * Type of the safe action function passed to hooks. Same as `SafeActionFn` except it accepts * just a single input, without bind arguments. */ type SingleInputActionFn<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data> = (input: InferInputOrDefault<Schema, undefined>) => Promise<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>; /** * Type of the stateful safe action function passed to hooks. Same as `SafeStateActionFn` except it accepts * just a single input, without bind arguments. */ type SingleInputStateActionFn<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data> = (prevResult: SafeActionResult<ServerError, Schema, ShapedErrors, Data>, input: InferInputOrDefault<Schema, undefined>) => Promise<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>; /** * Type of the action status returned by `useAction`, `useOptimisticAction` and `useStateAction` hooks. */ type HookActionStatus = "idle" | "executing" | "hasSucceeded" | "hasErrored" | "hasNavigated"; /** * Type of the shorthand status object returned by `useAction`, `useOptimisticAction` and `useStateAction` hooks. */ type HookShorthandStatus = { isIdle: boolean; isExecuting: boolean; isTransitioning: boolean; isPending: boolean; hasSucceeded: boolean; hasErrored: boolean; hasNavigated: boolean; }; /** * Result shape when no action has completed yet (idle, executing, navigated). */ type HookIdleResult = { data?: undefined; serverError?: undefined; validationErrors?: undefined; }; /** * Result shape for the success branch. For void-returning actions, collapses to `HookIdleResult` * so that `result.data` is `undefined` rather than `void`. */ type HookSuccessResult<Data> = [Data] extends [void] ? HookIdleResult : { data: Data; serverError?: undefined; validationErrors?: undefined; }; /** * Result shape for the error branch. Includes the idle shape for thrown errors * (where `result` is `{}` and the error is captured internally). */ type HookErrorResult<ServerError, ShapedErrors> = HookIdleResult | { data?: undefined; serverError: ServerError; validationErrors?: undefined; } | { data?: undefined; serverError?: undefined; validationErrors: ShapedErrors; }; /** * Common properties shared across all status branches of the hook return type. */ type HookResultCommon<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data> = { execute: (input: InferInputOrDefault<Schema, void>) => void; executeAsync: (input: InferInputOrDefault<Schema, void>) => Promise<NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>>; input: InferInputOrDefault<Schema, undefined>; reset: () => void; isTransitioning: boolean; }; /** * Type of the return object of the `useAction` hook. * * This is a discriminated union keyed on `status` and the shorthand boolean * properties (`hasSucceeded`, `hasErrored`, etc.). Checking any discriminant * narrows the `result` type: * * ```ts * const action = useAction(myAction); * if (action.hasSucceeded) { * action.result.data // Data (guaranteed) * action.result.serverError // undefined * } * ``` * * Destructured narrowing works too (TypeScript 4.6+): * * ```ts * const { status, result } = useAction(myAction); * if (status === "hasSucceeded") { * result.data // narrowed to Data * } * ``` * * `result` and `executeAsync` are run through `NormalizeActionResult` so that * void-returning actions expose `result.data: undefined` rather than `void | undefined`. */ type UseActionHookReturn<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data> = HookResultCommon<ServerError, Schema, ShapedErrors, Data> & ({ status: "idle"; isIdle: true; isExecuting: false; isPending: boolean; hasSucceeded: false; hasErrored: false; hasNavigated: false; result: Prettify<HookIdleResult>; } | { status: "executing"; isIdle: false; isExecuting: true; isPending: true; hasSucceeded: false; hasErrored: false; hasNavigated: false; result: Prettify<NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>>; } | { status: "hasSucceeded"; isIdle: false; isExecuting: false; isPending: boolean; hasSucceeded: true; hasErrored: false; hasNavigated: false; result: Prettify<HookSuccessResult<Data>>; } | { status: "hasErrored"; isIdle: false; isExecuting: false; isPending: boolean; hasSucceeded: false; hasErrored: true; hasNavigated: false; result: Prettify<HookErrorResult<ServerError, ShapedErrors>>; } | { status: "hasNavigated"; isIdle: false; isExecuting: false; isPending: boolean; hasSucceeded: false; hasErrored: false; hasNavigated: true; result: Prettify<HookIdleResult>; }); /** * Type of the return object of the `useOptimisticAction` hook. * Extends `UseActionHookReturn` with `optimisticState`. TypeScript distributes * the intersection over the union, preserving the discriminated union narrowing. */ type UseOptimisticActionHookReturn<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data, State> = UseActionHookReturn<ServerError, Schema, ShapedErrors, Data> & { optimisticState: State; }; /** * Type of the return object of the `useStateAction` hook. * * Extends `UseActionHookReturn` with `formAction` for `<form action={formAction}>` integration. * TypeScript distributes the intersection over the union, preserving the discriminated union narrowing. * * The optional `InitR` generic represents the shape of the `initResult` option. When provided, * it narrows the idle branch's `result` to exactly that shape, so seeded fields are typed as * required rather than `Data | undefined`. For example, `initResult: { data: { id: 1 } }` gives * `result.data` the type `{ id: number }` on the idle branch — matching the runtime value that * is seeded at mount and restored after `reset()`. Defaults to `HookIdleResult` (empty result) * when `initResult` is not provided. */ type UseStateActionHookReturn<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data, InitR extends SafeActionResult<ServerError, Schema, ShapedErrors, Data> = HookIdleResult> = (UseActionHookReturn<ServerError, Schema, ShapedErrors, Data> extends infer R ? R extends { status: "idle"; } ? Omit<R, "result"> & { result: Prettify<{ data: "data" extends keyof InitR ? InitR["data"] : undefined; serverError: "serverError" extends keyof InitR ? InitR["serverError"] : undefined; validationErrors: "validationErrors" extends keyof InitR ? InitR["validationErrors"] : undefined; }>; } : R : never) & { formAction: (input: InferInputOrDefault<Schema, void>) => void; }; /** * Type of the return object of the `useAction` hook. */ type InferUseActionHookReturn<T extends Function> = T extends SafeActionFn<infer ServerError, infer Schema extends StandardSchemaV1 | undefined, any, infer ShapedErrors, infer Data> ? UseActionHookReturn<ServerError, Schema, ShapedErrors, Data> : never; /** * Type of the return object of the `useOptimisticAction` hook. */ type InferUseOptimisticActionHookReturn<T extends Function, State = any> = T extends SafeActionFn<infer ServerError, infer Schema extends StandardSchemaV1 | undefined, any, infer ShapedErrors, infer Data> ? UseOptimisticActionHookReturn<ServerError, Schema, ShapedErrors, Data, State> : never; /** * Type of the return object of the `useStateAction` hook. */ type InferUseStateActionHookReturn<T extends Function> = T extends SafeStateActionFn<infer ServerError, infer Schema extends StandardSchemaV1 | undefined, any, infer ShapedErrors, infer Data> ? UseStateActionHookReturn<ServerError, Schema, ShapedErrors, Data> : never; /** * Deprecated aliases kept for backward compatibility. */ /** * @deprecated Use `SingleInputActionFn` instead. */ type HookSafeActionFn<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data> = SingleInputActionFn<ServerError, Schema, ShapedErrors, Data>; /** * @deprecated Use `SingleInputStateActionFn` instead. */ type HookSafeStateActionFn<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data> = SingleInputStateActionFn<ServerError, Schema, ShapedErrors, Data>; //#endregion //#region src/hooks.d.ts /** * Use the action from a Client Component via hook. * @param safeActionFn The action function * @param opts Optional configuration and callbacks * * {@link https://next-safe-action.dev/docs/execute-actions/hooks/useaction See docs for more information} */ declare const useAction: <ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data>(safeActionFn: SingleInputActionFn<ServerError, Schema, ShapedErrors, Data>, opts?: HookBaseOptions<ServerError, Schema, ShapedErrors, Data>) => UseActionHookReturn<ServerError, Schema, ShapedErrors, Data>; /** * Use the action from a Client Component via hook, with optimistic data update. * @param safeActionFn The action function * @param utils Required `currentData` and `updateFn` and optional callbacks * * {@link https://next-safe-action.dev/docs/execute-actions/hooks/useoptimisticaction See docs for more information} */ declare const useOptimisticAction: <ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data, State>(safeActionFn: SingleInputActionFn<ServerError, Schema, ShapedErrors, Data>, utils: { currentState: State; updateFn: (state: State, input: InferInputOrDefault<Schema, void>) => State; } & HookBaseOptions<ServerError, Schema, ShapedErrors, Data>) => UseOptimisticActionHookReturn<ServerError, Schema, ShapedErrors, Data, State>; /** * Use the stateful action from a Client Component via hook. Used for actions defined with * [`stateAction`](https://next-safe-action.dev/docs/define-actions/instance-methods#action--stateaction). * * Provides full lifecycle control: callbacks, status tracking, navigation error handling, * `executeAsync`, `reset`, and `formAction` for `<form action={formAction}>` integration. * * Requires React 19+ (Next.js 15+). On older versions, a runtime error is thrown with guidance. * * @param safeActionFn The stateful action function created with `.stateAction()`. * @param opts Optional configuration: `initResult` for initial state, plus all hook options and callbacks. * * {@link https://next-safe-action.dev/docs/execute-actions/hooks/usestateaction See docs for more information} */ declare const useStateAction: <ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data, InitR extends SafeActionResult<ServerError, Schema, ShapedErrors, Data> = HookIdleResult>(safeActionFn: SingleInputStateActionFn<ServerError, Schema, ShapedErrors, Data>, opts?: { initResult?: InitR; } & HookBaseOptions<ServerError, Schema, ShapedErrors, Data>) => UseStateActionHookReturn<ServerError, Schema, ShapedErrors, Data, InitR>; //#endregion export { HookActionStatus, HookBaseOptions, HookCallbacks, HookErrorResult, HookIdleResult, HookSafeActionFn, HookSafeStateActionFn, HookShorthandStatus, HookSuccessResult, InferUseActionHookReturn, InferUseOptimisticActionHookReturn, InferUseStateActionHookReturn, SingleInputActionFn, SingleInputStateActionFn, UseActionHookReturn, UseOptimisticActionHookReturn, UseStateActionHookReturn, useAction, useOptimisticAction, useStateAction }; //# sourceMappingURL=hooks.d.mts.map