{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "auth-provider",
  "title": "Auth Provider",
  "description": "Wraps the Better Auth UI provider and mounts an ErrorToaster that surfaces query and mutation failures via sonner.",
  "dependencies": [
    "@better-auth-ui/react@latest",
    "@better-auth-ui/core@latest",
    "@tanstack/react-query",
    "better-auth"
  ],
  "registryDependencies": [
    "sonner"
  ],
  "files": [
    {
      "path": "src/components/auth/auth-provider.tsx",
      "content": "import {\n  AuthProvider as AuthProviderPrimitive,\n  type AuthProviderProps\n} from \"@better-auth-ui/react\"\nimport type {\n  ComponentPropsWithoutRef,\n  ComponentType,\n  PropsWithChildren,\n  ReactNode\n} from \"react\"\n\nimport { ErrorToaster } from \"./error-toaster\"\n\ndeclare module \"@better-auth-ui/core\" {\n  interface AuthConfig {\n    /**\n     * React component used to render internal navigation links.\n     * Typically TanStack Router's `Link` or Next.js's `Link`.\n     */\n    Link: ComponentType<\n      PropsWithChildren<\n        { className?: string; href: string; to?: string } & Pick<\n          ComponentPropsWithoutRef<\"a\">,\n          \"aria-disabled\" | \"tabIndex\" | \"onClick\"\n        >\n      >\n    >\n  }\n\n  /** Widen `AdditionalField.label` to `ReactNode` in the shadcn package. */\n  interface AdditionalFieldRegister {\n    label: ReactNode\n  }\n}\n\n/**\n * Provides an authentication context by rendering an auth provider with the sonner toast handler injected, forwarding remaining configuration and rendering `children` inside it.\n *\n * @param children - React nodes to render inside the authentication provider\n * @returns A React element that renders an authentication provider configured with the provided props and toast handler\n */\nexport function AuthProvider({ children, ...config }: AuthProviderProps) {\n  return (\n    <AuthProviderPrimitive {...config}>\n      {children}\n\n      <ErrorToaster />\n    </AuthProviderPrimitive>\n  )\n}\n",
      "type": "registry:component",
      "target": "@components/auth/auth-provider.tsx"
    },
    {
      "path": "src/components/auth/error-toaster.tsx",
      "content": "import { authMutationKeys, authQueryKeys } from \"@better-auth-ui/core\"\nimport { oneTapMutationKeys } from \"@better-auth-ui/core/plugins\"\nimport {\n  matchMutation,\n  matchQuery,\n  useQueryClient\n} from \"@tanstack/react-query\"\nimport type { BetterFetchError } from \"better-auth/react\"\nimport { useEffect } from \"react\"\nimport { toast } from \"sonner\"\n\nexport function ErrorToaster() {\n  const queryClient = useQueryClient()\n\n  useEffect(() => {\n    const queryCache = queryClient.getQueryCache()\n    const previousQueryOnError = queryCache.config.onError\n\n    queryCache.config.onError = (error, query) => {\n      previousQueryOnError?.(error, query)\n\n      if (!matchQuery({ queryKey: authQueryKeys.all }, query)) return\n\n      const err = error as BetterFetchError\n      if (err?.error?.code === \"EMAIL_NOT_VERIFIED\") return\n      if (err?.error) toast.error(err.error.message)\n    }\n\n    const mutationCache = queryClient.getMutationCache()\n    const previousMutationOnError = mutationCache.config.onError\n\n    mutationCache.config.onError = (\n      error,\n      variables,\n      onMutateResult,\n      mutation,\n      context\n    ) => {\n      previousMutationOnError?.(\n        error,\n        variables,\n        onMutateResult,\n        mutation,\n        context\n      )\n\n      if (!matchMutation({ mutationKey: authMutationKeys.all }, mutation)) {\n        return\n      }\n\n      const err = error as BetterFetchError\n      if (\n        err.error?.code === \"EMAIL_NOT_VERIFIED\" &&\n        !matchMutation({ mutationKey: oneTapMutationKeys.prompt }, mutation)\n      ) {\n        return\n      }\n      toast.error(err.error?.message || err.message)\n    }\n\n    return () => {\n      queryCache.config.onError = previousQueryOnError\n      mutationCache.config.onError = previousMutationOnError\n    }\n  }, [queryClient])\n\n  return null\n}\n",
      "type": "registry:component",
      "target": "@components/auth/error-toaster.tsx"
    }
  ],
  "type": "registry:component"
}