From f80a5387b197e86a87c4714331fced3fc3c476dc Mon Sep 17 00:00:00 2001 From: cd996 Date: Fri, 29 May 2026 10:15:56 +0000 Subject: [PATCH] feat(flox): add better-auth (email/password + Google), replace PasswordGate Integrate better-auth backed by a Cloudflare D1 + Drizzle adapter. The auth instance is built per-request so it can read the D1 binding via next-on-pages getRequestContext on the Edge runtime; local dev falls back to a libsql file through a DB_TYPE switch. Email/password is enabled and Google is wired conditionally from env. A client AuthGate (useSession) replaces the old client-side PasswordGate. Also removes the obsolete PasswordGate, unlock store and PasswordSettings, and drops the password branch from the /api/config route. --- apps/flox/cloudflare-env.d.ts | 23 + apps/flox/drizzle.config.ts | 45 ++ apps/flox/package.json | 11 +- apps/flox/src/app/api/auth/[...all]/route.ts | 13 + apps/flox/src/app/api/config/route.ts | 24 -- apps/flox/src/app/layout.tsx | 6 +- .../src/app/settings/hooks/useSettingsPage.ts | 11 +- apps/flox/src/components/AuthGate.tsx | 163 +++++++ apps/flox/src/components/PasswordGate.tsx | 235 ----------- .../components/settings/PasswordSettings.tsx | 40 -- .../settings/SettingsPageContent.tsx | 5 - .../src/database/0000_military_eternity.sql | 53 +++ .../flox/src/database/meta/0000_snapshot.json | 370 ++++++++++++++++ apps/flox/src/database/meta/_journal.json | 13 + apps/flox/src/database/schema.ts | 96 +++++ apps/flox/src/lib/auth-client.ts | 8 + apps/flox/src/lib/auth.ts | 36 ++ apps/flox/src/lib/db.ts | 46 ++ apps/flox/src/lib/store/init.ts | 1 - apps/flox/src/lib/store/unlock-store.ts | 43 -- apps/flox/wrangler.jsonc | 24 ++ pnpm-lock.yaml | 398 +++++++++++++++--- pnpm-workspace.yaml | 1 + 23 files changed, 1246 insertions(+), 419 deletions(-) create mode 100644 apps/flox/cloudflare-env.d.ts create mode 100644 apps/flox/drizzle.config.ts create mode 100644 apps/flox/src/app/api/auth/[...all]/route.ts create mode 100644 apps/flox/src/components/AuthGate.tsx delete mode 100644 apps/flox/src/components/PasswordGate.tsx delete mode 100644 apps/flox/src/components/settings/PasswordSettings.tsx create mode 100644 apps/flox/src/database/0000_military_eternity.sql create mode 100644 apps/flox/src/database/meta/0000_snapshot.json create mode 100644 apps/flox/src/database/meta/_journal.json create mode 100644 apps/flox/src/database/schema.ts create mode 100644 apps/flox/src/lib/auth-client.ts create mode 100644 apps/flox/src/lib/auth.ts create mode 100644 apps/flox/src/lib/db.ts delete mode 100644 apps/flox/src/lib/store/unlock-store.ts create mode 100644 apps/flox/wrangler.jsonc diff --git a/apps/flox/cloudflare-env.d.ts b/apps/flox/cloudflare-env.d.ts new file mode 100644 index 00000000..5d364fd3 --- /dev/null +++ b/apps/flox/cloudflare-env.d.ts @@ -0,0 +1,23 @@ +/// + +// Bindings/vars available through `getRequestContext().env` on next-on-pages. +interface CloudflareEnv { + DB: D1Database + DB_TYPE?: string + BETTER_AUTH_SECRET?: string + BETTER_AUTH_URL?: string + GOOGLE_CLIENT_ID?: string + GOOGLE_CLIENT_SECRET?: string + LIBSQL_URL?: string + LIBSQL_AUTH_TOKEN?: string +} + +// @cloudflare/next-on-pages ships no types for its root export, so declare the +// only symbol we use here. +declare module '@cloudflare/next-on-pages' { + export function getRequestContext(): { + env: CloudflareEnv + cf: IncomingRequestCfProperties + ctx: ExecutionContext + } +} diff --git a/apps/flox/drizzle.config.ts b/apps/flox/drizzle.config.ts new file mode 100644 index 00000000..6a003d42 --- /dev/null +++ b/apps/flox/drizzle.config.ts @@ -0,0 +1,45 @@ +import type { Config } from 'drizzle-kit' +import { defineConfig } from 'drizzle-kit' + +const { + DB_TYPE = 'libsql', + CLOUDFLARE_ACCOUNT_ID = '', + CLOUDFLARE_DATABASE_ID = '', + CLOUDFLARE_API_TOKEN = '', + LIBSQL_URL = 'file:./src/database/data.db', + LIBSQL_AUTH_TOKEN = undefined, +} = process.env + +const configFactory = { + base: { + schema: './src/database/schema.ts', + out: './src/database', + } as const, + + libsql: () => + ({ + ...configFactory.base, + dialect: 'turso', + dbCredentials: { + url: LIBSQL_URL, + authToken: LIBSQL_AUTH_TOKEN, + }, + }) as const satisfies Config, + + d1: () => + ({ + ...configFactory.base, + dialect: 'sqlite', + driver: 'd1-http', + dbCredentials: { + accountId: CLOUDFLARE_ACCOUNT_ID, + databaseId: CLOUDFLARE_DATABASE_ID, + token: CLOUDFLARE_API_TOKEN, + }, + }) as const satisfies Config, +} as const + +const config = + DB_TYPE === 'libsql' ? configFactory.libsql() : configFactory.d1() + +export default defineConfig(config) diff --git a/apps/flox/package.json b/apps/flox/package.json index 259ed1a3..b71df91e 100644 --- a/apps/flox/package.json +++ b/apps/flox/package.json @@ -18,7 +18,11 @@ "start": "next start", "lint": "next lint", "lint:fix": "next lint --fix", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "db:gen": "drizzle-kit generate", + "db:migrate": "drizzle-kit migrate", + "cf:localdb": "wrangler d1 migrations apply flox", + "cf:remotedb": "wrangler d1 migrations apply flox --remote" }, "dependencies": { "@cdlab996/genid": "catalog:prod", @@ -27,8 +31,11 @@ "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", + "@libsql/client": "catalog:prod", "@tanstack/react-form": "catalog:prod", "@tanstack/react-query": "catalog:prod", + "better-auth": "catalog:prod", + "drizzle-orm": "catalog:prod", "hls.js": "catalog:prod", "date-fns": "catalog:prod", "lucide-react": "catalog:prod", @@ -43,7 +50,9 @@ "devDependencies": { "@cdlab996/tsconfig": "workspace:*", "@cloudflare/next-on-pages": "catalog:dev", + "@cloudflare/workers-types": "catalog:dev", "@types/node": "catalog:dev", + "drizzle-kit": "catalog:dev", "@types/react": "catalog:dev", "@types/react-dom": "catalog:dev", "typescript": "catalog:dev" diff --git a/apps/flox/src/app/api/auth/[...all]/route.ts b/apps/flox/src/app/api/auth/[...all]/route.ts new file mode 100644 index 00000000..979655bb --- /dev/null +++ b/apps/flox/src/app/api/auth/[...all]/route.ts @@ -0,0 +1,13 @@ +import { getAuth } from '@/lib/auth' + +export const runtime = 'edge' + +export async function GET(req: Request) { + const auth = await getAuth() + return auth.handler(req) +} + +export async function POST(req: Request) { + const auth = await getAuth() + return auth.handler(req) +} diff --git a/apps/flox/src/app/api/config/route.ts b/apps/flox/src/app/api/config/route.ts index 2fdbb503..878cd591 100644 --- a/apps/flox/src/app/api/config/route.ts +++ b/apps/flox/src/app/api/config/route.ts @@ -3,14 +3,10 @@ * Exposes configuration status (never actual values) to the client */ -import { verifyPasswordFn } from '@cdlab996/utils' -import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' export const runtime = 'edge' -const ACCESS_PASSWORD = process.env.ACCESS_PASSWORD || '' -const PERSIST_PASSWORD = process.env.PERSIST_PASSWORD !== 'false' const SUBSCRIPTION_SOURCES = process.env.SUBSCRIPTION_SOURCES || process.env.NEXT_PUBLIC_SUBSCRIPTION_SOURCES || @@ -18,26 +14,6 @@ const SUBSCRIPTION_SOURCES = export async function GET() { return NextResponse.json({ - hasEnvPassword: ACCESS_PASSWORD.length > 0, - persistPassword: PERSIST_PASSWORD, subscriptionSources: SUBSCRIPTION_SOURCES, }) } - -export async function POST(request: NextRequest) { - try { - const { hash } = await request.json() - - if (!ACCESS_PASSWORD) { - return NextResponse.json({ valid: false, message: 'No env password set' }) - } - - const valid = await verifyPasswordFn(hash, ACCESS_PASSWORD) - return NextResponse.json({ valid }) - } catch { - return NextResponse.json( - { valid: false, message: 'Invalid request' }, - { status: 400 }, - ) - } -} diff --git a/apps/flox/src/app/layout.tsx b/apps/flox/src/app/layout.tsx index 0a8af7e9..45b30457 100644 --- a/apps/flox/src/app/layout.tsx +++ b/apps/flox/src/app/layout.tsx @@ -10,10 +10,10 @@ import { Suspense } from 'react' import '@cdlab996/ui/globals.css' import { AdKeywordsInjector } from '@/components/AdKeywordsInjector' +import { AuthGate } from '@/components/AuthGate' import { FavoritesSidebar } from '@/components/favorites/FavoritesSidebar' import { WatchHistorySidebar } from '@/components/history/WatchHistorySidebar' import { ClientProviders, Header } from '@/components/layout' -import { PasswordGate } from '@/components/PasswordGate' import { ScrollPositionManager } from '@/components/ScrollPositionManager' import { ServiceWorkerRegister } from '@/components/ServiceWorkerRegister' import { BackToTop } from '@/components/ui/BackToTop' @@ -242,7 +242,7 @@ export default function RootLayout({ suppressHydrationWarning > - +
{children} @@ -254,7 +254,7 @@ export default function RootLayout({ - + diff --git a/apps/flox/src/app/settings/hooks/useSettingsPage.ts b/apps/flox/src/app/settings/hooks/useSettingsPage.ts index f725a5bc..517545f8 100644 --- a/apps/flox/src/app/settings/hooks/useSettingsPage.ts +++ b/apps/flox/src/app/settings/hooks/useSettingsPage.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { useState } from 'react' import { toast } from 'sonner' import { useSourceSettings } from '@/lib/hooks/useSourceSettings' import { clearAppCaches, resetAllStores } from '@/lib/store/registry' @@ -67,14 +67,6 @@ export function useSettingsPage({ const [isExportModalOpen, setIsExportModalOpen] = useState(false) const [isImportModalOpen, setIsImportModalOpen] = useState(false) const [isResetDialogOpen, setIsResetDialogOpen] = useState(false) - const [envPasswordSet, setEnvPasswordSet] = useState(false) - - useEffect(() => { - fetch('/api/config') - .then((res) => res.json()) - .then((data) => setEnvPasswordSet(data.hasEnvPassword)) - .catch(() => setEnvPasswordSet(false)) - }, []) const handleExport = ( includeSearchHistory: boolean, @@ -166,7 +158,6 @@ export function useSettingsPage({ sources, subscriptions, sortBy, - envPasswordSet, realtimeLatency, searchDisplayMode, fullscreenType, diff --git a/apps/flox/src/components/AuthGate.tsx b/apps/flox/src/components/AuthGate.tsx new file mode 100644 index 00000000..4649e6da --- /dev/null +++ b/apps/flox/src/components/AuthGate.tsx @@ -0,0 +1,163 @@ +'use client' + +import { Button } from '@cdlab996/ui/components/button' +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from '@cdlab996/ui/components/card' +import { Input } from '@cdlab996/ui/components/input' +import { Label } from '@cdlab996/ui/components/label' +import type React from 'react' +import { useState } from 'react' +import { authClient } from '@/lib/auth-client' + +const GOOGLE_ENABLED = process.env.NEXT_PUBLIC_GOOGLE_ENABLED === 'true' + +function LoginScreen() { + const [mode, setMode] = useState<'signIn' | 'signUp'>('signIn') + const [name, setName] = useState('') + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [error, setError] = useState(null) + const [loading, setLoading] = useState(false) + + async function submit() { + setError(null) + setLoading(true) + try { + const res = + mode === 'signIn' + ? await authClient.signIn.email({ email, password }) + : await authClient.signUp.email({ name, email, password }) + if (res.error) { + setError(res.error.message || '操作失败,请重试') + } + // On success the session cookie is set; useSession() refetches and the + // gate swaps to the app automatically. + } catch { + setError('网络错误,请稍后再试') + } finally { + setLoading(false) + } + } + + async function google() { + setError(null) + setLoading(true) + try { + await authClient.signIn.social({ provider: 'google', callbackURL: '/' }) + } catch { + setError('无法跳转 Google 登录') + setLoading(false) + } + } + + return ( +
+ + + {mode === 'signIn' ? '登录 flox' : '注册 flox'} + + {mode === 'signIn' + ? '使用邮箱密码登录以继续' + : '创建账号以继续使用'} + + + +
{ + e.preventDefault() + void submit() + }} + > + {mode === 'signUp' && ( +
+ + setName(e.target.value)} + required + /> +
+ )} +
+ + setEmail(e.target.value)} + required + /> +
+
+ + setPassword(e.target.value)} + required + minLength={8} + /> +
+ + {error &&

{error}

} + + +
+ + {GOOGLE_ENABLED && ( + + )} + + +
+
+
+ ) +} + +export function AuthGate({ children }: { children: React.ReactNode }) { + const { data: session, isPending } = authClient.useSession() + + if (isPending) { + return ( +
+ 加载中… +
+ ) + } + + if (!session) return + + return <>{children} +} diff --git a/apps/flox/src/components/PasswordGate.tsx b/apps/flox/src/components/PasswordGate.tsx deleted file mode 100644 index 5fc28323..00000000 --- a/apps/flox/src/components/PasswordGate.tsx +++ /dev/null @@ -1,235 +0,0 @@ -'use client' - -import { Button } from '@cdlab996/ui/components/button' -import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from '@cdlab996/ui/components/card' -import { - Field, - FieldDescription, - FieldGroup, -} from '@cdlab996/ui/components/field' -import { PasswordInput } from '@cdlab996/ui/components/password-input' -import { Spinner } from '@cdlab996/ui/components/spinner' -import { hashPasswordFn } from '@cdlab996/utils' -import { useForm } from '@tanstack/react-form' -import { useMutation, useQuery } from '@tanstack/react-query' -import { useEffect, useRef, useState } from 'react' -import * as z from 'zod' -import { useSubscriptionSync } from '@/lib/hooks/useSubscriptionSync' -import { useSettingsStore } from '@/lib/store/settings-store' -import { useUnlockStore } from '@/lib/store/unlock-store' - -const passwordSchema = z.object({ - password: z.string().min(1, '请输入密码'), -}) - -type PasswordForm = z.infer - -type UnlockResult = { valid: true; token: string } | { valid: false } - -interface AppConfig { - hasEnvPassword: boolean - persistPassword: boolean - subscriptionSources?: string[] -} - -async function fetchConfig(): Promise { - const res = await fetch('/api/config') - if (!res.ok) throw new Error('Failed to fetch config') - return res.json() -} - -function LoadingScreen() { - return ( -
-
- -

加载中...

-
-
- ) -} - -export function PasswordGate({ - children, - hasEnvPassword: initialHasEnvPassword, -}: { - children: React.ReactNode - hasEnvPassword: boolean -}) { - useSubscriptionSync() - - const isUnlocked = useUnlockStore((s) => s.isUnlocked) - const hasHydrated = useUnlockStore((s) => s._hasHydrated) - const envToken = useUnlockStore((s) => s.envToken) - const doUnlock = useUnlockStore((s) => s.unlock) - const setEnvToken = useUnlockStore((s) => s.setEnvToken) - const clearEnvToken = useUnlockStore((s) => s.clearEnvToken) - - const cardRef = useRef(null) - const [isEnvVerifying, setIsEnvVerifying] = useState(false) - - const { data: config, isLoading } = useQuery({ - queryKey: ['app-config'], - queryFn: async () => { - const data = await fetchConfig() - if (data.subscriptionSources) { - useSettingsStore - .getState() - .syncEnvSubscriptions(JSON.stringify(data.subscriptionSources)) - } - return data - }, - initialData: { - hasEnvPassword: initialHasEnvPassword, - persistPassword: false, - } satisfies AppConfig, - staleTime: Infinity, - }) - - useEffect(() => { - if (!hasHydrated) return - if (!config?.hasEnvPassword || !envToken) return - - setIsEnvVerifying(true) - fetch('/api/config', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ hash: envToken }), - }) - .then((r) => r.json()) - .then((d) => { - if (d.valid) doUnlock() - else clearEnvToken() - }) - .catch(() => clearEnvToken()) - .finally(() => setIsEnvVerifying(false)) - }, [hasHydrated, config?.hasEnvPassword, clearEnvToken, doUnlock, envToken]) - - const { mutateAsync: unlock, isPending } = useMutation({ - mutationFn: async (pwd: string): Promise => { - if (!config?.hasEnvPassword) return { valid: false } - const envHash = await hashPasswordFn(pwd) - const res = await fetch('/api/config', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ hash: envHash }), - }) - const data = await res.json() - return data.valid ? { valid: true, token: envHash } : { valid: false } - }, - onSuccess: (result) => { - if (!result.valid) return - setEnvToken(result.token) - doUnlock() - }, - }) - - const form = useForm({ - defaultValues: { password: '' } satisfies PasswordForm, - validators: { - onSubmit: passwordSchema, - }, - onSubmit: async ({ value, formApi }) => { - const result = await unlock(value.password) - if (!result.valid) { - formApi.setFieldMeta('password', (prev) => ({ - ...prev, - errors: ['密码错误'], - errorMap: { onSubmit: '密码错误' }, - })) - cardRef.current?.classList.add('animate-shake') - cardRef.current?.addEventListener( - 'animationend', - () => cardRef.current?.classList.remove('animate-shake'), - { once: true }, - ) - } - }, - }) - - const isProtected = config?.hasEnvPassword ?? initialHasEnvPassword - - if (!hasHydrated || isEnvVerifying || (isLoading && !initialHasEnvPassword)) { - return - } - - if (!isProtected || isUnlocked) return <>{children} - - return ( -
- - - 访问受限 - 请输入访问密码以继续 - - -
{ - e.preventDefault() - e.stopPropagation() - form.handleSubmit() - }} - > - - - {(field) => ( - <> - - - field.handleChange(e.target.value)} - onBlur={field.handleBlur} - placeholder="输入密码..." - autoFocus - aria-invalid={field.state.meta.errors.length > 0} - aria-describedby={ - field.state.meta.errors.length > 0 - ? 'pwd-gate-error' - : undefined - } - /> - {field.state.meta.errors.length > 0 && ( - - {typeof field.state.meta.errors[0] === 'string' - ? field.state.meta.errors[0] - : field.state.meta.errors[0]?.message} - - )} - - - - - - - - )} - - -
-
-
- ) -} diff --git a/apps/flox/src/components/settings/PasswordSettings.tsx b/apps/flox/src/components/settings/PasswordSettings.tsx deleted file mode 100644 index 91ed3617..00000000 --- a/apps/flox/src/components/settings/PasswordSettings.tsx +++ /dev/null @@ -1,40 +0,0 @@ -'use client' - -import { - Alert, - AlertDescription, - AlertTitle, -} from '@cdlab996/ui/components/alert' -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from '@cdlab996/ui/components/card' -import { ShieldCheck } from 'lucide-react' - -export function PasswordSettings() { - return ( - - - 访问控制 - 应用通过环境变量启用访问密码保护。 - - - - - - 环境变量密码已启用 - - 通过{' '} - - ACCESS_PASSWORD - {' '} - 环境变量设置,无法在此修改 - - - - - ) -} diff --git a/apps/flox/src/components/settings/SettingsPageContent.tsx b/apps/flox/src/components/settings/SettingsPageContent.tsx index 4c71b309..5eb5d82d 100644 --- a/apps/flox/src/components/settings/SettingsPageContent.tsx +++ b/apps/flox/src/components/settings/SettingsPageContent.tsx @@ -7,7 +7,6 @@ import { DataSettings } from '@/components/settings/DataSettings' import { DisplaySettings } from '@/components/settings/DisplaySettings' import { ExportModal } from '@/components/settings/ExportModal' import { ImportModal } from '@/components/settings/ImportModal' -import { PasswordSettings } from '@/components/settings/PasswordSettings' import { PlayerSettings } from '@/components/settings/PlayerSettings' import { SortSettings } from '@/components/settings/SortSettings' import { SourceSettings } from '@/components/settings/SourceSettings' @@ -22,7 +21,6 @@ export function SettingsPageContent({ const { sources, sortBy, - envPasswordSet, realtimeLatency, searchDisplayMode, fullscreenType, @@ -81,9 +79,6 @@ export function SettingsPageContent({ onAdKeywordsChange={handleAdKeywordsChange} /> - {/* Password Settings (env-only info card) */} - {envPasswordSet && } - {/* Display Settings */} statement-breakpoint +CREATE INDEX `account_user_id_idx` ON `account` (`user_id`);--> statement-breakpoint +CREATE TABLE `session` ( + `id` text PRIMARY KEY NOT NULL, + `expires_at` integer NOT NULL, + `token` text NOT NULL, + `created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL, + `updated_at` integer NOT NULL, + `ip_address` text, + `user_agent` text, + `user_id` text NOT NULL, + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `session_token_unique` ON `session` (`token`);--> statement-breakpoint +CREATE INDEX `session_user_id_idx` ON `session` (`user_id`);--> statement-breakpoint +CREATE TABLE `user` ( + `id` text PRIMARY KEY NOT NULL, + `name` text NOT NULL, + `email` text NOT NULL, + `email_verified` integer DEFAULT false NOT NULL, + `image` text, + `created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL, + `updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL +); +--> statement-breakpoint +CREATE UNIQUE INDEX `user_email_unique` ON `user` (`email`);--> statement-breakpoint +CREATE TABLE `verification` ( + `id` text PRIMARY KEY NOT NULL, + `identifier` text NOT NULL, + `value` text NOT NULL, + `expires_at` integer NOT NULL, + `created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL, + `updated_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL +); +--> statement-breakpoint +CREATE INDEX `verification_identifier_idx` ON `verification` (`identifier`); \ No newline at end of file diff --git a/apps/flox/src/database/meta/0000_snapshot.json b/apps/flox/src/database/meta/0000_snapshot.json new file mode 100644 index 00000000..4d74331a --- /dev/null +++ b/apps/flox/src/database/meta/0000_snapshot.json @@ -0,0 +1,370 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "eeb8fc56-8536-4d08-bf6a-0b12e75575ce", + "prevId": "00000000-0000-0000-0000-000000000000", + "tables": { + "account": { + "name": "account", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "account_user_id_idx": { + "name": "account_user_id_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session": { + "name": "session", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "session_token_unique": { + "name": "session_token_unique", + "columns": [ + "token" + ], + "isUnique": true + }, + "session_user_id_idx": { + "name": "session_user_id_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email_verified": { + "name": "email_verified", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + } + }, + "indexes": { + "user_email_unique": { + "name": "user_email_unique", + "columns": [ + "email" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "verification": { + "name": "verification", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + } + }, + "indexes": { + "verification_identifier_idx": { + "name": "verification_identifier_idx", + "columns": [ + "identifier" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/apps/flox/src/database/meta/_journal.json b/apps/flox/src/database/meta/_journal.json new file mode 100644 index 00000000..37cedf1c --- /dev/null +++ b/apps/flox/src/database/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "sqlite", + "entries": [ + { + "idx": 0, + "version": "6", + "when": 1780048022337, + "tag": "0000_military_eternity", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/apps/flox/src/database/schema.ts b/apps/flox/src/database/schema.ts new file mode 100644 index 00000000..c3726061 --- /dev/null +++ b/apps/flox/src/database/schema.ts @@ -0,0 +1,96 @@ +import { sql } from 'drizzle-orm' +import { index, integer, sqliteTable, text } from 'drizzle-orm/sqlite-core' + +// better-auth core tables. Column/table names must match better-auth's +// expected schema so the drizzle adapter can map them without overrides. + +export const user = sqliteTable('user', { + id: text('id').primaryKey(), + name: text('name').notNull(), + email: text('email').notNull().unique(), + emailVerified: integer('email_verified', { mode: 'boolean' }) + .default(false) + .notNull(), + image: text('image'), + createdAt: integer('created_at', { mode: 'timestamp_ms' }) + .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) + .notNull(), + updatedAt: integer('updated_at', { mode: 'timestamp_ms' }) + .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) + .$onUpdate(() => new Date()) + .notNull(), +}) + +export const session = sqliteTable( + 'session', + { + id: text('id').primaryKey(), + expiresAt: integer('expires_at', { mode: 'timestamp_ms' }).notNull(), + token: text('token').notNull().unique(), + createdAt: integer('created_at', { mode: 'timestamp_ms' }) + .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) + .notNull(), + updatedAt: integer('updated_at', { mode: 'timestamp_ms' }) + .$onUpdate(() => new Date()) + .notNull(), + ipAddress: text('ip_address'), + userAgent: text('user_agent'), + userId: text('user_id') + .notNull() + .references(() => user.id, { onDelete: 'cascade' }), + }, + (table) => [index('session_user_id_idx').on(table.userId)], +) + +export const account = sqliteTable( + 'account', + { + id: text('id').primaryKey(), + accountId: text('account_id').notNull(), + providerId: text('provider_id').notNull(), + userId: text('user_id') + .notNull() + .references(() => user.id, { onDelete: 'cascade' }), + accessToken: text('access_token'), + refreshToken: text('refresh_token'), + idToken: text('id_token'), + accessTokenExpiresAt: integer('access_token_expires_at', { + mode: 'timestamp_ms', + }), + refreshTokenExpiresAt: integer('refresh_token_expires_at', { + mode: 'timestamp_ms', + }), + scope: text('scope'), + password: text('password'), + createdAt: integer('created_at', { mode: 'timestamp_ms' }) + .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) + .notNull(), + updatedAt: integer('updated_at', { mode: 'timestamp_ms' }) + .$onUpdate(() => new Date()) + .notNull(), + }, + (table) => [index('account_user_id_idx').on(table.userId)], +) + +export const verification = sqliteTable( + 'verification', + { + id: text('id').primaryKey(), + identifier: text('identifier').notNull(), + value: text('value').notNull(), + expiresAt: integer('expires_at', { mode: 'timestamp_ms' }).notNull(), + createdAt: integer('created_at', { mode: 'timestamp_ms' }) + .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) + .notNull(), + updatedAt: integer('updated_at', { mode: 'timestamp_ms' }) + .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`) + .$onUpdate(() => new Date()) + .notNull(), + }, + (table) => [index('verification_identifier_idx').on(table.identifier)], +) + +export type User = typeof user.$inferSelect +export type Session = typeof session.$inferSelect +export type Account = typeof account.$inferSelect +export type Verification = typeof verification.$inferSelect diff --git a/apps/flox/src/lib/auth-client.ts b/apps/flox/src/lib/auth-client.ts new file mode 100644 index 00000000..33385aaa --- /dev/null +++ b/apps/flox/src/lib/auth-client.ts @@ -0,0 +1,8 @@ +import { createAuthClient } from 'better-auth/react' + +export const authClient = createAuthClient({ + // Falls back to the current origin when unset. + baseURL: process.env.NEXT_PUBLIC_BETTER_AUTH_URL, +}) + +export const { signIn, signUp, signOut, useSession } = authClient diff --git a/apps/flox/src/lib/auth.ts b/apps/flox/src/lib/auth.ts new file mode 100644 index 00000000..c8729798 --- /dev/null +++ b/apps/flox/src/lib/auth.ts @@ -0,0 +1,36 @@ +import { betterAuth } from 'better-auth' +import { drizzleAdapter } from 'better-auth/adapters/drizzle' +import { nextCookies } from 'better-auth/next-js' +import * as schema from '@/database/schema' +import { getDb } from '@/lib/db' + +// Built per-request: on next-on-pages the D1 binding (and process.env vars) are +// only populated inside a request, so the auth instance can't live at module +// top. Cheap enough to construct on each auth call. +export async function getAuth() { + const db = await getDb() + + const googleEnabled = + !!process.env.GOOGLE_CLIENT_ID && !!process.env.GOOGLE_CLIENT_SECRET + + return betterAuth({ + appName: 'flox', + database: drizzleAdapter(db, { provider: 'sqlite', schema }), + secret: process.env.BETTER_AUTH_SECRET, + baseURL: process.env.BETTER_AUTH_URL, + emailAndPassword: { + enabled: true, + // No email service wired yet — keep verification off for now. + requireEmailVerification: false, + }, + socialProviders: googleEnabled + ? { + google: { + clientId: process.env.GOOGLE_CLIENT_ID as string, + clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, + }, + } + : undefined, + plugins: [nextCookies()], + }) +} diff --git a/apps/flox/src/lib/db.ts b/apps/flox/src/lib/db.ts new file mode 100644 index 00000000..8a2a6c18 --- /dev/null +++ b/apps/flox/src/lib/db.ts @@ -0,0 +1,46 @@ +import { drizzle as drizzleD1 } from 'drizzle-orm/d1' +import type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core' +import * as schema from '@/database/schema' + +// Common base type — both LibSQLDatabase and DrizzleD1Database extend this, +// so a single `DB` reference accepts either driver. +export type DB = BaseSQLiteDatabase<'async', unknown, typeof schema> + +let cachedLibsqlDb: DB | undefined + +// flox deploys via @cloudflare/next-on-pages (Edge), so the D1 binding is only +// reachable through `getRequestContext()` inside a request — never at module +// load. Local `next dev` has no binding, so DB_TYPE falls back to libsql. +export async function getDb(): Promise { + const dbType = process.env.DB_TYPE || 'libsql' + + if (dbType === 'd1') { + const { getRequestContext } = await import('@cloudflare/next-on-pages') + const binding = getRequestContext().env.DB + if (!binding) { + throw new Error( + 'D1 binding "DB" not found — set d1_databases in wrangler.jsonc', + ) + } + return drizzleD1(binding, { schema }) + } + + if (cachedLibsqlDb) return cachedLibsqlDb + + // Dev-only path. `new Function` hides the import from bundlers so the build + // never tries to bundle @libsql/* (which fails under pnpm hoisting). In + // production we always take the D1 branch above, so this never runs there. + const dynamicImport = new Function('p', 'return import(p)') as ( + p: string, + ) => Promise + const [{ createClient }, { drizzle: drizzleSqlite }] = await Promise.all([ + dynamicImport('@libsql/client/web'), + dynamicImport('drizzle-orm/libsql'), + ]) + const client = createClient({ + url: process.env.LIBSQL_URL || 'file:./src/database/data.db', + authToken: process.env.LIBSQL_AUTH_TOKEN || undefined, + }) + cachedLibsqlDb = drizzleSqlite(client, { schema }) + return cachedLibsqlDb +} diff --git a/apps/flox/src/lib/store/init.ts b/apps/flox/src/lib/store/init.ts index 65f9b45f..fba28527 100644 --- a/apps/flox/src/lib/store/init.ts +++ b/apps/flox/src/lib/store/init.ts @@ -19,5 +19,4 @@ import './favorites-store' import './history-store' import './search-history-store' import './watch-later-store' -import './unlock-store' import './tag-orders-store' diff --git a/apps/flox/src/lib/store/unlock-store.ts b/apps/flox/src/lib/store/unlock-store.ts deleted file mode 100644 index d0fa044d..00000000 --- a/apps/flox/src/lib/store/unlock-store.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createPersistedStore } from './create-persisted-store' - -interface UnlockState { - isUnlocked: boolean - envToken: string | null - /** True once persisted state has been loaded — gate UI on this to avoid flashes. */ - _hasHydrated: boolean -} - -interface UnlockActions { - unlock: () => void - lock: () => void - setEnvToken: (token: string) => void - clearEnvToken: () => void - setHasHydrated: (state: boolean) => void -} - -export const useUnlockStore = createPersistedStore({ - key: 'flox:unlock', - // Session-scoped auth state. Reset still wipes it; backups intentionally - // skip it so an exported file can't be replayed to bypass the password - // gate on another device. - includeInBackup: false, - defaultState: () => ({ - isUnlocked: false, - envToken: null, - _hasHydrated: false, - }), - partialize: (state) => ({ - isUnlocked: state.isUnlocked, - envToken: state.envToken, - }), - onRehydrate: (state) => { - state?.setHasHydrated(true) - }, - actions: (set) => ({ - unlock: () => set({ isUnlocked: true }), - lock: () => set({ isUnlocked: false, envToken: null }), - setEnvToken: (token) => set({ envToken: token }), - clearEnvToken: () => set({ envToken: null }), - setHasHydrated: (state) => set({ _hasHydrated: state }), - }), -}) diff --git a/apps/flox/wrangler.jsonc b/apps/flox/wrangler.jsonc new file mode 100644 index 00000000..bb6680b3 --- /dev/null +++ b/apps/flox/wrangler.jsonc @@ -0,0 +1,24 @@ +/** + * Cloudflare Pages config for next-on-pages. + * Build with `pnpm --filter @cdlab996/flox build:cf`, preview/deploy with + * `wrangler pages dev .vercel/output/static` / `wrangler pages deploy`. + */ +{ + "$schema": "node_modules/wrangler/config-schema.json", + "name": "flox", + "pages_build_output_dir": ".vercel/output/static", + "compatibility_date": "2026-05-25", + "compatibility_flags": ["nodejs_compat"], + "vars": { + // Driver selector: "d1" uses the binding below; "libsql" uses LIBSQL_URL. + "DB_TYPE": "d1" + }, + "d1_databases": [ + { + "binding": "DB", + "database_name": "flox", + "migrations_dir": "./src/database", + "database_id": "your-d1-database-id" + } + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d72d6be..aae62e03 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,6 +85,9 @@ catalogs: '@vercel/analytics': specifier: ^2.0.1 version: 2.0.1 + better-auth: + specifier: ^1.3.4 + version: 1.6.11 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -468,7 +471,7 @@ importers: version: 0.17.3 drizzle-orm: specifier: catalog:prod - version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8) + version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8) hono: specifier: catalog:prod version: 4.12.16 @@ -508,7 +511,7 @@ importers: version: link:../../packages/utils '@vercel/analytics': specifier: catalog:prod - version: 2.0.1(959052c78f7cd082e78a8dcf08be319b) + version: 2.0.1(a24cc78cc95028d3ec3e390c96b49e10) cloudinary: specifier: 2.10.0 version: 2.10.0 @@ -745,7 +748,7 @@ importers: version: 1.0.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) drizzle-orm: specifier: catalog:prod - version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8) + version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8) hono: specifier: catalog:prod version: 4.12.16 @@ -862,15 +865,24 @@ importers: '@dnd-kit/utilities': specifier: ^3.2.2 version: 3.2.2(react@19.2.4) + '@libsql/client': + specifier: catalog:prod + version: 0.17.3 '@tanstack/react-form': specifier: catalog:prod version: 1.29.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tanstack/react-query': specifier: catalog:prod version: 5.100.9(react@19.2.4) + better-auth: + specifier: catalog:prod + version: 1.6.11(@cloudflare/workers-types@4.20260525.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(next@16.2.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.1.5(@types/node@25.3.3)(happy-dom@20.9.0)(jsdom@29.0.2(@noble/hashes@2.2.0))(msw@2.12.10(@types/node@25.3.3)(typescript@6.0.2))(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)))(vue@3.5.34(typescript@6.0.2)) date-fns: specifier: catalog:prod version: 4.1.0 + drizzle-orm: + specifier: catalog:prod + version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8) hls.js: specifier: catalog:prod version: 1.6.16 @@ -905,6 +917,9 @@ importers: '@cloudflare/next-on-pages': specifier: catalog:dev version: 1.13.16(@cloudflare/workers-types@4.20260525.1)(next@16.2.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(wrangler@4.94.0(@cloudflare/workers-types@4.20260525.1)) + '@cloudflare/workers-types': + specifier: catalog:dev + version: 4.20260525.1 '@types/node': specifier: catalog:dev version: 25.3.3 @@ -914,6 +929,9 @@ importers: '@types/react-dom': specifier: catalog:dev version: 19.2.3(@types/react@19.2.14) + drizzle-kit: + specifier: catalog:dev + version: 0.31.10 typescript: specifier: catalog:dev version: 6.0.2 @@ -947,22 +965,22 @@ importers: version: 1.2.83 '@nuxt/ui': specifier: ^4.8.0 - version: 4.8.0(@internationalized/date@3.12.0)(@internationalized/number@3.6.5)(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))(@tiptap/y-tiptap@3.0.2(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6)(y-protocols@1.0.7(yjs@13.6.29))(yjs@13.6.29))(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(embla-carousel@8.6.0)(ioredis@5.10.1)(magicast@0.5.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.2.1)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-router@4.6.4(vue@3.5.34(typescript@6.0.2)))(vue@3.5.34(typescript@6.0.2))(yjs@13.6.29)(zod@4.4.3) + version: 4.8.0(@internationalized/date@3.12.0)(@internationalized/number@3.6.5)(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))(@tiptap/y-tiptap@3.0.2(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6)(y-protocols@1.0.7(yjs@13.6.29))(yjs@13.6.29))(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(embla-carousel@8.6.0)(ioredis@5.10.1)(magicast@0.5.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.2.1)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-router@4.6.4(vue@3.5.34(typescript@6.0.2)))(vue@3.5.34(typescript@6.0.2))(yjs@13.6.29)(zod@4.4.3) '@nuxtjs/mdc': specifier: 0.22.0 version: 0.22.0(magicast@0.5.2) '@vercel/analytics': specifier: catalog:prod - version: 2.0.1(69cbc562e2aa4db64c08dbde2202a0b4) + version: 2.0.1(5f84e5ce70377eef916bfcf0646b7161) '@vueuse/core': specifier: 14.3.0 version: 14.3.0(vue@3.5.34(typescript@6.0.2)) '@vueuse/nuxt': specifier: 14.3.0 - version: 14.3.0(2f4853b5a9b4589519c82e80b223f67d) + version: 14.3.0(9f74aa348e2bc513125fe6f03521f39c) nuxt: specifier: 4.4.6 - version: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) + version: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) remark-mdc: specifier: ^3.11.0 version: 3.11.0 @@ -1002,7 +1020,7 @@ importers: version: 2.2.0 drizzle-orm: specifier: catalog:prod - version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8) + version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8) hono: specifier: catalog:prod version: 4.12.16 @@ -1255,7 +1273,7 @@ importers: version: 4.1.0 drizzle-orm: specifier: catalog:prod - version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8) + version: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8) lucide-react: specifier: catalog:prod version: 1.14.0(react@19.2.4) @@ -1969,6 +1987,85 @@ packages: '@types/react': optional: true + '@better-auth/core@1.6.11': + resolution: {integrity: sha512-LrwidLCV8azdMGjvtwp30nj9tIv1BwI3VhtC0UaGSjQkAVWw4bN42I8qwbxRziPeSQoj+zUVkOpxZzAWBDARtQ==} + peerDependencies: + '@better-auth/utils': 0.4.0 + '@better-fetch/fetch': 1.1.21 + '@cloudflare/workers-types': '>=4' + '@opentelemetry/api': ^1.9.0 + better-call: 1.3.5 + jose: ^6.1.0 + kysely: ^0.28.5 + nanostores: ^1.0.1 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + '@opentelemetry/api': + optional: true + + '@better-auth/drizzle-adapter@1.6.11': + resolution: {integrity: sha512-4jpkETIGZOHCf7BK4jnu22fdN6jjomH0/HhEzkaWy3+Eppi5PYlHTF/460jrTmA3Xc+Vqwp9t282ymHiEPypGw==} + peerDependencies: + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + drizzle-orm: ^0.45.2 + peerDependenciesMeta: + drizzle-orm: + optional: true + + '@better-auth/kysely-adapter@1.6.11': + resolution: {integrity: sha512-/g8M9RfIjdcZDnbstSUvQiINkvdNlCeZr248zwqx2/PVksQI1MhQofbzUn3RnQnbPKp0EPwpX/dR3oudRFenUg==} + peerDependencies: + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + kysely: ^0.28.17 + peerDependenciesMeta: + kysely: + optional: true + + '@better-auth/memory-adapter@1.6.11': + resolution: {integrity: sha512-hpdfw0BBf8MuzLkIdmbcUZICbY9r/bhLO2RxSnkzT5+/O+0I0u2I8+m0YUP7vNllP/ZCKASHOYgXPLO75Z0f9Q==} + peerDependencies: + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + + '@better-auth/mongo-adapter@1.6.11': + resolution: {integrity: sha512-3Tor8rSv8vSEIMEaV2PFpPEuVhqc1gNoZ6eGvoh3LwExXXuj8madew6ob+H1pH7Aphn3Ar5PQ08AguT8TbwFAA==} + peerDependencies: + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + mongodb: ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + mongodb: + optional: true + + '@better-auth/prisma-adapter@1.6.11': + resolution: {integrity: sha512-Pw+7q7zTp+VSci1V+CYMvuxIbAeVMZLe4lRo46LJoAKMHfjFl5T/ycsyFvWs/DkWC7n9gZZzRDEbHp0I5FiKKw==} + peerDependencies: + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + '@prisma/client': + optional: true + prisma: + optional: true + + '@better-auth/telemetry@1.6.11': + resolution: {integrity: sha512-hsjDHc8MZbm6/AHeNdtywrWedXevnBjmdvnHTcZub+rTVjOv+Td0roI8USKuC6uUibmrl//2rJfVCsGbopihNA==} + peerDependencies: + '@better-auth/core': ^1.6.11 + '@better-auth/utils': 0.4.0 + '@better-fetch/fetch': 1.1.21 + + '@better-auth/utils@0.4.0': + resolution: {integrity: sha512-RpMtLUIQAEWMgdPLNVbIF5ON2mm+CH0U3rCdUCU1VyeAUui4m38DyK7/aXMLZov2YDjG684pS1D0MBllrmgjQA==} + + '@better-fetch/fetch@1.1.21': + resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==} + '@biomejs/biome@2.4.15': resolution: {integrity: sha512-j5VH3a/h/HXTKBM50MDMxRCzkeLv9S2XJcW2WgnZT1+xyisi+0bISrXR82gCX+8S9lvK0skEvHJRN+3Ktr2hlw==} engines: {node: '>=14.21.3'} @@ -3329,6 +3426,10 @@ packages: next: '>=15.5.18 <16 || >=16.2.6' wrangler: ^4.86.0 + '@opentelemetry/semantic-conventions@1.41.1': + resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} + engines: {node: '>=14'} + '@oxc-minify/binding-android-arm-eabi@0.131.0': resolution: {integrity: sha512-yLa7y9jjJgUeUUMm6AtjmBIQzK1YU5sYcNJnVVtr6WtoWu5SpuNDZ8u6cl/dhn0g/oQgVlf+E+8WJfsExt8R+Q==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6767,6 +6868,76 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + better-auth@1.6.11: + resolution: {integrity: sha512-Wwt6+q07dwIhsp6XiM7L1qSXVUWBEtNl+eZvwM778CguFqDZFBN9Pt6LtFaHl55t8Z+Zc//5kxcbgDY8/79vFQ==} + peerDependencies: + '@lynx-js/react': '*' + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 + '@sveltejs/kit': ^2.0.0 + '@tanstack/react-start': ^1.0.0 + '@tanstack/solid-start': ^1.0.0 + better-sqlite3: ^12.0.0 + drizzle-kit: '>=0.31.4' + drizzle-orm: ^0.45.2 + mongodb: ^6.0.0 || ^7.0.0 + mysql2: ^3.0.0 + next: ^14.0.0 || ^15.0.0 || ^16.0.0 + pg: ^8.0.0 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + solid-js: ^1.0.0 + svelte: ^4.0.0 || ^5.0.0 + vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 + vue: ^3.0.0 + peerDependenciesMeta: + '@lynx-js/react': + optional: true + '@prisma/client': + optional: true + '@sveltejs/kit': + optional: true + '@tanstack/react-start': + optional: true + '@tanstack/solid-start': + optional: true + better-sqlite3: + optional: true + drizzle-kit: + optional: true + drizzle-orm: + optional: true + mongodb: + optional: true + mysql2: + optional: true + next: + optional: true + pg: + optional: true + prisma: + optional: true + react: + optional: true + react-dom: + optional: true + solid-js: + optional: true + svelte: + optional: true + vitest: + optional: true + vue: + optional: true + + better-call@1.3.5: + resolution: {integrity: sha512-kOFJkBP7utAQLEYrobZm3vkTH8mXq5GNgvjc5/XEST1ilVHaxXUXfeDeFlqoETMtyqS4+3/h4ONX2i++ebZrvA==} + peerDependencies: + zod: ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} @@ -8517,8 +8688,8 @@ packages: kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - kysely@0.28.13: - resolution: {integrity: sha512-jCkYDvlfzOyHaVsrvR4vnNZxG30oNv2jbbFBjTQAUG8n0h07HW0sZJHk4KAQIRyu9ay+Rg+L8qGa3lwt8Gve9w==} + kysely@0.28.17: + resolution: {integrity: sha512-nbD8lB9EB3wNdMhOCdx5Li8DxnLbvKByylRLcJ1h+4SkrowVeECAyZlyiKMThF7xFdRz0jSQ2MoJr+wXux2y0Q==} engines: {node: '>=20.0.0'} launch-editor@2.13.1: @@ -9106,6 +9277,10 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanostores@1.3.0: + resolution: {integrity: sha512-XPUa/jz+P1oJvN9VBxw4L9MtdFfaH3DAryqPssqhb2kXjmb9npz0dly6rCsgFWOPr4Yg9mTfM3MDZgZZ+7A3lA==} + engines: {node: ^20.0.0 || >=22.0.0} + nanotar@0.3.0: resolution: {integrity: sha512-Kv2JYYiCzt16Kt5QwAc9BFG89xfPNBx+oQL4GQXD9nLqPkZBiNaqaCWtwnbk/q7UVsTYevvM1b0UF8zmEI4pCg==} @@ -10209,6 +10384,9 @@ packages: engines: {node: '>=18'} hasBin: true + rou3@0.7.12: + resolution: {integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==} + rou3@0.8.1: resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==} @@ -10293,6 +10471,9 @@ packages: resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} engines: {node: '>= 18'} + set-cookie-parser@3.1.0: + resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} + setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} @@ -12625,6 +12806,61 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 + '@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)': + dependencies: + '@better-auth/utils': 0.4.0 + '@better-fetch/fetch': 1.1.21 + '@opentelemetry/semantic-conventions': 1.41.1 + '@standard-schema/spec': 1.1.0 + better-call: 1.3.5(zod@4.4.3) + jose: 6.2.3 + kysely: 0.28.17 + nanostores: 1.3.0 + zod: 4.4.3 + optionalDependencies: + '@cloudflare/workers-types': 4.20260525.1 + + '@better-auth/drizzle-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))': + dependencies: + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + '@better-auth/utils': 0.4.0 + optionalDependencies: + drizzle-orm: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8) + + '@better-auth/kysely-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(kysely@0.28.17)': + dependencies: + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + '@better-auth/utils': 0.4.0 + optionalDependencies: + kysely: 0.28.17 + + '@better-auth/memory-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)': + dependencies: + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + '@better-auth/utils': 0.4.0 + + '@better-auth/mongo-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)': + dependencies: + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + '@better-auth/utils': 0.4.0 + + '@better-auth/prisma-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)': + dependencies: + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + '@better-auth/utils': 0.4.0 + + '@better-auth/telemetry@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)': + dependencies: + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + '@better-auth/utils': 0.4.0 + '@better-fetch/fetch': 1.1.21 + + '@better-auth/utils@0.4.0': + dependencies: + '@noble/hashes': 2.2.0 + + '@better-fetch/fetch@1.1.21': {} + '@biomejs/biome@2.4.15': optionalDependencies: '@biomejs/cli-darwin-arm64': 2.4.15 @@ -13678,13 +13914,13 @@ snapshots: - utf-8-validate - vue - '@nuxt/fonts@0.14.0(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))': + '@nuxt/fonts@0.14.0(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)) '@nuxt/kit': 4.4.6(magicast@0.5.2) consola: 3.4.2 defu: 6.1.7 - fontless: 0.2.1(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)) + fontless: 0.2.1(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)) h3: 1.15.10 magic-regexp: 0.10.0 ofetch: 1.5.1 @@ -13694,7 +13930,7 @@ snapshots: ufo: 1.6.4 unifont: 0.7.4 unplugin: 3.0.0 - unstorage: 1.17.4(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) + unstorage: 1.17.4(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13790,7 +14026,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/nitro-server@4.4.6(5424abe12766e7800106a257e87682f5)': + '@nuxt/nitro-server@4.4.6(6054195f5183f2aba4215267c78fe83c)': dependencies: '@nuxt/devalue': 2.0.2 '@nuxt/kit': 4.4.6(magicast@0.5.2) @@ -13807,8 +14043,8 @@ snapshots: impound: 1.1.5 klona: 2.0.6 mocked-exports: 0.1.1 - nitropack: 2.13.4(@libsql/client@0.17.3)(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(oxc-parser@0.131.0)(rolldown@1.0.0) - nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) + nitropack: 2.13.4(@libsql/client@0.17.3)(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(oxc-parser@0.131.0)(rolldown@1.0.0) + nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0) nypm: 0.6.6 ohash: 2.0.11 pathe: 2.0.3 @@ -13816,7 +14052,7 @@ snapshots: std-env: 4.1.0 ufo: 1.6.4 unctx: 2.5.0 - unstorage: 1.17.5(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) + unstorage: 1.17.5(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) vue: 3.5.34(typescript@6.0.2) vue-bundle-renderer: 2.2.0 vue-devtools-stub: 0.1.0 @@ -13858,8 +14094,9 @@ snapshots: - typescript - uploadthing - xml2js + optional: true - '@nuxt/nitro-server@4.4.6(ec89a7f07916b2ae003de36166f386e2)': + '@nuxt/nitro-server@4.4.6(87c944ed3f8aad1419ceb7e12125aad1)': dependencies: '@nuxt/devalue': 2.0.2 '@nuxt/kit': 4.4.6(magicast@0.5.2) @@ -13876,8 +14113,8 @@ snapshots: impound: 1.1.5 klona: 2.0.6 mocked-exports: 0.1.1 - nitropack: 2.13.4(@libsql/client@0.17.3)(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(oxc-parser@0.131.0)(rolldown@1.0.0) - nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0) + nitropack: 2.13.4(@libsql/client@0.17.3)(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(oxc-parser@0.131.0)(rolldown@1.0.0) + nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) nypm: 0.6.6 ohash: 2.0.11 pathe: 2.0.3 @@ -13885,7 +14122,7 @@ snapshots: std-env: 4.1.0 ufo: 1.6.4 unctx: 2.5.0 - unstorage: 1.17.5(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) + unstorage: 1.17.5(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) vue: 3.5.34(typescript@6.0.2) vue-bundle-renderer: 2.2.0 vue-devtools-stub: 0.1.0 @@ -13927,7 +14164,6 @@ snapshots: - typescript - uploadthing - xml2js - optional: true '@nuxt/schema@4.4.6': dependencies: @@ -13946,11 +14182,11 @@ snapshots: rc9: 3.0.0 std-env: 4.1.0 - '@nuxt/ui@4.8.0(@internationalized/date@3.12.0)(@internationalized/number@3.6.5)(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))(@tiptap/y-tiptap@3.0.2(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6)(y-protocols@1.0.7(yjs@13.6.29))(yjs@13.6.29))(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(embla-carousel@8.6.0)(ioredis@5.10.1)(magicast@0.5.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.2.1)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-router@4.6.4(vue@3.5.34(typescript@6.0.2)))(vue@3.5.34(typescript@6.0.2))(yjs@13.6.29)(zod@4.4.3)': + '@nuxt/ui@4.8.0(@internationalized/date@3.12.0)(@internationalized/number@3.6.5)(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))(@tiptap/y-tiptap@3.0.2(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6)(y-protocols@1.0.7(yjs@13.6.29))(yjs@13.6.29))(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(embla-carousel@8.6.0)(ioredis@5.10.1)(magicast@0.5.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.2.1)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-router@4.6.4(vue@3.5.34(typescript@6.0.2)))(vue@3.5.34(typescript@6.0.2))(yjs@13.6.29)(zod@4.4.3)': dependencies: '@floating-ui/dom': 1.7.6 '@iconify/vue': 5.0.1(vue@3.5.34(typescript@6.0.2)) - '@nuxt/fonts': 0.14.0(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)) + '@nuxt/fonts': 0.14.0(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)) '@nuxt/icon': 2.2.2(magicast@0.5.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue@3.5.34(typescript@6.0.2)) '@nuxt/kit': 4.4.6(magicast@0.5.2) '@nuxt/schema': 4.4.6 @@ -14059,7 +14295,7 @@ snapshots: - vue - yjs - '@nuxt/vite-builder@4.4.6(cab89addef953cad17fe498ca6ffd702)': + '@nuxt/vite-builder@4.4.6(66d5b84f7787b4f978ce9bcf998787b1)': dependencies: '@nuxt/kit': 4.4.6(magicast@0.5.2) '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) @@ -14077,7 +14313,7 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.2 mocked-exports: 0.1.1 - nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0) + nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) nypm: 0.6.6 pathe: 2.0.3 pkg-types: 2.3.1 @@ -14119,9 +14355,8 @@ snapshots: - vti - vue-tsc - yaml - optional: true - '@nuxt/vite-builder@4.4.6(e80810b8d42dc8b251e9706a3123d690)': + '@nuxt/vite-builder@4.4.6(faa8d7b2659de68ca6702bd33e445989)': dependencies: '@nuxt/kit': 4.4.6(magicast@0.5.2) '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) @@ -14139,7 +14374,7 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.2 mocked-exports: 0.1.1 - nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) + nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0) nypm: 0.6.6 pathe: 2.0.3 pkg-types: 2.3.1 @@ -14181,6 +14416,7 @@ snapshots: - vti - vue-tsc - yaml + optional: true '@nuxtjs/color-mode@3.5.2(magicast@0.5.2)': dependencies: @@ -14293,6 +14529,8 @@ snapshots: - encoding - supports-color + '@opentelemetry/semantic-conventions@1.41.1': {} + '@oxc-minify/binding-android-arm-eabi@0.131.0': optional: true @@ -16877,18 +17115,18 @@ snapshots: uncrypto: 0.1.3 optional: true - '@vercel/analytics@2.0.1(69cbc562e2aa4db64c08dbde2202a0b4)': + '@vercel/analytics@2.0.1(5f84e5ce70377eef916bfcf0646b7161)': optionalDependencies: next: 16.2.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) + nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) react: 19.2.4 vue: 3.5.34(typescript@6.0.2) vue-router: 4.6.4(vue@3.5.34(typescript@6.0.2)) - '@vercel/analytics@2.0.1(959052c78f7cd082e78a8dcf08be319b)': + '@vercel/analytics@2.0.1(a24cc78cc95028d3ec3e390c96b49e10)': optionalDependencies: next: 16.2.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0) + nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0) react: 19.2.4 vue: 3.5.34(typescript@6.0.2) vue-router: 4.6.4(vue@3.5.34(typescript@6.0.2)) @@ -17181,13 +17419,13 @@ snapshots: '@vueuse/metadata@14.3.0': {} - '@vueuse/nuxt@14.3.0(2f4853b5a9b4589519c82e80b223f67d)': + '@vueuse/nuxt@14.3.0(9f74aa348e2bc513125fe6f03521f39c)': dependencies: '@nuxt/kit': 4.4.6(magicast@0.5.2) '@vueuse/core': 14.3.0(vue@3.5.34(typescript@6.0.2)) '@vueuse/metadata': 14.3.0 local-pkg: 1.1.2 - nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) + nuxt: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0) vue: 3.5.34(typescript@6.0.2) transitivePeerDependencies: - magicast @@ -17392,6 +17630,47 @@ snapshots: baseline-browser-mapping@2.10.31: {} + better-auth@1.6.11(@cloudflare/workers-types@4.20260525.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(next@16.2.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.1.5(@types/node@25.3.3)(happy-dom@20.9.0)(jsdom@29.0.2(@noble/hashes@2.2.0))(msw@2.12.10(@types/node@25.3.3)(typescript@6.0.2))(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)))(vue@3.5.34(typescript@6.0.2)): + dependencies: + '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + '@better-auth/drizzle-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)) + '@better-auth/kysely-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(kysely@0.28.17) + '@better-auth/memory-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + '@better-auth/mongo-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + '@better-auth/prisma-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + '@better-auth/telemetry': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20260525.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21) + '@better-auth/utils': 0.4.0 + '@better-fetch/fetch': 1.1.21 + '@noble/ciphers': 2.2.0 + '@noble/hashes': 2.2.0 + better-call: 1.3.5(zod@4.4.3) + defu: 6.1.7 + jose: 6.2.3 + kysely: 0.28.17 + nanostores: 1.3.0 + zod: 4.4.3 + optionalDependencies: + drizzle-kit: 0.31.10 + drizzle-orm: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8) + next: 16.2.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + pg: 8.20.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + vitest: 4.1.5(@types/node@25.3.3)(happy-dom@20.9.0)(jsdom@29.0.2(@noble/hashes@2.2.0))(msw@2.12.10(@types/node@25.3.3)(typescript@6.0.2))(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)) + vue: 3.5.34(typescript@6.0.2) + transitivePeerDependencies: + - '@cloudflare/workers-types' + - '@opentelemetry/api' + + better-call@1.3.5(zod@4.4.3): + dependencies: + '@better-auth/utils': 0.4.0 + '@better-fetch/fetch': 1.1.21 + rou3: 0.7.12 + set-cookie-parser: 3.1.0 + optionalDependencies: + zod: 4.4.3 + bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 @@ -17879,10 +18158,10 @@ snapshots: date-fns@4.3.0: {} - db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)): + db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)): optionalDependencies: '@libsql/client': 0.17.3 - drizzle-orm: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8) + drizzle-orm: 0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8) debug@4.4.3: dependencies: @@ -17988,13 +18267,13 @@ snapshots: esbuild: 0.25.12 tsx: 4.21.0 - drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8): + drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8): optionalDependencies: '@cloudflare/workers-types': 4.20260525.1 '@libsql/client': 0.17.3 '@types/pg': 8.18.0 '@upstash/redis': 1.37.0 - kysely: 0.28.13 + kysely: 0.28.17 pg: 8.20.0 postgres: 3.4.8 @@ -18414,7 +18693,7 @@ snapshots: dependencies: tiny-inflate: 1.0.3 - fontless@0.2.1(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)): + fontless@0.2.1(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0)): dependencies: consola: 3.4.2 css-tree: 3.2.1 @@ -18428,7 +18707,7 @@ snapshots: pathe: 2.0.3 ufo: 1.6.4 unifont: 0.7.4 - unstorage: 1.17.4(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) + unstorage: 1.17.4(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) optionalDependencies: vite: 7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0) transitivePeerDependencies: @@ -19186,8 +19465,7 @@ snapshots: kuler@2.0.0: {} - kysely@0.28.13: - optional: true + kysely@0.28.17: {} launch-editor@2.13.1: dependencies: @@ -19935,6 +20213,8 @@ snapshots: nanoid@3.3.12: {} + nanostores@1.3.0: {} + nanotar@0.3.0: {} negotiator@1.0.0: {} @@ -19987,7 +20267,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - nitropack@2.13.4(@libsql/client@0.17.3)(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(oxc-parser@0.131.0)(rolldown@1.0.0): + nitropack@2.13.4(@libsql/client@0.17.3)(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(oxc-parser@0.131.0)(rolldown@1.0.0): dependencies: '@cloudflare/kv-asset-handler': 0.4.2 '@rollup/plugin-alias': 6.0.0(rollup@4.60.4) @@ -20008,7 +20288,7 @@ snapshots: cookie-es: 2.0.1 croner: 10.0.1 crossws: 0.3.5 - db0: 0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)) + db0: 0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)) defu: 6.1.7 destr: 2.0.5 dot-prop: 10.1.0 @@ -20054,7 +20334,7 @@ snapshots: unenv: 2.0.0-rc.24 unimport: 6.3.0(oxc-parser@0.131.0)(rolldown@1.0.0) unplugin-utils: 0.3.1 - unstorage: 1.17.5(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) + unstorage: 1.17.5(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1) untyped: 2.0.0 unwasm: 0.5.3 youch: 4.1.1 @@ -20145,16 +20425,16 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0): + nuxt@4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue-tsc@3.3.1(typescript@6.0.2))(yaml@2.9.0): dependencies: '@dxup/nuxt': 0.4.1(magicast@0.5.2)(typescript@6.0.2) '@nuxt/cli': 3.35.2(@nuxt/schema@4.4.6)(cac@6.7.14)(magicast@0.5.2) '@nuxt/devtools': 3.2.4(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue@3.5.34(typescript@6.0.2)) '@nuxt/kit': 4.4.6(magicast@0.5.2) - '@nuxt/nitro-server': 4.4.6(5424abe12766e7800106a257e87682f5) + '@nuxt/nitro-server': 4.4.6(87c944ed3f8aad1419ceb7e12125aad1) '@nuxt/schema': 4.4.6 '@nuxt/telemetry': 2.8.0(@nuxt/kit@4.4.6(magicast@0.5.2)) - '@nuxt/vite-builder': 4.4.6(e80810b8d42dc8b251e9706a3123d690) + '@nuxt/vite-builder': 4.4.6(66d5b84f7787b4f978ce9bcf998787b1) '@unhead/vue': 2.1.15(vue@3.5.34(typescript@6.0.2)) '@vue/shared': 3.5.34 chokidar: 5.0.0 @@ -20274,16 +20554,16 @@ snapshots: - xml2js - yaml - nuxt@4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0): + nuxt@4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@biomejs/biome@2.4.15)(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.3.3)(@upstash/redis@1.37.0)(@vue/compiler-sfc@3.5.34)(aws4fetch@1.0.20)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(rolldown@1.0.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0)(rollup@4.60.4))(rollup@4.60.4)(terser@5.46.0)(tsx@4.21.0)(typescript@6.0.2)(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0): dependencies: '@dxup/nuxt': 0.4.1(magicast@0.5.2)(typescript@6.0.2) '@nuxt/cli': 3.35.2(@nuxt/schema@4.4.6)(cac@6.7.14)(magicast@0.5.2) '@nuxt/devtools': 3.2.4(vite@7.3.3(@types/node@25.3.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.9.0))(vue@3.5.34(typescript@6.0.2)) '@nuxt/kit': 4.4.6(magicast@0.5.2) - '@nuxt/nitro-server': 4.4.6(ec89a7f07916b2ae003de36166f386e2) + '@nuxt/nitro-server': 4.4.6(6054195f5183f2aba4215267c78fe83c) '@nuxt/schema': 4.4.6 '@nuxt/telemetry': 2.8.0(@nuxt/kit@4.4.6(magicast@0.5.2)) - '@nuxt/vite-builder': 4.4.6(cab89addef953cad17fe498ca6ffd702) + '@nuxt/vite-builder': 4.4.6(faa8d7b2659de68ca6702bd33e445989) '@unhead/vue': 2.1.15(vue@3.5.34(typescript@6.0.2)) '@vue/shared': 3.5.34 chokidar: 5.0.0 @@ -21676,6 +21956,8 @@ snapshots: rosie-skills-freebsd-x64: 0.6.4 rosie-skills-linux-x64: 0.6.4 + rou3@0.7.12: {} + rou3@0.8.1: {} router@2.2.0: @@ -21761,6 +22043,8 @@ snapshots: transitivePeerDependencies: - supports-color + set-cookie-parser@3.1.0: {} + setimmediate@1.0.5: {} setprototypeof@1.2.0: {} @@ -22474,7 +22758,7 @@ snapshots: rolldown: 1.0.0-rc.17 optional: true - unstorage@1.17.4(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1): + unstorage@1.17.4(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1): dependencies: anymatch: 3.1.3 chokidar: 5.0.0 @@ -22487,10 +22771,10 @@ snapshots: optionalDependencies: '@upstash/redis': 1.37.0 aws4fetch: 1.0.20 - db0: 0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)) + db0: 0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)) ioredis: 5.10.1 - unstorage@1.17.5(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1): + unstorage@1.17.5(@upstash/redis@1.37.0)(aws4fetch@1.0.20)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)))(ioredis@5.10.1): dependencies: anymatch: 3.1.3 chokidar: 5.0.0 @@ -22503,7 +22787,7 @@ snapshots: optionalDependencies: '@upstash/redis': 1.37.0 aws4fetch: 1.0.20 - db0: 0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.13)(pg@8.20.0)(postgres@3.4.8)) + db0: 0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260525.1)(@libsql/client@0.17.3)(@types/pg@8.18.0)(@upstash/redis@1.37.0)(kysely@0.28.17)(pg@8.20.0)(postgres@3.4.8)) ioredis: 5.10.1 until-async@3.0.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 2bbc8ce3..46834548 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -32,6 +32,7 @@ catalogs: '@tanstack/react-form': ^1.29.1 '@tanstack/react-query': ^5.100.9 '@vercel/analytics': ^2.0.1 + better-auth: ^1.3.4 class-variance-authority: ^0.7.1 clsx: ^2.1.1 cmdk: ^1.1.1