{"version":3,"sources":["../../../src/hooks/form/use-form-action.ts","../../../src/hooks/internal/use-action-runner.ts","../../../src/next/errors/redirect.ts","../../../src/next/errors/http-access-fallback.ts","../../../src/next/errors/framework.ts","../../../src/next/errors/index.ts","../../../src/core/redirect.ts","../../../src/hooks/provider.tsx"],"sourcesContent":["import { useCallback, useLayoutEffect, useMemo, useRef, type BaseSyntheticEvent } from \"react\";\r\nimport {\r\n  useForm,\r\n  type DefaultValues,\r\n  type FieldValues,\r\n  type Path,\r\n  type Resolver,\r\n  type UseFormProps,\r\n  type UseFormReturn,\r\n} from \"react-hook-form\";\r\nimport { zodResolver } from \"@hookform/resolvers/zod\";\r\nimport type { $ZodType } from \"zod/v4/core\";\r\nimport type {\r\n  ActionResult,\r\n  ServerActionError,\r\n  ServerActionResponse,\r\n  ToastAdapter,\r\n} from \"../../types\";\r\nimport { useActionRunner, type RunnableAction } from \"../internal/use-action-runner\";\r\n\r\n/**\r\n * A regular server action receiving the form values. Its input is not tied\r\n * to the form's field types, so an action chosen at runtime\r\n * (`isEdit ? updateUser : createUser`) works; the action's schema validates\r\n * on the server. Actions created with `.formAction()` expect FormData and are\r\n * rejected by their `~formAction` marker.\r\n */\r\nexport type FormSubmitAction<TOutput> = ((input: never) => Promise<ServerActionResponse<TOutput>>) & {\r\n  readonly \"~formAction\"?: never;\r\n};\r\n\r\n/** What the action returns on success; distributes over an action chosen at runtime. */\r\nexport type FormActionOutput<TAction> = TAction extends (...args: any[]) => Promise<ServerActionResponse<infer TOutput>>\r\n  ? TOutput\r\n  : never;\r\n\r\nexport interface UseFormActionOptions<\r\n  TFieldValues extends FieldValues,\r\n  TAction extends FormSubmitAction<any> = FormSubmitAction<unknown>,\r\n> {\r\n  /**\r\n   * A server action created with `.action()`: it receives the form values\r\n   * as an object, so Dates, numbers, booleans and Files keep their types.\r\n   * A `.formAction()` expects FormData and is rejected.\r\n   */\r\n  action: TAction;\r\n\r\n  /**\r\n   * Schema for client-side validation (Zod or Zod Mini). The action still\r\n   * validates on the server; the form sends the raw values, not the parsed ones.\r\n   */\r\n  schema?: $ZodType;\r\n\r\n  /**\r\n   * Initial values. They also type the form fields, which keeps fields such\r\n   * as `z.coerce.number()` (whose schema input is `unknown`) typed as numbers.\r\n   */\r\n  defaultValues?: DefaultValues<TFieldValues>;\r\n  mode?: UseFormProps<TFieldValues>[\"mode\"];\r\n  /** Any other react-hook-form option. */\r\n  formOptions?: Omit<UseFormProps<TFieldValues>, \"resolver\" | \"defaultValues\" | \"mode\">;\r\n\r\n  /** Map the form values to the action input when they differ. */\r\n  transformData?: (values: TFieldValues) => unknown;\r\n\r\n  onSuccess?: (data: FormActionOutput<TAction>) => void | Promise<void>;\r\n  onError?: (error: ServerActionError) => void | Promise<void>;\r\n\r\n  /** Reset the form after a success. Default `false`. */\r\n  resetOnSuccess?: boolean;\r\n  /** `true` (\"Success!\"), a message, or a function returning it. Default `false`. */\r\n  showSuccessToast?: boolean | string | ((data: FormActionOutput<TAction>) => string);\r\n  /**\r\n   * Toast for errors that do not belong to a field: `true` (the error\r\n   * message), a message, or a function returning it. Field errors are shown\r\n   * on their inputs instead. Default `true`.\r\n   */\r\n  showErrorToast?: boolean | string | ((error: ServerActionError) => string);\r\n  /** Overrides the adapter of `<ActionForgeProvider>` for this hook. */\r\n  toast?: ToastAdapter;\r\n\r\n  /** Ignore the redirect returned by the action. Default `false`. */\r\n  preventRedirect?: boolean;\r\n  /** Delay in ms before following a redirect without its own `delay`. Default `0`. */\r\n  redirectDelay?: number;\r\n  /** Follow `shouldRedirect`/`redirectTo` on authentication errors. Default `true`. */\r\n  redirectOnAuthError?: boolean;\r\n}\r\n\r\nexport interface UseFormActionReturn<TFieldValues extends FieldValues, TOutput> {\r\n  /** The react-hook-form instance. */\r\n  form: UseFormReturn<TFieldValues>;\r\n  /** Submit handler for `<form onSubmit>`: validates, then calls the action. */\r\n  onSubmit: (event?: BaseSyntheticEvent) => Promise<void>;\r\n  /** True from the submit until the action settled. */\r\n  isSubmitting: boolean;\r\n  /** True while a redirect returned by the action is in progress. */\r\n  isRedirecting: boolean;\r\n  /** The last result, as returned by `useServerAction`. */\r\n  result: ActionResult<TOutput> | undefined;\r\n  /** The last response of the action, or `undefined` before the first submit. */\r\n  actionState: ServerActionResponse<TOutput> | undefined;\r\n  /** Reset the form and the last result. */\r\n  reset: () => void;\r\n  /** Call the action with already validated values, bypassing the form's validation. */\r\n  handleSubmit: (values: TFieldValues) => Promise<void>;\r\n}\r\n\r\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\r\n  if (typeof value !== \"object\" || value === null) return false;\r\n  const prototype = Object.getPrototypeOf(value);\r\n  return prototype === Object.prototype || prototype === null;\r\n}\r\n\r\n/**\r\n * Server Action arguments are serialized by React, which supports File but\r\n * not FileList, the value react-hook-form keeps for `<input type=\"file\">`.\r\n */\r\nfunction toTransportable(value: unknown): unknown {\r\n  if (typeof FileList !== \"undefined\" && value instanceof FileList) return Array.from(value);\r\n  if (Array.isArray(value)) return value.map(toTransportable);\r\n  if (isPlainObject(value)) {\r\n    const copy: Record<string, unknown> = {};\r\n    for (const [key, item] of Object.entries(value)) copy[key] = toTransportable(item);\r\n    return copy;\r\n  }\r\n  return value;\r\n}\r\n\r\nfunction hasFieldErrors(error: ServerActionError): boolean {\r\n  return Boolean(error.field) || Object.keys(error.fields ?? {}).length > 0;\r\n}\r\n\r\nfunction toActionState<TOutput>(\r\n  result: ActionResult<TOutput> | undefined,\r\n): ServerActionResponse<TOutput> | undefined {\r\n  if (!result || result.status === \"navigation\") return undefined;\r\n  if (result.status === \"success\") return { success: true, data: result.data as TOutput };\r\n  return {\r\n    success: false,\r\n    error: result.serverError ?? { message: result.fetchError ?? \"An error occurred\", code: \"FETCH_ERROR\" },\r\n  };\r\n}\r\n\r\n/**\r\n * react-hook-form bound to a server action: client-side validation with an\r\n * optional schema, the values sent as an object to a `.action()`, server\r\n * field errors mapped to their inputs (dotted paths), form-level errors on\r\n * `errors.root` and in a toast, and the redirects of `useServerAction`.\r\n */\r\nexport function useFormAction<\r\n  TFieldValues extends FieldValues = FieldValues,\r\n  TAction extends FormSubmitAction<any> = FormSubmitAction<unknown>,\r\n>(\r\n  options: UseFormActionOptions<TFieldValues, TAction>,\r\n): UseFormActionReturn<TFieldValues, FormActionOutput<TAction>> {\r\n  type TOutput = FormActionOutput<TAction>;\r\n  const {\r\n    action,\r\n    schema,\r\n    defaultValues,\r\n    mode = \"onChange\",\r\n    formOptions,\r\n    resetOnSuccess = false,\r\n    showSuccessToast = false,\r\n    showErrorToast = true,\r\n  } = options;\r\n\r\n  const form = useForm<TFieldValues>({\r\n    ...formOptions,\r\n    // raw: the action validates on the server, so it receives what the user typed.\r\n    resolver: schema\r\n      ? (zodResolver(schema as never, undefined, { raw: true }) as unknown as Resolver<TFieldValues>)\r\n      : undefined,\r\n    defaultValues: defaultValues as DefaultValues<TFieldValues> | undefined,\r\n    mode,\r\n  });\r\n\r\n  const optionsRef = useRef(options);\r\n  useLayoutEffect(() => {\r\n    optionsRef.current = options;\r\n  });\r\n\r\n  const runner = useActionRunner<TOutput>(action as unknown as RunnableAction<TOutput>, {\r\n    successToast: (data) => {\r\n      if (!showSuccessToast) return undefined;\r\n      if (typeof showSuccessToast === \"string\") return showSuccessToast;\r\n      if (typeof showSuccessToast === \"function\") return showSuccessToast(data);\r\n      return \"Success!\";\r\n    },\r\n    errorToast: (result) => {\r\n      if (!showErrorToast) return undefined;\r\n      const error = result.serverError;\r\n      if (!error) return result.fetchError;\r\n      // Field errors are shown on their inputs; only form-level errors toast.\r\n      if (hasFieldErrors(error) && !error.formErrors?.length) return undefined;\r\n      const message = error.formErrors?.[0] ?? error.message;\r\n      if (typeof showErrorToast === \"string\") return showErrorToast;\r\n      if (typeof showErrorToast === \"function\") return showErrorToast(error);\r\n      return message;\r\n    },\r\n    onSuccess: async (data) => {\r\n      if (optionsRef.current.resetOnSuccess ?? resetOnSuccess) form.reset();\r\n      await optionsRef.current.onSuccess?.(data);\r\n    },\r\n    onError: async (result) => {\r\n      const error: ServerActionError = result.serverError ?? {\r\n        message: result.fetchError ?? \"An error occurred\",\r\n        code: \"FETCH_ERROR\",\r\n      };\r\n      if (result.serverError) {\r\n        for (const [path, messages] of Object.entries(error.fields ?? {})) {\r\n          if (messages?.length) {\r\n            form.setError(path as Path<TFieldValues>, { type: \"server\", message: messages[0] });\r\n          }\r\n        }\r\n        if (error.field && !error.fields) {\r\n          form.setError(error.field as Path<TFieldValues>, { type: \"server\", message: error.message });\r\n        }\r\n      }\r\n      const rootMessage = error.formErrors?.[0] ?? (hasFieldErrors(error) ? undefined : error.message);\r\n      if (rootMessage) {\r\n        form.setError(\"root\", { type: \"server\", message: rootMessage });\r\n      }\r\n      await optionsRef.current.onError?.(error);\r\n    },\r\n    redirectOnAuthError: options.redirectOnAuthError,\r\n    preventRedirect: options.preventRedirect,\r\n    redirectDelay: options.redirectDelay,\r\n    toast: options.toast,\r\n  });\r\n\r\n  const { execute, reset: resetRunner } = runner;\r\n  const handleSubmit = useCallback(\r\n    async (values: TFieldValues) => {\r\n      const transform = optionsRef.current.transformData;\r\n      const input = transform ? transform(values) : values;\r\n      form.clearErrors();\r\n      await execute(toTransportable(input));\r\n    },\r\n    [execute, form],\r\n  );\r\n\r\n  const onSubmit = useCallback(\r\n    (event?: BaseSyntheticEvent) =>\r\n      form.handleSubmit(handleSubmit)(event).catch((error: unknown) => {\r\n        console.error(\"[next-action-forge] The form submission failed:\", error);\r\n      }),\r\n    [form, handleSubmit],\r\n  );\r\n\r\n  const reset = useCallback(() => {\r\n    form.reset();\r\n    resetRunner();\r\n  }, [form, resetRunner]);\r\n\r\n  // Same object until the result changes, so it can sit in effect dependencies.\r\n  const actionState = useMemo(() => toActionState(runner.result), [runner.result]);\r\n\r\n  return {\r\n    form,\r\n    onSubmit,\r\n    isSubmitting: runner.isExecuting || form.formState.isSubmitting,\r\n    isRedirecting: runner.isRedirecting,\r\n    result: runner.result,\r\n    actionState,\r\n    reset,\r\n    handleSubmit,\r\n  };\r\n}\r\n","import { useCallback, useEffect, useLayoutEffect, useRef, useState, useTransition } from \"react\";\r\nimport { usePathname, useRouter } from \"next/navigation\";\r\nimport type {\r\n  ActionResult,\r\n  RedirectConfig,\r\n  ServerActionResponse,\r\n  ToastAdapter,\r\n} from \"../../types\";\r\nimport { isNextNavigationError, isRedirectError } from \"../../next/errors\";\r\nimport { getURLFromRedirectError } from \"../../next/errors/redirect\";\r\nimport { isSafeRedirectPath } from \"../../core/redirect\";\r\nimport { useActionForgeConfig } from \"../provider\";\r\n\r\n/** Options the runner reads on every call; the hooks translate theirs into these. */\r\nexport interface ActionRunnerOptions<TOutput> {\r\n  onSuccess?: (data: TOutput) => void | Promise<void>;\r\n  onError?: (result: ActionResult<TOutput>) => void | Promise<void>;\r\n  /** Message of the success toast for this result, or `undefined` for none. */\r\n  successToast?: (data: TOutput) => string | undefined;\r\n  /** Message of the error toast for this result, or `undefined` for none. */\r\n  errorToast?: (result: ActionResult<TOutput>) => string | undefined;\r\n  redirectOnAuthError?: boolean;\r\n  preventRedirect?: boolean;\r\n  redirectDelay?: number;\r\n  toast?: ToastAdapter;\r\n}\r\n\r\nexport interface RunOutcome<TOutput> {\r\n  result: ActionResult<TOutput>;\r\n  /** A Next.js navigation error to rethrow inside the caller's transition. */\r\n  rethrow?: unknown;\r\n}\r\n\r\nexport type RunnableAction<TOutput> = (...args: any[]) => Promise<ServerActionResponse<TOutput>>;\r\n\r\nlet warnedAboutMissingToast = false;\r\n\r\n/**\r\n * Whether following `target` from `pathname` changes what usePathname()\r\n * returns. An external target counts: the page unloads.\r\n */\r\nfunction leavesPathname(target: string, pathname: string): boolean {\r\n  try {\r\n    const from = new URL(pathname, \"http://next-action-forge.invalid\");\r\n    const to = new URL(target, from);\r\n    return to.origin !== from.origin || to.pathname !== from.pathname;\r\n  } catch {\r\n    return true;\r\n  }\r\n}\r\n\r\nfunction isResponse(value: unknown): value is ServerActionResponse<unknown> {\r\n  return typeof value === \"object\" && value !== null && \"success\" in value;\r\n}\r\n\r\nasync function runCallback<T>(name: string, callback: ((value: T) => unknown) | undefined, value: T) {\r\n  if (!callback) return;\r\n  try {\r\n    await callback(value);\r\n  } catch (error) {\r\n    // A bug in a consumer callback must not turn a completed action into a failure.\r\n    console.error(`[next-action-forge] The ${name} callback threw:`, error);\r\n  }\r\n}\r\n\r\n/**\r\n * Shared engine of the hooks: calls the action, maps its response to an\r\n * `ActionResult`, shows toasts, runs callbacks and follows redirects.\r\n *\r\n * - `run` does not start a transition, so callers can combine it with their\r\n *   own work in one transition (`useOptimisticAction`); they call\r\n *   `markStarted()` synchronously right before starting it.\r\n * - `execute` wraps `run` in a transition and rethrows `notFound()`,\r\n *   `forbidden()` and `unauthorized()` there, so Next's boundaries render.\r\n */\r\nexport function useActionRunner<TOutput>(\r\n  action: RunnableAction<TOutput>,\r\n  options: ActionRunnerOptions<TOutput>,\r\n) {\r\n  const router = useRouter();\r\n  const pathname = usePathname();\r\n  const config = useActionForgeConfig();\r\n\r\n  // Latest options and config, read at call time: execute stays stable even\r\n  // when callbacks are inline functions recreated on every render.\r\n  const optionsRef = useRef(options);\r\n  const toastRef = useRef<ToastAdapter | undefined>(options.toast ?? config.toast);\r\n  const pathnameRef = useRef(pathname);\r\n  useLayoutEffect(() => {\r\n    optionsRef.current = options;\r\n    toastRef.current = options.toast ?? config.toast;\r\n    pathnameRef.current = pathname;\r\n  });\r\n\r\n  const [result, setResult] = useState<ActionResult<TOutput>>();\r\n  const [isExecuting, setIsExecuting] = useState(false);\r\n  const pendingCalls = useRef(0);\r\n\r\n  // isRedirecting is derived, not synchronised by effects:\r\n  // - `redirectFrom` remembers the pathname a redirect started from. A server\r\n  //   redirect sets it only when it leads to another pathname, the one change\r\n  //   the hook can observe;\r\n  // - once the pathname differs, the redirect landed: `redirectFrom` is\r\n  //   cleared during render, so coming back to the page later does not\r\n  //   report it again. A new call clears it too (`markStarted`);\r\n  // - client navigations run in a transition that also clears `redirectFrom`,\r\n  //   so both flip back only when the navigation settles, a redirect to the\r\n  //   current URL included.\r\n  const [redirectFrom, setRedirectFrom] = useState<string | null>(null);\r\n  const [isNavigating, startNavigation] = useTransition();\r\n  const redirectTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\r\n  if (redirectFrom !== null && redirectFrom !== pathname) {\r\n    // Adjusting state while rendering: React re-renders right away, before\r\n    // the children see the stale value.\r\n    setRedirectFrom(null);\r\n  }\r\n  const isRedirecting = isNavigating || redirectFrom !== null;\r\n\r\n  useEffect(() => () => clearTimeout(redirectTimer.current), []);\r\n\r\n  const showToast = useCallback((kind: \"success\" | \"error\", message: string | undefined) => {\r\n    if (!message) return;\r\n    const toast = toastRef.current;\r\n    if (toast) {\r\n      toast[kind](message);\r\n    } else if (process.env.NODE_ENV === \"development\" && !warnedAboutMissingToast) {\r\n      warnedAboutMissingToast = true;\r\n      console.warn(\r\n        \"[next-action-forge] A toast was requested but no toast adapter is configured. \" +\r\n          \"Wrap your app in <ActionForgeProvider toast={toast}> or pass { toast } to the hook.\",\r\n      );\r\n    }\r\n  }, []);\r\n\r\n  const navigate = useCallback(\r\n    (target: RedirectConfig) => {\r\n      if (!isSafeRedirectPath(target.url)) {\r\n        console.error(\r\n          `[next-action-forge] Ignored a redirect to ${JSON.stringify(target.url)}: only same-origin paths are allowed.`,\r\n        );\r\n        return;\r\n      }\r\n      setRedirectFrom(pathnameRef.current);\r\n      const go = () =>\r\n        startNavigation(() => {\r\n          // Part of the navigation transition: commits when it settles.\r\n          setRedirectFrom(null);\r\n          if (target.replace) router.replace(target.url);\r\n          else router.push(target.url);\r\n        });\r\n      clearTimeout(redirectTimer.current);\r\n      if (target.delay && target.delay > 0) {\r\n        redirectTimer.current = setTimeout(go, target.delay);\r\n      } else {\r\n        go();\r\n      }\r\n    },\r\n    [router],\r\n  );\r\n\r\n  /**\r\n   * Mark a call as started. Must run synchronously before the transition\r\n   * that calls `run`: an update made inside a transition only commits when\r\n   * the transition ends, so the pending state would appear too late to\r\n   * disable a button against double submits.\r\n   */\r\n  const markStarted = useCallback(() => {\r\n    pendingCalls.current += 1;\r\n    setIsExecuting(true);\r\n    // A server redirect that never landed is not pending anymore.\r\n    setRedirectFrom(null);\r\n  }, []);\r\n\r\n  /** Call the action; `markStarted()` must have been called first. */\r\n  const run = useCallback(\r\n    async (input: unknown): Promise<RunOutcome<TOutput>> => {\r\n      const opts = optionsRef.current;\r\n\r\n      let response: unknown;\r\n      let thrown: unknown;\r\n      let didThrow = false;\r\n      try {\r\n        response = await (input === undefined ? action() : action(input));\r\n      } catch (error) {\r\n        didThrow = true;\r\n        thrown = error;\r\n      } finally {\r\n        pendingCalls.current -= 1;\r\n        if (pendingCalls.current === 0) setIsExecuting(false);\r\n      }\r\n\r\n      if (didThrow) {\r\n        if (isRedirectError(thrown)) {\r\n          // Next performs the navigation itself; the rejection only settles the call.\r\n          const navigation: ActionResult<TOutput> = { status: \"navigation\" };\r\n          setResult(navigation);\r\n          // A redirect that keeps the pathname (new search params only) ends\r\n          // without any change the hook could wait for: nothing to report.\r\n          const from = pathnameRef.current;\r\n          if (leavesPathname(getURLFromRedirectError(thrown), from)) setRedirectFrom(from);\r\n          return { result: navigation };\r\n        }\r\n        if (isNextNavigationError(thrown)) {\r\n          const navigation: ActionResult<TOutput> = { status: \"navigation\" };\r\n          setResult(navigation);\r\n          return { result: navigation, rethrow: thrown };\r\n        }\r\n        const failure: ActionResult<TOutput> = {\r\n          status: \"error\",\r\n          fetchError: thrown instanceof Error ? thrown.message : \"Network error\",\r\n        };\r\n        setResult(failure);\r\n        showToast(\"error\", opts.errorToast?.(failure));\r\n        await runCallback(\"onError\", opts.onError, failure);\r\n        return { result: failure };\r\n      }\r\n\r\n      if (!isResponse(response)) {\r\n        // Next.js resolves a Server Action to undefined on some redirect paths,\r\n        // without telling where to: assume another page.\r\n        const navigation: ActionResult<TOutput> = { status: \"navigation\" };\r\n        setResult(navigation);\r\n        setRedirectFrom(pathnameRef.current);\r\n        return { result: navigation };\r\n      }\r\n\r\n      if (response.success) {\r\n        const data = response.data as TOutput;\r\n        const success: ActionResult<TOutput> = { status: \"success\", data };\r\n        setResult(success);\r\n        showToast(\"success\", opts.successToast?.(data));\r\n        await runCallback(\"onSuccess\", opts.onSuccess, data);\r\n        if (response.redirect && !opts.preventRedirect) {\r\n          const target =\r\n            typeof response.redirect === \"string\" ? { url: response.redirect } : response.redirect;\r\n          navigate({ ...target, delay: target.delay ?? opts.redirectDelay });\r\n        }\r\n        return { result: success };\r\n      }\r\n\r\n      const error = response.error;\r\n      const failure: ActionResult<TOutput> = {\r\n        status: \"error\",\r\n        serverError: error,\r\n        validationErrors: error.fields,\r\n      };\r\n      setResult(failure);\r\n      showToast(\"error\", opts.errorToast?.(failure));\r\n      await runCallback(\"onError\", opts.onError, failure);\r\n      if ((opts.redirectOnAuthError ?? true) && error.shouldRedirect) {\r\n        navigate({ url: error.redirectTo ?? \"/login\" });\r\n      }\r\n      return { result: failure };\r\n    },\r\n    [action, navigate, showToast],\r\n  );\r\n\r\n  const [, startTransition] = useTransition();\r\n\r\n  const execute = useCallback(\r\n    (input?: unknown) => {\r\n      markStarted();\r\n      return new Promise<ActionResult<TOutput>>((resolve) => {\r\n        startTransition(async () => {\r\n          const outcome = await run(input);\r\n          resolve(outcome.result);\r\n          if (outcome.rethrow !== undefined) {\r\n            // Unhandled errors in a transition reach the nearest error\r\n            // boundary, which is how notFound() renders its page.\r\n            throw outcome.rethrow;\r\n          }\r\n        });\r\n      });\r\n    },\r\n    [markStarted, run],\r\n  );\r\n\r\n  const reset = useCallback(() => {\r\n    clearTimeout(redirectTimer.current);\r\n    setResult(undefined);\r\n    setRedirectFrom(null);\r\n  }, []);\r\n\r\n  return {\r\n    markStarted,\r\n    run,\r\n    execute,\r\n    result,\r\n    isExecuting,\r\n    isRedirecting,\r\n    reset,\r\n  };\r\n}\r\n","// Comes from: https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/redirect-error.ts\r\n\r\nenum RedirectStatusCode {\r\n\tSeeOther = 303,\r\n\tTemporaryRedirect = 307,\r\n\tPermanentRedirect = 308,\r\n}\r\n\r\nconst REDIRECT_ERROR_CODE = \"NEXT_REDIRECT\";\r\n\r\nenum RedirectType {\r\n\tpush = \"push\",\r\n\treplace = \"replace\",\r\n}\r\n\r\nexport type RedirectError = Error & {\r\n\tdigest: `${typeof REDIRECT_ERROR_CODE};${RedirectType};${string};${RedirectStatusCode};`;\r\n};\r\n\r\n/**\r\n * Checks an error to determine if it's an error generated by the\r\n * `redirect(url)` helper.\r\n *\r\n * @param error the error that may reference a redirect error\r\n * @returns true if the error is a redirect error\r\n */\r\nexport function isRedirectError(error: unknown): error is RedirectError {\r\n\tif (typeof error !== \"object\" || error === null || !(\"digest\" in error) || typeof error.digest !== \"string\") {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst digest = error.digest.split(\";\");\r\n\tconst [errorCode, type] = digest;\r\n\tconst destination = digest.slice(2, -2).join(\";\");\r\n\tconst status = digest.at(-2);\r\n\r\n\tconst statusCode = Number(status);\r\n\r\n\treturn (\r\n\t\terrorCode === REDIRECT_ERROR_CODE &&\r\n\t\t(type === \"replace\" || type === \"push\") &&\r\n\t\ttypeof destination === \"string\" &&\r\n\t\t!isNaN(statusCode) &&\r\n\t\tstatusCode in RedirectStatusCode\r\n\t);\r\n}\r\n\r\n/**\r\n * The destination of a redirect error. For a Server Action call that\r\n * redirected, Next.js puts there the path and search it navigates to\r\n * (without the base path), or the full URL of an external target.\r\n */\r\nexport function getURLFromRedirectError(error: RedirectError): string {\r\n\treturn error.digest.split(\";\").slice(2, -2).join(\";\");\r\n}","// Comes from https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/http-access-fallback/http-access-fallback.ts\r\n\r\nconst HTTPAccessErrorStatus = {\r\n\tNOT_FOUND: 404,\r\n\tFORBIDDEN: 403,\r\n\tUNAUTHORIZED: 401,\r\n};\r\n\r\nconst ALLOWED_CODES = new Set(Object.values(HTTPAccessErrorStatus));\r\n\r\nconst HTTP_ERROR_FALLBACK_ERROR_CODE = \"NEXT_HTTP_ERROR_FALLBACK\";\r\n\r\nexport type HTTPAccessFallbackError = Error & {\r\n\tdigest: `${typeof HTTP_ERROR_FALLBACK_ERROR_CODE};${string}`;\r\n};\r\n\r\n/**\r\n * Checks an error to determine if it's an error generated by\r\n * the HTTP navigation APIs `notFound()`, `forbidden()` or `unauthorized()`.\r\n *\r\n * @param error the error that may reference a HTTP access error\r\n * @returns true if the error is a HTTP access error\r\n */\r\nexport function isHTTPAccessFallbackError(error: unknown): error is HTTPAccessFallbackError {\r\n\tif (typeof error !== \"object\" || error === null || !(\"digest\" in error) || typeof error.digest !== \"string\") {\r\n\t\treturn false;\r\n\t}\r\n\tconst [prefix, httpStatus] = error.digest.split(\";\");\r\n\r\n\treturn prefix === HTTP_ERROR_FALLBACK_ERROR_CODE && ALLOWED_CODES.has(Number(httpStatus));\r\n}\r\n\r\nexport function getAccessFallbackHTTPStatus(error: HTTPAccessFallbackError): number {\r\n\tconst httpStatus = error.digest.split(\";\")[1];\r\n\treturn Number(httpStatus);\r\n}","// Mirrors of the checks behind `unstable_rethrow` in next/navigation\r\n// (Next.js 16.3: client/components/unstable-rethrow.server.js and the\r\n// modules it imports). They are copied rather than imported because plain\r\n// Node ESM cannot resolve \"next/navigation\" (Next ships no \"exports\" map),\r\n// which would break this package's ESM build outside a bundler.\r\n\r\nfunction hasDigest(error: unknown): error is { digest: string } {\r\n  return (\r\n    typeof error === \"object\" &&\r\n    error !== null &&\r\n    \"digest\" in error &&\r\n    typeof (error as { digest: unknown }).digest === \"string\"\r\n  );\r\n}\r\n\r\n/** `notFound()` on Next.js 14 and 15.0, before NEXT_HTTP_ERROR_FALLBACK. */\r\nexport function isLegacyNotFoundError(error: unknown): boolean {\r\n  return hasDigest(error) && error.digest === \"NEXT_NOT_FOUND\";\r\n}\r\n\r\n/** Dynamic API used while prerendering (hooks-server-context). */\r\nexport function isDynamicServerError(error: unknown): boolean {\r\n  return hasDigest(error) && error.digest === \"DYNAMIC_SERVER_USAGE\";\r\n}\r\n\r\n/** `useSearchParams()` and friends opting a subtree out of prerendering. */\r\nexport function isBailoutToCSRError(error: unknown): boolean {\r\n  return hasDigest(error) && error.digest === \"BAILOUT_TO_CLIENT_SIDE_RENDERING\";\r\n}\r\n\r\n/** Prerendering stopped a promise that will never settle (cache components). */\r\nexport function isHangingPromiseRejectionError(error: unknown): boolean {\r\n  return hasDigest(error) && error.digest === \"HANGING_PROMISE_REJECTION\";\r\n}\r\n\r\n/** Prerendering interrupted by dynamic access (cache components). */\r\nexport function isPrerenderInterruptedError(error: unknown): boolean {\r\n  return (\r\n    hasDigest(error) &&\r\n    error.digest === \"NEXT_PRERENDER_INTERRUPTED\" &&\r\n    error instanceof Error\r\n  );\r\n}\r\n\r\n/** React's postpone signal used by partial prerendering. */\r\nexport function isPostpone(error: unknown): boolean {\r\n  return (\r\n    typeof error === \"object\" &&\r\n    error !== null &&\r\n    (error as { $$typeof?: unknown }).$$typeof === Symbol.for(\"react.postpone\")\r\n  );\r\n}\r\n\r\n/** Partial prerendering postponing because a dynamic API was used. */\r\nexport function isDynamicPostpone(error: unknown): boolean {\r\n  if (typeof error !== \"object\" || error === null) return false;\r\n  const message = (error as { message?: unknown }).message;\r\n  return (\r\n    typeof message === \"string\" &&\r\n    message.includes(\"needs to bail out of prerendering at this point because it used\") &&\r\n    message.includes(\"Learn more: https://nextjs.org/docs/messages/ppr-caught-error\")\r\n  );\r\n}\r\n","import { isRedirectError } from \"./redirect\";\r\nimport { isHTTPAccessFallbackError, getAccessFallbackHTTPStatus } from \"./http-access-fallback\";\r\nimport {\r\n  isBailoutToCSRError,\r\n  isDynamicPostpone,\r\n  isDynamicServerError,\r\n  isHangingPromiseRejectionError,\r\n  isLegacyNotFoundError,\r\n  isPostpone,\r\n  isPrerenderInterruptedError,\r\n} from \"./framework\";\r\n\r\nexport { isRedirectError } from \"./redirect\";\r\nexport type { RedirectError } from \"./redirect\";\r\n\r\nexport { isHTTPAccessFallbackError, getAccessFallbackHTTPStatus } from \"./http-access-fallback\";\r\nexport type { HTTPAccessFallbackError } from \"./http-access-fallback\";\r\n\r\n/**\r\n * Checks if the error is a navigation error that should be re-thrown:\r\n * `redirect()`, `permanentRedirect()`, `notFound()`, `forbidden()` and\r\n * `unauthorized()`, including the `notFound()` digest of Next.js 14 and 15.0.\r\n */\r\nexport function isNextNavigationError(error: unknown): boolean {\r\n\treturn isRedirectError(error) || isHTTPAccessFallbackError(error) || isLegacyNotFoundError(error);\r\n}\r\n\r\n/**\r\n * Checks if the error is a notFound error\r\n * Note: Next.js implements notFound() using HTTP_ERROR_FALLBACK with status 404,\r\n * not as a separate error type like NEXT_REDIRECT (Next.js 14 and 15.0 used\r\n * the NEXT_NOT_FOUND digest instead).\r\n */\r\nexport function isNotFoundError(error: unknown): boolean {\r\n\treturn (\r\n\t\tisLegacyNotFoundError(error) ||\r\n\t\t(isHTTPAccessFallbackError(error) && getAccessFallbackHTTPStatus(error) === 404)\r\n\t);\r\n}\r\n\r\n/**\r\n * Whether the error is Next.js control flow that user code must never\r\n * swallow: navigation errors plus the signals Next uses while rendering\r\n * (dynamic usage, client-side-rendering bailouts, postpones). The same set\r\n * `unstable_rethrow` from next/navigation checks.\r\n */\r\nexport function isNextInternalError(error: unknown): boolean {\r\n\treturn (\r\n\t\tisNextNavigationError(error) ||\r\n\t\tisBailoutToCSRError(error) ||\r\n\t\tisDynamicServerError(error) ||\r\n\t\tisDynamicPostpone(error) ||\r\n\t\tisPostpone(error) ||\r\n\t\tisHangingPromiseRejectionError(error) ||\r\n\t\tisPrerenderInterruptedError(error)\r\n\t);\r\n}\r\n\r\nconst MAX_CAUSE_DEPTH = 10;\r\n\r\n/**\r\n * Rethrow the error, or the first error in its `cause` chain, when it is\r\n * Next.js control flow. Mirrors `unstable_rethrow`, so an action called from\r\n * a Server Component keeps redirects, `notFound()` and prerendering bailouts\r\n * working even when user code wraps them in another error.\r\n */\r\nexport function rethrowIfNextInternal(error: unknown): void {\r\n\tlet current: unknown = error;\r\n\tfor (let depth = 0; depth < MAX_CAUSE_DEPTH && current !== undefined && current !== null; depth++) {\r\n\t\tif (isNextInternalError(current)) {\r\n\t\t\tthrow current;\r\n\t\t}\r\n\t\tcurrent = current instanceof Error ? current.cause : undefined;\r\n\t}\r\n}\r\n","import type { ActionLogger, RedirectSpec, RedirectTarget } from \"../types\";\r\n\r\nexport type { RedirectSpec } from \"../types\";\r\nimport { describeAction } from \"./logger\";\r\n\r\nconst PARSE_BASE = \"http://next-action-forge.invalid\";\r\n\r\n// Browsers strip tabs and newlines from URLs before parsing them, so a path\r\n// such as \"/\\t/evil.example\" would turn into the protocol-relative\r\n// \"//evil.example\". Any control character is rejected outright.\r\n// eslint-disable-next-line no-control-regex -- matching control characters is the point.\r\nconst CONTROL_CHARACTERS = /[\\u0000-\\u001F\\u007F]/;\r\n\r\n/**\r\n * Whether `value` is a same-origin path that is safe to navigate to: it\r\n * starts with a single \"/\" and, once parsed the way a browser parses it,\r\n * still points to the current origin. Rejects absolute and\r\n * protocol-relative URLs, backslash tricks (\"/\\\\evil.example\") and control\r\n * characters.\r\n */\r\nexport function isSafeRedirectPath(value: unknown): value is string {\r\n  if (typeof value !== \"string\" || !value.startsWith(\"/\")) return false;\r\n  if (value[1] === \"/\" || value[1] === \"\\\\\") return false;\r\n  if (CONTROL_CHARACTERS.test(value)) return false;\r\n  try {\r\n    return new URL(value, PARSE_BASE).origin === PARSE_BASE;\r\n  } catch {\r\n    return false;\r\n  }\r\n}\r\n\r\n/** Throws at definition time when a static redirect points outside the app. */\r\nexport function assertSafeRedirectPath(url: unknown, source: string): void {\r\n  if (!isSafeRedirectPath(url)) {\r\n    throw new TypeError(\r\n      `[next-action-forge] ${source} only accepts a same-origin path starting with \"/\", received ${JSON.stringify(url)}. ` +\r\n        `Use redirect() from next/navigation inside the handler to leave the app.`,\r\n    );\r\n  }\r\n}\r\n\r\n/** Validate a fixed target at definition time; callbacks are checked on each call. */\r\nexport function assertStaticRedirect(spec: RedirectSpec | undefined, source: string): void {\r\n  if (typeof spec === \"string\") {\r\n    assertSafeRedirectPath(spec, source);\r\n  } else if (typeof spec === \"object\" && spec !== null) {\r\n    assertSafeRedirectPath(spec.url, source);\r\n  }\r\n}\r\n\r\n/**\r\n * Resolve the redirect attached to a successful result. The callback may be\r\n * async. A callback that throws or returns an unsafe target is logged and\r\n * yields no redirect: the mutation already happened, so the success must\r\n * still reach the client.\r\n */\r\nexport async function resolveRedirect(\r\n  spec: RedirectSpec | undefined,\r\n  output: unknown,\r\n  logger: ActionLogger,\r\n  actionName: string | undefined,\r\n): Promise<RedirectTarget | undefined> {\r\n  if (!spec) return undefined;\r\n\r\n  let value: RedirectTarget | undefined;\r\n  try {\r\n    value = typeof spec === \"function\" ? await spec(output) : spec;\r\n  } catch (error) {\r\n    logger.error(`[next-action-forge] The redirect callback threw${describeAction(actionName)}:`, error);\r\n    return undefined;\r\n  }\r\n\r\n  if (value === undefined || value === null) return undefined;\r\n\r\n  const url = typeof value === \"string\" ? value : value.url;\r\n  if (!isSafeRedirectPath(url)) {\r\n    logger.error(\r\n      `[next-action-forge] Ignored a redirect to ${JSON.stringify(url)}${describeAction(actionName)}: only same-origin paths are allowed.`,\r\n    );\r\n    return undefined;\r\n  }\r\n  return value;\r\n}\r\n","import { createContext, useContext, useMemo, type Context, type ReactNode } from \"react\";\r\nimport type { ToastAdapter } from \"../types\";\r\n\r\nexport interface ActionForgeConfig {\r\n  /** Shows the success and error toasts requested by the hooks. */\r\n  toast?: ToastAdapter;\r\n}\r\n\r\n// The hooks ship in two entry points (next-action-forge/hooks and\r\n// next-action-forge/hooks/form), each bundled with its own copy of this\r\n// module. A global symbol gives both copies the same context object, so one\r\n// provider serves every hook.\r\nconst CONTEXT_KEY = Symbol.for(\"next-action-forge.config\");\r\nconst globalStore = globalThis as { [CONTEXT_KEY]?: Context<ActionForgeConfig> };\r\nconst ActionForgeContext: Context<ActionForgeConfig> =\r\n  globalStore[CONTEXT_KEY] ?? (globalStore[CONTEXT_KEY] = createContext<ActionForgeConfig>({}));\r\n\r\nexport interface ActionForgeProviderProps extends ActionForgeConfig {\r\n  children: ReactNode;\r\n}\r\n\r\n/**\r\n * Configures every next-action-forge hook below it. Render it inside a\r\n * Client Component, because `toast` is a function:\r\n *\r\n * ```tsx\r\n * \"use client\";\r\n * import { toast } from \"sonner\";\r\n * import { ActionForgeProvider } from \"next-action-forge/hooks\";\r\n *\r\n * export function Providers({ children }: { children: React.ReactNode }) {\r\n *   return <ActionForgeProvider toast={toast}>{children}</ActionForgeProvider>;\r\n * }\r\n * ```\r\n */\r\nexport function ActionForgeProvider({ toast, children }: ActionForgeProviderProps) {\r\n  const value = useMemo<ActionForgeConfig>(() => ({ toast }), [toast]);\r\n  return <ActionForgeContext.Provider value={value}>{children}</ActionForgeContext.Provider>;\r\n}\r\n\r\nexport function useActionForgeConfig(): ActionForgeConfig {\r\n  return useContext(ActionForgeContext);\r\n}\r\n"],"mappings":"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","names":["useCallback","useLayoutEffect","useMemo","useRef","RedirectStatusCode","error","failure","useRef","useLayoutEffect","useCallback","useMemo"]}