├── .github └── workflows │ └── nextjs.yml ├── .gitignore ├── LICENSE ├── README.md ├── biome.json ├── docs ├── .gitignore ├── README.md ├── app │ ├── (docs) │ │ ├── [[...slug]] │ │ │ └── page.tsx │ │ └── layout.tsx │ ├── api │ │ └── search │ │ │ └── route.ts │ ├── favicon.ico │ ├── global.css │ ├── layout.config.tsx │ └── layout.tsx ├── content │ └── docs │ │ ├── index.mdx │ │ └── test.mdx ├── lib │ └── source.ts ├── next.config.mjs ├── package.json ├── pnpm-lock.yaml ├── postcss.config.mjs ├── source.config.ts ├── tsconfig.json └── turbo.json ├── package.json ├── pnpm-lock.yaml ├── src ├── hooks │ ├── accounts │ │ ├── use-list-accounts.ts │ │ └── use-unlink-account.ts │ ├── api-key │ │ ├── use-create-api-key.ts │ │ ├── use-delete-api-key.ts │ │ └── use-list-api-keys.ts │ ├── device-sessions │ │ ├── use-list-device-sessions.ts │ │ ├── use-revoke-device-session.ts │ │ ├── use-revoke-device-sessions.ts │ │ └── use-set-active-session.ts │ ├── organization │ │ ├── use-active-organization.ts │ │ ├── use-has-permission.ts │ │ ├── use-invitation.ts │ │ └── use-list-organizations.ts │ ├── passkey │ │ ├── use-delete-passkey.ts │ │ └── use-list-passkeys.ts │ ├── session │ │ ├── use-session.ts │ │ └── use-update-user.ts │ ├── sessions │ │ ├── use-list-sessions.ts │ │ ├── use-revoke-other-sessions.ts │ │ ├── use-revoke-session.ts │ │ └── use-revoke-sessions.ts │ ├── shared │ │ ├── use-auth-mutation.ts │ │ ├── use-auth-query.ts │ │ └── use-mutate-error.ts │ └── token │ │ └── use-token.ts ├── index.ts ├── lib │ ├── auth-query-provider.tsx │ ├── create-auth-hooks.ts │ ├── create-auth-prefetches.ts │ ├── prefetch-session-server.ts │ └── prefetch-session.ts ├── server.ts └── types │ ├── any-auth-client.ts │ ├── auth-client.ts │ ├── better-auth.ts │ └── list-account.ts ├── tsconfig.json ├── tsup.config.ts └── turbo.json /.github/workflows/nextjs.yml: -------------------------------------------------------------------------------- 1 | # Sample workflow for building and deploying a Next.js site to GitHub Pages 2 | # 3 | # To get started with Next.js see: https://nextjs.org/docs/getting-started 4 | # 5 | name: Deploy Next.js site to Pages 6 | 7 | on: 8 | # Runs on pushes targeting the default branch 9 | push: 10 | branches: ["main"] 11 | 12 | # Allows you to run this workflow manually from the Actions tab 13 | workflow_dispatch: 14 | 15 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 16 | permissions: 17 | contents: read 18 | pages: write 19 | id-token: write 20 | 21 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 22 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 23 | concurrency: 24 | group: "pages" 25 | cancel-in-progress: false 26 | 27 | jobs: 28 | # Build job 29 | build: 30 | runs-on: ubuntu-latest 31 | defaults: 32 | run: 33 | working-directory: docs 34 | 35 | steps: 36 | - name: Checkout 37 | uses: actions/checkout@v4 38 | - name: pnpm-setup 39 | uses: pnpm/action-setup@v4 40 | with: 41 | package_json_file: docs/package.json 42 | - name: Detect package manager 43 | id: detect-package-manager 44 | run: | 45 | if [ -f "yarn.lock" ]; then 46 | echo "manager=yarn" >> $GITHUB_OUTPUT 47 | echo "command=install" >> $GITHUB_OUTPUT 48 | echo "runner=yarn" >> $GITHUB_OUTPUT 49 | exit 0 50 | elif [ -f "package-lock.json" ]; then 51 | echo "manager=npm" >> $GITHUB_OUTPUT 52 | echo "command=ci" >> $GITHUB_OUTPUT 53 | echo "runner=npx --no-install" >> $GITHUB_OUTPUT 54 | exit 0 55 | elif [ -f "pnpm-lock.yaml" ]; then 56 | echo "manager=pnpm" >> $GITHUB_OUTPUT 57 | echo "command=install" >> $GITHUB_OUTPUT 58 | echo "runner=pnpm" >> $GITHUB_OUTPUT 59 | exit 0 60 | else 61 | echo "Unable to determine package manager" 62 | exit 1 63 | fi 64 | - name: Setup Node 65 | uses: actions/setup-node@v4 66 | with: 67 | node-version: "20" 68 | cache-dependency-path: docs/pnpm-lock.yaml 69 | cache: ${{ steps.detect-package-manager.outputs.manager }} 70 | - name: Setup Pages 71 | uses: actions/configure-pages@v5 72 | with: 73 | # Automatically inject basePath in your Next.js configuration file and disable 74 | # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized). 75 | # 76 | # You may remove this line if you want to manage the configuration yourself. 77 | static_site_generator: next 78 | - name: Restore cache 79 | uses: actions/cache@v4 80 | with: 81 | path: | 82 | .next/cache 83 | # Generate a new cache whenever packages or source files change. 84 | key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock', '**/pnpm-lock.yaml') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} 85 | # If source files changed but packages didn't, rebuild from a prior cache. 86 | restore-keys: | 87 | ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock', '**/pnpm-lock.yaml') }}- 88 | - name: Install dependencies 89 | run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} 90 | - name: Build with Next.js 91 | run: ${{ steps.detect-package-manager.outputs.runner }} next build 92 | - name: Upload artifact 93 | uses: actions/upload-pages-artifact@v3 94 | with: 95 | path: docs/out 96 | 97 | # Deployment job 98 | deploy: 99 | environment: 100 | name: github-pages 101 | url: ${{ steps.deployment.outputs.page_url }} 102 | runs-on: ubuntu-latest 103 | needs: build 104 | steps: 105 | - name: Deploy to GitHub Pages 106 | id: deployment 107 | uses: actions/deploy-pages@v4 108 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | /.vscode 132 | .turbo 133 | .DS_Store 134 | .source -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Daveyplate 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @daveyplate/better-auth-tanstack 2 | 3 | Tanstack Query hooks for Better Auth. Provides tighter control of when requests are made, optimistic mutations, and supports offline caching for offline auth via Persist Cients. 4 | 5 | More to come soon... (e.g. more SSR prefetches, organization & stripe plugin hooks, SWR port...) 6 | 7 | ☕️ [Buy me a coffee](https://buymeacoffee.com/daveycodez) 8 | 9 | ## Prerequisites 10 | 11 | First, you need to install and integrate [Better Auth](https://better-auth.com) & [Tanstack Query](https://tanstack.com/query). 12 | 13 | ## Installation 14 | 15 | pnpm 16 | ```bash 17 | pnpm add @daveyplate/better-auth-tanstack@latest 18 | ``` 19 | 20 | npm 21 | ```bash 22 | npm install @daveyplate/better-auth-tanstack@latest 23 | ``` 24 | 25 | For the `useSession` hook to refresh on sign in, sign out, and sign up without email verification, you must manually call `refetch` or `queryClient.resetQueries()` for `["session"]` in the `onSuccess` callback of each of those functions or after awaiting and checking for an error. 26 | 27 | If you are using Next.js App Router with protected middleware routes, `router.refresh()` is required as well to clear the router cache. 28 | 29 | [@daveyplate/better-auth-ui](https://better-auth-ui.com) Better Auth UI supports better-auth-tanstack out of the box! You simply need to use the `AuthUIProviderTanstack`. 30 | 31 | ## Setting up the AuthQueryProvider 32 | 33 | First, you need to set up the `AuthQueryProvider` in your application. This provider will supply the necessary context for the hooks to function. Requires `"use client"` directive for Next.js App Router. 34 | 35 | ### app/providers.tsx 36 | ```tsx 37 | "use client" 38 | 39 | import { AuthQueryProvider } from "@daveyplate/better-auth-tanstack" 40 | 41 | export default function Providers({ 42 | children, 43 | }: { 44 | children: React.ReactNode 45 | }) { 46 | return ( 47 | 48 | {children} 49 | 50 | ) 51 | } 52 | ``` 53 | 54 | ### app/layout.tsx 55 | ```tsx 56 | import { Providers } from "./providers" 57 | 58 | export default function RootLayout({ 59 | children, 60 | }: { 61 | children: React.ReactNode 62 | }) { 63 | return ( 64 | 65 | {children} 66 | 67 | ) 68 | } 69 | ``` 70 | 71 | ## AuthQueryProvider Props 72 | 73 | The `AuthQueryProvider` component accepts the following props. The default `staleTime` for `useSession` is 60 seconds and for `useToken` is 10 minutes. 74 | 75 | | Prop | Type | Description | 76 | |-----------------------|----------------------------------------------------------------------|-----------------------------------------------------------------------------| 77 | | queryOptions? | UseQueryOptions | Optional query options for the provider. | 78 | | sessionQueryOptions? | UseQueryOptions | Optional query options for the session query. | 79 | | tokenQueryOptions? | UseQueryOptions | Optional query options for the token query. | 80 | | sessionKey? | string[] | Optional key for the session query. The default is `["session"]`. | 81 | | tokenKey? | string[] | Optional key for the token query. The default is `["token"]`. | 82 | | listAccountsKey? | string[] | Optional key for the listAccounts query. The default is `["list-accounts"]`. | 83 | | listSessionsKey? | string[] | Optional key for the listSessions query. The default is `["list-sessions"]`. | 84 | | optimistic? | boolean | Whether to perform optimistic updates. The default is `true`. | 85 | | refetchOnMutate? | boolean | Whether to refetch after mutates. The default is `true`. | 86 | 87 | 88 | ## Creating `auth-hooks.ts` 89 | 90 | Create a file named `auth-hooks.ts` and set up the hooks using `createAuthHooks` function. This function takes the `authClient` instance and returns the hooks with full type safety and inference from your `authClient`. 91 | 92 | ```ts 93 | import { createAuthHooks } from "@daveyplate/better-auth-tanstack" 94 | import { authClient } from "@/lib/auth-client" 95 | 96 | export const authHooks = createAuthHooks(authClient) 97 | 98 | export const { 99 | useSession, 100 | usePrefetchSession, 101 | useToken, 102 | useListAccounts, 103 | useListSessions, 104 | useListDeviceSessions, 105 | useListPasskeys, 106 | useUpdateUser, 107 | useUnlinkAccount, 108 | useRevokeOtherSessions, 109 | useRevokeSession, 110 | useRevokeSessions, 111 | useSetActiveSession, 112 | useRevokeDeviceSession, 113 | useDeletePasskey, 114 | useAuthQuery, 115 | useAuthMutation 116 | } = authHooks 117 | ``` 118 | 119 | ## Using the Hooks 120 | 121 | ### useSession 122 | 123 | The `useSession` hook is used to fetch the session. 124 | 125 | #### Props 126 | 127 | | Prop | Type | Description | 128 | |-----------|----------------------------------------------------------------------|----------------------------------------------| 129 | | options? | UseQueryOptions | Optional query options for the session query.| 130 | 131 | #### Example 132 | 133 | ```tsx 134 | import { useSession } from "@/hooks/auth-hooks" 135 | 136 | function MyComponent() { 137 | const { 138 | data: sessionData, 139 | session, 140 | user, 141 | isPending, 142 | refetch, 143 | error 144 | } = useSession() 145 | 146 | if (isPending) return
Loading...
147 | 148 | return
Welcome, {user?.email}
149 | } 150 | ``` 151 | 152 | ### useToken 153 | 154 | The `useToken` hook is used to fetch the JWT token if better-auth JWT plugin is enabled. 155 | 156 | #### Props 157 | 158 | | Prop | Type | Description | 159 | |-----------|----------------------------------------------------------------------|----------------------------------------------| 160 | | options? | UseQueryOptions | Optional query options for the token query. | 161 | 162 | #### Example 163 | 164 | ```tsx 165 | import { useToken } from "@/hooks/auth-hooks" 166 | 167 | function MyComponent() { 168 | const { data, token, payload, isPending, error } = useToken() 169 | 170 | if (isPending) return
Loading...
171 | 172 | return
JWT: {token}
173 | } 174 | ``` 175 | 176 | ## useListAccounts 177 | 178 | The `useListAccounts` hook allows you to list and manage user accounts linked to different providers. 179 | 180 | ### Usage 181 | 182 | ```ts 183 | import { useListAccounts } from "@/hooks/auth-hooks" 184 | 185 | function AccountList() { 186 | const { data: accounts, isPending, error } = useListAccounts() 187 | 188 | if (isPending) return
Loading...
; 189 | if (error) return
Error: {error.message}
190 | 191 | return ( 192 |
193 |

Linked Accounts

194 | 202 |
203 | ) 204 | } 205 | ``` 206 | 207 | Use the `unlinkAccount` function to unlink an account by provider ID. This is the optimistic example. See below for non-optimistic examples. 208 | 209 | ```ts 210 | unlinkAccount({ providerId: "github" }) 211 | ``` 212 | 213 | ## useListSessions 214 | 215 | ```ts 216 | import { useListSessions, useRevokeSession } from "@/hooks/auth-hooks" 217 | 218 | function SessionList() { 219 | const { 220 | data: sessions, 221 | isPending, 222 | error 223 | } = useListSessions() 224 | const { mutate: revokeSession } = useRevokeSession() 225 | 226 | if (isPending) return
Loading...
; 227 | if (error) return
Error: {error.message}
228 | 229 | return ( 230 |
231 |

Active Sessions

232 | 240 |
241 | ) 242 | } 243 | ``` 244 | 245 | ## useListDeviceSessions 246 | 247 | ```ts 248 | const { 249 | data: deviceSessions, 250 | isPending, 251 | error 252 | } = useListDeviceSessions() 253 | ``` 254 | 255 | ## useListPasskeys 256 | 257 | ```ts 258 | const { 259 | data: passkeys, 260 | isPending, 261 | error 262 | } = useListPasskeys() 263 | ``` 264 | 265 | ### Mutations - updateUser 266 | 267 | #### Optimistic example 268 | 269 | Optimistic example to update user's name with no loaders. Optimistically updates the user in the Tanstack Query cache instantly. Revalidates on success, reverts on error. Uses the default setting for `optimistic` (true) prop on `AuthQueryProvider`. 270 | 271 | This package supports the Tanstack Query global error configuration: 272 | 273 | `queryClient.getQueryCache().config.onError` gets called automatically, so you can set up global error toasts to show `error.message || error.statusText`. [Tanstack Query Global Error Callbacks](https://tkdodo.eu/blog/react-query-error-handling#the-global-callbacks) 274 | 275 | ```tsx 276 | "use client" 277 | 278 | import { useState } from "react" 279 | 280 | import { Button } from "@/components/ui/button" 281 | import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" 282 | import { Input } from "@/components/ui/input" 283 | import { Label } from "@/components/ui/label" 284 | import { useSession, useUpdateUser } from "@/hooks/auth-hooks" 285 | 286 | export default function SettingsPage() { 287 | const { user, isPending } = useSession() 288 | const { mutate: updateUser, error: updateError } = useUpdateUser() 289 | const [disabled, setDisabled] = useState(true) 290 | 291 | const updateProfile = (formData: FormData) => { 292 | const name = formData.get("name") as string 293 | 294 | setDisabled(true) 295 | updateUser({ name: name }) 296 | } 297 | 298 | useEffect(() => { 299 | if (updateError) { 300 | // Show an error Toast 301 | } 302 | }, [updateError]) 303 | 304 | if (isPending || !user) { 305 | return ( 306 |
307 | Loading... 308 |
309 | ) 310 | } 311 | 312 | return ( 313 |
314 | 315 | 316 | 317 | Change Name 318 | 319 | 320 | 321 | 322 |
326 | 329 | 330 | setDisabled(false)} 335 | /> 336 | 337 | 340 |
341 |
342 |
343 |
344 | ) 345 | } 346 | ``` 347 | 348 | #### Unoptimistic example 349 | 350 | Unoptimistic example with `useActionState` to show loaders for updating a user's name. Set `optimistic` to `false` in the `AuthQueryProvider` props to disable optimistic cache updates. Sends a request to `/api/auth/update-user` then updates the user in the Tanstack Query cache after the request is successful. Then revalidates the session by refetching. 351 | 352 | Note that we use `updateUserAsync` 353 | 354 | ```tsx 355 | "use client" 356 | 357 | import { Loader2 } from "lucide-react" 358 | import { useActionState } from "react" 359 | 360 | import { Button } from "@/components/ui/button" 361 | import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" 362 | import { Input } from "@/components/ui/input" 363 | import { Label } from "@/components/ui/label" 364 | import { useSession, useUpdateUser } from "@/hooks/auth-hooks" 365 | import { cn } from "@/lib/utils" 366 | 367 | export default function SettingsPage() { 368 | const { user, isPending } = useSession() 369 | const { mutate: updateUser, error: updateError } = useUpdateUser() 370 | const [disabled, setDisabled] = useState(true) 371 | 372 | type ActionState = Parameters[0] 373 | 374 | const updateProfile = async (_: ActionState, formData: FormData) => { 375 | const name = formData.get("name") as string 376 | 377 | setDisabled(true) 378 | 379 | const { error } = await updateUserAsync({ name, fetchOptions: { throw: false } }) 380 | 381 | if (error) { 382 | // Show an error Toast or throw an error to an ErrorBoundary 383 | 384 | setDisabled(false) 385 | } 386 | 387 | return { name } as ActionState 388 | } 389 | 390 | const [state, action, isSubmitting] = useActionState(updateProfile, {}) 391 | 392 | // useEffect(() => { 393 | // if (updateError) { 394 | // setDisabled(false) 395 | // // Show an error Toast 396 | // } 397 | // }, [updateError]) 398 | 399 | if (isPending || !user) { 400 | return ( 401 |
402 | Loading... 403 |
404 | ) 405 | } 406 | 407 | return ( 408 |
409 | 410 | 411 | 412 | Change Name 413 | 414 | 415 | 416 | 417 |
421 | 424 | 425 | setDisabled(false)} 430 | /> 431 | 432 | 439 |
440 |
441 |
442 |
443 | ) 444 | } 445 | ``` 446 | 447 | ### Server-Side Prefetch - Advanced Usage 448 | If you want to use a hybrid prefetching strategy, this is totally supported. 449 | 450 | [Tanstack Query - Advanced Server Rendering](https://tanstack.com/query/latest/docs/framework/react/guides/advanced-ssr) 451 | 452 | ### SSR prefetchSession 453 | 454 | The `prefetchSession` function is used in the server to prefetch session data and store it in the query client. 455 | 456 | #### Props 457 | 458 | | Prop | Type | Description | 459 | |-------------|---------------|-------------------------------------------------------| 460 | | auth | Auth | The server auth instance. | 461 | | queryClient | QueryClient | The query client instance. | 462 | | headers | Headers | The headers object from the server request. | 463 | | queryKey? | string[] | Optional key for the session query. Default is `["session"]`. | 464 | 465 | #### RSC Example 466 | 467 | 468 | ```ts 469 | import { prefetchSession } from "@daveyplate/better-auth-tanstack/server" 470 | import { HydrationBoundary, QueryClient, dehydrate } from "@tanstack/react-query" 471 | import { headers } from "next/headers" 472 | 473 | import { betterAuth } from "better-auth" 474 | import { auth } from "@/lib/auth" 475 | 476 | export default async function Page() { 477 | const queryClient = new QueryClient() 478 | 479 | const { data, session, user } = await prefetchSession( 480 | auth, queryClient, await headers() 481 | ) 482 | 483 | return ( 484 | 485 | 486 | 487 | ) 488 | } 489 | ``` 490 | 491 | ### useAuthQuery 492 | ```ts 493 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 494 | import { useAuthQuery } from "@/lib/auth-hooks" 495 | import { authClient } from "@/lib/auth-client" 496 | 497 | export function useListDeviceSessions( 498 | options?: Partial 499 | ) { 500 | return useAuthQuery({ 501 | queryKey: ["device-sessions"], 502 | queryFn: authClient.multiSession.listDeviceSessions, 503 | options 504 | }) 505 | } 506 | ``` 507 | 508 | ### useAuthMutation 509 | ```ts 510 | import { AuthQueryContext, type AuthQueryOptions } from "@daveyplate/better-auth-tanstack" 511 | import { authClient } from "@/lib/auth-client" 512 | import { useAuthMutation } from "@/lib/auth-hooks" 513 | 514 | export function useUpdateUser( 515 | options?: Partial 516 | ) { 517 | type SessionData = typeof authClient["$Infer"]["Session"] 518 | const { sessionKey: queryKey } = useContext(AuthQueryContext) 519 | 520 | return useAuthMutation({ 521 | queryKey, 522 | mutationFn: authClient.updateUser, 523 | optimisticData: (params, previousSession: SessionData) => ({ 524 | ...previousSession, 525 | user: { ...previousSession.user, ...params } 526 | }), 527 | options 528 | }) 529 | } 530 | ``` 531 | 532 | ## License 533 | 534 | This project is licensed under the MIT License. See the LICENSE file for details. 535 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", 3 | "vcs": { 4 | "enabled": true, 5 | "clientKind": "git", 6 | "useIgnoreFile": true, 7 | "defaultBranch": "main" 8 | }, 9 | "files": { 10 | "ignore": ["./src/components/ui/**"] 11 | }, 12 | "formatter": { 13 | "indentStyle": "space", 14 | "indentWidth": 4, 15 | "lineWidth": 100 16 | }, 17 | "linter": { 18 | "rules": { 19 | "a11y": { 20 | "noSvgWithoutTitle": "off", 21 | "useGenericFontNames": "off" 22 | }, 23 | "suspicious": { 24 | "noArrayIndexKey": "off", 25 | "noDoubleEquals": { 26 | "fix": "safe", 27 | "level": "warn", 28 | "options": {} 29 | } 30 | }, 31 | "style": { 32 | "noNonNullAssertion": "off", 33 | "useTemplate": { 34 | "fix": "safe", 35 | "level": "warn" 36 | } 37 | }, 38 | "correctness": { 39 | "noUnusedImports": "info" 40 | }, 41 | "nursery": { 42 | "useSortedClasses": { 43 | "fix": "safe", 44 | "level": "info", 45 | "options": { 46 | "functions": ["cn"] 47 | } 48 | } 49 | } 50 | } 51 | }, 52 | "javascript": { 53 | "formatter": { 54 | "semicolons": "asNeeded", 55 | "trailingCommas": "none" 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # deps 2 | /node_modules 3 | 4 | # generated content 5 | .contentlayer 6 | .content-collections 7 | .source 8 | 9 | # test & build 10 | /coverage 11 | /.next/ 12 | /out/ 13 | /build 14 | *.tsbuildinfo 15 | 16 | # misc 17 | .DS_Store 18 | *.pem 19 | /.pnp 20 | .pnp.js 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # others 26 | .env*.local 27 | .vercel 28 | next-env.d.ts 29 | .vscode 30 | .turbo -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # fumadocs 2 | 3 | This is a Next.js application generated with 4 | [Create Fumadocs](https://github.com/fuma-nama/fumadocs). 5 | 6 | Run development server: 7 | 8 | ```bash 9 | npm run dev 10 | # or 11 | pnpm dev 12 | # or 13 | yarn dev 14 | ``` 15 | 16 | Open http://localhost:3000 with your browser to see the result. 17 | 18 | ## Learn More 19 | 20 | To learn more about Next.js and Fumadocs, take a look at the following 21 | resources: 22 | 23 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js 24 | features and API. 25 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 26 | - [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs 27 | -------------------------------------------------------------------------------- /docs/app/(docs)/[[...slug]]/page.tsx: -------------------------------------------------------------------------------- 1 | import defaultMdxComponents from "fumadocs-ui/mdx" 2 | import { DocsBody, DocsDescription, DocsPage, DocsTitle } from "fumadocs-ui/page" 3 | import { notFound } from "next/navigation" 4 | 5 | import { source } from "@/lib/source" 6 | 7 | export default async function Page(props: { 8 | params: Promise<{ slug?: string[] }> 9 | }) { 10 | const params = await props.params 11 | const page = source.getPage(params.slug) 12 | 13 | if (!page) notFound() 14 | 15 | const MDX = page.data.body 16 | 17 | return ( 18 | 19 | {page.data.title} 20 | 21 | {page.data.description} 22 | 23 | 24 | 25 | 26 | 27 | ) 28 | } 29 | 30 | export async function generateStaticParams() { 31 | return source.generateParams() 32 | } 33 | 34 | export async function generateMetadata(props: { 35 | params: Promise<{ slug?: string[] }> 36 | }) { 37 | const params = await props.params 38 | const page = source.getPage(params.slug) 39 | 40 | if (!page) notFound() 41 | 42 | return { 43 | title: page.data.title, 44 | description: page.data.description 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /docs/app/(docs)/layout.tsx: -------------------------------------------------------------------------------- 1 | import { ThemeToggle } from "fumadocs-ui/components/layout/theme-toggle" 2 | import { DocsLayout } from "fumadocs-ui/layouts/docs" 3 | import type { ReactNode } from "react" 4 | 5 | import { baseOptions } from "@/app/layout.config" 6 | import { source } from "@/lib/source" 7 | 8 | export default function Layout({ children }: { children: ReactNode }) { 9 | return ( 10 | 17 | 18 | 19 | ) 20 | }} 21 | > 22 | {children} 23 | 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /docs/app/api/search/route.ts: -------------------------------------------------------------------------------- 1 | import { createFromSource } from "fumadocs-core/search/server" 2 | 3 | import { source } from "@/lib/source" 4 | 5 | // it should be cached forever 6 | export const revalidate = false 7 | 8 | export const { staticGET: GET } = createFromSource(source) 9 | -------------------------------------------------------------------------------- /docs/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveyplate/better-auth-tanstack/9024c4e9b646fd99f42dae1166f16b6013839669/docs/app/favicon.ico -------------------------------------------------------------------------------- /docs/app/global.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | @import "fumadocs-ui/css/black.css"; 4 | 5 | @import "fumadocs-ui/css/preset.css"; 6 | 7 | @source '../node_modules/fumadocs-ui/dist/**/*.js'; 8 | 9 | /* 10 | Set the default cursor for buttons. 11 | */ 12 | button, 13 | [role="button"] { 14 | cursor: pointer; 15 | } 16 | 17 | /* 18 | Make sure disabled buttons don't get the pointer cursor. 19 | */ 20 | :disabled { 21 | cursor: default; 22 | } 23 | 24 | @theme { 25 | --color-fd-ring: hsl(221.2, 83.2%, 53.3%); 26 | --color-fd-primary: hsl(221.2, 83.2%, 53.3%); 27 | } 28 | 29 | .dark { 30 | --color-fd-ring: hsl(217.2, 91.2%, 59.8%); 31 | --color-fd-primary: hsl(217.2, 91.2%, 59.8%); 32 | } 33 | -------------------------------------------------------------------------------- /docs/app/layout.config.tsx: -------------------------------------------------------------------------------- 1 | import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared" 2 | 3 | /** 4 | * Shared layout configurations 5 | * 6 | * you can configure layouts individually from: 7 | * Home Layout: app/(home)/layout.tsx 8 | * Docs Layout: app/docs/layout.tsx 9 | */ 10 | export const baseOptions: BaseLayoutProps = { 11 | nav: { 12 | // can be JSX too! 13 | title: "My App" 14 | }, 15 | links: [ 16 | { 17 | text: "Documentation", 18 | url: "/docs", 19 | active: "nested-url" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /docs/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { RootProvider } from "fumadocs-ui/provider" 2 | import { Inter } from "next/font/google" 3 | import type { ReactNode } from "react" 4 | 5 | import "./global.css" 6 | 7 | const inter = Inter({ 8 | subsets: ["latin"] 9 | }) 10 | 11 | export default function Layout({ children }: { children: ReactNode }) { 12 | return ( 13 | 14 | 15 | {children} 16 | 17 | 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /docs/content/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World 3 | description: Your first document 4 | --- 5 | 6 | Welcome to the docs! You can start writing documents in `/content/docs`. 7 | 8 | ## What is Next? 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/content/docs/test.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Components 3 | description: Components 4 | --- 5 | 6 | ## Code Block 7 | 8 | ```js 9 | console.log('Hello World'); 10 | ``` 11 | 12 | ## Cards 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/lib/source.ts: -------------------------------------------------------------------------------- 1 | import { loader } from "fumadocs-core/source" 2 | import { createMDXSource } from "fumadocs-mdx" 3 | 4 | import { docs, meta } from "@/.source" 5 | 6 | export const source = loader({ 7 | baseUrl: "/", 8 | source: createMDXSource(docs, meta) 9 | }) 10 | -------------------------------------------------------------------------------- /docs/next.config.mjs: -------------------------------------------------------------------------------- 1 | import { createMDX } from "fumadocs-mdx/next" 2 | 3 | const withMDX = createMDX() 4 | 5 | /** @type {import('next').NextConfig} */ 6 | const config = { 7 | reactStrictMode: true, 8 | output: "export", 9 | basePath: process.env.NODE_ENV === "production" ? "/better-auth-tanstack" : "", 10 | images: { unoptimized: true } 11 | } 12 | 13 | export default withMDX(config) 14 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fumadocs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "next build", 7 | "dev": "next dev --turbo", 8 | "start": "next start", 9 | "postinstall": "fumadocs-mdx", 10 | "check-types": "tsc --noEmit" 11 | }, 12 | "dependencies": { 13 | "fumadocs-core": "15.0.16", 14 | "fumadocs-mdx": "11.5.6", 15 | "fumadocs-ui": "15.0.16", 16 | "next": "15.2.2", 17 | "react": "^19.0.0", 18 | "react-dom": "^19.0.0" 19 | }, 20 | "devDependencies": { 21 | "@tailwindcss/postcss": "^4.0.13", 22 | "@types/mdx": "^2.0.13", 23 | "@types/node": "22.13.10", 24 | "@types/react": "^19.0.10", 25 | "@types/react-dom": "^19.0.4", 26 | "postcss": "^8.5.3", 27 | "tailwindcss": "^4.0.13", 28 | "turbo": "^2.4.4", 29 | "typescript": "^5.8.2" 30 | }, 31 | "packageManager": "pnpm@10.1.0" 32 | } 33 | -------------------------------------------------------------------------------- /docs/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const postcssConfig = { 2 | plugins: { 3 | "@tailwindcss/postcss": {} 4 | } 5 | } 6 | 7 | export default postcssConfig 8 | -------------------------------------------------------------------------------- /docs/source.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, defineDocs } from "fumadocs-mdx/config" 2 | 3 | export const { docs, meta } = defineDocs({ 4 | dir: "content/docs" 5 | }) 6 | 7 | export default defineConfig() 8 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "ESNext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "strict": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "noEmit": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "bundler", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "preserve", 17 | "incremental": true, 18 | "paths": { 19 | "@/*": ["./*"] 20 | }, 21 | "plugins": [ 22 | { 23 | "name": "next" 24 | } 25 | ] 26 | }, 27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 28 | "exclude": ["node_modules"] 29 | } 30 | -------------------------------------------------------------------------------- /docs/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "tasks": { 4 | "build": { 5 | "dependsOn": ["^build"], 6 | "outputs": [".next/**", "!.next/cache/**"] 7 | }, 8 | "check-types": { 9 | "dependsOn": ["^check-types"] 10 | }, 11 | "dev": { 12 | "persistent": true, 13 | "cache": false 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@daveyplate/better-auth-tanstack", 3 | "homepage": "https://github.com/daveyplate/better-auth-tanstack", 4 | "version": "1.3.6", 5 | "description": "Tanstack hooks for better-auth", 6 | "scripts": { 7 | "build": "tsup --clean --dts", 8 | "dev": "tsc-watch --onSuccess 'biome check'", 9 | "prepublishOnly": "rm -rf dist && tsup --clean --dts" 10 | }, 11 | "type": "module", 12 | "main": "./dist/index.cjs", 13 | "module": "./dist/index.js", 14 | "exports": { 15 | ".": { 16 | "import": { 17 | "types": "./dist/index.d.ts", 18 | "default": "./dist/index.js" 19 | }, 20 | "require": { 21 | "types": "./dist/index.d.cts", 22 | "default": "./dist/index.cjs" 23 | } 24 | }, 25 | "./server": { 26 | "import": { 27 | "types": "./dist/server.d.ts", 28 | "default": "./dist/server.js" 29 | }, 30 | "require": { 31 | "types": "./dist/server.d.cts", 32 | "default": "./dist/server.cjs" 33 | } 34 | } 35 | }, 36 | "files": [ 37 | "src", 38 | "dist" 39 | ], 40 | "keywords": [ 41 | "better-auth", 42 | "tanstack", 43 | "react-query", 44 | "tanstack-query", 45 | "query", 46 | "auth", 47 | "hooks", 48 | "prefetch", 49 | "ssr", 50 | "typescript" 51 | ], 52 | "author": "daveycodez", 53 | "license": "MIT", 54 | "devDependencies": { 55 | "@biomejs/biome": "1.9.4", 56 | "@types/node": "^22.15.29", 57 | "@types/react": "^19.1.6", 58 | "@types/react-dom": "^19.1.5", 59 | "better-auth": "^1.2.8", 60 | "next": "^15.3.3", 61 | "tsc-watch": "^7.1.1", 62 | "tsup": "^8.5.0", 63 | "tsx": "^4.19.4", 64 | "turbo": "^2.5.4", 65 | "typescript": "^5.8.3" 66 | }, 67 | "peerDependencies": { 68 | "@tanstack/query-core": ">=5.65.0", 69 | "@tanstack/react-query": ">=5.65.0", 70 | "better-auth": ">=1.2.8", 71 | "react": ">=18.0.0", 72 | "react-dom": ">=18.0.0" 73 | }, 74 | "packageManager": "pnpm@10.2.1" 75 | } 76 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@tanstack/query-core': 12 | specifier: '>=5.65.0' 13 | version: 5.69.0 14 | '@tanstack/react-query': 15 | specifier: '>=5.65.0' 16 | version: 5.69.0(react@19.0.0) 17 | react: 18 | specifier: '>=18.0.0' 19 | version: 19.0.0 20 | react-dom: 21 | specifier: '>=18.0.0' 22 | version: 19.0.0(react@19.0.0) 23 | devDependencies: 24 | '@biomejs/biome': 25 | specifier: 1.9.4 26 | version: 1.9.4 27 | '@types/node': 28 | specifier: ^22.15.29 29 | version: 22.15.29 30 | '@types/react': 31 | specifier: ^19.1.6 32 | version: 19.1.6 33 | '@types/react-dom': 34 | specifier: ^19.1.5 35 | version: 19.1.5(@types/react@19.1.6) 36 | better-auth: 37 | specifier: ^1.2.8 38 | version: 1.2.8 39 | next: 40 | specifier: ^15.3.3 41 | version: 15.3.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 42 | tsc-watch: 43 | specifier: ^7.1.1 44 | version: 7.1.1(typescript@5.8.3) 45 | tsup: 46 | specifier: ^8.5.0 47 | version: 8.5.0(postcss@8.4.31)(tsx@4.19.4)(typescript@5.8.3) 48 | tsx: 49 | specifier: ^4.19.4 50 | version: 4.19.4 51 | turbo: 52 | specifier: ^2.5.4 53 | version: 2.5.4 54 | typescript: 55 | specifier: ^5.8.3 56 | version: 5.8.3 57 | 58 | packages: 59 | 60 | '@better-auth/utils@0.2.5': 61 | resolution: {integrity: sha512-uI2+/8h/zVsH8RrYdG8eUErbuGBk16rZKQfz8CjxQOyCE6v7BqFYEbFwvOkvl1KbUdxhqOnXp78+uE5h8qVEgQ==} 62 | 63 | '@better-fetch/fetch@1.1.18': 64 | resolution: {integrity: sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA==} 65 | 66 | '@biomejs/biome@1.9.4': 67 | resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} 68 | engines: {node: '>=14.21.3'} 69 | hasBin: true 70 | 71 | '@biomejs/cli-darwin-arm64@1.9.4': 72 | resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} 73 | engines: {node: '>=14.21.3'} 74 | cpu: [arm64] 75 | os: [darwin] 76 | 77 | '@biomejs/cli-darwin-x64@1.9.4': 78 | resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} 79 | engines: {node: '>=14.21.3'} 80 | cpu: [x64] 81 | os: [darwin] 82 | 83 | '@biomejs/cli-linux-arm64-musl@1.9.4': 84 | resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} 85 | engines: {node: '>=14.21.3'} 86 | cpu: [arm64] 87 | os: [linux] 88 | 89 | '@biomejs/cli-linux-arm64@1.9.4': 90 | resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} 91 | engines: {node: '>=14.21.3'} 92 | cpu: [arm64] 93 | os: [linux] 94 | 95 | '@biomejs/cli-linux-x64-musl@1.9.4': 96 | resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} 97 | engines: {node: '>=14.21.3'} 98 | cpu: [x64] 99 | os: [linux] 100 | 101 | '@biomejs/cli-linux-x64@1.9.4': 102 | resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} 103 | engines: {node: '>=14.21.3'} 104 | cpu: [x64] 105 | os: [linux] 106 | 107 | '@biomejs/cli-win32-arm64@1.9.4': 108 | resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} 109 | engines: {node: '>=14.21.3'} 110 | cpu: [arm64] 111 | os: [win32] 112 | 113 | '@biomejs/cli-win32-x64@1.9.4': 114 | resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} 115 | engines: {node: '>=14.21.3'} 116 | cpu: [x64] 117 | os: [win32] 118 | 119 | '@emnapi/runtime@1.4.3': 120 | resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} 121 | 122 | '@esbuild/aix-ppc64@0.25.5': 123 | resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} 124 | engines: {node: '>=18'} 125 | cpu: [ppc64] 126 | os: [aix] 127 | 128 | '@esbuild/android-arm64@0.25.5': 129 | resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} 130 | engines: {node: '>=18'} 131 | cpu: [arm64] 132 | os: [android] 133 | 134 | '@esbuild/android-arm@0.25.5': 135 | resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} 136 | engines: {node: '>=18'} 137 | cpu: [arm] 138 | os: [android] 139 | 140 | '@esbuild/android-x64@0.25.5': 141 | resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} 142 | engines: {node: '>=18'} 143 | cpu: [x64] 144 | os: [android] 145 | 146 | '@esbuild/darwin-arm64@0.25.5': 147 | resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} 148 | engines: {node: '>=18'} 149 | cpu: [arm64] 150 | os: [darwin] 151 | 152 | '@esbuild/darwin-x64@0.25.5': 153 | resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} 154 | engines: {node: '>=18'} 155 | cpu: [x64] 156 | os: [darwin] 157 | 158 | '@esbuild/freebsd-arm64@0.25.5': 159 | resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} 160 | engines: {node: '>=18'} 161 | cpu: [arm64] 162 | os: [freebsd] 163 | 164 | '@esbuild/freebsd-x64@0.25.5': 165 | resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} 166 | engines: {node: '>=18'} 167 | cpu: [x64] 168 | os: [freebsd] 169 | 170 | '@esbuild/linux-arm64@0.25.5': 171 | resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} 172 | engines: {node: '>=18'} 173 | cpu: [arm64] 174 | os: [linux] 175 | 176 | '@esbuild/linux-arm@0.25.5': 177 | resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} 178 | engines: {node: '>=18'} 179 | cpu: [arm] 180 | os: [linux] 181 | 182 | '@esbuild/linux-ia32@0.25.5': 183 | resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} 184 | engines: {node: '>=18'} 185 | cpu: [ia32] 186 | os: [linux] 187 | 188 | '@esbuild/linux-loong64@0.25.5': 189 | resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} 190 | engines: {node: '>=18'} 191 | cpu: [loong64] 192 | os: [linux] 193 | 194 | '@esbuild/linux-mips64el@0.25.5': 195 | resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} 196 | engines: {node: '>=18'} 197 | cpu: [mips64el] 198 | os: [linux] 199 | 200 | '@esbuild/linux-ppc64@0.25.5': 201 | resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} 202 | engines: {node: '>=18'} 203 | cpu: [ppc64] 204 | os: [linux] 205 | 206 | '@esbuild/linux-riscv64@0.25.5': 207 | resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} 208 | engines: {node: '>=18'} 209 | cpu: [riscv64] 210 | os: [linux] 211 | 212 | '@esbuild/linux-s390x@0.25.5': 213 | resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} 214 | engines: {node: '>=18'} 215 | cpu: [s390x] 216 | os: [linux] 217 | 218 | '@esbuild/linux-x64@0.25.5': 219 | resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} 220 | engines: {node: '>=18'} 221 | cpu: [x64] 222 | os: [linux] 223 | 224 | '@esbuild/netbsd-arm64@0.25.5': 225 | resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} 226 | engines: {node: '>=18'} 227 | cpu: [arm64] 228 | os: [netbsd] 229 | 230 | '@esbuild/netbsd-x64@0.25.5': 231 | resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} 232 | engines: {node: '>=18'} 233 | cpu: [x64] 234 | os: [netbsd] 235 | 236 | '@esbuild/openbsd-arm64@0.25.5': 237 | resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} 238 | engines: {node: '>=18'} 239 | cpu: [arm64] 240 | os: [openbsd] 241 | 242 | '@esbuild/openbsd-x64@0.25.5': 243 | resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} 244 | engines: {node: '>=18'} 245 | cpu: [x64] 246 | os: [openbsd] 247 | 248 | '@esbuild/sunos-x64@0.25.5': 249 | resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} 250 | engines: {node: '>=18'} 251 | cpu: [x64] 252 | os: [sunos] 253 | 254 | '@esbuild/win32-arm64@0.25.5': 255 | resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} 256 | engines: {node: '>=18'} 257 | cpu: [arm64] 258 | os: [win32] 259 | 260 | '@esbuild/win32-ia32@0.25.5': 261 | resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} 262 | engines: {node: '>=18'} 263 | cpu: [ia32] 264 | os: [win32] 265 | 266 | '@esbuild/win32-x64@0.25.5': 267 | resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} 268 | engines: {node: '>=18'} 269 | cpu: [x64] 270 | os: [win32] 271 | 272 | '@hexagon/base64@1.1.28': 273 | resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} 274 | 275 | '@img/sharp-darwin-arm64@0.34.2': 276 | resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} 277 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 278 | cpu: [arm64] 279 | os: [darwin] 280 | 281 | '@img/sharp-darwin-x64@0.34.2': 282 | resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} 283 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 284 | cpu: [x64] 285 | os: [darwin] 286 | 287 | '@img/sharp-libvips-darwin-arm64@1.1.0': 288 | resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} 289 | cpu: [arm64] 290 | os: [darwin] 291 | 292 | '@img/sharp-libvips-darwin-x64@1.1.0': 293 | resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} 294 | cpu: [x64] 295 | os: [darwin] 296 | 297 | '@img/sharp-libvips-linux-arm64@1.1.0': 298 | resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} 299 | cpu: [arm64] 300 | os: [linux] 301 | 302 | '@img/sharp-libvips-linux-arm@1.1.0': 303 | resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} 304 | cpu: [arm] 305 | os: [linux] 306 | 307 | '@img/sharp-libvips-linux-ppc64@1.1.0': 308 | resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} 309 | cpu: [ppc64] 310 | os: [linux] 311 | 312 | '@img/sharp-libvips-linux-s390x@1.1.0': 313 | resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} 314 | cpu: [s390x] 315 | os: [linux] 316 | 317 | '@img/sharp-libvips-linux-x64@1.1.0': 318 | resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} 319 | cpu: [x64] 320 | os: [linux] 321 | 322 | '@img/sharp-libvips-linuxmusl-arm64@1.1.0': 323 | resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} 324 | cpu: [arm64] 325 | os: [linux] 326 | 327 | '@img/sharp-libvips-linuxmusl-x64@1.1.0': 328 | resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} 329 | cpu: [x64] 330 | os: [linux] 331 | 332 | '@img/sharp-linux-arm64@0.34.2': 333 | resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} 334 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 335 | cpu: [arm64] 336 | os: [linux] 337 | 338 | '@img/sharp-linux-arm@0.34.2': 339 | resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} 340 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 341 | cpu: [arm] 342 | os: [linux] 343 | 344 | '@img/sharp-linux-s390x@0.34.2': 345 | resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} 346 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 347 | cpu: [s390x] 348 | os: [linux] 349 | 350 | '@img/sharp-linux-x64@0.34.2': 351 | resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} 352 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 353 | cpu: [x64] 354 | os: [linux] 355 | 356 | '@img/sharp-linuxmusl-arm64@0.34.2': 357 | resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} 358 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 359 | cpu: [arm64] 360 | os: [linux] 361 | 362 | '@img/sharp-linuxmusl-x64@0.34.2': 363 | resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} 364 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 365 | cpu: [x64] 366 | os: [linux] 367 | 368 | '@img/sharp-wasm32@0.34.2': 369 | resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} 370 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 371 | cpu: [wasm32] 372 | 373 | '@img/sharp-win32-arm64@0.34.2': 374 | resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} 375 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 376 | cpu: [arm64] 377 | os: [win32] 378 | 379 | '@img/sharp-win32-ia32@0.34.2': 380 | resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} 381 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 382 | cpu: [ia32] 383 | os: [win32] 384 | 385 | '@img/sharp-win32-x64@0.34.2': 386 | resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} 387 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 388 | cpu: [x64] 389 | os: [win32] 390 | 391 | '@isaacs/cliui@8.0.2': 392 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 393 | engines: {node: '>=12'} 394 | 395 | '@jridgewell/gen-mapping@0.3.8': 396 | resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} 397 | engines: {node: '>=6.0.0'} 398 | 399 | '@jridgewell/resolve-uri@3.1.2': 400 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 401 | engines: {node: '>=6.0.0'} 402 | 403 | '@jridgewell/set-array@1.2.1': 404 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 405 | engines: {node: '>=6.0.0'} 406 | 407 | '@jridgewell/sourcemap-codec@1.5.0': 408 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 409 | 410 | '@jridgewell/trace-mapping@0.3.25': 411 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 412 | 413 | '@levischuck/tiny-cbor@0.2.11': 414 | resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==} 415 | 416 | '@next/env@15.3.3': 417 | resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==} 418 | 419 | '@next/swc-darwin-arm64@15.3.3': 420 | resolution: {integrity: sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg==} 421 | engines: {node: '>= 10'} 422 | cpu: [arm64] 423 | os: [darwin] 424 | 425 | '@next/swc-darwin-x64@15.3.3': 426 | resolution: {integrity: sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw==} 427 | engines: {node: '>= 10'} 428 | cpu: [x64] 429 | os: [darwin] 430 | 431 | '@next/swc-linux-arm64-gnu@15.3.3': 432 | resolution: {integrity: sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw==} 433 | engines: {node: '>= 10'} 434 | cpu: [arm64] 435 | os: [linux] 436 | 437 | '@next/swc-linux-arm64-musl@15.3.3': 438 | resolution: {integrity: sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA==} 439 | engines: {node: '>= 10'} 440 | cpu: [arm64] 441 | os: [linux] 442 | 443 | '@next/swc-linux-x64-gnu@15.3.3': 444 | resolution: {integrity: sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==} 445 | engines: {node: '>= 10'} 446 | cpu: [x64] 447 | os: [linux] 448 | 449 | '@next/swc-linux-x64-musl@15.3.3': 450 | resolution: {integrity: sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==} 451 | engines: {node: '>= 10'} 452 | cpu: [x64] 453 | os: [linux] 454 | 455 | '@next/swc-win32-arm64-msvc@15.3.3': 456 | resolution: {integrity: sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ==} 457 | engines: {node: '>= 10'} 458 | cpu: [arm64] 459 | os: [win32] 460 | 461 | '@next/swc-win32-x64-msvc@15.3.3': 462 | resolution: {integrity: sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw==} 463 | engines: {node: '>= 10'} 464 | cpu: [x64] 465 | os: [win32] 466 | 467 | '@noble/ciphers@0.6.0': 468 | resolution: {integrity: sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==} 469 | 470 | '@noble/hashes@1.7.1': 471 | resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} 472 | engines: {node: ^14.21.3 || >=16} 473 | 474 | '@peculiar/asn1-android@2.3.15': 475 | resolution: {integrity: sha512-8U2TIj59cRlSXTX2d0mzUKP7whfWGFMzTeC3qPgAbccXFrPNZLaDhpNEdG5U2QZ/tBv/IHlCJ8s+KYXpJeop6w==} 476 | 477 | '@peculiar/asn1-ecc@2.3.15': 478 | resolution: {integrity: sha512-/HtR91dvgog7z/WhCVdxZJ/jitJuIu8iTqiyWVgRE9Ac5imt2sT/E4obqIVGKQw7PIy+X6i8lVBoT6wC73XUgA==} 479 | 480 | '@peculiar/asn1-rsa@2.3.15': 481 | resolution: {integrity: sha512-p6hsanvPhexRtYSOHihLvUUgrJ8y0FtOM97N5UEpC+VifFYyZa0iZ5cXjTkZoDwxJ/TTJ1IJo3HVTB2JJTpXvg==} 482 | 483 | '@peculiar/asn1-schema@2.3.15': 484 | resolution: {integrity: sha512-QPeD8UA8axQREpgR5UTAfu2mqQmm97oUqahDtNdBcfj3qAnoXzFdQW+aNf/tD2WVXF8Fhmftxoj0eMIT++gX2w==} 485 | 486 | '@peculiar/asn1-x509@2.3.15': 487 | resolution: {integrity: sha512-0dK5xqTqSLaxv1FHXIcd4Q/BZNuopg+u1l23hT9rOmQ1g4dNtw0g/RnEi+TboB0gOwGtrWn269v27cMgchFIIg==} 488 | 489 | '@pkgjs/parseargs@0.11.0': 490 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 491 | engines: {node: '>=14'} 492 | 493 | '@rollup/rollup-android-arm-eabi@4.41.1': 494 | resolution: {integrity: sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==} 495 | cpu: [arm] 496 | os: [android] 497 | 498 | '@rollup/rollup-android-arm64@4.41.1': 499 | resolution: {integrity: sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==} 500 | cpu: [arm64] 501 | os: [android] 502 | 503 | '@rollup/rollup-darwin-arm64@4.41.1': 504 | resolution: {integrity: sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==} 505 | cpu: [arm64] 506 | os: [darwin] 507 | 508 | '@rollup/rollup-darwin-x64@4.41.1': 509 | resolution: {integrity: sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==} 510 | cpu: [x64] 511 | os: [darwin] 512 | 513 | '@rollup/rollup-freebsd-arm64@4.41.1': 514 | resolution: {integrity: sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==} 515 | cpu: [arm64] 516 | os: [freebsd] 517 | 518 | '@rollup/rollup-freebsd-x64@4.41.1': 519 | resolution: {integrity: sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==} 520 | cpu: [x64] 521 | os: [freebsd] 522 | 523 | '@rollup/rollup-linux-arm-gnueabihf@4.41.1': 524 | resolution: {integrity: sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==} 525 | cpu: [arm] 526 | os: [linux] 527 | 528 | '@rollup/rollup-linux-arm-musleabihf@4.41.1': 529 | resolution: {integrity: sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==} 530 | cpu: [arm] 531 | os: [linux] 532 | 533 | '@rollup/rollup-linux-arm64-gnu@4.41.1': 534 | resolution: {integrity: sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==} 535 | cpu: [arm64] 536 | os: [linux] 537 | 538 | '@rollup/rollup-linux-arm64-musl@4.41.1': 539 | resolution: {integrity: sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==} 540 | cpu: [arm64] 541 | os: [linux] 542 | 543 | '@rollup/rollup-linux-loongarch64-gnu@4.41.1': 544 | resolution: {integrity: sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==} 545 | cpu: [loong64] 546 | os: [linux] 547 | 548 | '@rollup/rollup-linux-powerpc64le-gnu@4.41.1': 549 | resolution: {integrity: sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==} 550 | cpu: [ppc64] 551 | os: [linux] 552 | 553 | '@rollup/rollup-linux-riscv64-gnu@4.41.1': 554 | resolution: {integrity: sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==} 555 | cpu: [riscv64] 556 | os: [linux] 557 | 558 | '@rollup/rollup-linux-riscv64-musl@4.41.1': 559 | resolution: {integrity: sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==} 560 | cpu: [riscv64] 561 | os: [linux] 562 | 563 | '@rollup/rollup-linux-s390x-gnu@4.41.1': 564 | resolution: {integrity: sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==} 565 | cpu: [s390x] 566 | os: [linux] 567 | 568 | '@rollup/rollup-linux-x64-gnu@4.41.1': 569 | resolution: {integrity: sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==} 570 | cpu: [x64] 571 | os: [linux] 572 | 573 | '@rollup/rollup-linux-x64-musl@4.41.1': 574 | resolution: {integrity: sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==} 575 | cpu: [x64] 576 | os: [linux] 577 | 578 | '@rollup/rollup-win32-arm64-msvc@4.41.1': 579 | resolution: {integrity: sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==} 580 | cpu: [arm64] 581 | os: [win32] 582 | 583 | '@rollup/rollup-win32-ia32-msvc@4.41.1': 584 | resolution: {integrity: sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==} 585 | cpu: [ia32] 586 | os: [win32] 587 | 588 | '@rollup/rollup-win32-x64-msvc@4.41.1': 589 | resolution: {integrity: sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==} 590 | cpu: [x64] 591 | os: [win32] 592 | 593 | '@simplewebauthn/browser@13.1.0': 594 | resolution: {integrity: sha512-WuHZ/PYvyPJ9nxSzgHtOEjogBhwJfC8xzYkPC+rR/+8chl/ft4ngjiK8kSU5HtRJfczupyOh33b25TjYbvwAcg==} 595 | 596 | '@simplewebauthn/server@13.1.1': 597 | resolution: {integrity: sha512-1hsLpRHfSuMB9ee2aAdh0Htza/X3f4djhYISrggqGe3xopNjOcePiSDkDDoPzDYaaMCrbqGP1H2TYU7bgL9PmA==} 598 | engines: {node: '>=20.0.0'} 599 | 600 | '@swc/counter@0.1.3': 601 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} 602 | 603 | '@swc/helpers@0.5.15': 604 | resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} 605 | 606 | '@tanstack/query-core@5.69.0': 607 | resolution: {integrity: sha512-Kn410jq6vs1P8Nm+ZsRj9H+U3C0kjuEkYLxbiCyn3MDEiYor1j2DGVULqAz62SLZtUZ/e9Xt6xMXiJ3NJ65WyQ==} 608 | 609 | '@tanstack/react-query@5.69.0': 610 | resolution: {integrity: sha512-Ift3IUNQqTcaFa1AiIQ7WCb/PPy8aexZdq9pZWLXhfLcLxH0+PZqJ2xFImxCpdDZrFRZhLJrh76geevS5xjRhA==} 611 | peerDependencies: 612 | react: ^18 || ^19 613 | 614 | '@types/estree@1.0.7': 615 | resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} 616 | 617 | '@types/node@22.15.29': 618 | resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==} 619 | 620 | '@types/react-dom@19.1.5': 621 | resolution: {integrity: sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==} 622 | peerDependencies: 623 | '@types/react': ^19.0.0 624 | 625 | '@types/react@19.1.6': 626 | resolution: {integrity: sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==} 627 | 628 | acorn@8.14.1: 629 | resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} 630 | engines: {node: '>=0.4.0'} 631 | hasBin: true 632 | 633 | ansi-regex@5.0.1: 634 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 635 | engines: {node: '>=8'} 636 | 637 | ansi-regex@6.1.0: 638 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} 639 | engines: {node: '>=12'} 640 | 641 | ansi-styles@4.3.0: 642 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 643 | engines: {node: '>=8'} 644 | 645 | ansi-styles@6.2.1: 646 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 647 | engines: {node: '>=12'} 648 | 649 | any-promise@1.3.0: 650 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} 651 | 652 | asn1js@3.0.5: 653 | resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} 654 | engines: {node: '>=12.0.0'} 655 | 656 | balanced-match@1.0.2: 657 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 658 | 659 | better-auth@1.2.8: 660 | resolution: {integrity: sha512-y8ry7ZW3/3ZIr82Eo1zUDtMzdoQlFnwNuZ0+b0RxoNZgqmvgTIc/0tCDC7NDJerqSu4UCzer0dvYxBsv3WMIGg==} 661 | 662 | better-call@1.0.9: 663 | resolution: {integrity: sha512-Qfm0gjk0XQz0oI7qvTK1hbqTsBY4xV2hsHAxF8LZfUYl3RaECCIifXuVqtPpZJWvlCCMlQSvkvhhyuApGUba6g==} 664 | 665 | brace-expansion@2.0.1: 666 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 667 | 668 | bundle-require@5.1.0: 669 | resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} 670 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 671 | peerDependencies: 672 | esbuild: '>=0.18' 673 | 674 | busboy@1.6.0: 675 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} 676 | engines: {node: '>=10.16.0'} 677 | 678 | cac@6.7.14: 679 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 680 | engines: {node: '>=8'} 681 | 682 | caniuse-lite@1.0.30001720: 683 | resolution: {integrity: sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g==} 684 | 685 | chokidar@4.0.3: 686 | resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} 687 | engines: {node: '>= 14.16.0'} 688 | 689 | client-only@0.0.1: 690 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} 691 | 692 | color-convert@2.0.1: 693 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 694 | engines: {node: '>=7.0.0'} 695 | 696 | color-name@1.1.4: 697 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 698 | 699 | color-string@1.9.1: 700 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} 701 | 702 | color@4.2.3: 703 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} 704 | engines: {node: '>=12.5.0'} 705 | 706 | commander@4.1.1: 707 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} 708 | engines: {node: '>= 6'} 709 | 710 | confbox@0.1.8: 711 | resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} 712 | 713 | consola@3.4.2: 714 | resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} 715 | engines: {node: ^14.18.0 || >=16.10.0} 716 | 717 | cross-spawn@7.0.6: 718 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 719 | engines: {node: '>= 8'} 720 | 721 | csstype@3.1.3: 722 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 723 | 724 | debug@4.4.1: 725 | resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} 726 | engines: {node: '>=6.0'} 727 | peerDependencies: 728 | supports-color: '*' 729 | peerDependenciesMeta: 730 | supports-color: 731 | optional: true 732 | 733 | defu@6.1.4: 734 | resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} 735 | 736 | detect-libc@2.0.4: 737 | resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} 738 | engines: {node: '>=8'} 739 | 740 | duplexer@0.1.2: 741 | resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} 742 | 743 | eastasianwidth@0.2.0: 744 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 745 | 746 | emoji-regex@8.0.0: 747 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 748 | 749 | emoji-regex@9.2.2: 750 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 751 | 752 | esbuild@0.25.5: 753 | resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} 754 | engines: {node: '>=18'} 755 | hasBin: true 756 | 757 | event-stream@3.3.4: 758 | resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} 759 | 760 | fdir@6.4.5: 761 | resolution: {integrity: sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==} 762 | peerDependencies: 763 | picomatch: ^3 || ^4 764 | peerDependenciesMeta: 765 | picomatch: 766 | optional: true 767 | 768 | fix-dts-default-cjs-exports@1.0.1: 769 | resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} 770 | 771 | foreground-child@3.3.1: 772 | resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} 773 | engines: {node: '>=14'} 774 | 775 | from@0.1.7: 776 | resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} 777 | 778 | fsevents@2.3.3: 779 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 780 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 781 | os: [darwin] 782 | 783 | get-tsconfig@4.10.1: 784 | resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} 785 | 786 | glob@10.4.5: 787 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} 788 | hasBin: true 789 | 790 | is-arrayish@0.3.2: 791 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} 792 | 793 | is-fullwidth-code-point@3.0.0: 794 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 795 | engines: {node: '>=8'} 796 | 797 | isexe@2.0.0: 798 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 799 | 800 | jackspeak@3.4.3: 801 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} 802 | 803 | jose@5.10.0: 804 | resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} 805 | 806 | joycon@3.1.1: 807 | resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} 808 | engines: {node: '>=10'} 809 | 810 | kysely@0.28.2: 811 | resolution: {integrity: sha512-4YAVLoF0Sf0UTqlhgQMFU9iQECdah7n+13ANkiuVfRvlK+uI0Etbgd7bVP36dKlG+NXWbhGua8vnGt+sdhvT7A==} 812 | engines: {node: '>=18.0.0'} 813 | 814 | lilconfig@3.1.3: 815 | resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} 816 | engines: {node: '>=14'} 817 | 818 | lines-and-columns@1.2.4: 819 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 820 | 821 | load-tsconfig@0.2.5: 822 | resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} 823 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 824 | 825 | lodash.sortby@4.7.0: 826 | resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} 827 | 828 | lru-cache@10.4.3: 829 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 830 | 831 | magic-string@0.30.17: 832 | resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} 833 | 834 | map-stream@0.1.0: 835 | resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} 836 | 837 | minimatch@9.0.5: 838 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 839 | engines: {node: '>=16 || 14 >=14.17'} 840 | 841 | minipass@7.1.2: 842 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} 843 | engines: {node: '>=16 || 14 >=14.17'} 844 | 845 | mlly@1.7.4: 846 | resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} 847 | 848 | ms@2.1.3: 849 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 850 | 851 | mz@2.7.0: 852 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} 853 | 854 | nanoid@3.3.11: 855 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} 856 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 857 | hasBin: true 858 | 859 | nanostores@0.11.4: 860 | resolution: {integrity: sha512-k1oiVNN4hDK8NcNERSZLQiMfRzEGtfnvZvdBvey3SQbgn8Dcrk0h1I6vpxApjb10PFUflZrgJ2WEZyJQ+5v7YQ==} 861 | engines: {node: ^18.0.0 || >=20.0.0} 862 | 863 | next@15.3.3: 864 | resolution: {integrity: sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==} 865 | engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} 866 | hasBin: true 867 | peerDependencies: 868 | '@opentelemetry/api': ^1.1.0 869 | '@playwright/test': ^1.41.2 870 | babel-plugin-react-compiler: '*' 871 | react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 872 | react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 873 | sass: ^1.3.0 874 | peerDependenciesMeta: 875 | '@opentelemetry/api': 876 | optional: true 877 | '@playwright/test': 878 | optional: true 879 | babel-plugin-react-compiler: 880 | optional: true 881 | sass: 882 | optional: true 883 | 884 | node-cleanup@2.1.2: 885 | resolution: {integrity: sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==} 886 | 887 | object-assign@4.1.1: 888 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 889 | engines: {node: '>=0.10.0'} 890 | 891 | package-json-from-dist@1.0.1: 892 | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} 893 | 894 | path-key@3.1.1: 895 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 896 | engines: {node: '>=8'} 897 | 898 | path-scurry@1.11.1: 899 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} 900 | engines: {node: '>=16 || 14 >=14.18'} 901 | 902 | pathe@2.0.3: 903 | resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 904 | 905 | pause-stream@0.0.11: 906 | resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} 907 | 908 | picocolors@1.1.1: 909 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 910 | 911 | picomatch@4.0.2: 912 | resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} 913 | engines: {node: '>=12'} 914 | 915 | pirates@4.0.7: 916 | resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} 917 | engines: {node: '>= 6'} 918 | 919 | pkg-types@1.3.1: 920 | resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} 921 | 922 | postcss-load-config@6.0.1: 923 | resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} 924 | engines: {node: '>= 18'} 925 | peerDependencies: 926 | jiti: '>=1.21.0' 927 | postcss: '>=8.0.9' 928 | tsx: ^4.8.1 929 | yaml: ^2.4.2 930 | peerDependenciesMeta: 931 | jiti: 932 | optional: true 933 | postcss: 934 | optional: true 935 | tsx: 936 | optional: true 937 | yaml: 938 | optional: true 939 | 940 | postcss@8.4.31: 941 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} 942 | engines: {node: ^10 || ^12 || >=14} 943 | 944 | ps-tree@1.2.0: 945 | resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} 946 | engines: {node: '>= 0.10'} 947 | hasBin: true 948 | 949 | punycode@2.3.1: 950 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 951 | engines: {node: '>=6'} 952 | 953 | pvtsutils@1.3.6: 954 | resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} 955 | 956 | pvutils@1.1.3: 957 | resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} 958 | engines: {node: '>=6.0.0'} 959 | 960 | react-dom@19.0.0: 961 | resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} 962 | peerDependencies: 963 | react: ^19.0.0 964 | 965 | react@19.0.0: 966 | resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} 967 | engines: {node: '>=0.10.0'} 968 | 969 | readdirp@4.1.2: 970 | resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} 971 | engines: {node: '>= 14.18.0'} 972 | 973 | resolve-from@5.0.0: 974 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 975 | engines: {node: '>=8'} 976 | 977 | resolve-pkg-maps@1.0.0: 978 | resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 979 | 980 | rollup@4.41.1: 981 | resolution: {integrity: sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==} 982 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 983 | hasBin: true 984 | 985 | rou3@0.5.1: 986 | resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} 987 | 988 | scheduler@0.25.0: 989 | resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} 990 | 991 | semver@7.7.2: 992 | resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} 993 | engines: {node: '>=10'} 994 | hasBin: true 995 | 996 | set-cookie-parser@2.7.1: 997 | resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} 998 | 999 | sharp@0.34.2: 1000 | resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} 1001 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 1002 | 1003 | shebang-command@2.0.0: 1004 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1005 | engines: {node: '>=8'} 1006 | 1007 | shebang-regex@3.0.0: 1008 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1009 | engines: {node: '>=8'} 1010 | 1011 | signal-exit@4.1.0: 1012 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1013 | engines: {node: '>=14'} 1014 | 1015 | simple-swizzle@0.2.2: 1016 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} 1017 | 1018 | source-map-js@1.2.1: 1019 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 1020 | engines: {node: '>=0.10.0'} 1021 | 1022 | source-map@0.8.0-beta.0: 1023 | resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} 1024 | engines: {node: '>= 8'} 1025 | 1026 | split@0.3.3: 1027 | resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} 1028 | 1029 | stream-combiner@0.0.4: 1030 | resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} 1031 | 1032 | streamsearch@1.1.0: 1033 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} 1034 | engines: {node: '>=10.0.0'} 1035 | 1036 | string-argv@0.3.2: 1037 | resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} 1038 | engines: {node: '>=0.6.19'} 1039 | 1040 | string-width@4.2.3: 1041 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1042 | engines: {node: '>=8'} 1043 | 1044 | string-width@5.1.2: 1045 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 1046 | engines: {node: '>=12'} 1047 | 1048 | strip-ansi@6.0.1: 1049 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1050 | engines: {node: '>=8'} 1051 | 1052 | strip-ansi@7.1.0: 1053 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 1054 | engines: {node: '>=12'} 1055 | 1056 | styled-jsx@5.1.6: 1057 | resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} 1058 | engines: {node: '>= 12.0.0'} 1059 | peerDependencies: 1060 | '@babel/core': '*' 1061 | babel-plugin-macros: '*' 1062 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' 1063 | peerDependenciesMeta: 1064 | '@babel/core': 1065 | optional: true 1066 | babel-plugin-macros: 1067 | optional: true 1068 | 1069 | sucrase@3.35.0: 1070 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} 1071 | engines: {node: '>=16 || 14 >=14.17'} 1072 | hasBin: true 1073 | 1074 | thenify-all@1.6.0: 1075 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} 1076 | engines: {node: '>=0.8'} 1077 | 1078 | thenify@3.3.1: 1079 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} 1080 | 1081 | through@2.3.8: 1082 | resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} 1083 | 1084 | tinyexec@0.3.2: 1085 | resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} 1086 | 1087 | tinyglobby@0.2.14: 1088 | resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} 1089 | engines: {node: '>=12.0.0'} 1090 | 1091 | tr46@1.0.1: 1092 | resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} 1093 | 1094 | tree-kill@1.2.2: 1095 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 1096 | hasBin: true 1097 | 1098 | ts-interface-checker@0.1.13: 1099 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} 1100 | 1101 | tsc-watch@7.1.1: 1102 | resolution: {integrity: sha512-r6t37Dkk4vK44HwxOe+OzjpE/gDamZAwqXhtcAJD/hPVblcjJK45NxbK0HcDASXG0U4pEnCh640JZbeDVSC6yA==} 1103 | engines: {node: '>=12.12.0'} 1104 | hasBin: true 1105 | peerDependencies: 1106 | typescript: '*' 1107 | 1108 | tslib@2.8.1: 1109 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 1110 | 1111 | tsup@8.5.0: 1112 | resolution: {integrity: sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==} 1113 | engines: {node: '>=18'} 1114 | hasBin: true 1115 | peerDependencies: 1116 | '@microsoft/api-extractor': ^7.36.0 1117 | '@swc/core': ^1 1118 | postcss: ^8.4.12 1119 | typescript: '>=4.5.0' 1120 | peerDependenciesMeta: 1121 | '@microsoft/api-extractor': 1122 | optional: true 1123 | '@swc/core': 1124 | optional: true 1125 | postcss: 1126 | optional: true 1127 | typescript: 1128 | optional: true 1129 | 1130 | tsx@4.19.4: 1131 | resolution: {integrity: sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==} 1132 | engines: {node: '>=18.0.0'} 1133 | hasBin: true 1134 | 1135 | turbo-darwin-64@2.5.4: 1136 | resolution: {integrity: sha512-ah6YnH2dErojhFooxEzmvsoZQTMImaruZhFPfMKPBq8sb+hALRdvBNLqfc8NWlZq576FkfRZ/MSi4SHvVFT9PQ==} 1137 | cpu: [x64] 1138 | os: [darwin] 1139 | 1140 | turbo-darwin-arm64@2.5.4: 1141 | resolution: {integrity: sha512-2+Nx6LAyuXw2MdXb7pxqle3MYignLvS7OwtsP9SgtSBaMlnNlxl9BovzqdYAgkUW3AsYiQMJ/wBRb7d+xemM5A==} 1142 | cpu: [arm64] 1143 | os: [darwin] 1144 | 1145 | turbo-linux-64@2.5.4: 1146 | resolution: {integrity: sha512-5May2kjWbc8w4XxswGAl74GZ5eM4Gr6IiroqdLhXeXyfvWEdm2mFYCSWOzz0/z5cAgqyGidF1jt1qzUR8hTmOA==} 1147 | cpu: [x64] 1148 | os: [linux] 1149 | 1150 | turbo-linux-arm64@2.5.4: 1151 | resolution: {integrity: sha512-/2yqFaS3TbfxV3P5yG2JUI79P7OUQKOUvAnx4MV9Bdz6jqHsHwc9WZPpO4QseQm+NvmgY6ICORnoVPODxGUiJg==} 1152 | cpu: [arm64] 1153 | os: [linux] 1154 | 1155 | turbo-windows-64@2.5.4: 1156 | resolution: {integrity: sha512-EQUO4SmaCDhO6zYohxIjJpOKRN3wlfU7jMAj3CgcyTPvQR/UFLEKAYHqJOnJtymbQmiiM/ihX6c6W6Uq0yC7mA==} 1157 | cpu: [x64] 1158 | os: [win32] 1159 | 1160 | turbo-windows-arm64@2.5.4: 1161 | resolution: {integrity: sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A==} 1162 | cpu: [arm64] 1163 | os: [win32] 1164 | 1165 | turbo@2.5.4: 1166 | resolution: {integrity: sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA==} 1167 | hasBin: true 1168 | 1169 | typescript@5.8.3: 1170 | resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} 1171 | engines: {node: '>=14.17'} 1172 | hasBin: true 1173 | 1174 | ufo@1.6.1: 1175 | resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} 1176 | 1177 | uncrypto@0.1.3: 1178 | resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} 1179 | 1180 | undici-types@6.21.0: 1181 | resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} 1182 | 1183 | webidl-conversions@4.0.2: 1184 | resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} 1185 | 1186 | whatwg-url@7.1.0: 1187 | resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} 1188 | 1189 | which@2.0.2: 1190 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1191 | engines: {node: '>= 8'} 1192 | hasBin: true 1193 | 1194 | wrap-ansi@7.0.0: 1195 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1196 | engines: {node: '>=10'} 1197 | 1198 | wrap-ansi@8.1.0: 1199 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 1200 | engines: {node: '>=12'} 1201 | 1202 | zod@3.24.2: 1203 | resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} 1204 | 1205 | snapshots: 1206 | 1207 | '@better-auth/utils@0.2.5': 1208 | dependencies: 1209 | typescript: 5.8.3 1210 | uncrypto: 0.1.3 1211 | 1212 | '@better-fetch/fetch@1.1.18': {} 1213 | 1214 | '@biomejs/biome@1.9.4': 1215 | optionalDependencies: 1216 | '@biomejs/cli-darwin-arm64': 1.9.4 1217 | '@biomejs/cli-darwin-x64': 1.9.4 1218 | '@biomejs/cli-linux-arm64': 1.9.4 1219 | '@biomejs/cli-linux-arm64-musl': 1.9.4 1220 | '@biomejs/cli-linux-x64': 1.9.4 1221 | '@biomejs/cli-linux-x64-musl': 1.9.4 1222 | '@biomejs/cli-win32-arm64': 1.9.4 1223 | '@biomejs/cli-win32-x64': 1.9.4 1224 | 1225 | '@biomejs/cli-darwin-arm64@1.9.4': 1226 | optional: true 1227 | 1228 | '@biomejs/cli-darwin-x64@1.9.4': 1229 | optional: true 1230 | 1231 | '@biomejs/cli-linux-arm64-musl@1.9.4': 1232 | optional: true 1233 | 1234 | '@biomejs/cli-linux-arm64@1.9.4': 1235 | optional: true 1236 | 1237 | '@biomejs/cli-linux-x64-musl@1.9.4': 1238 | optional: true 1239 | 1240 | '@biomejs/cli-linux-x64@1.9.4': 1241 | optional: true 1242 | 1243 | '@biomejs/cli-win32-arm64@1.9.4': 1244 | optional: true 1245 | 1246 | '@biomejs/cli-win32-x64@1.9.4': 1247 | optional: true 1248 | 1249 | '@emnapi/runtime@1.4.3': 1250 | dependencies: 1251 | tslib: 2.8.1 1252 | optional: true 1253 | 1254 | '@esbuild/aix-ppc64@0.25.5': 1255 | optional: true 1256 | 1257 | '@esbuild/android-arm64@0.25.5': 1258 | optional: true 1259 | 1260 | '@esbuild/android-arm@0.25.5': 1261 | optional: true 1262 | 1263 | '@esbuild/android-x64@0.25.5': 1264 | optional: true 1265 | 1266 | '@esbuild/darwin-arm64@0.25.5': 1267 | optional: true 1268 | 1269 | '@esbuild/darwin-x64@0.25.5': 1270 | optional: true 1271 | 1272 | '@esbuild/freebsd-arm64@0.25.5': 1273 | optional: true 1274 | 1275 | '@esbuild/freebsd-x64@0.25.5': 1276 | optional: true 1277 | 1278 | '@esbuild/linux-arm64@0.25.5': 1279 | optional: true 1280 | 1281 | '@esbuild/linux-arm@0.25.5': 1282 | optional: true 1283 | 1284 | '@esbuild/linux-ia32@0.25.5': 1285 | optional: true 1286 | 1287 | '@esbuild/linux-loong64@0.25.5': 1288 | optional: true 1289 | 1290 | '@esbuild/linux-mips64el@0.25.5': 1291 | optional: true 1292 | 1293 | '@esbuild/linux-ppc64@0.25.5': 1294 | optional: true 1295 | 1296 | '@esbuild/linux-riscv64@0.25.5': 1297 | optional: true 1298 | 1299 | '@esbuild/linux-s390x@0.25.5': 1300 | optional: true 1301 | 1302 | '@esbuild/linux-x64@0.25.5': 1303 | optional: true 1304 | 1305 | '@esbuild/netbsd-arm64@0.25.5': 1306 | optional: true 1307 | 1308 | '@esbuild/netbsd-x64@0.25.5': 1309 | optional: true 1310 | 1311 | '@esbuild/openbsd-arm64@0.25.5': 1312 | optional: true 1313 | 1314 | '@esbuild/openbsd-x64@0.25.5': 1315 | optional: true 1316 | 1317 | '@esbuild/sunos-x64@0.25.5': 1318 | optional: true 1319 | 1320 | '@esbuild/win32-arm64@0.25.5': 1321 | optional: true 1322 | 1323 | '@esbuild/win32-ia32@0.25.5': 1324 | optional: true 1325 | 1326 | '@esbuild/win32-x64@0.25.5': 1327 | optional: true 1328 | 1329 | '@hexagon/base64@1.1.28': {} 1330 | 1331 | '@img/sharp-darwin-arm64@0.34.2': 1332 | optionalDependencies: 1333 | '@img/sharp-libvips-darwin-arm64': 1.1.0 1334 | optional: true 1335 | 1336 | '@img/sharp-darwin-x64@0.34.2': 1337 | optionalDependencies: 1338 | '@img/sharp-libvips-darwin-x64': 1.1.0 1339 | optional: true 1340 | 1341 | '@img/sharp-libvips-darwin-arm64@1.1.0': 1342 | optional: true 1343 | 1344 | '@img/sharp-libvips-darwin-x64@1.1.0': 1345 | optional: true 1346 | 1347 | '@img/sharp-libvips-linux-arm64@1.1.0': 1348 | optional: true 1349 | 1350 | '@img/sharp-libvips-linux-arm@1.1.0': 1351 | optional: true 1352 | 1353 | '@img/sharp-libvips-linux-ppc64@1.1.0': 1354 | optional: true 1355 | 1356 | '@img/sharp-libvips-linux-s390x@1.1.0': 1357 | optional: true 1358 | 1359 | '@img/sharp-libvips-linux-x64@1.1.0': 1360 | optional: true 1361 | 1362 | '@img/sharp-libvips-linuxmusl-arm64@1.1.0': 1363 | optional: true 1364 | 1365 | '@img/sharp-libvips-linuxmusl-x64@1.1.0': 1366 | optional: true 1367 | 1368 | '@img/sharp-linux-arm64@0.34.2': 1369 | optionalDependencies: 1370 | '@img/sharp-libvips-linux-arm64': 1.1.0 1371 | optional: true 1372 | 1373 | '@img/sharp-linux-arm@0.34.2': 1374 | optionalDependencies: 1375 | '@img/sharp-libvips-linux-arm': 1.1.0 1376 | optional: true 1377 | 1378 | '@img/sharp-linux-s390x@0.34.2': 1379 | optionalDependencies: 1380 | '@img/sharp-libvips-linux-s390x': 1.1.0 1381 | optional: true 1382 | 1383 | '@img/sharp-linux-x64@0.34.2': 1384 | optionalDependencies: 1385 | '@img/sharp-libvips-linux-x64': 1.1.0 1386 | optional: true 1387 | 1388 | '@img/sharp-linuxmusl-arm64@0.34.2': 1389 | optionalDependencies: 1390 | '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 1391 | optional: true 1392 | 1393 | '@img/sharp-linuxmusl-x64@0.34.2': 1394 | optionalDependencies: 1395 | '@img/sharp-libvips-linuxmusl-x64': 1.1.0 1396 | optional: true 1397 | 1398 | '@img/sharp-wasm32@0.34.2': 1399 | dependencies: 1400 | '@emnapi/runtime': 1.4.3 1401 | optional: true 1402 | 1403 | '@img/sharp-win32-arm64@0.34.2': 1404 | optional: true 1405 | 1406 | '@img/sharp-win32-ia32@0.34.2': 1407 | optional: true 1408 | 1409 | '@img/sharp-win32-x64@0.34.2': 1410 | optional: true 1411 | 1412 | '@isaacs/cliui@8.0.2': 1413 | dependencies: 1414 | string-width: 5.1.2 1415 | string-width-cjs: string-width@4.2.3 1416 | strip-ansi: 7.1.0 1417 | strip-ansi-cjs: strip-ansi@6.0.1 1418 | wrap-ansi: 8.1.0 1419 | wrap-ansi-cjs: wrap-ansi@7.0.0 1420 | 1421 | '@jridgewell/gen-mapping@0.3.8': 1422 | dependencies: 1423 | '@jridgewell/set-array': 1.2.1 1424 | '@jridgewell/sourcemap-codec': 1.5.0 1425 | '@jridgewell/trace-mapping': 0.3.25 1426 | 1427 | '@jridgewell/resolve-uri@3.1.2': {} 1428 | 1429 | '@jridgewell/set-array@1.2.1': {} 1430 | 1431 | '@jridgewell/sourcemap-codec@1.5.0': {} 1432 | 1433 | '@jridgewell/trace-mapping@0.3.25': 1434 | dependencies: 1435 | '@jridgewell/resolve-uri': 3.1.2 1436 | '@jridgewell/sourcemap-codec': 1.5.0 1437 | 1438 | '@levischuck/tiny-cbor@0.2.11': {} 1439 | 1440 | '@next/env@15.3.3': {} 1441 | 1442 | '@next/swc-darwin-arm64@15.3.3': 1443 | optional: true 1444 | 1445 | '@next/swc-darwin-x64@15.3.3': 1446 | optional: true 1447 | 1448 | '@next/swc-linux-arm64-gnu@15.3.3': 1449 | optional: true 1450 | 1451 | '@next/swc-linux-arm64-musl@15.3.3': 1452 | optional: true 1453 | 1454 | '@next/swc-linux-x64-gnu@15.3.3': 1455 | optional: true 1456 | 1457 | '@next/swc-linux-x64-musl@15.3.3': 1458 | optional: true 1459 | 1460 | '@next/swc-win32-arm64-msvc@15.3.3': 1461 | optional: true 1462 | 1463 | '@next/swc-win32-x64-msvc@15.3.3': 1464 | optional: true 1465 | 1466 | '@noble/ciphers@0.6.0': {} 1467 | 1468 | '@noble/hashes@1.7.1': {} 1469 | 1470 | '@peculiar/asn1-android@2.3.15': 1471 | dependencies: 1472 | '@peculiar/asn1-schema': 2.3.15 1473 | asn1js: 3.0.5 1474 | tslib: 2.8.1 1475 | 1476 | '@peculiar/asn1-ecc@2.3.15': 1477 | dependencies: 1478 | '@peculiar/asn1-schema': 2.3.15 1479 | '@peculiar/asn1-x509': 2.3.15 1480 | asn1js: 3.0.5 1481 | tslib: 2.8.1 1482 | 1483 | '@peculiar/asn1-rsa@2.3.15': 1484 | dependencies: 1485 | '@peculiar/asn1-schema': 2.3.15 1486 | '@peculiar/asn1-x509': 2.3.15 1487 | asn1js: 3.0.5 1488 | tslib: 2.8.1 1489 | 1490 | '@peculiar/asn1-schema@2.3.15': 1491 | dependencies: 1492 | asn1js: 3.0.5 1493 | pvtsutils: 1.3.6 1494 | tslib: 2.8.1 1495 | 1496 | '@peculiar/asn1-x509@2.3.15': 1497 | dependencies: 1498 | '@peculiar/asn1-schema': 2.3.15 1499 | asn1js: 3.0.5 1500 | pvtsutils: 1.3.6 1501 | tslib: 2.8.1 1502 | 1503 | '@pkgjs/parseargs@0.11.0': 1504 | optional: true 1505 | 1506 | '@rollup/rollup-android-arm-eabi@4.41.1': 1507 | optional: true 1508 | 1509 | '@rollup/rollup-android-arm64@4.41.1': 1510 | optional: true 1511 | 1512 | '@rollup/rollup-darwin-arm64@4.41.1': 1513 | optional: true 1514 | 1515 | '@rollup/rollup-darwin-x64@4.41.1': 1516 | optional: true 1517 | 1518 | '@rollup/rollup-freebsd-arm64@4.41.1': 1519 | optional: true 1520 | 1521 | '@rollup/rollup-freebsd-x64@4.41.1': 1522 | optional: true 1523 | 1524 | '@rollup/rollup-linux-arm-gnueabihf@4.41.1': 1525 | optional: true 1526 | 1527 | '@rollup/rollup-linux-arm-musleabihf@4.41.1': 1528 | optional: true 1529 | 1530 | '@rollup/rollup-linux-arm64-gnu@4.41.1': 1531 | optional: true 1532 | 1533 | '@rollup/rollup-linux-arm64-musl@4.41.1': 1534 | optional: true 1535 | 1536 | '@rollup/rollup-linux-loongarch64-gnu@4.41.1': 1537 | optional: true 1538 | 1539 | '@rollup/rollup-linux-powerpc64le-gnu@4.41.1': 1540 | optional: true 1541 | 1542 | '@rollup/rollup-linux-riscv64-gnu@4.41.1': 1543 | optional: true 1544 | 1545 | '@rollup/rollup-linux-riscv64-musl@4.41.1': 1546 | optional: true 1547 | 1548 | '@rollup/rollup-linux-s390x-gnu@4.41.1': 1549 | optional: true 1550 | 1551 | '@rollup/rollup-linux-x64-gnu@4.41.1': 1552 | optional: true 1553 | 1554 | '@rollup/rollup-linux-x64-musl@4.41.1': 1555 | optional: true 1556 | 1557 | '@rollup/rollup-win32-arm64-msvc@4.41.1': 1558 | optional: true 1559 | 1560 | '@rollup/rollup-win32-ia32-msvc@4.41.1': 1561 | optional: true 1562 | 1563 | '@rollup/rollup-win32-x64-msvc@4.41.1': 1564 | optional: true 1565 | 1566 | '@simplewebauthn/browser@13.1.0': {} 1567 | 1568 | '@simplewebauthn/server@13.1.1': 1569 | dependencies: 1570 | '@hexagon/base64': 1.1.28 1571 | '@levischuck/tiny-cbor': 0.2.11 1572 | '@peculiar/asn1-android': 2.3.15 1573 | '@peculiar/asn1-ecc': 2.3.15 1574 | '@peculiar/asn1-rsa': 2.3.15 1575 | '@peculiar/asn1-schema': 2.3.15 1576 | '@peculiar/asn1-x509': 2.3.15 1577 | 1578 | '@swc/counter@0.1.3': {} 1579 | 1580 | '@swc/helpers@0.5.15': 1581 | dependencies: 1582 | tslib: 2.8.1 1583 | 1584 | '@tanstack/query-core@5.69.0': {} 1585 | 1586 | '@tanstack/react-query@5.69.0(react@19.0.0)': 1587 | dependencies: 1588 | '@tanstack/query-core': 5.69.0 1589 | react: 19.0.0 1590 | 1591 | '@types/estree@1.0.7': {} 1592 | 1593 | '@types/node@22.15.29': 1594 | dependencies: 1595 | undici-types: 6.21.0 1596 | 1597 | '@types/react-dom@19.1.5(@types/react@19.1.6)': 1598 | dependencies: 1599 | '@types/react': 19.1.6 1600 | 1601 | '@types/react@19.1.6': 1602 | dependencies: 1603 | csstype: 3.1.3 1604 | 1605 | acorn@8.14.1: {} 1606 | 1607 | ansi-regex@5.0.1: {} 1608 | 1609 | ansi-regex@6.1.0: {} 1610 | 1611 | ansi-styles@4.3.0: 1612 | dependencies: 1613 | color-convert: 2.0.1 1614 | 1615 | ansi-styles@6.2.1: {} 1616 | 1617 | any-promise@1.3.0: {} 1618 | 1619 | asn1js@3.0.5: 1620 | dependencies: 1621 | pvtsutils: 1.3.6 1622 | pvutils: 1.1.3 1623 | tslib: 2.8.1 1624 | 1625 | balanced-match@1.0.2: {} 1626 | 1627 | better-auth@1.2.8: 1628 | dependencies: 1629 | '@better-auth/utils': 0.2.5 1630 | '@better-fetch/fetch': 1.1.18 1631 | '@noble/ciphers': 0.6.0 1632 | '@noble/hashes': 1.7.1 1633 | '@simplewebauthn/browser': 13.1.0 1634 | '@simplewebauthn/server': 13.1.1 1635 | better-call: 1.0.9 1636 | defu: 6.1.4 1637 | jose: 5.10.0 1638 | kysely: 0.28.2 1639 | nanostores: 0.11.4 1640 | zod: 3.24.2 1641 | 1642 | better-call@1.0.9: 1643 | dependencies: 1644 | '@better-fetch/fetch': 1.1.18 1645 | rou3: 0.5.1 1646 | set-cookie-parser: 2.7.1 1647 | uncrypto: 0.1.3 1648 | 1649 | brace-expansion@2.0.1: 1650 | dependencies: 1651 | balanced-match: 1.0.2 1652 | 1653 | bundle-require@5.1.0(esbuild@0.25.5): 1654 | dependencies: 1655 | esbuild: 0.25.5 1656 | load-tsconfig: 0.2.5 1657 | 1658 | busboy@1.6.0: 1659 | dependencies: 1660 | streamsearch: 1.1.0 1661 | 1662 | cac@6.7.14: {} 1663 | 1664 | caniuse-lite@1.0.30001720: {} 1665 | 1666 | chokidar@4.0.3: 1667 | dependencies: 1668 | readdirp: 4.1.2 1669 | 1670 | client-only@0.0.1: {} 1671 | 1672 | color-convert@2.0.1: 1673 | dependencies: 1674 | color-name: 1.1.4 1675 | 1676 | color-name@1.1.4: {} 1677 | 1678 | color-string@1.9.1: 1679 | dependencies: 1680 | color-name: 1.1.4 1681 | simple-swizzle: 0.2.2 1682 | optional: true 1683 | 1684 | color@4.2.3: 1685 | dependencies: 1686 | color-convert: 2.0.1 1687 | color-string: 1.9.1 1688 | optional: true 1689 | 1690 | commander@4.1.1: {} 1691 | 1692 | confbox@0.1.8: {} 1693 | 1694 | consola@3.4.2: {} 1695 | 1696 | cross-spawn@7.0.6: 1697 | dependencies: 1698 | path-key: 3.1.1 1699 | shebang-command: 2.0.0 1700 | which: 2.0.2 1701 | 1702 | csstype@3.1.3: {} 1703 | 1704 | debug@4.4.1: 1705 | dependencies: 1706 | ms: 2.1.3 1707 | 1708 | defu@6.1.4: {} 1709 | 1710 | detect-libc@2.0.4: 1711 | optional: true 1712 | 1713 | duplexer@0.1.2: {} 1714 | 1715 | eastasianwidth@0.2.0: {} 1716 | 1717 | emoji-regex@8.0.0: {} 1718 | 1719 | emoji-regex@9.2.2: {} 1720 | 1721 | esbuild@0.25.5: 1722 | optionalDependencies: 1723 | '@esbuild/aix-ppc64': 0.25.5 1724 | '@esbuild/android-arm': 0.25.5 1725 | '@esbuild/android-arm64': 0.25.5 1726 | '@esbuild/android-x64': 0.25.5 1727 | '@esbuild/darwin-arm64': 0.25.5 1728 | '@esbuild/darwin-x64': 0.25.5 1729 | '@esbuild/freebsd-arm64': 0.25.5 1730 | '@esbuild/freebsd-x64': 0.25.5 1731 | '@esbuild/linux-arm': 0.25.5 1732 | '@esbuild/linux-arm64': 0.25.5 1733 | '@esbuild/linux-ia32': 0.25.5 1734 | '@esbuild/linux-loong64': 0.25.5 1735 | '@esbuild/linux-mips64el': 0.25.5 1736 | '@esbuild/linux-ppc64': 0.25.5 1737 | '@esbuild/linux-riscv64': 0.25.5 1738 | '@esbuild/linux-s390x': 0.25.5 1739 | '@esbuild/linux-x64': 0.25.5 1740 | '@esbuild/netbsd-arm64': 0.25.5 1741 | '@esbuild/netbsd-x64': 0.25.5 1742 | '@esbuild/openbsd-arm64': 0.25.5 1743 | '@esbuild/openbsd-x64': 0.25.5 1744 | '@esbuild/sunos-x64': 0.25.5 1745 | '@esbuild/win32-arm64': 0.25.5 1746 | '@esbuild/win32-ia32': 0.25.5 1747 | '@esbuild/win32-x64': 0.25.5 1748 | 1749 | event-stream@3.3.4: 1750 | dependencies: 1751 | duplexer: 0.1.2 1752 | from: 0.1.7 1753 | map-stream: 0.1.0 1754 | pause-stream: 0.0.11 1755 | split: 0.3.3 1756 | stream-combiner: 0.0.4 1757 | through: 2.3.8 1758 | 1759 | fdir@6.4.5(picomatch@4.0.2): 1760 | optionalDependencies: 1761 | picomatch: 4.0.2 1762 | 1763 | fix-dts-default-cjs-exports@1.0.1: 1764 | dependencies: 1765 | magic-string: 0.30.17 1766 | mlly: 1.7.4 1767 | rollup: 4.41.1 1768 | 1769 | foreground-child@3.3.1: 1770 | dependencies: 1771 | cross-spawn: 7.0.6 1772 | signal-exit: 4.1.0 1773 | 1774 | from@0.1.7: {} 1775 | 1776 | fsevents@2.3.3: 1777 | optional: true 1778 | 1779 | get-tsconfig@4.10.1: 1780 | dependencies: 1781 | resolve-pkg-maps: 1.0.0 1782 | 1783 | glob@10.4.5: 1784 | dependencies: 1785 | foreground-child: 3.3.1 1786 | jackspeak: 3.4.3 1787 | minimatch: 9.0.5 1788 | minipass: 7.1.2 1789 | package-json-from-dist: 1.0.1 1790 | path-scurry: 1.11.1 1791 | 1792 | is-arrayish@0.3.2: 1793 | optional: true 1794 | 1795 | is-fullwidth-code-point@3.0.0: {} 1796 | 1797 | isexe@2.0.0: {} 1798 | 1799 | jackspeak@3.4.3: 1800 | dependencies: 1801 | '@isaacs/cliui': 8.0.2 1802 | optionalDependencies: 1803 | '@pkgjs/parseargs': 0.11.0 1804 | 1805 | jose@5.10.0: {} 1806 | 1807 | joycon@3.1.1: {} 1808 | 1809 | kysely@0.28.2: {} 1810 | 1811 | lilconfig@3.1.3: {} 1812 | 1813 | lines-and-columns@1.2.4: {} 1814 | 1815 | load-tsconfig@0.2.5: {} 1816 | 1817 | lodash.sortby@4.7.0: {} 1818 | 1819 | lru-cache@10.4.3: {} 1820 | 1821 | magic-string@0.30.17: 1822 | dependencies: 1823 | '@jridgewell/sourcemap-codec': 1.5.0 1824 | 1825 | map-stream@0.1.0: {} 1826 | 1827 | minimatch@9.0.5: 1828 | dependencies: 1829 | brace-expansion: 2.0.1 1830 | 1831 | minipass@7.1.2: {} 1832 | 1833 | mlly@1.7.4: 1834 | dependencies: 1835 | acorn: 8.14.1 1836 | pathe: 2.0.3 1837 | pkg-types: 1.3.1 1838 | ufo: 1.6.1 1839 | 1840 | ms@2.1.3: {} 1841 | 1842 | mz@2.7.0: 1843 | dependencies: 1844 | any-promise: 1.3.0 1845 | object-assign: 4.1.1 1846 | thenify-all: 1.6.0 1847 | 1848 | nanoid@3.3.11: {} 1849 | 1850 | nanostores@0.11.4: {} 1851 | 1852 | next@15.3.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0): 1853 | dependencies: 1854 | '@next/env': 15.3.3 1855 | '@swc/counter': 0.1.3 1856 | '@swc/helpers': 0.5.15 1857 | busboy: 1.6.0 1858 | caniuse-lite: 1.0.30001720 1859 | postcss: 8.4.31 1860 | react: 19.0.0 1861 | react-dom: 19.0.0(react@19.0.0) 1862 | styled-jsx: 5.1.6(react@19.0.0) 1863 | optionalDependencies: 1864 | '@next/swc-darwin-arm64': 15.3.3 1865 | '@next/swc-darwin-x64': 15.3.3 1866 | '@next/swc-linux-arm64-gnu': 15.3.3 1867 | '@next/swc-linux-arm64-musl': 15.3.3 1868 | '@next/swc-linux-x64-gnu': 15.3.3 1869 | '@next/swc-linux-x64-musl': 15.3.3 1870 | '@next/swc-win32-arm64-msvc': 15.3.3 1871 | '@next/swc-win32-x64-msvc': 15.3.3 1872 | sharp: 0.34.2 1873 | transitivePeerDependencies: 1874 | - '@babel/core' 1875 | - babel-plugin-macros 1876 | 1877 | node-cleanup@2.1.2: {} 1878 | 1879 | object-assign@4.1.1: {} 1880 | 1881 | package-json-from-dist@1.0.1: {} 1882 | 1883 | path-key@3.1.1: {} 1884 | 1885 | path-scurry@1.11.1: 1886 | dependencies: 1887 | lru-cache: 10.4.3 1888 | minipass: 7.1.2 1889 | 1890 | pathe@2.0.3: {} 1891 | 1892 | pause-stream@0.0.11: 1893 | dependencies: 1894 | through: 2.3.8 1895 | 1896 | picocolors@1.1.1: {} 1897 | 1898 | picomatch@4.0.2: {} 1899 | 1900 | pirates@4.0.7: {} 1901 | 1902 | pkg-types@1.3.1: 1903 | dependencies: 1904 | confbox: 0.1.8 1905 | mlly: 1.7.4 1906 | pathe: 2.0.3 1907 | 1908 | postcss-load-config@6.0.1(postcss@8.4.31)(tsx@4.19.4): 1909 | dependencies: 1910 | lilconfig: 3.1.3 1911 | optionalDependencies: 1912 | postcss: 8.4.31 1913 | tsx: 4.19.4 1914 | 1915 | postcss@8.4.31: 1916 | dependencies: 1917 | nanoid: 3.3.11 1918 | picocolors: 1.1.1 1919 | source-map-js: 1.2.1 1920 | 1921 | ps-tree@1.2.0: 1922 | dependencies: 1923 | event-stream: 3.3.4 1924 | 1925 | punycode@2.3.1: {} 1926 | 1927 | pvtsutils@1.3.6: 1928 | dependencies: 1929 | tslib: 2.8.1 1930 | 1931 | pvutils@1.1.3: {} 1932 | 1933 | react-dom@19.0.0(react@19.0.0): 1934 | dependencies: 1935 | react: 19.0.0 1936 | scheduler: 0.25.0 1937 | 1938 | react@19.0.0: {} 1939 | 1940 | readdirp@4.1.2: {} 1941 | 1942 | resolve-from@5.0.0: {} 1943 | 1944 | resolve-pkg-maps@1.0.0: {} 1945 | 1946 | rollup@4.41.1: 1947 | dependencies: 1948 | '@types/estree': 1.0.7 1949 | optionalDependencies: 1950 | '@rollup/rollup-android-arm-eabi': 4.41.1 1951 | '@rollup/rollup-android-arm64': 4.41.1 1952 | '@rollup/rollup-darwin-arm64': 4.41.1 1953 | '@rollup/rollup-darwin-x64': 4.41.1 1954 | '@rollup/rollup-freebsd-arm64': 4.41.1 1955 | '@rollup/rollup-freebsd-x64': 4.41.1 1956 | '@rollup/rollup-linux-arm-gnueabihf': 4.41.1 1957 | '@rollup/rollup-linux-arm-musleabihf': 4.41.1 1958 | '@rollup/rollup-linux-arm64-gnu': 4.41.1 1959 | '@rollup/rollup-linux-arm64-musl': 4.41.1 1960 | '@rollup/rollup-linux-loongarch64-gnu': 4.41.1 1961 | '@rollup/rollup-linux-powerpc64le-gnu': 4.41.1 1962 | '@rollup/rollup-linux-riscv64-gnu': 4.41.1 1963 | '@rollup/rollup-linux-riscv64-musl': 4.41.1 1964 | '@rollup/rollup-linux-s390x-gnu': 4.41.1 1965 | '@rollup/rollup-linux-x64-gnu': 4.41.1 1966 | '@rollup/rollup-linux-x64-musl': 4.41.1 1967 | '@rollup/rollup-win32-arm64-msvc': 4.41.1 1968 | '@rollup/rollup-win32-ia32-msvc': 4.41.1 1969 | '@rollup/rollup-win32-x64-msvc': 4.41.1 1970 | fsevents: 2.3.3 1971 | 1972 | rou3@0.5.1: {} 1973 | 1974 | scheduler@0.25.0: {} 1975 | 1976 | semver@7.7.2: 1977 | optional: true 1978 | 1979 | set-cookie-parser@2.7.1: {} 1980 | 1981 | sharp@0.34.2: 1982 | dependencies: 1983 | color: 4.2.3 1984 | detect-libc: 2.0.4 1985 | semver: 7.7.2 1986 | optionalDependencies: 1987 | '@img/sharp-darwin-arm64': 0.34.2 1988 | '@img/sharp-darwin-x64': 0.34.2 1989 | '@img/sharp-libvips-darwin-arm64': 1.1.0 1990 | '@img/sharp-libvips-darwin-x64': 1.1.0 1991 | '@img/sharp-libvips-linux-arm': 1.1.0 1992 | '@img/sharp-libvips-linux-arm64': 1.1.0 1993 | '@img/sharp-libvips-linux-ppc64': 1.1.0 1994 | '@img/sharp-libvips-linux-s390x': 1.1.0 1995 | '@img/sharp-libvips-linux-x64': 1.1.0 1996 | '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 1997 | '@img/sharp-libvips-linuxmusl-x64': 1.1.0 1998 | '@img/sharp-linux-arm': 0.34.2 1999 | '@img/sharp-linux-arm64': 0.34.2 2000 | '@img/sharp-linux-s390x': 0.34.2 2001 | '@img/sharp-linux-x64': 0.34.2 2002 | '@img/sharp-linuxmusl-arm64': 0.34.2 2003 | '@img/sharp-linuxmusl-x64': 0.34.2 2004 | '@img/sharp-wasm32': 0.34.2 2005 | '@img/sharp-win32-arm64': 0.34.2 2006 | '@img/sharp-win32-ia32': 0.34.2 2007 | '@img/sharp-win32-x64': 0.34.2 2008 | optional: true 2009 | 2010 | shebang-command@2.0.0: 2011 | dependencies: 2012 | shebang-regex: 3.0.0 2013 | 2014 | shebang-regex@3.0.0: {} 2015 | 2016 | signal-exit@4.1.0: {} 2017 | 2018 | simple-swizzle@0.2.2: 2019 | dependencies: 2020 | is-arrayish: 0.3.2 2021 | optional: true 2022 | 2023 | source-map-js@1.2.1: {} 2024 | 2025 | source-map@0.8.0-beta.0: 2026 | dependencies: 2027 | whatwg-url: 7.1.0 2028 | 2029 | split@0.3.3: 2030 | dependencies: 2031 | through: 2.3.8 2032 | 2033 | stream-combiner@0.0.4: 2034 | dependencies: 2035 | duplexer: 0.1.2 2036 | 2037 | streamsearch@1.1.0: {} 2038 | 2039 | string-argv@0.3.2: {} 2040 | 2041 | string-width@4.2.3: 2042 | dependencies: 2043 | emoji-regex: 8.0.0 2044 | is-fullwidth-code-point: 3.0.0 2045 | strip-ansi: 6.0.1 2046 | 2047 | string-width@5.1.2: 2048 | dependencies: 2049 | eastasianwidth: 0.2.0 2050 | emoji-regex: 9.2.2 2051 | strip-ansi: 7.1.0 2052 | 2053 | strip-ansi@6.0.1: 2054 | dependencies: 2055 | ansi-regex: 5.0.1 2056 | 2057 | strip-ansi@7.1.0: 2058 | dependencies: 2059 | ansi-regex: 6.1.0 2060 | 2061 | styled-jsx@5.1.6(react@19.0.0): 2062 | dependencies: 2063 | client-only: 0.0.1 2064 | react: 19.0.0 2065 | 2066 | sucrase@3.35.0: 2067 | dependencies: 2068 | '@jridgewell/gen-mapping': 0.3.8 2069 | commander: 4.1.1 2070 | glob: 10.4.5 2071 | lines-and-columns: 1.2.4 2072 | mz: 2.7.0 2073 | pirates: 4.0.7 2074 | ts-interface-checker: 0.1.13 2075 | 2076 | thenify-all@1.6.0: 2077 | dependencies: 2078 | thenify: 3.3.1 2079 | 2080 | thenify@3.3.1: 2081 | dependencies: 2082 | any-promise: 1.3.0 2083 | 2084 | through@2.3.8: {} 2085 | 2086 | tinyexec@0.3.2: {} 2087 | 2088 | tinyglobby@0.2.14: 2089 | dependencies: 2090 | fdir: 6.4.5(picomatch@4.0.2) 2091 | picomatch: 4.0.2 2092 | 2093 | tr46@1.0.1: 2094 | dependencies: 2095 | punycode: 2.3.1 2096 | 2097 | tree-kill@1.2.2: {} 2098 | 2099 | ts-interface-checker@0.1.13: {} 2100 | 2101 | tsc-watch@7.1.1(typescript@5.8.3): 2102 | dependencies: 2103 | cross-spawn: 7.0.6 2104 | node-cleanup: 2.1.2 2105 | ps-tree: 1.2.0 2106 | string-argv: 0.3.2 2107 | typescript: 5.8.3 2108 | 2109 | tslib@2.8.1: {} 2110 | 2111 | tsup@8.5.0(postcss@8.4.31)(tsx@4.19.4)(typescript@5.8.3): 2112 | dependencies: 2113 | bundle-require: 5.1.0(esbuild@0.25.5) 2114 | cac: 6.7.14 2115 | chokidar: 4.0.3 2116 | consola: 3.4.2 2117 | debug: 4.4.1 2118 | esbuild: 0.25.5 2119 | fix-dts-default-cjs-exports: 1.0.1 2120 | joycon: 3.1.1 2121 | picocolors: 1.1.1 2122 | postcss-load-config: 6.0.1(postcss@8.4.31)(tsx@4.19.4) 2123 | resolve-from: 5.0.0 2124 | rollup: 4.41.1 2125 | source-map: 0.8.0-beta.0 2126 | sucrase: 3.35.0 2127 | tinyexec: 0.3.2 2128 | tinyglobby: 0.2.14 2129 | tree-kill: 1.2.2 2130 | optionalDependencies: 2131 | postcss: 8.4.31 2132 | typescript: 5.8.3 2133 | transitivePeerDependencies: 2134 | - jiti 2135 | - supports-color 2136 | - tsx 2137 | - yaml 2138 | 2139 | tsx@4.19.4: 2140 | dependencies: 2141 | esbuild: 0.25.5 2142 | get-tsconfig: 4.10.1 2143 | optionalDependencies: 2144 | fsevents: 2.3.3 2145 | 2146 | turbo-darwin-64@2.5.4: 2147 | optional: true 2148 | 2149 | turbo-darwin-arm64@2.5.4: 2150 | optional: true 2151 | 2152 | turbo-linux-64@2.5.4: 2153 | optional: true 2154 | 2155 | turbo-linux-arm64@2.5.4: 2156 | optional: true 2157 | 2158 | turbo-windows-64@2.5.4: 2159 | optional: true 2160 | 2161 | turbo-windows-arm64@2.5.4: 2162 | optional: true 2163 | 2164 | turbo@2.5.4: 2165 | optionalDependencies: 2166 | turbo-darwin-64: 2.5.4 2167 | turbo-darwin-arm64: 2.5.4 2168 | turbo-linux-64: 2.5.4 2169 | turbo-linux-arm64: 2.5.4 2170 | turbo-windows-64: 2.5.4 2171 | turbo-windows-arm64: 2.5.4 2172 | 2173 | typescript@5.8.3: {} 2174 | 2175 | ufo@1.6.1: {} 2176 | 2177 | uncrypto@0.1.3: {} 2178 | 2179 | undici-types@6.21.0: {} 2180 | 2181 | webidl-conversions@4.0.2: {} 2182 | 2183 | whatwg-url@7.1.0: 2184 | dependencies: 2185 | lodash.sortby: 4.7.0 2186 | tr46: 1.0.1 2187 | webidl-conversions: 4.0.2 2188 | 2189 | which@2.0.2: 2190 | dependencies: 2191 | isexe: 2.0.0 2192 | 2193 | wrap-ansi@7.0.0: 2194 | dependencies: 2195 | ansi-styles: 4.3.0 2196 | string-width: 4.2.3 2197 | strip-ansi: 6.0.1 2198 | 2199 | wrap-ansi@8.1.0: 2200 | dependencies: 2201 | ansi-styles: 6.2.1 2202 | string-width: 5.1.2 2203 | strip-ansi: 7.1.0 2204 | 2205 | zod@3.24.2: {} 2206 | -------------------------------------------------------------------------------- /src/hooks/accounts/use-list-accounts.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import { useContext } from "react" 3 | 4 | import { AuthQueryContext } from "../../lib/auth-query-provider" 5 | import type { AnyAuthClient } from "../../types/any-auth-client" 6 | import { useAuthQuery } from "../shared/use-auth-query" 7 | 8 | export function useListAccounts( 9 | authClient: TAuthClient, 10 | options?: Partial 11 | ) { 12 | const { listAccountsKey: queryKey } = useContext(AuthQueryContext) 13 | 14 | return useAuthQuery({ 15 | authClient, 16 | queryKey, 17 | queryFn: authClient.listAccounts, 18 | options 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /src/hooks/accounts/use-unlink-account.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AnyAuthClient } from "../../types/any-auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useUnlinkAccount( 7 | authClient: TAuthClient, 8 | options?: AuthQueryOptions 9 | ) { 10 | const { listAccountsKey: queryKey } = useContext(AuthQueryContext) 11 | 12 | return useAuthMutation({ 13 | queryKey, 14 | mutationFn: authClient.unlinkAccount, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/api-key/use-create-api-key.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AuthClient } from "../../types/auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useCreateApiKey( 7 | authClient: TAuthClient, 8 | options?: Partial 9 | ) { 10 | const { listApiKeysKey: queryKey } = useContext(AuthQueryContext) 11 | 12 | return useAuthMutation({ 13 | queryKey, 14 | mutationFn: authClient.apiKey.create, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/api-key/use-delete-api-key.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AuthClient } from "../../types/auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useDeleteApiKey( 7 | authClient: TAuthClient, 8 | options?: Partial 9 | ) { 10 | const { listApiKeysKey: queryKey } = useContext(AuthQueryContext) 11 | 12 | return useAuthMutation({ 13 | queryKey, 14 | mutationFn: authClient.apiKey.delete, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/api-key/use-list-api-keys.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import { useContext } from "react" 3 | 4 | import { AuthQueryContext } from "../../lib/auth-query-provider" 5 | 6 | import type { AuthClient } from "../../types/auth-client" 7 | import { useAuthQuery } from "../shared/use-auth-query" 8 | 9 | export function useListApiKeys( 10 | authClient: TAuthClient, 11 | options?: Partial 12 | ) { 13 | const { listApiKeysKey: queryKey } = useContext(AuthQueryContext) 14 | 15 | return useAuthQuery({ 16 | authClient, 17 | queryKey, 18 | queryFn: authClient.apiKey.list, 19 | options 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /src/hooks/device-sessions/use-list-device-sessions.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import { useContext } from "react" 3 | 4 | import { AuthQueryContext } from "../../lib/auth-query-provider" 5 | 6 | import type { AuthClient } from "../../types/auth-client" 7 | import { useAuthQuery } from "../shared/use-auth-query" 8 | 9 | export function useListDeviceSessions( 10 | authClient: TAuthClient, 11 | options?: Partial 12 | ) { 13 | const { listDeviceSessionsKey: queryKey } = useContext(AuthQueryContext) 14 | 15 | return useAuthQuery({ 16 | authClient, 17 | queryKey, 18 | queryFn: authClient.multiSession.listDeviceSessions, 19 | options 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /src/hooks/device-sessions/use-revoke-device-session.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AuthClient } from "../../types/auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useRevokeDeviceSession( 7 | authClient: TAuthClient, 8 | options?: Partial 9 | ) { 10 | const { listDeviceSessionsKey: queryKey } = useContext(AuthQueryContext) 11 | 12 | return useAuthMutation({ 13 | queryKey, 14 | mutationFn: authClient.multiSession.revoke, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/device-sessions/use-revoke-device-sessions.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AuthClient } from "../../types/auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useRevokeDeviceSessions( 7 | authClient: TAuthClient, 8 | options?: AuthQueryOptions 9 | ) { 10 | const { listDeviceSessionsKey: queryKey } = useContext(AuthQueryContext) 11 | 12 | return useAuthMutation({ 13 | queryKey, 14 | mutationFn: authClient.revokeSessions, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/device-sessions/use-set-active-session.ts: -------------------------------------------------------------------------------- 1 | import { useMutation } from "@tanstack/react-query" 2 | import { useQueryClient } from "@tanstack/react-query" 3 | import { useContext } from "react" 4 | 5 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 6 | 7 | import type { AuthClient } from "../../types/auth-client" 8 | import { useOnMutateError } from "../shared/use-mutate-error" 9 | 10 | export function useSetActiveSession( 11 | authClient: TAuthClient, 12 | options?: Partial 13 | ) { 14 | type SetActiveSessionParams = Parameters[0] 15 | 16 | const queryClient = useQueryClient() 17 | const { onMutateError } = useOnMutateError() 18 | const context = useContext(AuthQueryContext) 19 | const { listDeviceSessionsKey: queryKey } = { ...context, ...options } 20 | 21 | const mutation = useMutation({ 22 | mutationFn: ({ fetchOptions = { throw: true }, ...params }: SetActiveSessionParams) => 23 | authClient.multiSession.setActive({ fetchOptions, ...params }), 24 | onError: (error) => onMutateError(error, queryKey), 25 | onSettled: () => queryClient.clear() 26 | }) 27 | 28 | const { 29 | mutate: setActiveSession, 30 | mutateAsync: setActiveSessionAsync, 31 | isPending: setActiveSessionPending, 32 | error: setActiveSessionError 33 | } = mutation 34 | 35 | return { 36 | ...mutation, 37 | setActiveSession, 38 | setActiveSessionAsync, 39 | setActiveSessionPending, 40 | setActiveSessionError 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/hooks/organization/use-active-organization.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import type { AuthClient } from "../../types/auth-client" 3 | import { useAuthQuery } from "../shared/use-auth-query" 4 | 5 | export function useActiveOrganization( 6 | authClient: TAuthClient, 7 | options?: Partial 8 | ) { 9 | const queryKey = ["active-organization"] 10 | 11 | return useAuthQuery({ 12 | authClient, 13 | queryKey, 14 | queryFn: authClient.organization.getFullOrganization, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/organization/use-has-permission.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import type { AnyAuthClient } from "../../types/any-auth-client" 3 | import type { AuthClient } from "../../types/auth-client" 4 | import { useAuthQuery } from "../shared/use-auth-query" 5 | 6 | export function useHasPermission( 7 | authClient: TAuthClient, 8 | params: Parameters[0], 9 | options?: Partial 10 | ) { 11 | const queryKey = ["has-permission", JSON.stringify(params)] 12 | 13 | return useAuthQuery({ 14 | authClient, 15 | queryKey, 16 | queryFn: (fnParams) => 17 | (authClient as AuthClient).organization.hasPermission({ ...params, ...fnParams }), 18 | options 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /src/hooks/organization/use-invitation.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import type { AnyAuthClient } from "../../types/any-auth-client" 3 | import type { AuthClient } from "../../types/auth-client" 4 | import { useAuthQuery } from "../shared/use-auth-query" 5 | 6 | export function useInvitation( 7 | authClient: TAuthClient, 8 | params: Parameters[0], 9 | options?: Partial 10 | ) { 11 | const queryKey = ["invitation", JSON.stringify(params)] 12 | 13 | return useAuthQuery({ 14 | authClient, 15 | queryKey, 16 | queryFn: (fnParams) => 17 | (authClient as AuthClient).organization.getInvitation({ ...params, ...fnParams }), 18 | options 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /src/hooks/organization/use-list-organizations.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import type { AuthClient } from "../../types/auth-client" 3 | import { useAuthQuery } from "../shared/use-auth-query" 4 | 5 | export function useListOrganizations( 6 | authClient: TAuthClient, 7 | options?: Partial 8 | ) { 9 | const queryKey = ["organizations"] 10 | 11 | return useAuthQuery({ 12 | authClient, 13 | queryKey, 14 | queryFn: authClient.organization.list, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/passkey/use-delete-passkey.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AuthClient } from "../../types/auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useDeletePasskey( 7 | authClient: TAuthClient, 8 | options?: Partial 9 | ) { 10 | const { listPasskeysKey: queryKey } = useContext(AuthQueryContext) 11 | 12 | return useAuthMutation({ 13 | queryKey, 14 | mutationFn: authClient.passkey.deletePasskey, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/passkey/use-list-passkeys.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import { useContext } from "react" 3 | 4 | import { AuthQueryContext } from "../../lib/auth-query-provider" 5 | import type { AuthClient } from "../../types/auth-client" 6 | import { useAuthQuery } from "../shared/use-auth-query" 7 | 8 | export function useListPasskeys( 9 | authClient: TAuthClient, 10 | options?: Partial 11 | ) { 12 | const { listPasskeysKey: queryKey } = useContext(AuthQueryContext) 13 | 14 | return useAuthQuery({ 15 | authClient, 16 | queryKey, 17 | queryFn: authClient.passkey.listUserPasskeys, 18 | options 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /src/hooks/session/use-session.ts: -------------------------------------------------------------------------------- 1 | import { type AnyUseQueryOptions, useQuery } from "@tanstack/react-query" 2 | import { useContext } from "react" 3 | 4 | import { AuthQueryContext } from "../../lib/auth-query-provider" 5 | import type { AnyAuthClient } from "../../types/any-auth-client" 6 | import type { AuthClient } from "../../types/auth-client" 7 | 8 | export function useSession( 9 | authClient: TAuthClient, 10 | options?: Partial 11 | ) { 12 | type SessionData = TAuthClient["$Infer"]["Session"] 13 | type User = TAuthClient["$Infer"]["Session"]["user"] 14 | type Session = TAuthClient["$Infer"]["Session"]["session"] 15 | 16 | const { sessionQueryOptions, sessionKey: queryKey, queryOptions } = useContext(AuthQueryContext) 17 | const mergedOptions = { ...queryOptions, ...sessionQueryOptions, ...options } 18 | 19 | const result = useQuery({ 20 | queryKey, 21 | queryFn: () => (authClient as AuthClient).getSession({ fetchOptions: { throw: true } }), 22 | ...mergedOptions 23 | }) 24 | 25 | return { 26 | ...result, 27 | session: result.data?.session as Session | undefined, 28 | user: result.data?.user as User | undefined 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/hooks/session/use-update-user.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AnyAuthClient } from "../../types/any-auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useUpdateUser( 7 | authClient: TAuthClient, 8 | options?: Partial 9 | ) { 10 | type SessionData = TAuthClient["$Infer"]["Session"] 11 | 12 | const { sessionKey: queryKey } = useContext(AuthQueryContext) 13 | 14 | return useAuthMutation({ 15 | queryKey, 16 | mutationFn: authClient.updateUser, 17 | optimisticData: (params, previousSession: SessionData) => ({ 18 | ...previousSession, 19 | user: { ...previousSession.user, ...params } 20 | }), 21 | options 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /src/hooks/sessions/use-list-sessions.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import { useContext } from "react" 3 | 4 | import { AuthQueryContext } from "../../lib/auth-query-provider" 5 | import type { AnyAuthClient } from "../../types/any-auth-client" 6 | import { useAuthQuery } from "../shared/use-auth-query" 7 | 8 | export function useListSessions( 9 | authClient: TAuthClient, 10 | options?: Partial 11 | ) { 12 | const { listSessionsKey: queryKey } = useContext(AuthQueryContext) 13 | return useAuthQuery({ authClient, queryKey, queryFn: authClient.listSessions, options }) 14 | } 15 | -------------------------------------------------------------------------------- /src/hooks/sessions/use-revoke-other-sessions.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AnyAuthClient } from "../../types/any-auth-client" 4 | import { useSession } from "../session/use-session" 5 | import { useAuthMutation } from "../shared/use-auth-mutation" 6 | 7 | export function useRevokeOtherSessions( 8 | authClient: TAuthClient, 9 | options?: Partial 10 | ) { 11 | type Session = TAuthClient["$Infer"]["Session"]["session"] 12 | 13 | const { listSessionsKey: queryKey } = useContext(AuthQueryContext) 14 | const { data: sessionData } = useSession(authClient) 15 | 16 | return useAuthMutation({ 17 | queryKey, 18 | mutationFn: authClient.revokeOtherSessions, 19 | options 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /src/hooks/sessions/use-revoke-session.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AnyAuthClient } from "../../types/any-auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useRevokeSession( 7 | authClient: TAuthClient, 8 | options?: Partial 9 | ) { 10 | type Session = TAuthClient["$Infer"]["Session"]["session"] 11 | const { listSessionsKey: queryKey } = useContext(AuthQueryContext) 12 | 13 | return useAuthMutation({ 14 | queryKey, 15 | mutationFn: authClient.revokeSession, 16 | options 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /src/hooks/sessions/use-revoke-sessions.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react" 2 | import { AuthQueryContext, type AuthQueryOptions } from "../../lib/auth-query-provider" 3 | import type { AnyAuthClient } from "../../types/any-auth-client" 4 | import { useAuthMutation } from "../shared/use-auth-mutation" 5 | 6 | export function useRevokeSessions( 7 | authClient: TAuthClient, 8 | options?: Partial 9 | ) { 10 | const { listSessionsKey: queryKey } = useContext(AuthQueryContext) 11 | 12 | return useAuthMutation({ 13 | queryKey, 14 | mutationFn: authClient.revokeSessions, 15 | options 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/shared/use-auth-mutation.ts: -------------------------------------------------------------------------------- 1 | import { type QueryKey, useMutation, useQueryClient } from "@tanstack/react-query" 2 | import type { BetterFetchOption } from "better-auth/react" 3 | import { useContext } from "react" 4 | import type { AuthQueryOptions, NonThrowableResult, ThrowableResult } from "../.." 5 | import { AuthQueryContext } from "../../lib/auth-query-provider" 6 | import { useOnMutateError } from "./use-mutate-error" 7 | 8 | type AuthMutationFn = (params: TParams) => Promise 9 | 10 | export function useAuthMutation< 11 | // biome-ignore lint/suspicious/noExplicitAny: 12 | TAuthFn extends AuthMutationFn 13 | >({ 14 | queryKey, 15 | mutationFn, 16 | optimisticData, 17 | options 18 | }: { 19 | queryKey: QueryKey 20 | mutationFn: TAuthFn 21 | optimisticData?( 22 | params: Omit[0], "fetchOptions">, 23 | previousData: unknown 24 | ): unknown 25 | options?: Partial 26 | }) { 27 | type TParams = Parameters[0] 28 | const queryClient = useQueryClient() 29 | const context = useContext(AuthQueryContext) 30 | const { optimistic } = { ...context, ...options } 31 | const { onMutateError } = useOnMutateError() 32 | 33 | const mutation = useMutation({ 34 | mutationFn: ({ fetchOptions = { throw: true }, ...params }: TParams) => 35 | mutationFn({ fetchOptions, ...params }), 36 | onMutate: async (params: TParams) => { 37 | if (!optimistic || !optimisticData) return 38 | await queryClient.cancelQueries({ queryKey }) 39 | 40 | const previousData = queryClient.getQueryData(queryKey) 41 | if (!previousData) return 42 | 43 | queryClient.setQueryData(queryKey, () => optimisticData(params, previousData)) 44 | return { previousData } 45 | }, 46 | onError: (error, _, context) => onMutateError(error, queryKey, context), 47 | onSettled: () => queryClient.invalidateQueries({ queryKey }) 48 | }) 49 | 50 | const { mutate, isPending, error } = mutation 51 | 52 | async function mutateAsync( 53 | params: Omit & { fetchOptions?: { throw?: true } | undefined } 54 | ): Promise 55 | 56 | async function mutateAsync( 57 | params: Omit & { fetchOptions?: BetterFetchOption } 58 | ): Promise 59 | 60 | async function mutateAsync(params: TParams): Promise { 61 | return await mutation.mutateAsync(params) 62 | } 63 | 64 | return { 65 | ...mutation, 66 | mutate, 67 | mutateAsync, 68 | isPending, 69 | error 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/hooks/shared/use-auth-query.ts: -------------------------------------------------------------------------------- 1 | import { type QueryKey, skipToken } from "@tanstack/query-core" 2 | import { type AnyUseQueryOptions, useQuery } from "@tanstack/react-query" 3 | import type { BetterFetchOption, BetterFetchResponse } from "better-auth/react" 4 | import { useContext } from "react" 5 | 6 | import { AuthQueryContext } from "../../lib/auth-query-provider" 7 | import type { AnyAuthClient } from "../../types/any-auth-client" 8 | import { useSession } from "../session/use-session" 9 | 10 | export type BetterFetchRequest = ({ 11 | fetchOptions 12 | }: { fetchOptions: BetterFetchOption }) => Promise> 13 | 14 | type UseAuthQueryProps = { 15 | authClient: TAuthClient 16 | queryKey: QueryKey 17 | queryFn: BetterFetchRequest 18 | options?: Partial 19 | } 20 | 21 | export function useAuthQuery({ 22 | authClient, 23 | queryKey, 24 | queryFn, 25 | options 26 | }: UseAuthQueryProps) { 27 | const { data: sessionData } = useSession(authClient) 28 | const { queryOptions } = useContext(AuthQueryContext) 29 | const mergedOptions = { ...queryOptions, ...options } 30 | 31 | return useQuery({ 32 | queryKey, 33 | queryFn: sessionData ? () => queryFn({ fetchOptions: { throw: true } }) : skipToken, 34 | ...mergedOptions 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /src/hooks/shared/use-mutate-error.ts: -------------------------------------------------------------------------------- 1 | import { type Query, type QueryKey, useQueryClient } from "@tanstack/react-query" 2 | import { useContext } from "react" 3 | import { AuthQueryContext } from "../../lib/auth-query-provider" 4 | 5 | export const useOnMutateError = () => { 6 | const queryClient = useQueryClient() 7 | const { optimistic } = useContext(AuthQueryContext) 8 | 9 | const onMutateError = ( 10 | error: Error, 11 | queryKey: QueryKey, 12 | context?: { previousData?: unknown } 13 | ) => { 14 | if (error) { 15 | console.error(error) 16 | queryClient 17 | .getQueryCache() 18 | .config.onError?.(error, { queryKey } as unknown as Query) 19 | } 20 | 21 | if (!optimistic || !context?.previousData) return 22 | queryClient.setQueryData(queryKey, context.previousData) 23 | } 24 | 25 | return { onMutateError } 26 | } 27 | -------------------------------------------------------------------------------- /src/hooks/token/use-token.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions } from "@tanstack/react-query" 2 | import { useCallback, useContext, useEffect, useMemo } from "react" 3 | 4 | import { AuthQueryContext } from "../../lib/auth-query-provider" 5 | 6 | import type { AnyAuthClient } from "../../types/any-auth-client" 7 | import { useSession } from "../session/use-session" 8 | import { useAuthQuery } from "../shared/use-auth-query" 9 | 10 | export const decodeJwt = (token: string) => { 11 | const decode = (data: string) => { 12 | if (typeof Buffer === "undefined") { 13 | return atob(data) 14 | } 15 | 16 | return Buffer.from(data, "base64").toString() 17 | } 18 | const parts = token.split(".").map((part) => decode(part.replace(/-/g, "+").replace(/_/g, "/"))) 19 | 20 | return JSON.parse(parts[1]) 21 | } 22 | 23 | export function useToken( 24 | authClient: TAuthClient, 25 | options?: Partial 26 | ) { 27 | const { data: sessionData } = useSession(authClient, options) 28 | const { tokenKey, tokenQueryOptions, queryOptions } = useContext(AuthQueryContext) 29 | const mergedOptions = { ...queryOptions, ...tokenQueryOptions, ...options } 30 | 31 | const queryResult = useAuthQuery<{ token: string }>({ 32 | authClient, 33 | queryKey: tokenKey, 34 | queryFn: ({ fetchOptions }) => authClient.$fetch("/token", fetchOptions), 35 | options: { 36 | enabled: !!sessionData && (mergedOptions.enabled ?? true) 37 | } 38 | }) 39 | 40 | const { data, refetch, ...rest } = queryResult 41 | const payload = useMemo(() => (data ? decodeJwt(data.token) : null), [data]) 42 | 43 | useEffect(() => { 44 | if (!data?.token) return 45 | 46 | const payload = decodeJwt(data.token) 47 | if (!payload?.exp) return 48 | 49 | const expiresAt = payload.exp * 1000 50 | const expiresIn = expiresAt - Date.now() 51 | 52 | const timeout = setTimeout(() => refetch(), expiresIn) 53 | 54 | return () => clearTimeout(timeout) 55 | }, [data, refetch]) 56 | 57 | const isTokenExpired = useCallback(() => { 58 | if (!data?.token) return true 59 | 60 | const payload = decodeJwt(data.token) 61 | if (!payload?.exp) return true 62 | 63 | return payload.exp < Date.now() / 1000 64 | }, [data]) 65 | 66 | useEffect(() => { 67 | if (!sessionData) return 68 | 69 | if (payload?.sub !== sessionData.user.id) { 70 | refetch() 71 | } 72 | }, [payload, sessionData, refetch]) 73 | 74 | const tokenData = useMemo( 75 | () => 76 | !sessionData || isTokenExpired() || sessionData?.user.id !== payload?.sub 77 | ? undefined 78 | : data, 79 | [sessionData, isTokenExpired, payload, data] 80 | ) 81 | 82 | return { ...rest, data: tokenData, token: tokenData?.token, payload } 83 | } 84 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./lib/auth-query-provider" 2 | export * from "./lib/create-auth-hooks" 3 | export * from "./lib/create-auth-prefetches" 4 | export * from "./lib/prefetch-session" 5 | 6 | export type NonThrowableResult = { 7 | data: { 8 | status?: boolean 9 | success?: boolean 10 | [key: string]: unknown 11 | } | null 12 | error: { 13 | code?: string | undefined 14 | message?: string | undefined 15 | status: number 16 | statusText: string 17 | } | null 18 | } 19 | 20 | export type ThrowableResult = { status?: boolean; [key: string]: unknown } 21 | -------------------------------------------------------------------------------- /src/lib/auth-query-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import type { AnyUseQueryOptions, QueryKey } from "@tanstack/react-query" 4 | import { type ReactNode, createContext } from "react" 5 | 6 | export type AuthQueryOptions = { 7 | queryOptions?: Partial 8 | sessionQueryOptions?: Partial 9 | tokenQueryOptions?: Partial 10 | sessionKey: QueryKey 11 | tokenKey: QueryKey 12 | listAccountsKey: QueryKey 13 | listApiKeysKey: QueryKey 14 | listSessionsKey: QueryKey 15 | listDeviceSessionsKey: QueryKey 16 | listPasskeysKey: QueryKey 17 | optimistic: boolean 18 | refetchOnMutate: boolean 19 | } 20 | 21 | export const defaultAuthQueryOptions: AuthQueryOptions = { 22 | sessionKey: ["session"], 23 | tokenKey: ["token"], 24 | listAccountsKey: ["list-accounts"], 25 | listApiKeysKey: ["list-api-keys"], 26 | listSessionsKey: ["list-sessions"], 27 | listDeviceSessionsKey: ["list-device-sessions"], 28 | listPasskeysKey: ["list-passkeys"], 29 | optimistic: true, 30 | refetchOnMutate: true 31 | } 32 | 33 | export const AuthQueryContext = createContext(defaultAuthQueryOptions) 34 | 35 | export const AuthQueryProvider = ({ 36 | children, 37 | sessionQueryOptions, 38 | tokenQueryOptions, 39 | ...props 40 | }: { 41 | children: ReactNode 42 | } & Partial) => { 43 | return ( 44 | 58 | {children} 59 | 60 | ) 61 | } 62 | -------------------------------------------------------------------------------- /src/lib/create-auth-hooks.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions, QueryKey } from "@tanstack/react-query" 2 | import { useQueryClient } from "@tanstack/react-query" 3 | import { useContext } from "react" 4 | 5 | import { useListAccounts } from "../hooks/accounts/use-list-accounts" 6 | import { useUnlinkAccount } from "../hooks/accounts/use-unlink-account" 7 | import { useCreateApiKey } from "../hooks/api-key/use-create-api-key" 8 | import { useDeleteApiKey } from "../hooks/api-key/use-delete-api-key" 9 | import { useListApiKeys } from "../hooks/api-key/use-list-api-keys" 10 | import { useListDeviceSessions } from "../hooks/device-sessions/use-list-device-sessions" 11 | import { useRevokeDeviceSession } from "../hooks/device-sessions/use-revoke-device-session" 12 | import { useSetActiveSession } from "../hooks/device-sessions/use-set-active-session" 13 | import { useActiveOrganization } from "../hooks/organization/use-active-organization" 14 | import { useHasPermission } from "../hooks/organization/use-has-permission" 15 | import { useInvitation } from "../hooks/organization/use-invitation" 16 | import { useListOrganizations } from "../hooks/organization/use-list-organizations" 17 | import { useDeletePasskey } from "../hooks/passkey/use-delete-passkey" 18 | import { useListPasskeys } from "../hooks/passkey/use-list-passkeys" 19 | import { useSession } from "../hooks/session/use-session" 20 | import { useUpdateUser } from "../hooks/session/use-update-user" 21 | import { useListSessions } from "../hooks/sessions/use-list-sessions" 22 | import { useRevokeOtherSessions } from "../hooks/sessions/use-revoke-other-sessions" 23 | import { useRevokeSession } from "../hooks/sessions/use-revoke-session" 24 | import { useRevokeSessions } from "../hooks/sessions/use-revoke-sessions" 25 | import { useAuthMutation } from "../hooks/shared/use-auth-mutation" 26 | import { type BetterFetchRequest, useAuthQuery } from "../hooks/shared/use-auth-query" 27 | import { useToken } from "../hooks/token/use-token" 28 | import type { AnyAuthClient } from "../types/any-auth-client" 29 | import type { AuthClient } from "../types/auth-client" 30 | import { AuthQueryContext, type AuthQueryOptions } from "./auth-query-provider" 31 | import { prefetchSession } from "./prefetch-session" 32 | 33 | export function createAuthHooks(authClient: TAuthClient) { 34 | return { 35 | useSession: (options?: Partial) => useSession(authClient, options), 36 | usePrefetchSession: (options?: Partial) => { 37 | const queryClient = useQueryClient() 38 | const queryOptions = useContext(AuthQueryContext) 39 | 40 | return { 41 | prefetch: () => prefetchSession(authClient, queryClient, queryOptions, options) 42 | } 43 | }, 44 | useUpdateUser: (options?: Partial) => useUpdateUser(authClient, options), 45 | useToken: (options?: Partial) => useToken(authClient, options), 46 | useAuthQuery: ({ 47 | queryKey, 48 | queryFn, 49 | options 50 | }: { 51 | queryKey: QueryKey 52 | queryFn: BetterFetchRequest 53 | options?: Partial 54 | }) => useAuthQuery({ authClient, queryKey, queryFn, options }), 55 | useListAccounts: (options?: Partial) => 56 | useListAccounts(authClient, options), 57 | useUnlinkAccount: () => useUnlinkAccount(authClient), 58 | useListSessions: (options?: Partial) => 59 | useListSessions(authClient, options), 60 | useRevokeSession: (options?: Partial) => 61 | useRevokeSession(authClient, options), 62 | useRevokeSessions: (options?: Partial) => 63 | useRevokeSessions(authClient, options), 64 | useRevokeOtherSessions: (options?: Partial) => 65 | useRevokeOtherSessions(authClient, options), 66 | useListDeviceSessions: (options?: Partial) => 67 | useListDeviceSessions(authClient as AuthClient, options), 68 | useRevokeDeviceSession: (options?: Partial) => 69 | useRevokeDeviceSession(authClient as AuthClient, options), 70 | useSetActiveSession: (options?: Partial) => 71 | useSetActiveSession(authClient as AuthClient, options), 72 | useListPasskeys: (options?: Partial) => 73 | useListPasskeys(authClient as AuthClient, options), 74 | useDeletePasskey: (options?: Partial) => 75 | useDeletePasskey(authClient as AuthClient, options), 76 | useListApiKeys: (options?: Partial) => 77 | useListApiKeys(authClient as AuthClient, options), 78 | useCreateApiKey: (options?: Partial) => 79 | useCreateApiKey(authClient as AuthClient, options), 80 | useDeleteApiKey: (options?: Partial) => 81 | useDeleteApiKey(authClient as AuthClient, options), 82 | useActiveOrganization: (options?: Partial) => 83 | useActiveOrganization(authClient as AuthClient, options), 84 | useListOrganizations: (options?: Partial) => 85 | useListOrganizations(authClient as AuthClient, options), 86 | useHasPermission: ( 87 | params: Parameters[0], 88 | options?: Partial 89 | ) => useHasPermission(authClient as AuthClient, params, options), 90 | useInvitation: ( 91 | params: Parameters[0], 92 | options?: Partial 93 | ) => useInvitation(authClient as AuthClient, params, options), 94 | useAuthMutation: useAuthMutation 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/lib/create-auth-prefetches.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions, QueryClient } from "@tanstack/react-query" 2 | 3 | import type { AnyAuthClient } from "../types/any-auth-client" 4 | import { type AuthQueryOptions, defaultAuthQueryOptions } from "./auth-query-provider" 5 | import { prefetchSession } from "./prefetch-session" 6 | 7 | export function createAuthPrefetches( 8 | authClient: TAuthClient, 9 | queryOptions?: AuthQueryOptions 10 | ) { 11 | return { 12 | prefetchSession: (queryClient: QueryClient, options?: Partial) => { 13 | return prefetchSession( 14 | authClient, 15 | queryClient, 16 | { ...defaultAuthQueryOptions, ...queryOptions }, 17 | options 18 | ) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/lib/prefetch-session-server.ts: -------------------------------------------------------------------------------- 1 | import type { QueryClient } from "@tanstack/react-query" 2 | import { cache } from "react" 3 | import type { BetterAuth } from "../types/better-auth" 4 | 5 | type GetSessionParams = Parameters[0] 6 | 7 | const getSession = cache( 8 | async (auth: TAuth, params: GetSessionParams) => { 9 | type SessionData = TAuth["$Infer"]["Session"] | null 10 | 11 | return (await auth.api.getSession(params)) as SessionData 12 | } 13 | ) 14 | 15 | export async function prefetchSession( 16 | auth: TAuth, 17 | queryClient: QueryClient, 18 | params: GetSessionParams, 19 | queryKey = ["session"] 20 | ) { 21 | type SessionData = TAuth["$Infer"]["Session"] | null 22 | type User = TAuth["$Infer"]["Session"]["user"] 23 | type Session = TAuth["$Infer"]["Session"]["session"] 24 | 25 | const queryFn = async () => (await getSession(auth, params)) as SessionData 26 | 27 | await queryClient.prefetchQuery({ queryKey, queryFn }) 28 | 29 | const data = await queryFn() 30 | 31 | return { 32 | data, 33 | session: data?.session as Session | undefined, 34 | user: data?.user as User | undefined 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/lib/prefetch-session.ts: -------------------------------------------------------------------------------- 1 | import type { AnyUseQueryOptions, QueryClient } from "@tanstack/react-query" 2 | 3 | import type { AnyAuthClient } from "../types/any-auth-client" 4 | import type { AuthClient } from "../types/auth-client" 5 | import type { AuthQueryOptions } from "./auth-query-provider" 6 | 7 | export async function prefetchSession( 8 | authClient: TAuthClient, 9 | queryClient: QueryClient, 10 | queryOptions?: AuthQueryOptions, 11 | options?: Partial 12 | ) { 13 | const { error, data } = await (authClient as AuthClient).getSession() 14 | 15 | const mergedOptions = { 16 | ...queryOptions?.queryOptions, 17 | ...queryOptions?.sessionQueryOptions, 18 | ...options 19 | } 20 | 21 | await queryClient.prefetchQuery({ 22 | ...mergedOptions, 23 | queryKey: queryOptions?.sessionKey, 24 | queryFn: () => data as SessionData 25 | }) 26 | 27 | type SessionData = TAuthClient["$Infer"]["Session"] 28 | type User = TAuthClient["$Infer"]["Session"]["user"] 29 | type Session = TAuthClient["$Infer"]["Session"]["session"] 30 | 31 | return { 32 | error, 33 | data: data, 34 | session: data?.session as Session | undefined, 35 | user: data?.user as User | undefined 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/server.ts: -------------------------------------------------------------------------------- 1 | export * from "./lib/prefetch-session-server" 2 | -------------------------------------------------------------------------------- /src/types/any-auth-client.ts: -------------------------------------------------------------------------------- 1 | import type { createAuthClient } from "better-auth/react" 2 | 3 | export type AnyAuthClient = Omit, "signUp" | "getSession"> 4 | -------------------------------------------------------------------------------- /src/types/auth-client.ts: -------------------------------------------------------------------------------- 1 | import { 2 | anonymousClient, 3 | apiKeyClient, 4 | emailOTPClient, 5 | genericOAuthClient, 6 | magicLinkClient, 7 | multiSessionClient, 8 | oneTapClient, 9 | organizationClient, 10 | passkeyClient, 11 | twoFactorClient, 12 | usernameClient 13 | } from "better-auth/client/plugins" 14 | import { createAuthClient } from "better-auth/react" 15 | 16 | const authClient = createAuthClient({ 17 | plugins: [ 18 | apiKeyClient(), 19 | multiSessionClient(), 20 | passkeyClient(), 21 | oneTapClient({ 22 | clientId: "" 23 | }), 24 | genericOAuthClient(), 25 | anonymousClient(), 26 | usernameClient(), 27 | magicLinkClient(), 28 | emailOTPClient(), 29 | twoFactorClient(), 30 | organizationClient() 31 | ] 32 | }) 33 | 34 | export type AuthClient = typeof authClient 35 | 36 | export type Session = AuthClient["$Infer"]["Session"]["session"] 37 | export type User = AuthClient["$Infer"]["Session"]["user"] 38 | -------------------------------------------------------------------------------- /src/types/better-auth.ts: -------------------------------------------------------------------------------- 1 | import type { betterAuth } from "better-auth" 2 | 3 | export type BetterAuth = ReturnType 4 | -------------------------------------------------------------------------------- /src/types/list-account.ts: -------------------------------------------------------------------------------- 1 | export type ListAccount = { 2 | id: string 3 | provider: string 4 | createdAt: Date 5 | updatedAt: Date 6 | accountId: string 7 | scopes: string[] 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react-jsx", 4 | "declaration": true, 5 | "outDir": "dist", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "resolveJsonModule": true, 10 | "allowJs": true, 11 | "incremental": false, 12 | "lib": ["dom", "dom.iterable", "esnext"], 13 | "module": "esnext", 14 | "moduleResolution": "node" 15 | }, 16 | "include": ["src"] 17 | } 18 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup" 2 | 3 | export default defineConfig((env) => { 4 | return { 5 | entry: { 6 | index: "./src/index.ts", 7 | server: "./src/server.ts" 8 | }, 9 | format: ["esm", "cjs"], 10 | splitting: true, 11 | cjsInterop: true, 12 | skipNodeModulesBundle: true, 13 | treeshake: true 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "tasks": { 4 | "build": { 5 | "dependsOn": ["^build"], 6 | "outputs": ["dist/**"] 7 | }, 8 | "dev": { 9 | "persistent": true, 10 | "cache": false 11 | } 12 | } 13 | } 14 | --------------------------------------------------------------------------------