diff --git a/.changeset/root-auth-loader-options-removed.md b/.changeset/root-auth-loader-options-removed.md new file mode 100644 index 00000000000..6955bd34632 --- /dev/null +++ b/.changeset/root-auth-loader-options-removed.md @@ -0,0 +1,5 @@ +--- +'@clerk/react-router': minor +--- + +Remove the `options` argument from `rootAuthLoader()`. It had no effect, since `rootAuthLoader` reads auth state from `clerkMiddleware()`. Pass options like `secretKey` or `signInUrl` to `clerkMiddleware()` instead. The `rootAuthLoader()` callback request no longer types `request.user`, `request.session`, or `request.organization`, because they were always `undefined`. `RootAuthLoaderOptions` is deprecated in favor of `ClerkMiddlewareOptions`, and its unused `loadUser`, `loadSession`, and `loadOrganization` flags are removed. diff --git a/packages/react-router/src/server/__tests__/rootAuthLoader.test.ts b/packages/react-router/src/server/__tests__/rootAuthLoader.test.ts index a1da41dae47..4108e2fdd87 100644 --- a/packages/react-router/src/server/__tests__/rootAuthLoader.test.ts +++ b/packages/react-router/src/server/__tests__/rootAuthLoader.test.ts @@ -50,6 +50,12 @@ describe('rootAuthLoader', () => { await rootAuthLoader(args, () => ({ data: 'test' })); }); + it('should ignore a non-function second argument from older call sites', async () => { + const result = await rootAuthLoader(args, { secretKey: 'sk_test_ignored' } as any); + + expect(result).toHaveProperty('clerkState'); + }); + it('should handle no callback', async () => { const result = await rootAuthLoader(args); diff --git a/packages/react-router/src/server/rootAuthLoader.ts b/packages/react-router/src/server/rootAuthLoader.ts index 5a1d625e604..b828888ff9f 100644 --- a/packages/react-router/src/server/rootAuthLoader.ts +++ b/packages/react-router/src/server/rootAuthLoader.ts @@ -8,7 +8,6 @@ import type { LoaderFunctionArgsWithAuth, LoaderFunctionReturn, RootAuthLoaderCallback, - RootAuthLoaderOptions, } from './types'; import { getResponseClerkState, @@ -20,7 +19,7 @@ import { } from './utils'; interface RootAuthLoader { - >( + ( /** * Arguments passed to the loader function. */ @@ -29,10 +28,9 @@ interface RootAuthLoader { * A loader function with authentication state made available to it. Allows you to fetch route data based on the user's authentication state. */ callback: Callback, - options?: Options, ): Promise>; - (args: LoaderFunctionArgs, options?: RootAuthLoaderOptions): Promise; + (args: LoaderFunctionArgs): Promise; } /** @@ -42,7 +40,7 @@ async function processRootAuthLoader( args: LoaderFunctionArgs, requestState: RequestState, additionalState: AdditionalStateOptions, - handler?: RootAuthLoaderCallback, + handler?: RootAuthLoaderCallback, ): Promise { const hasMiddleware = IsOptIntoMiddleware(args.context) && !!args.context.get(authFnContext); const includeClerkHeaders = !hasMiddleware; @@ -59,7 +57,7 @@ async function processRootAuthLoader( const argsWithAuth = { ...args, request: Object.assign(args.request, { auth: requestState.toAuth() }), - } as LoaderFunctionArgsWithAuth; + } as LoaderFunctionArgsWithAuth; const handlerResult = await handler(argsWithAuth); @@ -115,9 +113,9 @@ async function processRootAuthLoader( */ export const rootAuthLoader: RootAuthLoader = async ( args: LoaderFunctionArgs, - handlerOrOptions: any, + callback?: unknown, ): Promise => { - const handler = typeof handlerOrOptions === 'function' ? handlerOrOptions : undefined; + const handler = typeof callback === 'function' ? (callback as RootAuthLoaderCallback) : undefined; const hasMiddlewareFlag = IsOptIntoMiddleware(args.context); const contextValue = hasMiddlewareFlag && args.context.get(requestStateContext); diff --git a/packages/react-router/src/server/types.ts b/packages/react-router/src/server/types.ts index 9342f6b39af..9a627f7a666 100644 --- a/packages/react-router/src/server/types.ts +++ b/packages/react-router/src/server/types.ts @@ -1,4 +1,4 @@ -import type { Organization, Session, User, VerifyTokenOptions } from '@clerk/backend'; +import type { VerifyTokenOptions } from '@clerk/backend'; import type { OrganizationSyncOptions, RequestState, @@ -48,20 +48,10 @@ export type ClerkMiddlewareOptions = { SignUpForceRedirectUrl & SignUpFallbackRedirectUrl; -export type RootAuthLoaderOptions = ClerkMiddlewareOptions & { - /** - * @deprecated Use [session token claims](https://clerk.com/docs/backend-requests/making/custom-session-token) instead. - */ - loadUser?: boolean; - /** - * @deprecated Use [session token claims](https://clerk.com/docs/backend-requests/making/custom-session-token) instead. - */ - loadSession?: boolean; - /** - * @deprecated Use [session token claims](https://clerk.com/docs/backend-requests/making/custom-session-token) instead. - */ - loadOrganization?: boolean; -}; +/** + * @deprecated Use `ClerkMiddlewareOptions` instead. `rootAuthLoader()` no longer accepts options. + */ +export type RootAuthLoaderOptions = ClerkMiddlewareOptions; export interface KeylessUrls { __keylessClaimUrl?: string; @@ -84,7 +74,7 @@ export type RequestStateWithRedirectUrls = RequestState & SignUpFallbackRedirectUrl & KeylessUrls; -export type RootAuthLoaderCallback = ( +export type RootAuthLoaderCallback = ( args: LoaderFunctionArgsWithAuth, ) => RootAuthLoaderCallbackReturn; @@ -109,8 +99,6 @@ export type LoaderFunctionArgsWithAuth; }; -export type RequestWithAuth = LoaderFunctionArgs['request'] & { +export type RequestWithAuth<_Options extends RootAuthLoaderOptions = any> = LoaderFunctionArgs['request'] & { auth: Omit; -} & (Options extends { loadSession: true } ? { session: Session | null } : object) & - (Options extends { loadUser: true } ? { user: User | null } : object) & - (Options extends { loadOrganization: true } ? { organization: Organization | null } : object); +};