next-safe-action
Version:
Type safe and validated Server Actions in your Next.js project.
1 lines • 30.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/hooks.ts","../src/hooks-utils.ts","../src/next/errors/bailout-to-csr.ts","../src/next/errors/http-access-fallback.ts","../src/next/errors/redirect.ts","../src/next/errors/router.ts","../src/next/errors/dynamic-usage.ts","../src/next/errors/postpone.ts","../src/next/errors/index.ts"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {} from \"react/experimental\";\nimport { getActionShorthandStatusObject, getActionStatus, useActionCallbacks } from \"./hooks-utils\";\nimport type {\n\tHookCallbacks,\n\tHookSafeActionFn,\n\tUseActionHookReturn,\n\tUseOptimisticActionHookReturn,\n} from \"./hooks.types\";\nimport type { SafeActionResult } from \"./index.types\";\nimport { FrameworkErrorHandler } from \"./next/errors\";\nimport type { InferInputOrDefault, StandardSchemaV1 } from \"./standard-schema\";\n\n// HOOKS\n\n/**\n * Use the action from a Client Component via hook.\n * @param safeActionFn The action function\n * @param cb Optional base utils and callbacks\n *\n * {@link https://next-safe-action.dev/docs/execute-actions/hooks/useaction See docs for more information}\n */\nexport const useAction = <ServerError, S extends StandardSchemaV1 | undefined, CVE, Data>(\n\tsafeActionFn: HookSafeActionFn<ServerError, S, CVE, Data>,\n\tcb?: HookCallbacks<ServerError, S, CVE, Data>\n): UseActionHookReturn<ServerError, S, CVE, Data> => {\n\tconst [isTransitioning, startTransition] = React.useTransition();\n\tconst [result, setResult] = React.useState<SafeActionResult<ServerError, S, CVE, Data>>({});\n\tconst [clientInput, setClientInput] = React.useState<InferInputOrDefault<S, void>>();\n\tconst [isExecuting, setIsExecuting] = React.useState(false);\n\tconst [navigationError, setNavigationError] = React.useState<Error | null>(null);\n\tconst [thrownError, setThrownError] = React.useState<Error | null>(null);\n\tconst [isIdle, setIsIdle] = React.useState(true);\n\n\tconst status = getActionStatus<ServerError, S, CVE, Data>({\n\t\tisExecuting,\n\t\tisTransitioning,\n\t\tresult,\n\t\tisIdle,\n\t\thasNavigated: navigationError !== null,\n\t\thasThrownError: thrownError !== null,\n\t});\n\n\tconst execute = React.useCallback(\n\t\t(input: InferInputOrDefault<S, void>) => {\n\t\t\tsetTimeout(() => {\n\t\t\t\tsetIsIdle(false);\n\t\t\t\tsetNavigationError(null);\n\t\t\t\tsetThrownError(null);\n\t\t\t\tsetClientInput(input);\n\t\t\t\tsetIsExecuting(true);\n\t\t\t}, 0);\n\n\t\t\tstartTransition(() => {\n\t\t\t\tsafeActionFn(input as InferInputOrDefault<S, undefined>)\n\t\t\t\t\t.then((res) => setResult(res ?? {}))\n\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\tsetResult({});\n\n\t\t\t\t\t\tif (FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\t\t\tsetNavigationError(e);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsetThrownError(e as Error);\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t})\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tsetIsExecuting(false);\n\t\t\t\t\t});\n\t\t\t});\n\t\t},\n\t\t[safeActionFn]\n\t);\n\n\tconst executeAsync = React.useCallback(\n\t\t(input: InferInputOrDefault<S, void>) => {\n\t\t\tconst fn = new Promise<Awaited<ReturnType<typeof safeActionFn>>>((resolve, reject) => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tsetIsIdle(false);\n\t\t\t\t\tsetNavigationError(null);\n\t\t\t\t\tsetThrownError(null);\n\t\t\t\t\tsetClientInput(input);\n\t\t\t\t\tsetIsExecuting(true);\n\t\t\t\t}, 0);\n\n\t\t\t\tstartTransition(() => {\n\t\t\t\t\tsafeActionFn(input as InferInputOrDefault<S, undefined>)\n\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\tsetResult(res ?? {});\n\t\t\t\t\t\t\tresolve(res);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\t\tsetResult({});\n\n\t\t\t\t\t\t\tif (FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\t\t\t\tsetNavigationError(e);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tsetThrownError(e as Error);\n\t\t\t\t\t\t\treject(e);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\tsetIsExecuting(false);\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\n\t\t\treturn fn;\n\t\t},\n\t\t[safeActionFn]\n\t);\n\n\tconst reset = React.useCallback(() => {\n\t\tsetIsIdle(true);\n\t\tsetNavigationError(null);\n\t\tsetThrownError(null);\n\t\tsetClientInput(undefined);\n\t\tsetResult({});\n\t}, []);\n\n\tuseActionCallbacks({\n\t\tresult: result ?? {},\n\t\tinput: clientInput as InferInputOrDefault<S, undefined>,\n\t\tstatus,\n\t\tnavigationError,\n\t\tthrownError,\n\t\tcb,\n\t});\n\n\treturn {\n\t\texecute,\n\t\texecuteAsync,\n\t\tinput: clientInput as InferInputOrDefault<S, undefined>,\n\t\tresult,\n\t\treset,\n\t\tstatus,\n\t\t...getActionShorthandStatusObject(status),\n\t};\n};\n\n/**\n * Use the action from a Client Component via hook, with optimistic data update.\n * @param safeActionFn The action function\n * @param utils Required `currentData` and `updateFn` and optional callbacks\n *\n * {@link https://next-safe-action.dev/docs/execute-actions/hooks/useoptimisticaction See docs for more information}\n */\nexport const useOptimisticAction = <ServerError, S extends StandardSchemaV1 | undefined, CVE, Data, State>(\n\tsafeActionFn: HookSafeActionFn<ServerError, S, CVE, Data>,\n\tutils: {\n\t\tcurrentState: State;\n\t\tupdateFn: (state: State, input: InferInputOrDefault<S, void>) => State;\n\t} & HookCallbacks<ServerError, S, CVE, Data>\n): UseOptimisticActionHookReturn<ServerError, S, CVE, Data, State> => {\n\tconst [isTransitioning, startTransition] = React.useTransition();\n\tconst [result, setResult] = React.useState<SafeActionResult<ServerError, S, CVE, Data>>({});\n\tconst [clientInput, setClientInput] = React.useState<InferInputOrDefault<S, void>>();\n\tconst [isExecuting, setIsExecuting] = React.useState(false);\n\tconst [navigationError, setNavigationError] = React.useState<Error | null>(null);\n\tconst [thrownError, setThrownError] = React.useState<Error | null>(null);\n\tconst [isIdle, setIsIdle] = React.useState(true);\n\tconst [optimisticState, setOptimisticValue] = React.useOptimistic<State, InferInputOrDefault<S, undefined>>(\n\t\tutils.currentState,\n\t\tutils.updateFn\n\t);\n\n\tconst status = getActionStatus<ServerError, S, CVE, Data>({\n\t\tisExecuting,\n\t\tisTransitioning,\n\t\tresult,\n\t\tisIdle,\n\t\thasNavigated: navigationError !== null,\n\t\thasThrownError: thrownError !== null,\n\t});\n\n\tconst execute = React.useCallback(\n\t\t(input: InferInputOrDefault<S, void>) => {\n\t\t\tsetTimeout(() => {\n\t\t\t\tsetIsIdle(false);\n\t\t\t\tsetClientInput(input);\n\t\t\t\tsetNavigationError(null);\n\t\t\t\tsetThrownError(null);\n\t\t\t\tsetIsExecuting(true);\n\t\t\t}, 0);\n\n\t\t\tstartTransition(() => {\n\t\t\t\tsetOptimisticValue(input as InferInputOrDefault<S, undefined>);\n\t\t\t\tsafeActionFn(input as InferInputOrDefault<S, undefined>)\n\t\t\t\t\t.then((res) => setResult(res ?? {}))\n\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\tsetResult({});\n\n\t\t\t\t\t\tif (FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\t\t\tsetNavigationError(e);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsetThrownError(e as Error);\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t})\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tsetIsExecuting(false);\n\t\t\t\t\t});\n\t\t\t});\n\t\t},\n\t\t[safeActionFn, setOptimisticValue]\n\t);\n\n\tconst executeAsync = React.useCallback(\n\t\t(input: InferInputOrDefault<S, void>) => {\n\t\t\tconst fn = new Promise<Awaited<ReturnType<typeof safeActionFn>>>((resolve, reject) => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tsetIsIdle(false);\n\t\t\t\t\tsetClientInput(input);\n\t\t\t\t\tsetNavigationError(null);\n\t\t\t\t\tsetThrownError(null);\n\t\t\t\t\tsetIsExecuting(true);\n\t\t\t\t}, 0);\n\n\t\t\t\tstartTransition(() => {\n\t\t\t\t\tsetOptimisticValue(input as InferInputOrDefault<S, undefined>);\n\t\t\t\t\tsafeActionFn(input as InferInputOrDefault<S, undefined>)\n\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\tsetResult(res ?? {});\n\t\t\t\t\t\t\tresolve(res);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\t\tsetResult({});\n\n\t\t\t\t\t\t\tif (FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\t\t\t\tsetNavigationError(e);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tsetThrownError(e as Error);\n\t\t\t\t\t\t\treject(e);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\tsetIsExecuting(false);\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\n\t\t\treturn fn;\n\t\t},\n\t\t[safeActionFn, setOptimisticValue]\n\t);\n\n\tconst reset = React.useCallback(() => {\n\t\tsetIsIdle(true);\n\t\tsetClientInput(undefined);\n\t\tsetNavigationError(null);\n\t\tsetThrownError(null);\n\t\tsetResult({});\n\t}, []);\n\n\tuseActionCallbacks({\n\t\tresult: result ?? {},\n\t\tinput: clientInput as InferInputOrDefault<S, undefined>,\n\t\tstatus,\n\t\tnavigationError,\n\t\tthrownError,\n\t\tcb: {\n\t\t\tonExecute: utils.onExecute,\n\t\t\tonSuccess: utils.onSuccess,\n\t\t\tonError: utils.onError,\n\t\t\tonSettled: utils.onSettled,\n\t\t\tonNavigation: utils.onNavigation,\n\t\t},\n\t});\n\n\treturn {\n\t\texecute,\n\t\texecuteAsync,\n\t\tinput: clientInput as InferInputOrDefault<S, undefined>,\n\t\tresult,\n\t\toptimisticState,\n\t\treset,\n\t\tstatus,\n\t\t...getActionShorthandStatusObject(status),\n\t};\n};\n\nexport type * from \"./hooks.types\";\n","import * as React from \"react\";\nimport {} from \"react/experimental\";\nimport type { HookActionStatus, HookCallbacks, HookShorthandStatus } from \"./hooks.types\";\nimport type { SafeActionResult } from \"./index.types\";\nimport { FrameworkErrorHandler } from \"./next/errors\";\nimport type { InferInputOrDefault, StandardSchemaV1 } from \"./standard-schema\";\n\nexport const getActionStatus = <ServerError, S extends StandardSchemaV1 | undefined, CVE, Data>({\n\tisIdle,\n\tisExecuting,\n\tisTransitioning,\n\tresult,\n\thasNavigated,\n\thasThrownError,\n}: {\n\tisIdle: boolean;\n\tisExecuting: boolean;\n\tisTransitioning: boolean;\n\thasNavigated: boolean;\n\thasThrownError: boolean;\n\tresult: SafeActionResult<ServerError, S, CVE, Data>;\n}): HookActionStatus => {\n\tif (isIdle) {\n\t\treturn \"idle\";\n\t} else if (isExecuting) {\n\t\treturn \"executing\";\n\t} else if (isTransitioning) {\n\t\treturn \"transitioning\";\n\t} else if (\n\t\thasThrownError ||\n\t\ttypeof result.validationErrors !== \"undefined\" ||\n\t\ttypeof result.serverError !== \"undefined\"\n\t) {\n\t\treturn \"hasErrored\";\n\t} else if (hasNavigated) {\n\t\treturn \"hasNavigated\";\n\t} else {\n\t\treturn \"hasSucceeded\";\n\t}\n};\n\nexport const getActionShorthandStatusObject = (status: HookActionStatus): HookShorthandStatus => {\n\treturn {\n\t\tisIdle: status === \"idle\",\n\t\tisExecuting: status === \"executing\",\n\t\tisTransitioning: status === \"transitioning\",\n\t\tisPending: status === \"executing\" || status === \"transitioning\",\n\t\thasSucceeded: status === \"hasSucceeded\",\n\t\thasErrored: status === \"hasErrored\",\n\t\thasNavigated: status === \"hasNavigated\",\n\t};\n};\n\nexport const useActionCallbacks = <ServerError, S extends StandardSchemaV1 | undefined, CVE, Data>({\n\tresult,\n\tinput,\n\tstatus,\n\tcb,\n\tnavigationError,\n\tthrownError,\n}: {\n\tresult: SafeActionResult<ServerError, S, CVE, Data>;\n\tinput: InferInputOrDefault<S, undefined>;\n\tstatus: HookActionStatus;\n\tcb?: HookCallbacks<ServerError, S, CVE, Data>;\n\tnavigationError: Error | null;\n\tthrownError: Error | null;\n}) => {\n\tconst onExecuteRef = React.useRef(cb?.onExecute);\n\tconst onSuccessRef = React.useRef(cb?.onSuccess);\n\tconst onErrorRef = React.useRef(cb?.onError);\n\tconst onSettledRef = React.useRef(cb?.onSettled);\n\tconst onNavigationRef = React.useRef(cb?.onNavigation);\n\n\t// Execute the callback when the action status changes.\n\tReact.useEffect(() => {\n\t\tconst onExecute = onExecuteRef.current;\n\t\tconst onSuccess = onSuccessRef.current;\n\t\tconst onError = onErrorRef.current;\n\t\tconst onSettled = onSettledRef.current;\n\t\tconst onNavigation = onNavigationRef.current;\n\n\t\tconst executeCallbacks = async () => {\n\t\t\tswitch (status) {\n\t\t\t\tcase \"executing\":\n\t\t\t\t\tawait Promise.resolve(onExecute?.({ input })).then(() => {});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"transitioning\":\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"hasSucceeded\":\n\t\t\t\t\tif (navigationError || thrownError) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait Promise.all([\n\t\t\t\t\t\tPromise.resolve(onSuccess?.({ data: result?.data, input })),\n\t\t\t\t\t\tPromise.resolve(onSettled?.({ result, input })),\n\t\t\t\t\t]);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"hasErrored\":\n\t\t\t\t\tawait Promise.all([\n\t\t\t\t\t\tPromise.resolve(onError?.({ error: { ...result, ...(thrownError ? { thrownError } : {}) }, input })),\n\t\t\t\t\t\tPromise.resolve(onSettled?.({ result, input })),\n\t\t\t\t\t]);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Navigation flow.\n\t\t\t// If the user redirected to a different page, the `hasNavigated` status never gets set.\n\t\t\t// In all the other cases, the `hasNavigated` status is set.\n\t\t\tif (!navigationError) return;\n\t\t\tconst navigationKind = FrameworkErrorHandler.getNavigationKind(navigationError);\n\n\t\t\tif (navigationKind === \"redirect\" || status === \"hasNavigated\") {\n\t\t\t\tconst navigationKind = FrameworkErrorHandler.getNavigationKind(navigationError);\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\tonNavigation?.({\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\tnavigationKind,\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t\tPromise.resolve(onSettled?.({ result, input, navigationKind })),\n\t\t\t\t]);\n\t\t\t}\n\n\t\t\tthrow navigationError;\n\t\t};\n\n\t\texecuteCallbacks().catch(console.error);\n\t}, [input, status, result, navigationError, thrownError]);\n};\n","// Comes from https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/lazy-dynamic/bailout-to-csr.ts\n\n// This has to be a shared module which is shared between client component error boundary and dynamic component\nconst BAILOUT_TO_CSR = \"BAILOUT_TO_CLIENT_SIDE_RENDERING\";\n\n/** An error that should be thrown when we want to bail out to client-side rendering. */\nclass BailoutToCSRError extends Error {\n\tpublic readonly digest = BAILOUT_TO_CSR;\n\n\tconstructor(public readonly reason: string) {\n\t\tsuper(`Bail out to client-side rendering: ${reason}`);\n\t}\n}\n\n/** Checks if a passed argument is an error that is thrown if we want to bail out to client-side rendering. */\nexport function isBailoutToCSRError(err: unknown): err is BailoutToCSRError {\n\tif (typeof err !== \"object\" || err === null || !(\"digest\" in err)) {\n\t\treturn false;\n\t}\n\n\treturn err.digest === BAILOUT_TO_CSR;\n}\n","// Comes from https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/http-access-fallback/http-access-fallback.ts\n\nconst HTTPAccessErrorStatus = {\n\tNOT_FOUND: 404,\n\tFORBIDDEN: 403,\n\tUNAUTHORIZED: 401,\n};\n\nconst ALLOWED_CODES = new Set(Object.values(HTTPAccessErrorStatus));\n\nconst HTTP_ERROR_FALLBACK_ERROR_CODE = \"NEXT_HTTP_ERROR_FALLBACK\";\n\nexport type HTTPAccessFallbackError = Error & {\n\tdigest: `${typeof HTTP_ERROR_FALLBACK_ERROR_CODE};${string}`;\n};\n\n/**\n * Checks an error to determine if it's an error generated by\n * the HTTP navigation APIs `notFound()`, `forbidden()` or `unauthorized()`.\n *\n * @param error the error that may reference a HTTP access error\n * @returns true if the error is a HTTP access error\n */\nexport function isHTTPAccessFallbackError(error: unknown): error is HTTPAccessFallbackError {\n\tif (typeof error !== \"object\" || error === null || !(\"digest\" in error) || typeof error.digest !== \"string\") {\n\t\treturn false;\n\t}\n\tconst [prefix, httpStatus] = error.digest.split(\";\");\n\n\treturn prefix === HTTP_ERROR_FALLBACK_ERROR_CODE && ALLOWED_CODES.has(Number(httpStatus));\n}\n\nexport function getAccessFallbackHTTPStatus(error: HTTPAccessFallbackError): number {\n\tconst httpStatus = error.digest.split(\";\")[1];\n\treturn Number(httpStatus);\n}\n","// Comes from: https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/redirect-error.ts\n\nenum RedirectStatusCode {\n\tSeeOther = 303,\n\tTemporaryRedirect = 307,\n\tPermanentRedirect = 308,\n}\n\nconst REDIRECT_ERROR_CODE = \"NEXT_REDIRECT\";\n\nenum RedirectType {\n\tpush = \"push\",\n\treplace = \"replace\",\n}\n\nexport type RedirectError = Error & {\n\tdigest: `${typeof REDIRECT_ERROR_CODE};${RedirectType};${string};${RedirectStatusCode};`;\n};\n\n/**\n * Checks an error to determine if it's an error generated by the\n * `redirect(url)` helper.\n *\n * @param error the error that may reference a redirect error\n * @returns true if the error is a redirect error\n */\nexport function isRedirectError(error: unknown): error is RedirectError {\n\tif (typeof error !== \"object\" || error === null || !(\"digest\" in error) || typeof error.digest !== \"string\") {\n\t\treturn false;\n\t}\n\n\tconst digest = error.digest.split(\";\");\n\tconst [errorCode, type] = digest;\n\tconst destination = digest.slice(2, -2).join(\";\");\n\tconst status = digest.at(-2);\n\n\tconst statusCode = Number(status);\n\n\treturn (\n\t\terrorCode === REDIRECT_ERROR_CODE &&\n\t\t(type === \"replace\" || type === \"push\") &&\n\t\ttypeof destination === \"string\" &&\n\t\t!isNaN(statusCode) &&\n\t\tstatusCode in RedirectStatusCode\n\t);\n}\n","// Comes from https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/is-next-router-error.ts\n\nimport { isHTTPAccessFallbackError, type HTTPAccessFallbackError } from \"./http-access-fallback\";\nimport { isRedirectError, type RedirectError } from \"./redirect\";\n\n/**\n * Returns true if the error is a navigation signal error. These errors are\n * thrown by user code to perform navigation operations and interrupt the React\n * render.\n */\nexport function isNextRouterError(error: unknown): error is RedirectError | HTTPAccessFallbackError {\n\treturn isRedirectError(error) || isHTTPAccessFallbackError(error);\n}\n","// Comes from https://github.com/vercel/next.js/blob/canary/packages/next/src/export/helpers/is-dynamic-usage-error.ts\n\nimport { isBailoutToCSRError } from \"./bailout-to-csr\";\nimport { isNextRouterError } from \"./router\";\n\nconst DYNAMIC_ERROR_CODE = \"DYNAMIC_SERVER_USAGE\";\n\nclass DynamicServerError extends Error {\n\tdigest: typeof DYNAMIC_ERROR_CODE = DYNAMIC_ERROR_CODE;\n\n\tconstructor(public readonly description: string) {\n\t\tsuper(`Dynamic server usage: ${description}`);\n\t}\n}\n\nfunction isDynamicServerError(err: unknown): err is DynamicServerError {\n\tif (typeof err !== \"object\" || err === null || !(\"digest\" in err) || typeof err.digest !== \"string\") {\n\t\treturn false;\n\t}\n\n\treturn err.digest === DYNAMIC_ERROR_CODE;\n}\n\nfunction isDynamicPostponeReason(reason: string) {\n\treturn (\n\t\treason.includes(\"needs to bail out of prerendering at this point because it used\") &&\n\t\treason.includes(\"Learn more: https://nextjs.org/docs/messages/ppr-caught-error\")\n\t);\n}\n\nfunction isDynamicPostpone(err: unknown) {\n\tif (\n\t\ttypeof err === \"object\" &&\n\t\terr !== null &&\n\t\t// eslint-disable-next-line\n\t\ttypeof (err as any).message === \"string\"\n\t) {\n\t\t// eslint-disable-next-line\n\t\treturn isDynamicPostponeReason((err as any).message);\n\t}\n\treturn false;\n}\n\nexport const isDynamicUsageError = (err: unknown) =>\n\tisDynamicServerError(err) || isBailoutToCSRError(err) || isNextRouterError(err) || isDynamicPostpone(err);\n","// Comes from https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/router-utils/is-postpone.ts\n\nconst REACT_POSTPONE_TYPE: symbol = Symbol.for(\"react.postpone\");\n\nexport function isPostpone(error: any): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t// eslint-disable-next-line\n\t\terror.$$typeof === REACT_POSTPONE_TYPE\n\t);\n}\n","import type { NavigationKind } from \"../../index.types\";\nimport { isBailoutToCSRError } from \"./bailout-to-csr\";\nimport { isDynamicUsageError } from \"./dynamic-usage\";\nimport { getAccessFallbackHTTPStatus, isHTTPAccessFallbackError } from \"./http-access-fallback\";\nimport { isPostpone } from \"./postpone\";\nimport { isRedirectError } from \"./redirect\";\nimport { isNextRouterError } from \"./router\";\n\nexport class FrameworkErrorHandler {\n\t#frameworkError: Error | undefined;\n\n\tstatic isNavigationError(error: unknown): error is Error {\n\t\treturn isNextRouterError(error) || isBailoutToCSRError(error) || isDynamicUsageError(error) || isPostpone(error);\n\t}\n\n\tstatic getNavigationKind(error: Error): NavigationKind {\n\t\tif (isRedirectError(error)) {\n\t\t\treturn \"redirect\";\n\t\t} else if (isHTTPAccessFallbackError(error) && getAccessFallbackHTTPStatus(error) === 404) {\n\t\t\treturn \"notFound\";\n\t\t} else if (isHTTPAccessFallbackError(error) && getAccessFallbackHTTPStatus(error) === 403) {\n\t\t\treturn \"forbidden\";\n\t\t} else if (isHTTPAccessFallbackError(error) && getAccessFallbackHTTPStatus(error) === 401) {\n\t\t\treturn \"unauthorized\";\n\t\t} else {\n\t\t\treturn \"other\";\n\t\t}\n\t}\n\n\t// Used in action builder.\n\thandleError(e: unknown) {\n\t\tif (FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\tthis.#frameworkError = e;\n\t\t\treturn;\n\t\t}\n\n\t\t// If it's not a framework error, rethrow it, so it gets returned as a server error.\n\t\tthrow e;\n\t}\n\n\tget error() {\n\t\treturn this.#frameworkError;\n\t}\n}\n"],"mappings":"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","names":["React","RedirectStatusCode","navigationKind"]}