From b0e2c21d0af922e3bd75e3831d06fb32cab4cdc5 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 11 May 2026 08:35:08 +0200 Subject: [PATCH] fix(auth): widen AuthBundle.handlers to (Request) => Promise NextAuthResult["handlers"] embeds NextRequest from the kit's own next/node_modules copy, which conflicts with the consumer's next and produces a spurious RouteHandlerConfig mismatch in .next/types/validator.ts for every app's [...nextauth]/route.ts. Replace the inferred type with a structural AuthRouteHandlers shape using web-standard Request/Response. NextRequest extends Request, so function-parameter contravariance makes this assignable wherever Next's validator wants (request: NextRequest, ctx) => ... Cast through unknown at the return site since TS can't prove the contravariance across the two next copies on its own. Verified: gscCRM `npm run build` clean, `tsc --noEmit` no longer flags validator.ts. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/auth/server.ts | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/auth/server.ts b/src/auth/server.ts index a33c593..4d7556f 100644 --- a/src/auth/server.ts +++ b/src/auth/server.ts @@ -6,13 +6,31 @@ import type { CreateAuthOptions, SessionUser } from "./types"; export type { SessionUser, CreateAuthOptions }; +/** + * Shape of the GET/POST route handlers NextAuth returns. Declared + * structurally (Request → Response) rather than via + * `NextAuthResult["handlers"]` — that type embeds `NextRequest` from + * the kit's own copy of `next`, which conflicts with the consumer's + * `next` and produces a spurious `RouteHandlerConfig` mismatch in + * `.next/types/validator.ts` for every app's `[...nextauth]/route.ts`. + * + * Web-standard `Request`/`Response` are valid for Next.js route + * handlers (NextRequest extends Request), and TS function-parameter + * contravariance makes this assignable wherever the validator wants + * `(request: NextRequest, ctx) => ...`. + */ +export type AuthRouteHandlers = { + GET: (request: Request) => Promise; + POST: (request: Request) => Promise; +}; + /** * Result of `createAuth()`. Mirrors NextAuth's return value plus * `requireAuth` and the resolved `signInPath` so consumers don't have to * thread these around. */ export interface AuthBundle { - handlers: NextAuthResult["handlers"]; + handlers: AuthRouteHandlers; signIn: NextAuthResult["signIn"]; signOut: NextAuthResult["signOut"]; auth: NextAuthResult["auth"]; @@ -114,7 +132,12 @@ export function createAuth(opts: CreateAuthOptions): AuthBundle { } return { - handlers: na.handlers, + // Cast through unknown: NextAuth's handler param type references its + // own NextRequest; the AuthRouteHandlers shape is structurally + // compatible (NextRequest extends Request), but TS can't prove the + // function-parameter contravariance across the two `next` copies on + // its own. + handlers: na.handlers as unknown as AuthRouteHandlers, signIn: na.signIn, signOut: na.signOut, auth: na.auth,