UNPKG

kitcn

Version:

kitcn - React Query integration and CLI tools for Convex

89 lines (87 loc) 2.97 kB
import { t as getToken } from "../../token-oA2EMtPA.js"; import { n as defaultIsUnauthorized } from "../../error-Bvo7YEhk.js"; import { t as createCallerFactory } from "../../caller-factory-NEfgD5E0.js"; //#region src/auth-nextjs/index.ts /** biome-ignore-all lint/suspicious/noExplicitAny: lib */ /** * Next.js + Better Auth wrapper for Convex caller factory. */ const TRAILING_COLON_RE = /:$/; const handler = async (request, siteUrl) => { const requestUrl = new URL(request.url); const nextUrl = `${siteUrl}${requestUrl.pathname}${requestUrl.search}`; const headers = new Headers(request.headers); headers.set("accept-encoding", "application/json"); headers.set("host", new URL(siteUrl).host); headers.set("x-forwarded-host", requestUrl.host); headers.set("x-forwarded-proto", requestUrl.protocol.replace(TRAILING_COLON_RE, "")); headers.set("x-better-auth-forwarded-host", requestUrl.host); headers.set("x-better-auth-forwarded-proto", requestUrl.protocol.replace(TRAILING_COLON_RE, "")); const body = request.method !== "GET" && request.method !== "HEAD" ? await request.arrayBuffer() : void 0; return fetch(nextUrl, { body, headers, method: request.method, redirect: "manual" }); }; const nextJsHandler = (siteUrl) => ({ GET: (request) => handler(request, siteUrl), POST: (request) => handler(request, siteUrl) }); /** * Create Convex caller factory with Better Auth integration for Next.js. * * @example * ```ts * // server.ts * export const { createContext, createCaller, handler } = convexBetterAuth({ * api, * convexSiteUrl: env.NEXT_PUBLIC_CONVEX_SITE_URL, * }); // JWT caching enabled by default * * // rsc.tsx * const createRSCContext = cache(async () => { * const heads = await headers(); * return createContext({ headers: heads }); * }); * export const caller = createCaller(createRSCContext); * * // app/page.tsx - single call! * const posts = await caller.posts.list(); * ``` */ function convexBetterAuth(opts) { const auth = opts.auth ?? {}; const jwtCacheEnabled = auth.jwtCache !== false; const { createContext, createCaller } = createCallerFactory({ api: opts.api, auth: jwtCacheEnabled ? { getToken: (siteUrl, headers, getTokenOpts) => { const mutableHeaders = new Headers(headers); mutableHeaders.delete("content-length"); mutableHeaders.delete("transfer-encoding"); mutableHeaders.set("accept-encoding", "identity"); return getToken(siteUrl, mutableHeaders, { basePath: auth.basePath, ...getTokenOpts, jwtCache: { enabled: true, expirationToleranceSeconds: auth.expirationToleranceSeconds, isAuthError: auth.isUnauthorized ?? defaultIsUnauthorized } }); }, isUnauthorized: auth.isUnauthorized ?? defaultIsUnauthorized } : void 0, convexSiteUrl: opts.convexSiteUrl, convexUrl: opts.convexUrl }); return { createCaller, createContext, handler: nextJsHandler(opts.convexSiteUrl) }; } //#endregion export { convexBetterAuth };