UNPKG

@better-auth-ui/core

Version:

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

164 lines (151 loc) 4.81 kB
import { type QueryClient, type QueryOptions, skipToken } from "@tanstack/query-core" import type { InferData } from "../../lib/auth-client" import type { AdminAuthClient } from "./admin-auth-client" import { adminQueryKeys } from "./admin-query-keys" type AdminResultError = { code?: string message?: string status: number statusText: string } /** Error returned by a Better Auth Admin client request. */ export class AdminClientError extends Error { readonly code?: string readonly status: number readonly statusText: string constructor(error: AdminResultError) { super(error.message || error.statusText || "Admin request failed") this.name = "AdminClientError" this.code = error.code this.status = error.status this.statusText = error.statusText } } type ListUsersInput = NonNullable< Parameters<AdminAuthClient["admin"]["listUsers"]>[0] > export type AdminListUsersParams = NonNullable<ListUsersInput["query"]> export type AdminUsersResponse = NonNullable< InferData<AdminAuthClient["admin"]["listUsers"]> > export type AdminUser = AdminUsersResponse["users"][number] export type AdminUserResponse = NonNullable< InferData<AdminAuthClient["admin"]["getUser"]> > export type AdminUserSessionsResponse = NonNullable< InferData<AdminAuthClient["admin"]["listUserSessions"]> > export type AdminUserSession = AdminUserSessionsResponse["sessions"][number] export type AdminPermission = Readonly<Record<string, readonly string[]>> export type AdminPermissionResponse = NonNullable< InferData<AdminAuthClient["admin"]["hasPermission"]> > const unwrapAdminResult = <TData>( result: { data: TData; error: null } | { data: null; error: AdminResultError } ) => { if (result.error) throw new AdminClientError(result.error) return result.data } /** Query options for the Admin user list. */ export function adminUsersOptions( authClient: AdminAuthClient, actorUserId?: string, params: AdminListUsersParams = {} ) { return { queryKey: adminQueryKeys.users.list(actorUserId, params), meta: { errorPresentation: "inline" }, queryFn: actorUserId ? async ({ signal }) => unwrapAdminResult( await authClient.admin.listUsers({ query: params, fetchOptions: { signal } }) ) : skipToken } satisfies QueryOptions<AdminUsersResponse> } /** Query options for one user selected in the Admin inspector. */ export function adminUserOptions( authClient: AdminAuthClient, actorUserId?: string, targetUserId?: string ) { return { queryKey: adminQueryKeys.users.detail(actorUserId, targetUserId), meta: { errorPresentation: "inline" }, queryFn: actorUserId && targetUserId ? async ({ signal }) => unwrapAdminResult( await authClient.admin.getUser({ query: { id: targetUserId }, fetchOptions: { signal } }) ) : skipToken } satisfies QueryOptions<AdminUserResponse> } /** Query options for sessions belonging to one selected user. */ export function adminUserSessionsOptions( authClient: AdminAuthClient, actorUserId?: string, targetUserId?: string ) { return { queryKey: adminQueryKeys.users.sessions(actorUserId, targetUserId), meta: { errorPresentation: "inline" }, queryFn: actorUserId && targetUserId ? async ({ signal }) => unwrapAdminResult( await authClient.admin.listUserSessions({ userId: targetUserId, fetchOptions: { signal } }) ) : skipToken } satisfies QueryOptions<AdminUserSessionsResponse> } /** Query options for one permission held by the acting user. */ export function adminPermissionOptions( authClient: AdminAuthClient, actorUserId: string | undefined, permission: AdminPermission ) { return { queryKey: adminQueryKeys.permissions.has(actorUserId, permission), queryFn: actorUserId ? async ({ signal }) => unwrapAdminResult( await authClient.admin.hasPermission({ permissions: permission as Record<string, string[]>, fetchOptions: { signal } }) ) : skipToken } satisfies QueryOptions<AdminPermissionResponse> } export const ensureAdminUsers = ( queryClient: QueryClient, authClient: AdminAuthClient, actorUserId: string, params?: AdminListUsersParams ) => queryClient.ensureQueryData( adminUsersOptions(authClient, actorUserId, params) ) export const fetchAdminUser = ( queryClient: QueryClient, authClient: AdminAuthClient, actorUserId: string, targetUserId: string ) => queryClient.fetchQuery( adminUserOptions(authClient, actorUserId, targetUserId) )