{"version":3,"file":"next-app-dir.mjs","names":[],"sources":["../../src/adapters/next-app-dir/redirect.ts","../../src/adapters/next-app-dir/rethrowNextErrors.ts","../../src/adapters/next-app-dir/nextAppDirCaller.ts","../../src/adapters/next-app-dir/notFound.ts"],"sourcesContent":["import type { RedirectType } from 'next/navigation';\nimport { TRPCError } from '../../@trpc/server';\n\n/**\n * @internal\n */\nexport class TRPCRedirectError extends TRPCError {\n  public readonly args;\n  constructor(url: URL | string, redirectType?: RedirectType) {\n    super({\n      // TODO(?): This should maybe a custom error code\n      code: 'UNPROCESSABLE_CONTENT',\n      message: `Redirect error to \"${url}\" that will be handled by Next.js`,\n    });\n\n    this.args = [url.toString(), redirectType] as const;\n  }\n}\n\n/**\n * Like `next/navigation`'s `redirect()` but throws a `TRPCError` that later will be handled by Next.js\n * This provides better typesafety than the `next/navigation`'s `redirect()` since the action continues\n * to execute on the frontend even if Next's `redirect()` has a return type of `never`.\n * @public\n * @remark You should only use this if you're also using `nextAppDirCaller`.\n */\nexport const redirect = (url: URL | string, redirectType?: RedirectType) => {\n  // We rethrow this internally so the returntype on the client is undefined.\n  return new TRPCRedirectError(url, redirectType) as unknown as undefined;\n};\n","import * as nextNavigation from 'next/navigation';\nimport type { TRPCError } from '../../@trpc/server';\nimport { TRPCRedirectError } from './redirect';\n\n/**\n * @remarks The helpers from `next/dist/client/components/*` has been removed in Next.js 15.\n * Inlining them here instead...\n * @see https://github.com/vercel/next.js/blob/5ae286ffd664e5c76841ed64f6e2da85a0835922/packages/next/src/client/components/redirect.ts#L97-L123\n */\nconst REDIRECT_ERROR_CODE = 'NEXT_REDIRECT';\nfunction isRedirectError(error: unknown) {\n  if (\n    typeof error !== 'object' ||\n    error === null ||\n    !('digest' in error) ||\n    typeof error.digest !== 'string'\n  ) {\n    return false;\n  }\n  const [errorCode, type, destination, status] = error.digest.split(';', 4);\n  const statusCode = Number(status);\n  return (\n    errorCode === REDIRECT_ERROR_CODE &&\n    (type === 'replace' || type === 'push') &&\n    typeof destination === 'string' &&\n    !isNaN(statusCode)\n  );\n}\n\n/**\n * @remarks The helpers from `next/dist/client/components/*` has been removed in Next.js 15.\n * Inlining them here instead...\n * @see https://github.com/vercel/next.js/blob/5ae286ffd664e5c76841ed64f6e2da85a0835922/packages/next/src/client/components/not-found.ts#L33-L39\n */\nconst NOT_FOUND_ERROR_CODE = 'NEXT_NOT_FOUND';\nfunction isNotFoundError(error: unknown) {\n  if (typeof error !== 'object' || error === null || !('digest' in error)) {\n    return false;\n  }\n  return error.digest === NOT_FOUND_ERROR_CODE;\n}\n\n/**\n * Rethrow errors that should be handled by Next.js\n */\nexport const rethrowNextErrors = (error: TRPCError) => {\n  if (error.code === 'NOT_FOUND') {\n    nextNavigation.notFound();\n  }\n  if (error instanceof TRPCRedirectError) {\n    nextNavigation.redirect(...error.args);\n  }\n  const { cause } = error;\n\n  // Next.js 15 has `unstable_rethrow`. Use that if it exists.\n  if (\n    'unstable_rethrow' in nextNavigation &&\n    typeof nextNavigation.unstable_rethrow === 'function'\n  ) {\n    nextNavigation.unstable_rethrow(cause);\n  }\n\n  // Before Next.js 15, we have to check and rethrow the error manually.\n  if (isRedirectError(cause) || isNotFoundError(cause)) {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    throw cause!;\n  }\n};\n","import type { CreateContextCallback } from '../../@trpc/server';\nimport { getTRPCErrorFromUnknown, TRPCError } from '../../@trpc/server';\n// eslint-disable-next-line no-restricted-imports\nimport { formDataToObject } from '../../unstable-core-do-not-import';\n// FIXME: fix lint rule, this is ok\n// eslint-disable-next-line no-restricted-imports\nimport type { ErrorHandlerOptions } from '../../unstable-core-do-not-import/procedure';\n// FIXME: fix lint rule, this is ok\n// eslint-disable-next-line no-restricted-imports\nimport type { CallerOverride } from '../../unstable-core-do-not-import/procedureBuilder';\n// FIXME: fix lint rule, this is ok\n// eslint-disable-next-line no-restricted-imports\nimport type {\n  MaybePromise,\n  Simplify,\n} from '../../unstable-core-do-not-import/types';\nimport { TRPCRedirectError } from './redirect';\nimport { rethrowNextErrors } from './rethrowNextErrors';\n\n/**\n * Create a caller that works with Next.js React Server Components & Server Actions\n */\nexport function nextAppDirCaller<TContext, TMeta>(\n  config: Simplify<\n    {\n      /**\n       * Extract the path from the procedure metadata\n       */\n      pathExtractor?: (opts: { meta: TMeta }) => string;\n      /**\n       * Transform form data to a `Record` before passing it to the procedure\n       * @default true\n       */\n      normalizeFormData?: boolean;\n      /**\n       * Called when an error occurs in the handler\n       */\n      onError?: (opts: ErrorHandlerOptions<TContext>) => void;\n    } & CreateContextCallback<TContext, () => MaybePromise<TContext>>\n  >,\n): CallerOverride<TContext> {\n  const {\n    normalizeFormData = true,\n\n    // rethrowNextErrors = true\n  } = config;\n  const createContext = async (): Promise<TContext> => {\n    return config?.createContext?.() ?? ({} as TContext);\n  };\n\n  return async (opts) => {\n    const path =\n      config.pathExtractor?.({ meta: opts._def.meta as TMeta }) ?? '';\n    const ctx: TContext = await createContext().catch((cause) => {\n      const error = new TRPCError({\n        code: 'INTERNAL_SERVER_ERROR',\n        message: 'Failed to create context',\n        cause,\n      });\n\n      throw error;\n    });\n\n    const handleError = (cause: unknown) => {\n      const error = getTRPCErrorFromUnknown(cause);\n\n      config.onError?.({\n        ctx,\n        error,\n        input: opts.args[0],\n        path,\n        type: opts._def.type,\n      });\n\n      rethrowNextErrors(error);\n\n      throw error;\n    };\n    switch (opts._def.type) {\n      case 'mutation': {\n        /**\n         * When you wrap an action with useFormState, it gets an extra argument as its first argument.\n         * The submitted form data is therefore its second argument instead of its first as it would usually be.\n         * The new first argument that gets added is the current state of the form.\n         * @see https://react.dev/reference/react-dom/hooks/useFormState#my-action-can-no-longer-read-the-submitted-form-data\n         */\n        let input = opts.args.length === 1 ? opts.args[0] : opts.args[1];\n        if (normalizeFormData && input instanceof FormData) {\n          input = formDataToObject(input);\n        }\n\n        return await opts\n          .invoke({\n            type: opts._def.type,\n            ctx,\n            getRawInput: async () => input,\n            path,\n            input,\n            signal: undefined,\n            batchIndex: 0,\n          })\n          .then((data) => {\n            if (data instanceof TRPCRedirectError) throw data;\n            return data;\n          })\n          .catch(handleError);\n      }\n      case 'query': {\n        const input = opts.args[0];\n        return await opts\n          .invoke({\n            type: opts._def.type,\n            ctx,\n            getRawInput: async () => input,\n            path,\n            input,\n            signal: undefined,\n            batchIndex: 0,\n          })\n          .then((data) => {\n            if (data instanceof TRPCRedirectError) throw data;\n            return data;\n          })\n          .catch(handleError);\n      }\n      case 'subscription':\n      default: {\n        throw new TRPCError({\n          code: 'NOT_IMPLEMENTED',\n          message: `Not implemented for type ${opts._def.type}`,\n        });\n      }\n    }\n  };\n}\n","import type { notFound as __notFound } from 'next/navigation';\nimport { TRPCError } from '../../@trpc/server';\n\n/**\n * Like `next/navigation`'s `notFound()` but throws a `TRPCError` that later will be handled by Next.js\n * @public\n */\nexport const notFound: typeof __notFound = () => {\n  throw new TRPCError({\n    code: 'NOT_FOUND',\n  });\n};\n"],"mappings":";;;;;;;;AAMA,IAAa,oBAAb,cAAuC,UAAU;CAE/C,YAAY,KAAmB,cAA6B;EAC1D,MAAM;GAEJ,MAAM;GACN,SAAS,sBAAsB,IAAI;EACrC,CAAC;EANa,gBAAA,MAAA,QAAA,KAAA,CAAA;EAQd,KAAK,OAAO,CAAC,IAAI,SAAS,GAAG,YAAY;CAC3C;AACF;;;;;;;;AASA,MAAa,YAAY,KAAmB,iBAAgC;CAE1E,OAAO,IAAI,kBAAkB,KAAK,YAAY;AAChD;;;;;;;;ACpBA,MAAM,sBAAsB;AAC5B,SAAS,gBAAgB,OAAgB;CACvC,IACE,OAAO,UAAU,YACjB,UAAU,QACV,EAAE,YAAY,UACd,OAAO,MAAM,WAAW,UAExB,OAAO;CAET,MAAM,CAAC,WAAW,MAAM,aAAa,UAAU,MAAM,OAAO,MAAM,KAAK,CAAC;CACxE,MAAM,aAAa,OAAO,MAAM;CAChC,OACE,cAAc,wBACb,SAAS,aAAa,SAAS,WAChC,OAAO,gBAAgB,YACvB,CAAC,MAAM,UAAU;AAErB;;;;;;AAOA,MAAM,uBAAuB;AAC7B,SAAS,gBAAgB,OAAgB;CACvC,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,YAAY,QAC/D,OAAO;CAET,OAAO,MAAM,WAAW;AAC1B;;;;AAKA,MAAa,qBAAqB,UAAqB;CACrD,IAAI,MAAM,SAAS,aACjB,eAAe,SAAS;CAE1B,IAAI,iBAAiB,mBACnB,eAAe,SAAS,GAAG,MAAM,IAAI;CAEvC,MAAM,EAAE,UAAU;CAGlB,IACE,sBAAsB,kBACtB,OAAO,eAAe,qBAAqB,YAE3C,eAAe,iBAAiB,KAAK;CAIvC,IAAI,gBAAgB,KAAK,KAAK,gBAAgB,KAAK,GAEjD,MAAM;AAEV;;;;;;AC7CA,SAAgB,iBACd,QAiB0B;CAC1B,MAAM,EACJ,oBAAoB,SAGlB;CACJ,MAAM,gBAAgB,YAA+B;;EACnD,QAAA,wBAAA,WAAA,QAAA,WAAA,KAAA,MAAA,yBAAO,OAAQ,mBAAA,QAAA,2BAAA,KAAA,IAAA,KAAA,IAAA,uBAAA,KAAA,MAAgB,OAAA,QAAA,0BAAA,KAAA,IAAA,wBAAM,CAAC;CACxC;CAEA,OAAO,OAAO,SAAS;;EACrB,MAAM,QAAA,yBAAA,yBACJ,OAAO,mBAAA,QAAA,2BAAA,KAAA,IAAA,KAAA,IAAA,uBAAA,KAAA,QAAgB,EAAE,MAAM,KAAK,KAAK,KAAc,CAAC,OAAA,QAAA,0BAAA,KAAA,IAAA,wBAAK;EAC/D,MAAM,MAAgB,MAAM,cAAc,CAAC,CAAC,OAAO,UAAU;GAO3D,MAAM,IANY,UAAU;IAC1B,MAAM;IACN,SAAS;IACT;GACF,CAEU;EACZ,CAAC;EAED,MAAM,eAAe,UAAmB;;GACtC,MAAM,QAAQ,wBAAwB,KAAK;GAE3C,CAAA,kBAAA,OAAO,aAAA,QAAA,oBAAA,KAAA,KAAA,gBAAA,KAAA,QAAU;IACf;IACA;IACA,OAAO,KAAK,KAAK;IACjB;IACA,MAAM,KAAK,KAAK;GAClB,CAAC;GAED,kBAAkB,KAAK;GAEvB,MAAM;EACR;EACA,QAAQ,KAAK,KAAK,MAAlB;GACE,KAAK,YAAY;;;;;;;IAOf,IAAI,QAAQ,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK;IAC9D,IAAI,qBAAqB,iBAAiB,UACxC,QAAQ,iBAAiB,KAAK;IAGhC,OAAO,MAAM,KACV,OAAO;KACN,MAAM,KAAK,KAAK;KAChB;KACA,aAAa,YAAY;KACzB;KACA;KACA,QAAQ,KAAA;KACR,YAAY;IACd,CAAC,CAAC,CACD,MAAM,SAAS;KACd,IAAI,gBAAgB,mBAAmB,MAAM;KAC7C,OAAO;IACT,CAAC,CAAC,CACD,MAAM,WAAW;GACtB;GACA,KAAK,SAAS;IACZ,MAAM,QAAQ,KAAK,KAAK;IACxB,OAAO,MAAM,KACV,OAAO;KACN,MAAM,KAAK,KAAK;KAChB;KACA,aAAa,YAAY;KACzB;KACA;KACA,QAAQ,KAAA;KACR,YAAY;IACd,CAAC,CAAC,CACD,MAAM,SAAS;KACd,IAAI,gBAAgB,mBAAmB,MAAM;KAC7C,OAAO;IACT,CAAC,CAAC,CACD,MAAM,WAAW;GACtB;GAEA,SACE,MAAM,IAAI,UAAU;IAClB,MAAM;IACN,SAAS,4BAA4B,KAAK,KAAK;GACjD,CAAC;EAEL;CACF;AACF;;;;;;;AC/HA,MAAa,iBAAoC;CAC/C,MAAM,IAAI,UAAU,EAClB,MAAM,YACR,CAAC;AACH"}