UNPKG

@better-auth-ui/core

Version:

Authentication components and data utilities for [Better Auth](https://better-auth.com), available for React and Solid.

128 lines (115 loc) 4.33 kB
import type { QueryClient, QueryOptions } from "@tanstack/query-core" import type { AuthClient, InferData } from "../../lib/auth-client" import { authQueryKeys } from "../../lib/auth-query-keys" import { createAuthQueryFetchOptions } from "../../lib/auth-query-retry" export type SessionData<TAuthClient extends AuthClient> = InferData< TAuthClient["getSession"] > export type SessionParams<TAuthClient extends AuthClient> = Parameters< TAuthClient["getSession"] >[0] export type SessionOptions<TAuthClient extends AuthClient> = Partial< Omit<QueryOptions<SessionData<TAuthClient>>, "queryKey"> > & SessionParams<TAuthClient> /** * Query options factory for the current session. * * Shares a query key with the server-side `sessionOptions` so that data * prefetched during SSR hydrates seamlessly into the client cache. * * @param authClient - The Better Auth client. * @param params - Parameters forwarded to `authClient.getSession`. */ export function sessionOptions<TAuthClient extends AuthClient>( authClient: TAuthClient, params?: SessionParams<TAuthClient> ) { type TData = SessionData<TAuthClient> const queryKey = authQueryKeys.session return { queryKey, queryFn: ({ signal }) => authClient.getSession({ ...params, fetchOptions: createAuthQueryFetchOptions(params?.fetchOptions, signal) }) as Promise<TData> } satisfies QueryOptions } /** * Get the current session from the query cache, calling `fetchSession` under * the hood if no cached entry exists. Resolves with the session data, making * it ideal for loaders or `beforeLoad` guards. * * @param queryClient - The TanStack Query client. * @param authClient - The Better Auth client. * @param options - Params forwarded to `authClient.getSession` and query options. */ export const ensureSession = <TAuthClient extends AuthClient>( queryClient: QueryClient, authClient: TAuthClient, options?: SessionOptions<TAuthClient> ) => { const { fetchOptions, query, ...queryOptions } = options ?? {} return queryClient.ensureQueryData({ ...sessionOptions(authClient, { query, fetchOptions }), ...queryOptions }) } /** * Prefetch the current session into the query cache. Behaves like * `fetchSession`, but does not throw on error and does not return the data — * use this to warm the cache without blocking navigation. * * @param queryClient - The TanStack Query client. * @param authClient - The Better Auth client. * @param options - Params forwarded to `authClient.getSession` and query options. */ export const prefetchSession = <TAuthClient extends AuthClient>( queryClient: QueryClient, authClient: TAuthClient, options?: SessionOptions<TAuthClient> ) => { const { fetchOptions, query, ...queryOptions } = options ?? {} return queryClient.prefetchQuery({ ...sessionOptions(authClient, { query, fetchOptions }), ...queryOptions }) } /** * Fetch and cache the current session, resolving with the data or throwing * on error. If a cached entry exists and is neither invalidated nor older * than `staleTime`, the cached value is returned without a network call; * otherwise the latest data is fetched. * * @param queryClient - The TanStack Query client. * @param authClient - The Better Auth client. * @param options - Params forwarded to `authClient.getSession` and query options. */ export const fetchSession = <TAuthClient extends AuthClient>( queryClient: QueryClient, authClient: TAuthClient, options?: SessionOptions<TAuthClient> ) => { const { fetchOptions, query, ...queryOptions } = options ?? {} return queryClient.fetchQuery({ ...sessionOptions(authClient, { query, fetchOptions }), ...queryOptions }) } /** * Read the current session synchronously from the query cache without * triggering a fetch. Returns the cached session data, or `undefined` when * no entry exists — use this for non-suspending reads where a network call * is undesirable. * * @param queryClient - The TanStack Query client. * @param authClient - The Better Auth client. */ export const getSession = <TAuthClient extends AuthClient = AuthClient>( queryClient: QueryClient, _authClient?: TAuthClient ) => { const queryKey = authQueryKeys.session return queryClient.getQueryData<SessionData<TAuthClient>>(queryKey) }