next-safe-action
Version:
Type safe and validated Server Actions in your Next.js project.
280 lines (279 loc) • 13.6 kB
text/typescript
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