From 9cc2e3d8abcf7fddb8ac765c2f10e8c0028b41c7 Mon Sep 17 00:00:00 2001 From: Bereket Engida <86073083+Bekacru@users.noreply.github.com> Date: Fri, 23 May 2025 12:44:51 -0700 Subject: [PATCH] feat: MCP plugin (#2666) * chore: wip * wip * feat: mcp plugin * wip * chore: fix lock file * clean up * schema * docs * chore: lint * chore: release v1.2.9-beta.1 * blog * chore: lint --- .../oauth-authorization-server/route.ts | 4 + demo/nextjs/app/api/[transport]/route.ts | 38 + demo/nextjs/app/api/auth/[...all]/route.ts | 8 +- demo/nextjs/lib/auth.ts | 17 +- docs/app/blog/[[...slug]]/page.tsx | 219 +++ docs/app/blog/_components/_layout.tsx | 110 ++ .../app/blog/_components/changelog-layout.tsx | 135 ++ .../blog/_components/default-changelog.tsx | 254 ++++ docs/app/blog/_components/fmt-dates.tsx | 25 + docs/app/blog/_components/icons.tsx | 35 + docs/app/blog/_components/stat-field.tsx | 219 +++ docs/app/blog/layout.tsx | 18 + docs/app/blogs/layout.tsx | 18 + docs/app/blogs/page.tsx | 104 ++ docs/components/nav-bar.tsx | 5 +- docs/components/sidebar-content.tsx | 32 + docs/content/blogs/mcp-auth.mdx | 178 +++ docs/content/blogs/meta.json | 10 + docs/content/docs/plugins/mcp.mdx | 224 +++ docs/lib/blog.ts | 76 + docs/lib/source.ts | 7 +- docs/public/avatar/beka.jpg | Bin 0 -> 10038 bytes docs/public/images/blogs/better auth (1).png | Bin 0 -> 35824 bytes docs/source.config.ts | 17 + examples/nextjs-mcp/.gitignore | 41 + examples/nextjs-mcp/README.md | 93 ++ .../oauth-authorization-server/route.ts | 4 + .../nextjs-mcp/app/api/[transport]/route.ts | 38 + .../nextjs-mcp/app/api/auth/[...all]/route.ts | 4 + examples/nextjs-mcp/app/favicon.ico | Bin 0 -> 25931 bytes examples/nextjs-mcp/app/globals.css | 26 + examples/nextjs-mcp/app/layout.tsx | 34 + examples/nextjs-mcp/app/login/page.tsx | 64 + examples/nextjs-mcp/app/page.tsx | 103 ++ examples/nextjs-mcp/lib/auth.ts | 16 + examples/nextjs-mcp/lib/authClient.ts | 3 + examples/nextjs-mcp/next.config.ts | 7 + examples/nextjs-mcp/package.json | 29 + examples/nextjs-mcp/postcss.config.mjs | 5 + examples/nextjs-mcp/public/file.svg | 1 + examples/nextjs-mcp/public/globe.svg | 1 + examples/nextjs-mcp/public/next.svg | 1 + examples/nextjs-mcp/public/vercel.svg | 1 + examples/nextjs-mcp/public/window.svg | 1 + examples/nextjs-mcp/tsconfig.json | 33 + examples/svelte-kit-example/tsconfig.json | 3 +- packages/better-auth/package.json | 2 +- packages/better-auth/src/plugins/index.ts | 1 + .../better-auth/src/plugins/mcp/authorize.ts | 232 +++ packages/better-auth/src/plugins/mcp/index.ts | 928 ++++++++++++ .../src/plugins/oidc-provider/index.ts | 3 +- .../src/plugins/oidc-provider/types.ts | 8 + packages/cli/package.json | 2 +- packages/expo/package.json | 2 +- packages/stripe/package.json | 2 +- pnpm-lock.yaml | 1338 ++++++++++++++--- 56 files changed, 4540 insertions(+), 239 deletions(-) create mode 100644 demo/nextjs/app/.well-known/oauth-authorization-server/route.ts create mode 100644 demo/nextjs/app/api/[transport]/route.ts create mode 100644 docs/app/blog/[[...slug]]/page.tsx create mode 100644 docs/app/blog/_components/_layout.tsx create mode 100644 docs/app/blog/_components/changelog-layout.tsx create mode 100644 docs/app/blog/_components/default-changelog.tsx create mode 100644 docs/app/blog/_components/fmt-dates.tsx create mode 100644 docs/app/blog/_components/icons.tsx create mode 100644 docs/app/blog/_components/stat-field.tsx create mode 100644 docs/app/blog/layout.tsx create mode 100644 docs/app/blogs/layout.tsx create mode 100644 docs/app/blogs/page.tsx create mode 100644 docs/content/blogs/mcp-auth.mdx create mode 100644 docs/content/blogs/meta.json create mode 100644 docs/content/docs/plugins/mcp.mdx create mode 100644 docs/lib/blog.ts create mode 100644 docs/public/avatar/beka.jpg create mode 100644 docs/public/images/blogs/better auth (1).png create mode 100644 examples/nextjs-mcp/.gitignore create mode 100644 examples/nextjs-mcp/README.md create mode 100644 examples/nextjs-mcp/app/.well-known/oauth-authorization-server/route.ts create mode 100644 examples/nextjs-mcp/app/api/[transport]/route.ts create mode 100644 examples/nextjs-mcp/app/api/auth/[...all]/route.ts create mode 100644 examples/nextjs-mcp/app/favicon.ico create mode 100644 examples/nextjs-mcp/app/globals.css create mode 100644 examples/nextjs-mcp/app/layout.tsx create mode 100644 examples/nextjs-mcp/app/login/page.tsx create mode 100644 examples/nextjs-mcp/app/page.tsx create mode 100644 examples/nextjs-mcp/lib/auth.ts create mode 100644 examples/nextjs-mcp/lib/authClient.ts create mode 100644 examples/nextjs-mcp/next.config.ts create mode 100644 examples/nextjs-mcp/package.json create mode 100644 examples/nextjs-mcp/postcss.config.mjs create mode 100644 examples/nextjs-mcp/public/file.svg create mode 100644 examples/nextjs-mcp/public/globe.svg create mode 100644 examples/nextjs-mcp/public/next.svg create mode 100644 examples/nextjs-mcp/public/vercel.svg create mode 100644 examples/nextjs-mcp/public/window.svg create mode 100644 examples/nextjs-mcp/tsconfig.json create mode 100644 packages/better-auth/src/plugins/mcp/authorize.ts create mode 100644 packages/better-auth/src/plugins/mcp/index.ts diff --git a/demo/nextjs/app/.well-known/oauth-authorization-server/route.ts b/demo/nextjs/app/.well-known/oauth-authorization-server/route.ts new file mode 100644 index 00000000..c236fffd --- /dev/null +++ b/demo/nextjs/app/.well-known/oauth-authorization-server/route.ts @@ -0,0 +1,4 @@ +import { oAuthDiscoveryMetadata } from "better-auth/plugins"; +import { auth } from "../../../lib/auth"; + +export const GET = oAuthDiscoveryMetadata(auth); diff --git a/demo/nextjs/app/api/[transport]/route.ts b/demo/nextjs/app/api/[transport]/route.ts new file mode 100644 index 00000000..056410b4 --- /dev/null +++ b/demo/nextjs/app/api/[transport]/route.ts @@ -0,0 +1,38 @@ +import { createMcpHandler } from "@vercel/mcp-adapter"; +import { withMcpAuth } from "better-auth/plugins"; +import { z } from "zod"; +import { auth } from "@/lib/auth"; + +const handler = withMcpAuth(auth, (req, session) => { + return createMcpHandler( + (server) => { + server.tool( + "echo", + "Echo a message", + { message: z.string() }, + async ({ message }) => { + return { + content: [{ type: "text", text: `Tool echo: ${message}` }], + }; + }, + ); + }, + { + capabilities: { + tools: { + echo: { + description: "Echo a message", + }, + }, + }, + }, + { + redisUrl: process.env.REDIS_URL, + basePath: "/api", + verboseLogs: true, + maxDuration: 60, + }, + )(req); +}); + +export { handler as GET, handler as POST, handler as DELETE }; diff --git a/demo/nextjs/app/api/auth/[...all]/route.ts b/demo/nextjs/app/api/auth/[...all]/route.ts index 6cba29b7..5b67b064 100644 --- a/demo/nextjs/app/api/auth/[...all]/route.ts +++ b/demo/nextjs/app/api/auth/[...all]/route.ts @@ -1,10 +1,4 @@ import { auth } from "@/lib/auth"; import { toNextJsHandler } from "better-auth/next-js"; -import { NextRequest } from "next/server"; -export const { GET } = toNextJsHandler(auth); - -export const POST = async (req: NextRequest) => { - const res = await auth.handler(req); - return res; -}; +export const { GET, POST } = toNextJsHandler(auth); diff --git a/demo/nextjs/lib/auth.ts b/demo/nextjs/lib/auth.ts index 53691a45..45635944 100644 --- a/demo/nextjs/lib/auth.ts +++ b/demo/nextjs/lib/auth.ts @@ -8,8 +8,8 @@ import { oneTap, oAuthProxy, openAPI, - oidcProvider, customSession, + mcp, } from "better-auth/plugins"; import { reactInvitationEmail } from "./email/invitation"; import { LibsqlDialect } from "@libsql/kysely-libsql"; @@ -19,9 +19,9 @@ import { MysqlDialect } from "kysely"; import { createPool } from "mysql2/promise"; import { nextCookies } from "better-auth/next-js"; import { passkey } from "better-auth/plugins/passkey"; -import { expo } from "@better-auth/expo"; import { stripe } from "@better-auth/stripe"; import { Stripe } from "stripe"; +import Database from "better-sqlite3"; const from = process.env.BETTER_AUTH_EMAIL || "delivered@resend.dev"; const to = process.env.TEST_EMAIL || ""; @@ -52,10 +52,7 @@ const STARTER_PRICE_ID = { export const auth = betterAuth({ appName: "Better Auth Demo", - database: { - dialect, - type: process.env.USE_MYSQL ? "mysql" : "sqlite", - }, + database: new Database("auth.db"), emailVerification: { async sendVerificationEmail({ user, url }) { const res = await resend.emails.send({ @@ -117,6 +114,9 @@ export const auth = betterAuth({ }, }, plugins: [ + mcp({ + loginPage: "/sign-in", + }), organization({ async sendInvitationEmail(data) { await resend.emails.send({ @@ -160,9 +160,7 @@ export const auth = betterAuth({ multiSession(), oAuthProxy(), nextCookies(), - oidcProvider({ - loginPage: "/sign-in", - }), + oneTap(), customSession(async (session) => { return { @@ -198,7 +196,6 @@ export const auth = betterAuth({ ], }, }), - expo(), ], trustedOrigins: ["exp://"], }); diff --git a/docs/app/blog/[[...slug]]/page.tsx b/docs/app/blog/[[...slug]]/page.tsx new file mode 100644 index 00000000..7cf64d11 --- /dev/null +++ b/docs/app/blog/[[...slug]]/page.tsx @@ -0,0 +1,219 @@ +import { blogs } from "@/lib/source"; +import { notFound } from "next/navigation"; +import { absoluteUrl, formatDate } from "@/lib/utils"; +import DatabaseTable from "@/components/mdx/database-tables"; +import { cn } from "@/lib/utils"; +import { Step, Steps } from "fumadocs-ui/components/steps"; +import { Tab, Tabs } from "fumadocs-ui/components/tabs"; +import { GenerateSecret } from "@/components/generate-secret"; +import { AnimatePresence } from "@/components/ui/fade-in"; +import { TypeTable } from "fumadocs-ui/components/type-table"; +import { Features } from "@/components/blocks/features"; +import { ForkButton } from "@/components/fork-button"; +import Link from "next/link"; +import defaultMdxComponents from "fumadocs-ui/mdx"; +import { File, Folder, Files } from "fumadocs-ui/components/files"; +import { Accordion, Accordions } from "fumadocs-ui/components/accordion"; +import { Pre } from "fumadocs-ui/components/codeblock"; +import { DocsBody } from "fumadocs-ui/page"; +import { Glow } from "../_components/default-changelog"; +import { IconLink } from "../_components/changelog-layout"; +import { BookIcon, GitHubIcon, XIcon } from "../_components/icons"; +import { DiscordLogoIcon } from "@radix-ui/react-icons"; +import { StarField } from "../_components/stat-field"; +import Image from "next/image"; + +const metaTitle = "Blogs"; +const metaDescription = "Latest changes , fixes and updates."; +const ogImage = "https://better-auth.com/release-og/changelog-og.png"; + +export default async function Page({ + params, +}: { + params: Promise<{ slug?: string[] }>; +}) { + const { slug } = await params; + const page = blogs.getPage(slug); + if (!page) { + notFound(); + } + const MDX = page.data?.body; + const toc = page.data?.toc; + const { title, description, date } = page.data; + return ( +
+
+ + + +
+
+
+ + + +
+

+ {title}{" "} +

+
+ +

{description}

+
+ By {page.data?.author.name} | {formatDate(page.data?.date)} +
+
+ {title} +
+
+
+ + Documentation + + + GitHub + + + Community + +
+

+ + BETTER-AUTH. + +

+
+
+
+
+ + ) => ( + + ), + Step, + Steps, + File, + Folder, + Files, + Tab, + Tabs, + Pre: Pre, + GenerateSecret, + AnimatePresence, + TypeTable, + Features, + ForkButton, + DatabaseTable, + Accordion, + Accordions, + }} + /> + +
+
+ ); +} + +export async function generateMetadata({ + params, +}: { + params: Promise<{ slug?: string[] }>; +}) { + const { slug } = await params; + if (!slug) { + return { + metadataBase: new URL("https://better-auth.com/blogs"), + title: metaTitle, + description: metaDescription, + openGraph: { + title: metaTitle, + description: metaDescription, + images: [ + { + url: ogImage, + }, + ], + url: "https://better-auth.com/blogs", + }, + twitter: { + card: "summary_large_image", + title: metaTitle, + description: metaDescription, + images: [ogImage], + }, + }; + } + const page = blogs.getPage(slug); + if (page == null) notFound(); + const baseUrl = process.env.NEXT_PUBLIC_URL || process.env.VERCEL_URL; + const url = new URL(`${baseUrl}/release-og/${slug.join("")}.png`); + const { title, description } = page.data; + + return { + title, + description, + openGraph: { + title, + description, + type: "website", + url: absoluteUrl(`blogs/${slug.join("")}`), + images: [ + { + url: url.toString(), + width: 1200, + height: 630, + alt: title, + }, + ], + }, + twitter: { + card: "summary_large_image", + title, + description, + images: [url.toString()], + }, + }; +} + +export function generateStaticParams() { + return blogs.generateParams(); +} diff --git a/docs/app/blog/_components/_layout.tsx b/docs/app/blog/_components/_layout.tsx new file mode 100644 index 00000000..4d2c0833 --- /dev/null +++ b/docs/app/blog/_components/_layout.tsx @@ -0,0 +1,110 @@ +import { useId } from "react"; + +import { Intro, IntroFooter } from "./changelog-layout"; +import { StarField } from "./stat-field"; + +function Timeline() { + let id = useId(); + + return ( +
+ + someone is +
+ ); +} + +function Glow() { + let id = useId(); + + return ( +
+ +
+
+ ); +} + +function FixedSidebar({ + main, + footer, +}: { + main: React.ReactNode; + footer: React.ReactNode; +}) { + return ( +
+ +
+
+
+
+ + {main} +
+
+
+ {footer} +
+
+
+
+ ); +} + +export function Layout({ children }: { children: React.ReactNode }) { + return ( + <> + } footer={} /> +
+
+ +
+ {children} +
+
+ + ); +} diff --git a/docs/app/blog/_components/changelog-layout.tsx b/docs/app/blog/_components/changelog-layout.tsx new file mode 100644 index 00000000..0da3ee83 --- /dev/null +++ b/docs/app/blog/_components/changelog-layout.tsx @@ -0,0 +1,135 @@ +import Link from "next/link"; +import { useId } from "react"; + +import clsx from "clsx"; +import { DiscordLogoIcon } from "@radix-ui/react-icons"; + +function BookIcon(props: React.ComponentPropsWithoutRef<"svg">) { + return ( + + ); +} + +function GitHubIcon(props: React.ComponentPropsWithoutRef<"svg">) { + return ( + + ); +} + +function FeedIcon(props: React.ComponentPropsWithoutRef<"svg">) { + return ( + + ); +} + +function XIcon(props: React.ComponentPropsWithoutRef<"svg">) { + return ( + + ); +} + +export function Intro() { + return ( + <> +

+ All of the changes made will be{" "} + available here. +

+

+ Better Auth is comprehensive authentication library for TypeScript that + provides a wide range of features to make authentication easier and more + secure. +

+
+
+ + Documentation + + + GitHub + + + Community + +
+ + ); +} + +export function IntroFooter() { + return ( +

+ Brought to you by{" "} + + BETTER-AUTH. + +

+ ); +} + +export function SignUpForm() { + let id = useId(); + + return ( +
+ + +
+
+ + ); +} + +export function IconLink({ + children, + className, + compact = false, + icon: Icon, + ...props +}: React.ComponentPropsWithoutRef & { + compact?: boolean; + icon?: React.ComponentType<{ className?: string }>; +}) { + return ( + + + {Icon && } + + {children} + + + ); +} diff --git a/docs/app/blog/_components/default-changelog.tsx b/docs/app/blog/_components/default-changelog.tsx new file mode 100644 index 00000000..544aaf58 --- /dev/null +++ b/docs/app/blog/_components/default-changelog.tsx @@ -0,0 +1,254 @@ +import Link from "next/link"; +import { useId } from "react"; +import { cn } from "@/lib/utils"; +import { IconLink } from "./changelog-layout"; +import { BookIcon, GitHubIcon, XIcon } from "./icons"; +import { DiscordLogoIcon } from "@radix-ui/react-icons"; +import { StarField } from "./stat-field"; +import { betterFetch } from "@better-fetch/fetch"; +import Markdown from "react-markdown"; +import defaultMdxComponents from "fumadocs-ui/mdx"; +import rehypeHighlight from "rehype-highlight"; +import "highlight.js/styles/dark.css"; + +export const dynamic = "force-static"; +const ChangelogPage = async () => { + const { data: releases } = await betterFetch< + { + id: number; + tag_name: string; + name: string; + body: string; + html_url: string; + prerelease: boolean; + published_at: string; + }[] + >("https://api.github.com/repos/better-auth/better-auth/releases"); + + const messages = releases + ?.filter((release) => !release.prerelease) + .map((release) => ({ + tag: release.tag_name, + title: release.name, + content: getContent(release.body), + date: new Date(release.published_at).toLocaleDateString("en-US", { + year: "numeric", + month: "short", + day: "numeric", + }), + url: release.html_url, + })); + + function getContent(content: string) { + const lines = content.split("\n"); + const newContext = lines.map((line) => { + if (line.startsWith("- ")) { + const mainContent = line.split(";")[0]; + const context = line.split(";")[2]; + const mentions = context + ?.split(" ") + .filter((word) => word.startsWith("@")) + .map((mention) => { + const username = mention.replace("@", ""); + const avatarUrl = `https://github.com/${username}.png`; + return `[![${mention}](${avatarUrl})](https://github.com/${username})`; + }); + if (!mentions) { + return line; + } + // Remove   + return mainContent.replace(/ /g, "") + " – " + mentions.join(" "); + } + return line; + }); + return newContext.join("\n"); + } + + return ( +
+
+ + + +
+

+ All of the changes made will be{" "} + available here. +

+

+ Better Auth is comprehensive authentication library for TypeScript + that provides a wide range of features to make authentication easier + and more secure. +

+
+
+ + Documentation + + + GitHub + + + Community + +
+

+ + BETTER-AUTH. + +

+
+
+
+
+ +
+ ( + + ), + h2: (props) => ( +

+
+

+ ), + h3: (props) => ( +

+ {props.children?.toString()?.trim()} +
+

+ ), + p: (props) =>

, + ul: (props) => ( +

    + ), + li: (props) =>
  • , + a: ({ className, ...props }: any) => ( + + ), + strong: (props) => ( + + ), + img: (props) => ( + + ), + }} + > + {messages + ?.map((message) => { + return ` +## ${message.title} date=${message.date} + +${message.content} + `; + }) + .join("\n")} + +
+
+
+ ); +}; + +export default ChangelogPage; + +export function Glow() { + let id = useId(); + + return ( +
+ +
+
+ ); +} diff --git a/docs/app/blog/_components/fmt-dates.tsx b/docs/app/blog/_components/fmt-dates.tsx new file mode 100644 index 00000000..7b3841c2 --- /dev/null +++ b/docs/app/blog/_components/fmt-dates.tsx @@ -0,0 +1,25 @@ +import { cn } from "@/lib/utils"; + +const dateFormatter = new Intl.DateTimeFormat("en-US", { + year: "numeric", + month: "short", + day: "numeric", + timeZone: "UTC", +}); + +export function FormattedDate({ + date, + ...props +}: React.ComponentPropsWithoutRef<"time"> & { date: string | Date }) { + date = typeof date === "string" ? new Date(date) : date; + + return ( + + ); +} diff --git a/docs/app/blog/_components/icons.tsx b/docs/app/blog/_components/icons.tsx new file mode 100644 index 00000000..52d7b5f2 --- /dev/null +++ b/docs/app/blog/_components/icons.tsx @@ -0,0 +1,35 @@ +export function BookIcon(props: React.ComponentPropsWithoutRef<"svg">) { + return ( + + ); +} + +export function GitHubIcon(props: React.ComponentPropsWithoutRef<"svg">) { + return ( + + ); +} + +export function FeedIcon(props: React.ComponentPropsWithoutRef<"svg">) { + return ( + + ); +} + +export function XIcon(props: React.ComponentPropsWithoutRef<"svg">) { + return ( + + ); +} diff --git a/docs/app/blog/_components/stat-field.tsx b/docs/app/blog/_components/stat-field.tsx new file mode 100644 index 00000000..5eeb89d2 --- /dev/null +++ b/docs/app/blog/_components/stat-field.tsx @@ -0,0 +1,219 @@ +"use client"; + +import { useEffect, useId, useRef } from "react"; +import clsx from "clsx"; +import { animate, Segment } from "motion/react"; + +type Star = [x: number, y: number, dim?: boolean, blur?: boolean]; + +const stars: Array = [ + [4, 4, true, true], + [4, 44, true], + [36, 22], + [50, 146, true, true], + [64, 43, true, true], + [76, 30, true], + [101, 116], + [140, 36, true], + [149, 134], + [162, 74, true], + [171, 96, true, true], + [210, 56, true, true], + [235, 90], + [275, 82, true, true], + [306, 6], + [307, 64, true, true], + [380, 68, true], + [380, 108, true, true], + [391, 148, true, true], + [405, 18, true], + [412, 86, true, true], + [426, 210, true, true], + [427, 56, true, true], + [538, 138], + [563, 88, true, true], + [611, 154, true, true], + [637, 150], + [651, 146, true], + [682, 70, true, true], + [683, 128], + [781, 82, true, true], + [785, 158, true], + [832, 146, true, true], + [852, 89], +]; + +const constellations: Array> = [ + [ + [247, 103], + [261, 86], + [307, 104], + [357, 36], + ], + [ + [586, 120], + [516, 100], + [491, 62], + [440, 107], + [477, 180], + [516, 100], + ], + [ + [733, 100], + [803, 120], + [879, 113], + [823, 164], + [803, 120], + ], +]; + +function Star({ + blurId, + point: [cx, cy, dim, blur], +}: { + blurId: string; + point: Star; +}) { + let groupRef = useRef>(null); + let ref = useRef>(null); + + useEffect(() => { + if (!groupRef.current || !ref.current) { + return; + } + + let delay = Math.random() * 2; + + let animations = [ + animate(groupRef.current, { opacity: 1 }, { duration: 4, delay }), + animate( + ref.current, + { + opacity: dim ? [0.2, 0.5] : [1, 0.6], + scale: dim ? [1, 1.2] : [1.2, 1], + }, + { + duration: 10, + delay, + }, + ), + ]; + + return () => { + for (let animation of animations) { + animation.cancel(); + } + }; + }, [dim]); + + return ( + + + + ); +} + +function Constellation({ + points, + blurId, +}: { + points: Array; + blurId: string; +}) { + let ref = useRef>(null); + let uniquePoints = points.filter( + (point, pointIndex) => + points.findIndex((p) => String(p) === String(point)) === pointIndex, + ); + let isFilled = uniquePoints.length !== points.length; + + useEffect(() => { + if (!ref.current) { + return; + } + + let sequence: Array = [ + [ + ref.current, + { strokeDashoffset: 0, visibility: "visible" }, + { duration: 5, delay: Math.random() * 3 + 2 }, + ], + ]; + + if (isFilled) { + sequence.push([ + ref.current, + { fill: "rgb(255 255 255 / 0.02)" }, + { duration: 1 }, + ]); + } + + let animation = animate(sequence); + + return () => { + animation.cancel(); + }; + }, [isFilled]); + + return ( + <> + + {uniquePoints.map((point, pointIndex) => ( + + ))} + + ); +} + +export function StarField({ className }: { className?: string }) { + let blurId = useId(); + + return ( + + ); +} diff --git a/docs/app/blog/layout.tsx b/docs/app/blog/layout.tsx new file mode 100644 index 00000000..3ce50d1d --- /dev/null +++ b/docs/app/blog/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Blog - Better Auth", + description: "Latest updates, articles, and insights about Better Auth", +}; + +interface BlogLayoutProps { + children: React.ReactNode; +} + +export default function BlogLayout({ children }: BlogLayoutProps) { + return ( +
+
{children}
+
+ ); +} diff --git a/docs/app/blogs/layout.tsx b/docs/app/blogs/layout.tsx new file mode 100644 index 00000000..3ce50d1d --- /dev/null +++ b/docs/app/blogs/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Blog - Better Auth", + description: "Latest updates, articles, and insights about Better Auth", +}; + +interface BlogLayoutProps { + children: React.ReactNode; +} + +export default function BlogLayout({ children }: BlogLayoutProps) { + return ( +
+
{children}
+
+ ); +} diff --git a/docs/app/blogs/page.tsx b/docs/app/blogs/page.tsx new file mode 100644 index 00000000..eebf0a91 --- /dev/null +++ b/docs/app/blogs/page.tsx @@ -0,0 +1,104 @@ +import { formatBlogDate } from "@/lib/blog"; +import Link from "next/link"; +import { blogs } from "@/lib/source"; +import { IconLink } from "../blog/_components/changelog-layout"; +import { GitHubIcon, BookIcon, XIcon } from "../blog/_components/icons"; +import { Glow } from "../blog/_components/default-changelog"; +import { StarField } from "../blog/_components/stat-field"; +import { DiscordLogoIcon } from "@radix-ui/react-icons"; + +export default async function BlogPage() { + const posts = blogs.getPages(); + + return ( +
+
+ + + +
+

+ Blogs +

+ +

+ Latest updates, articles, and insights about Better Auth +

+
+
+ + Documentation + + + GitHub + + + Community + +
+

+ + BETTER-AUTH. + +

+
+
+
+
+ {posts.map((post) => ( +
+
+ {/* {post.data?.image && ( + {post.data.title} + )} */} +
+

+ {formatBlogDate(post.data.date)} +

+

{post.data?.title}

+

+ {post.data?.description.substring(0, 100)}... +

+
+
+

+ {post.data.structuredData.contents[0].content.substring(0, 250)} + ... +

+ +

Read More

+ + + View Article + +
+ ))} +
+
+
+ ); +} diff --git a/docs/components/nav-bar.tsx b/docs/components/nav-bar.tsx index eab44a75..7a6ea987 100644 --- a/docs/components/nav-bar.tsx +++ b/docs/components/nav-bar.tsx @@ -115,7 +115,10 @@ export const navMenu = [ name: "docs", path: "/docs", }, - + { + name: "blog", + path: "/blogs", + }, { name: "changelogs", path: "/changelogs", diff --git a/docs/components/sidebar-content.tsx b/docs/components/sidebar-content.tsx index 2b9ae4b0..647a2817 100644 --- a/docs/components/sidebar-content.tsx +++ b/docs/components/sidebar-content.tsx @@ -1270,6 +1270,38 @@ C0.7,239.6,62.1,0.5,62.2,0.4c0,0,54,13.8,119.9,30.8S302.1,62,302.2,62c0.2,0,0.2, href: "/docs/plugins/api-key", icon: () => , }, + { + title: "MCP", + icon: () => ( + + + + + + ), + href: "/docs/plugins/mcp", + }, { title: "Organization", icon: () => , diff --git a/docs/content/blogs/mcp-auth.mdx b/docs/content/blogs/mcp-auth.mdx new file mode 100644 index 00000000..58952780 --- /dev/null +++ b/docs/content/blogs/mcp-auth.mdx @@ -0,0 +1,178 @@ +--- +title: Authenicating MCP servers +description: A deep dive into how to implement MCP auth with Better Auth & Vercel MCP adapter +date: 2025-05-19 +image: /images/blogs/mcp-auth.png +author: + name: Bereket Engida + avatar: /avatars/beka.jpg + twitter: imbereket +tags: + - mcp + - vercel + - ai + - nextjs + - neon +--- + +## Introduction + +[MCP](https://modelcontextprotocol.io) is an open protocol that standardizes how applications provide context to LLMs. It provides a standardized way to connect AI models to different data sources and tools. It's been sometime since the MCP spec by anthropic become a standard for building LLM based apps. + +The protocol covers both client and server implementations. When you make a server for MCP clients to connect to, one of the requirements is to have a proper way to authenticate and authorize them. The MCP spec recommends using [OAuth 2.0](https://oauth.net/2/) for this purpose with some additional requirements. + +In this article, we'll see how Better Auth MCP plugin integrates with your MCP server to authenticate and authorize MCP clients. + +## How Better Auth MCP Plugin Works + +The Better Auth MCP plugin implements the OAuth 2.0 authorization flow with some MCP-specific modifications. Let's break down how it works: + +### 1. OAuth Discovery Endpoint + +First, the plugin helps you expose an OAuth discovery endpoint at `/.well-known/oauth-authorization-server` that provides metadata about the authorization server: + + +```ts title=".well-known/oauth-authorization-server/route.ts" +import { oAuthDiscoveryMetadata } from "better-auth/plugins"; +import { auth } from "../../../lib/auth"; + +export const GET = oAuthDiscoveryMetadata(auth); +``` + +This endpoint returns standard OAuth metadata including: +- Authorization endpoint (`/mcp/authorize`) +- Token endpoint (`/mcp/token`) +- Supported scopes (`openid`, `profile`, `email`, `offline_access`) +- Supported response types (`code`) +- PKCE challenge methods (`S256`) + +### 2. Authorization Flow + +When an MCP client (like Claude Desktop) wants to connect to your server, it initiates the OAuth flow: + +1. The client makes a request to your authorization endpoint with: + - `client_id`: Unique identifier for the client + - `redirect_uri`: Where to send the authorization code + - `response_type`: Always "code" for MCP + - `code_challenge`: PKCE challenge for security + - `scope`: Requested permissions (e.g. "openid profile") + +2. If the client isn't registered yet (no `client_id`), it first needs to register using the dynamic client registration endpoint: + +```ts +// Client sends POST request to /mcp/register +{ + "redirect_uris": ["https://client.example.com/callback"], + "client_name": "My MCP Client", + "logo_uri": "https://client.example.com/logo.png", + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "response_types": ["code"], + "scope": "openid profile" +} + +// Server validates and responds with: +{ + "client_id": "generated-client-id", + "client_secret": "generated-client-secret", + "client_id_issued_at": 1683900000, + "client_secret_expires_at": 0 +} +``` + +3. Once registered (or if already registered), if the user isn't logged in, they're redirected to your login page: +```ts +await ctx.setSignedCookie( + 'oidc_login_prompt', + JSON.stringify(ctx.query), + ctx.context.secret, + { + maxAge: 600, + path: '/', + sameSite: 'lax', + } +); +throw ctx.redirect(`${options.loginPage}?${queryFromURL}`); +``` + +4. After login, the plugin validates: + - Client ID exists and is enabled + - Redirect URI matches registered URIs + - Requested scopes are valid + - PKCE challenge is present (if required) + +5. If everything is valid, it generates an authorization code: +```ts +const code = generateRandomString(32, "a-z", "A-Z", "0-9"); +const codeExpiresInMs = opts.codeExpiresIn * 1000; +const expiresAt = new Date(Date.now() + codeExpiresInMs); +``` + +### 3. Protecting Your MCP Server + +The plugin provides a `withMcpAuth` middleware to protect your MCP server routes: + +```ts +import { withMcpAuth } from "better-auth/plugins"; + +const handler = withMcpAuth(auth, (req, session) => { + // session contains the access token with scopes and user ID + return createMcpHandler( + (server) => { + // Define your MCP tools here + server.tool("echo", "Echo a message", + { message: z.string() }, + async ({ message }) => { + return { + content: [{ type: "text", text: message }], + }; + } + ); + }, + // ... rest of your MCP config + )(req); +}); +``` + + +or you can use `auth.api.getMcpSession` to get the session from the request headers. + +```ts +const session = await auth.api.getMcpSession({ + headers: req.headers +}); +``` + +Make sure to handle the unauthenticated case properly by returning a 401 status code. + +```ts +if (!session) { + return new Response(null, { + status: 401, + headers: { + "WWW-Authenticate": "Bearer" + } + }); +} +``` + +### 4. Configuration Options + +The plugin is highly configurable through the `mcp()` function: + +```ts +mcp({ + loginPage: "/sign-in", // Where to redirect for auth + oidcConfig: { + codeExpiresIn: 600, // Auth code expiry in seconds + accessTokenExpiresIn: 3600, // Access token expiry + refreshTokenExpiresIn: 604800, // Refresh token expiry + scopes: ["openid", "profile", "email"], // Supported scopes + requirePKCE: true, // Require PKCE security + } +}) +``` + +## Conclusion + +The Better Auth MCP plugin provides a secure and flexible way to authenticate and authorize MCP clients. It handles the OAuth flow, client registration, and session management, allowing you to focus on building your MCP server. diff --git a/docs/content/blogs/meta.json b/docs/content/blogs/meta.json new file mode 100644 index 00000000..47da3118 --- /dev/null +++ b/docs/content/blogs/meta.json @@ -0,0 +1,10 @@ +{ + "title": "Blog", + "description": "Latest updates, articles, and insights about Better Auth", + "items": [ + { + "title": "Latest", + "items": [] + } + ] +} diff --git a/docs/content/docs/plugins/mcp.mdx b/docs/content/docs/plugins/mcp.mdx new file mode 100644 index 00000000..03ee4ecf --- /dev/null +++ b/docs/content/docs/plugins/mcp.mdx @@ -0,0 +1,224 @@ +--- +title: MCP +description: MCP provider plugin for Better Auth +--- + +`OAuth` `MCP` + +The **MCP** plugin lets your app act as an OAuth provider for MCP clients. It handles authentication and makes it easy to issue and manage access tokens for MCP applications. + +## Installation + + + + ### Add the Plugin + + Add the MCP plugin to your auth configuration and specify the login page path. + + ```ts title="auth.ts" + import { betterAuth } from "better-auth"; + import { mcp } from "better-auth/plugins"; + + export const auth = betterAuth({ + plugins: [ + mcp({ + loginPage: "/sign-in" // path to your login page + }) + ] + }); + ``` + + This doesn't have a client plugin, so you don't need to make any changes to your authClient. + + + + + ### Generate Schema + + Run the migration or generate the schema to add the necessary fields and tables to the database. + + + + ```bash + npx @better-auth/cli migrate + ``` + + + ```bash + npx @better-auth/cli generate + ``` + + + The MCP plugin uses the same schema as the OIDC Provider plugin. See the [OIDC Provider Schema](#schema) section for details. + + + +## Usage + +### OAuth Discovery Metadata + +Add a route to expose OAuth metadata for MCP clients: + +```ts title=".well-known/oauth-authorization-server/route.ts" +import { oAuthDiscoveryMetadata } from "better-auth/plugins"; +import { auth } from "../../../lib/auth"; + +export const GET = oAuthDiscoveryMetadata(auth); +``` + +### MCP Session Handling + +You can use the helper function `withMcpAuth` to get the session and handle unauthenticated calls automatically. + + +```ts title="api/[transport]/route.ts" +import { auth } from "@/lib/auth"; +import { createMcpHandler } from "@vercel/mcp-adapter"; +import { withMcpAuth } from "better-auth/plugins"; +import { z } from "zod"; + +const handler = withMcpAuth(auth, (req, session) => { + // session contains the access token record with scopes and user ID + return createMcpHandler( + (server) => { + server.tool( + "echo", + "Echo a message", + { message: z.string() }, + async ({ message }) => { + return { + content: [{ type: "text", text: `Tool echo: ${message}` }], + }; + }, + ); + }, + { + capabilities: { + tools: { + echo: { + description: "Echo a message", + }, + }, + }, + }, + { + redisUrl: process.env.REDIS_URL, + basePath: "/api", + verboseLogs: true, + maxDuration: 60, + }, + )(req); +}); + +export { handler as GET, handler as POST, handler as DELETE }; +``` + +You can also use `auth.api.getMCPSession` to get the session using the access token sent from the MCP client: + +```ts title="api/[transport]/route.ts" +import { auth } from "@/lib/auth"; +import { createMcpHandler } from "@vercel/mcp-adapter"; +import { withMcpAuth } from "better-auth/plugins"; +import { z } from "zod"; + +const handler = async (req: Request) => { + // session contains the access token record with scopes and user ID + const session = await auth.api.getMCPSession({ + headers: req.headers + }) + if(!session){ + //this is important and you must return 401 + return new Response(null, { + status: 401 + }) + } + return createMcpHandler( + (server) => { + server.tool( + "echo", + "Echo a message", + { message: z.string() }, + async ({ message }) => { + return { + content: [{ type: "text", text: `Tool echo: ${message}` }], + }; + }, + ); + }, + { + capabilities: { + tools: { + echo: { + description: "Echo a message", + }, + }, + }, + }, + { + redisUrl: process.env.REDIS_URL, + basePath: "/api", + verboseLogs: true, + maxDuration: 60, + }, + )(req); +} + +export { handler as GET, handler as POST, handler as DELETE }; +``` + +## Configuration + +The MCP plugin accepts the following configuration options: + + + +### OIDC Configuration + +The plugin supports additional OIDC configuration options through the `oidcConfig` parameter: + + + +## Schema + +The MCP plugin uses the same schema as the OIDC Provider plugin. See the [OIDC Provider Schema](#schema) section for details. diff --git a/docs/lib/blog.ts b/docs/lib/blog.ts new file mode 100644 index 00000000..8f314ad8 --- /dev/null +++ b/docs/lib/blog.ts @@ -0,0 +1,76 @@ +import { readFile, readdir } from "fs/promises"; +import matter from "gray-matter"; +import { join } from "path"; +import { cache } from "react"; + +export interface BlogPost { + _id: string; + slug: string; + title: string; + description?: string; + date: string; + content: string; + image?: string; + author?: { + name: string; + avatar?: string; + twitter?: string; + }; + tags?: string[]; +} + +const BLOGS_PATH = join(process.cwd(), "docs/content/blogs"); + +export const getBlogPost = cache( + async (slug: string): Promise => { + try { + const filePath = join(BLOGS_PATH, `${slug}.mdx`); + const source = await readFile(filePath, "utf-8"); + const { data, content } = matter(source); + + return { + _id: slug, + slug, + content, + title: data.title, + description: data.description, + date: data.date, + image: data.image, + author: data.author, + tags: data.tags, + }; + } catch (error) { + return null; + } + }, +); + +export const getAllBlogPosts = cache(async (): Promise => { + try { + const files = await readdir(BLOGS_PATH); + const mdxFiles = files.filter((file) => file.endsWith(".mdx")); + + const posts = await Promise.all( + mdxFiles.map(async (file) => { + const slug = file.replace(/\.mdx$/, ""); + const post = await getBlogPost(slug); + return post; + }), + ); + + return posts + .filter((post): post is BlogPost => post !== null) + .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); + } catch (error) { + return []; + } +}); + +export function formatBlogDate(date: Date) { + let d = new Date(date); + return d.toLocaleDateString("en-US", { + month: "short", + day: "numeric", + year: "numeric", + }); +} diff --git a/docs/lib/source.ts b/docs/lib/source.ts index 579c7be1..b8d7e4f2 100644 --- a/docs/lib/source.ts +++ b/docs/lib/source.ts @@ -1,4 +1,4 @@ -import { changelogCollection, docs } from "@/.source"; +import { changelogCollection, docs, blogCollection } from "@/.source"; import { loader } from "fumadocs-core/source"; import { createMDXSource } from "fumadocs-mdx"; @@ -11,3 +11,8 @@ export const changelogs = loader({ baseUrl: "/changelogs", source: createMDXSource(changelogCollection), }); + +export const blogs = loader({ + baseUrl: "/blogs", + source: createMDXSource(blogCollection), +}); diff --git a/docs/public/avatar/beka.jpg b/docs/public/avatar/beka.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0d0873e3bf006571f2a16fb9f82e014c576723cc GIT binary patch literal 10038 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�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 { + //session => This isn’t a typical Better Auth session - instead, it returns the access token record along with the scopes and user ID. + return createMcpHandler( + (server) => { + server.tool( + "echo", + "Echo a message", + { message: z.string() }, + async ({ message }) => { + return { + content: [{ type: "text", text: `Tool echo: ${message}` }], + }; + }, + ); + }, + { + capabilities: { + tools: { + echo: { + description: "Echo a message", + }, + }, + }, + }, + { + redisUrl: process.env.REDIS_URL, + basePath: "/api", + verboseLogs: true, + maxDuration: 60, + }, + )(req); +}); + +export { handler as GET, handler as POST, handler as DELETE }; +``` + +And that's it!! \ No newline at end of file diff --git a/examples/nextjs-mcp/app/.well-known/oauth-authorization-server/route.ts b/examples/nextjs-mcp/app/.well-known/oauth-authorization-server/route.ts new file mode 100644 index 00000000..c236fffd --- /dev/null +++ b/examples/nextjs-mcp/app/.well-known/oauth-authorization-server/route.ts @@ -0,0 +1,4 @@ +import { oAuthDiscoveryMetadata } from "better-auth/plugins"; +import { auth } from "../../../lib/auth"; + +export const GET = oAuthDiscoveryMetadata(auth); diff --git a/examples/nextjs-mcp/app/api/[transport]/route.ts b/examples/nextjs-mcp/app/api/[transport]/route.ts new file mode 100644 index 00000000..a8b9b5b6 --- /dev/null +++ b/examples/nextjs-mcp/app/api/[transport]/route.ts @@ -0,0 +1,38 @@ +import { auth } from "@/lib/auth"; +import { createMcpHandler } from "@vercel/mcp-adapter"; +import { withMcpAuth } from "better-auth/plugins"; +import { z } from "zod"; + +const handler = withMcpAuth(auth, (req, sesssion) => { + return createMcpHandler( + (server) => { + server.tool( + "echo", + "Echo a message", + { message: z.string() }, + async ({ message }) => { + return { + content: [{ type: "text", text: `Tool echo: ${message}` }], + }; + }, + ); + }, + { + capabilities: { + tools: { + echo: { + description: "Echo a message", + }, + }, + }, + }, + { + redisUrl: process.env.REDIS_URL, + basePath: "/api", + verboseLogs: true, + maxDuration: 60, + }, + )(req); +}); + +export { handler as GET, handler as POST, handler as DELETE }; diff --git a/examples/nextjs-mcp/app/api/auth/[...all]/route.ts b/examples/nextjs-mcp/app/api/auth/[...all]/route.ts new file mode 100644 index 00000000..5b67b064 --- /dev/null +++ b/examples/nextjs-mcp/app/api/auth/[...all]/route.ts @@ -0,0 +1,4 @@ +import { auth } from "@/lib/auth"; +import { toNextJsHandler } from "better-auth/next-js"; + +export const { GET, POST } = toNextJsHandler(auth); diff --git a/examples/nextjs-mcp/app/favicon.ico b/examples/nextjs-mcp/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 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 LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/examples/nextjs-mcp/app/globals.css b/examples/nextjs-mcp/app/globals.css new file mode 100644 index 00000000..a2dc41ec --- /dev/null +++ b/examples/nextjs-mcp/app/globals.css @@ -0,0 +1,26 @@ +@import "tailwindcss"; + +:root { + --background: #ffffff; + --foreground: #171717; +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +body { + background: var(--background); + color: var(--foreground); + font-family: Arial, Helvetica, sans-serif; +} diff --git a/examples/nextjs-mcp/app/layout.tsx b/examples/nextjs-mcp/app/layout.tsx new file mode 100644 index 00000000..7371307e --- /dev/null +++ b/examples/nextjs-mcp/app/layout.tsx @@ -0,0 +1,34 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/examples/nextjs-mcp/app/login/page.tsx b/examples/nextjs-mcp/app/login/page.tsx new file mode 100644 index 00000000..358987a0 --- /dev/null +++ b/examples/nextjs-mcp/app/login/page.tsx @@ -0,0 +1,64 @@ +"use client"; + +import { authClient } from "@/lib/authClient"; +import { useState } from "react"; + +export default function Login() { + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const session = authClient.useSession(); + return ( +
+ {JSON.stringify({ session })} +

Sign Up

+
+

Name

+ setName(e.target.value)} + /> +
+
+

Email

+ setEmail(e.target.value)} + /> +
+
+

Password

+ setPassword(e.target.value)} + /> +
+ + +
+ ); +} diff --git a/examples/nextjs-mcp/app/page.tsx b/examples/nextjs-mcp/app/page.tsx new file mode 100644 index 00000000..721a4be1 --- /dev/null +++ b/examples/nextjs-mcp/app/page.tsx @@ -0,0 +1,103 @@ +import Image from "next/image"; + +export default function Home() { + return ( +
+
+ Next.js logo +
    +
  1. + Get started by editing{" "} + + app/page.tsx + + . +
  2. +
  3. + Save and see your changes instantly. +
  4. +
+ + +
+ +
+ ); +} diff --git a/examples/nextjs-mcp/lib/auth.ts b/examples/nextjs-mcp/lib/auth.ts new file mode 100644 index 00000000..d52c35a4 --- /dev/null +++ b/examples/nextjs-mcp/lib/auth.ts @@ -0,0 +1,16 @@ +import { betterAuth } from "better-auth"; +import { mcp } from "better-auth/plugins"; +import Database from "better-sqlite3"; + +export const auth = betterAuth({ + database: new Database("./auth.db"), + baseURL: "http://localhost:3000", + plugins: [ + mcp({ + loginPage: "/login", + }), + ], + emailAndPassword: { + enabled: true, + }, +}); diff --git a/examples/nextjs-mcp/lib/authClient.ts b/examples/nextjs-mcp/lib/authClient.ts new file mode 100644 index 00000000..f1012dd4 --- /dev/null +++ b/examples/nextjs-mcp/lib/authClient.ts @@ -0,0 +1,3 @@ +import { createAuthClient } from "better-auth/react"; + +export const authClient = createAuthClient(); diff --git a/examples/nextjs-mcp/next.config.ts b/examples/nextjs-mcp/next.config.ts new file mode 100644 index 00000000..7921f35d --- /dev/null +++ b/examples/nextjs-mcp/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/examples/nextjs-mcp/package.json b/examples/nextjs-mcp/package.json new file mode 100644 index 00000000..4a975e8d --- /dev/null +++ b/examples/nextjs-mcp/package.json @@ -0,0 +1,29 @@ +{ + "name": "nextjs-mcp", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@types/better-sqlite3": "^7.6.12", + "@vercel/mcp-adapter": "^0.4.1", + "better-auth": "workspace:^", + "better-sqlite3": "^11.6.0", + "next": "15.3.2", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "zod": "^3.24.4" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "tailwindcss": "^4", + "typescript": "^5" + } +} \ No newline at end of file diff --git a/examples/nextjs-mcp/postcss.config.mjs b/examples/nextjs-mcp/postcss.config.mjs new file mode 100644 index 00000000..f50127cd --- /dev/null +++ b/examples/nextjs-mcp/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"], +}; + +export default config; diff --git a/examples/nextjs-mcp/public/file.svg b/examples/nextjs-mcp/public/file.svg new file mode 100644 index 00000000..004145cd --- /dev/null +++ b/examples/nextjs-mcp/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/nextjs-mcp/public/globe.svg b/examples/nextjs-mcp/public/globe.svg new file mode 100644 index 00000000..567f17b0 --- /dev/null +++ b/examples/nextjs-mcp/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/nextjs-mcp/public/next.svg b/examples/nextjs-mcp/public/next.svg new file mode 100644 index 00000000..5174b28c --- /dev/null +++ b/examples/nextjs-mcp/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/nextjs-mcp/public/vercel.svg b/examples/nextjs-mcp/public/vercel.svg new file mode 100644 index 00000000..77053960 --- /dev/null +++ b/examples/nextjs-mcp/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/nextjs-mcp/public/window.svg b/examples/nextjs-mcp/public/window.svg new file mode 100644 index 00000000..b2b2a44f --- /dev/null +++ b/examples/nextjs-mcp/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/nextjs-mcp/tsconfig.json b/examples/nextjs-mcp/tsconfig.json new file mode 100644 index 00000000..3addb7e6 --- /dev/null +++ b/examples/nextjs-mcp/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + "app/.well-known/oauth-authorization-server/route.ts" + ], + "exclude": ["node_modules"] +} diff --git a/examples/svelte-kit-example/tsconfig.json b/examples/svelte-kit-example/tsconfig.json index 3c05e398..0f47472f 100644 --- a/examples/svelte-kit-example/tsconfig.json +++ b/examples/svelte-kit-example/tsconfig.json @@ -8,7 +8,6 @@ "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, - "strict": true, - "moduleResolution": "Bundler" + "strict": true } } diff --git a/packages/better-auth/package.json b/packages/better-auth/package.json index fba672ca..7c0f6655 100644 --- a/packages/better-auth/package.json +++ b/packages/better-auth/package.json @@ -1,6 +1,6 @@ { "name": "better-auth", - "version": "1.2.8", + "version": "1.2.9-beta.1", "description": "The most comprehensive authentication library for TypeScript.", "type": "module", "repository": { diff --git a/packages/better-auth/src/plugins/index.ts b/packages/better-auth/src/plugins/index.ts index f86e7871..e6d9d5f6 100644 --- a/packages/better-auth/src/plugins/index.ts +++ b/packages/better-auth/src/plugins/index.ts @@ -22,3 +22,4 @@ export * from "./captcha"; export * from "./api-key"; export * from "./haveibeenpwned"; export * from "./one-time-token"; +export * from "./mcp"; diff --git a/packages/better-auth/src/plugins/mcp/authorize.ts b/packages/better-auth/src/plugins/mcp/authorize.ts new file mode 100644 index 00000000..1c5a75d2 --- /dev/null +++ b/packages/better-auth/src/plugins/mcp/authorize.ts @@ -0,0 +1,232 @@ +import { APIError } from "better-call"; +import type { GenericEndpointContext } from "../../types"; +import { getSessionFromCtx } from "../../api"; +import type { + AuthorizationQuery, + Client, + OIDCOptions, +} from "../oidc-provider/types"; +import { generateRandomString } from "../../crypto"; + +function redirectErrorURL(url: string, error: string, description: string) { + return `${ + url.includes("?") ? "&" : "?" + }error=${error}&error_description=${description}`; +} + +export async function authorizeMCPOAuth( + ctx: GenericEndpointContext, + options: OIDCOptions, +) { + ctx.setHeader("Access-Control-Allow-Origin", "*"); + ctx.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS"); + ctx.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); + ctx.setHeader("Access-Control-Max-Age", "86400"); + const opts = { + codeExpiresIn: 600, + defaultScope: "openid", + ...options, + scopes: [ + "openid", + "profile", + "email", + "offline_access", + ...(options?.scopes || []), + ], + }; + if (!ctx.request) { + throw new APIError("UNAUTHORIZED", { + error_description: "request not found", + error: "invalid_request", + }); + } + const session = await getSessionFromCtx(ctx); + if (!session) { + /** + * If the user is not logged in, we need to redirect them to the + * login page. + */ + await ctx.setSignedCookie( + "oidc_login_prompt", + JSON.stringify(ctx.query), + ctx.context.secret, + { + maxAge: 600, + path: "/", + sameSite: "lax", + }, + ); + const queryFromURL = ctx.request.url?.split("?")[1]; + throw ctx.redirect(`${options.loginPage}?${queryFromURL}`); + } + + const query = ctx.query as AuthorizationQuery; + console.log(query); + if (!query.client_id) { + throw ctx.redirect(`${ctx.context.baseURL}/error?error=invalid_client`); + } + + if (!query.response_type) { + throw ctx.redirect( + redirectErrorURL( + `${ctx.context.baseURL}/error`, + "invalid_request", + "response_type is required", + ), + ); + } + + const client = await ctx.context.adapter + .findOne>({ + model: "oauthApplication", + where: [ + { + field: "clientId", + value: ctx.query.client_id, + }, + ], + }) + .then((res) => { + if (!res) { + return null; + } + return { + ...res, + redirectURLs: res.redirectURLs.split(","), + metadata: res.metadata ? JSON.parse(res.metadata) : {}, + } as Client; + }); + console.log(client); + if (!client) { + throw ctx.redirect(`${ctx.context.baseURL}/error?error=invalid_client`); + } + const redirectURI = client.redirectURLs.find( + (url) => url === ctx.query.redirect_uri, + ); + + if (!redirectURI || !query.redirect_uri) { + /** + * show UI error here warning the user that the redirect URI is invalid + */ + throw new APIError("BAD_REQUEST", { + message: "Invalid redirect URI", + }); + } + if (client.disabled) { + throw ctx.redirect(`${ctx.context.baseURL}/error?error=client_disabled`); + } + + if (query.response_type !== "code") { + throw ctx.redirect( + `${ctx.context.baseURL}/error?error=unsupported_response_type`, + ); + } + + const requestScope = + query.scope?.split(" ").filter((s) => s) || opts.defaultScope.split(" "); + const invalidScopes = requestScope.filter((scope) => { + const isInvalid = + !opts.scopes.includes(scope) || + (scope === "offline_access" && query.prompt !== "consent"); + return isInvalid; + }); + if (invalidScopes.length) { + throw ctx.redirect( + redirectErrorURL( + query.redirect_uri, + "invalid_scope", + `The following scopes are invalid: ${invalidScopes.join(", ")}`, + ), + ); + } + + if ( + (!query.code_challenge || !query.code_challenge_method) && + options.requirePKCE + ) { + throw ctx.redirect( + redirectErrorURL( + query.redirect_uri, + "invalid_request", + "pkce is required", + ), + ); + } + + if (!query.code_challenge_method) { + query.code_challenge_method = "plain"; + } + + if ( + ![ + "s256", + options.allowPlainCodeChallengeMethod ? "plain" : "s256", + ].includes(query.code_challenge_method?.toLowerCase() || "") + ) { + throw ctx.redirect( + redirectErrorURL( + query.redirect_uri, + "invalid_request", + "invalid code_challenge method", + ), + ); + } + + const code = generateRandomString(32, "a-z", "A-Z", "0-9"); + const codeExpiresInMs = opts.codeExpiresIn * 1000; + const expiresAt = new Date(Date.now() + codeExpiresInMs); + try { + /** + * Save the code in the database + */ + await ctx.context.internalAdapter.createVerificationValue( + { + value: JSON.stringify({ + clientId: client.clientId, + redirectURI: query.redirect_uri, + scope: requestScope, + userId: session.user.id, + authTime: session.session.createdAt.getTime(), + /** + * If the prompt is set to `consent`, then we need + * to require the user to consent to the scopes. + * + * This means the code now needs to be treated as a + * consent request. + * + * once the user consents, teh code will be updated + * with the actual code. This is to prevent the + * client from using the code before the user + * consents. + */ + requireConsent: query.prompt === "consent", + state: query.prompt === "consent" ? query.state : null, + codeChallenge: query.code_challenge, + codeChallengeMethod: query.code_challenge_method, + nonce: query.nonce, + }), + identifier: code, + expiresAt, + }, + ctx, + ); + } catch (e) { + throw ctx.redirect( + redirectErrorURL( + query.redirect_uri, + "server_error", + "An error occurred while processing the request", + ), + ); + } + + const redirectURIWithCode = new URL(redirectURI); + redirectURIWithCode.searchParams.set("code", code); + redirectURIWithCode.searchParams.set("state", ctx.query.state); + + if (query.prompt !== "consent") { + throw ctx.redirect(redirectURIWithCode.toString()); + } + + throw ctx.redirect(redirectURIWithCode.toString()); +} diff --git a/packages/better-auth/src/plugins/mcp/index.ts b/packages/better-auth/src/plugins/mcp/index.ts new file mode 100644 index 00000000..8002a8c2 --- /dev/null +++ b/packages/better-auth/src/plugins/mcp/index.ts @@ -0,0 +1,928 @@ +import { z } from "zod"; +import { + createAuthEndpoint, + createAuthMiddleware, + type BetterAuthPlugin, +} from ".."; +import { + oidcProvider, + type Client, + type CodeVerificationValue, + type OAuthAccessToken, + type OIDCMetadata, + type OIDCOptions, +} from "../oidc-provider"; +import { APIError, getSessionFromCtx } from "../../api"; +import { base64 } from "@better-auth/utils/base64"; +import { generateRandomString } from "../../crypto"; +import { createHash } from "@better-auth/utils/hash"; +import { subtle } from "@better-auth/utils"; +import { SignJWT } from "jose"; +import type { GenericEndpointContext } from "../../types"; +import { parseSetCookieHeader } from "../../cookies"; +import { schema } from "../oidc-provider/schema"; +import { authorizeMCPOAuth } from "./authorize"; + +interface MCPOptions { + loginPage: string; + oidcConfig?: OIDCOptions; +} + +export const getMCPProviderMetadata = ( + ctx: GenericEndpointContext, + options?: OIDCOptions, +): OIDCMetadata => { + const issuer = ctx.context.options.baseURL as string; + const baseURL = ctx.context.baseURL; + if (!issuer || !baseURL) { + throw new APIError("INTERNAL_SERVER_ERROR", { + error: "invalid_issuer", + error_description: + "issuer or baseURL is not set. If you're the app developer, please make sure to set the `baseURL` in your auth config.", + }); + } + return { + issuer, + authorization_endpoint: `${baseURL}/mcp/authorize`, + token_endpoint: `${baseURL}/mcp/token`, + userinfo_endpoint: `${baseURL}/mcp/userinfo`, + jwks_uri: `${baseURL}/mcp/jwks`, + registration_endpoint: `${baseURL}/mcp/register`, + scopes_supported: ["openid", "profile", "email", "offline_access"], + response_types_supported: ["code"], + response_modes_supported: ["query"], + grant_types_supported: ["authorization_code"], + acr_values_supported: [ + "urn:mace:incommon:iap:silver", + "urn:mace:incommon:iap:bronze", + ], + subject_types_supported: ["public"], + id_token_signing_alg_values_supported: ["RS256", "none"], + token_endpoint_auth_methods_supported: [ + "client_secret_basic", + "client_secret_post", + ], + code_challenge_methods_supported: ["S256"], + claims_supported: [ + "sub", + "iss", + "aud", + "exp", + "nbf", + "iat", + "jti", + "email", + "email_verified", + "name", + ], + ...options?.metadata, + }; +}; + +export const mcp = (options: MCPOptions) => { + const opts = { + codeExpiresIn: 600, + defaultScope: "openid", + accessTokenExpiresIn: 3600, + refreshTokenExpiresIn: 604800, + allowPlainCodeChallengeMethod: true, + ...options.oidcConfig, + loginPage: options.loginPage, + scopes: [ + "openid", + "profile", + "email", + "offline_access", + ...(options.oidcConfig?.scopes || []), + ], + }; + const modelName = { + oauthClient: "oauthApplication", + oauthAccessToken: "oauthAccessToken", + oauthConsent: "oauthConsent", + }; + const provider = oidcProvider(opts); + return { + id: "mcp", + hooks: { + after: [ + { + matcher() { + return true; + }, + handler: createAuthMiddleware(async (ctx) => { + const cookie = await ctx.getSignedCookie( + "oidc_login_prompt", + ctx.context.secret, + ); + const cookieName = ctx.context.authCookies.sessionToken.name; + const parsedSetCookieHeader = parseSetCookieHeader( + ctx.context.responseHeaders?.get("set-cookie") || "", + ); + const hasSessionToken = parsedSetCookieHeader.has(cookieName); + if (!cookie || !hasSessionToken) { + return; + } + ctx.setCookie("oidc_login_prompt", "", { + maxAge: 0, + }); + const sessionCookie = parsedSetCookieHeader.get(cookieName)?.value; + const sessionToken = sessionCookie?.split(".")[0]; + if (!sessionToken) { + return; + } + const session = + await ctx.context.internalAdapter.findSession(sessionToken); + if (!session) { + return; + } + ctx.query = JSON.parse(cookie); + ctx.query!.prompt = "consent"; + ctx.context.session = session; + const response = await authorizeMCPOAuth(ctx, opts).catch((e) => { + if (e instanceof APIError) { + if (e.statusCode === 302) { + return ctx.json({ + redirect: true, + //@ts-expect-error + url: e.headers.get("location"), + }); + } + } + throw e; + }); + return response; + }), + }, + ], + }, + endpoints: { + getMcpOAuthConfig: createAuthEndpoint( + "/.well-known/oauth-authorization-server", + { + method: "GET", + metadata: { + client: false, + }, + }, + async (c) => { + try { + const metadata = getMCPProviderMetadata(c, options); + return c.json(metadata); + } catch (e) { + console.log(e); + return c.json(null); + } + }, + ), + mcpOAuthAuthroize: createAuthEndpoint( + "/mcp/authorize", + { + method: "GET", + query: z.record(z.string(), z.any()), + metadata: { + openapi: { + description: "Authorize an OAuth2 request using MCP", + responses: { + "200": { + description: "Authorization response generated successfully", + content: { + "application/json": { + schema: { + type: "object", + additionalProperties: true, + description: + "Authorization response, contents depend on the authorize function implementation", + }, + }, + }, + }, + }, + }, + }, + }, + async (ctx) => { + return authorizeMCPOAuth(ctx, opts); + }, + ), + mcpOAuthToken: createAuthEndpoint( + "/mcp/token", + { + method: "POST", + body: z.record(z.any()), + metadata: { + isAction: false, + }, + }, + async (ctx) => { + //cors + ctx.setHeader("Access-Control-Allow-Origin", "*"); + ctx.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS"); + ctx.setHeader( + "Access-Control-Allow-Headers", + "Content-Type, Authorization", + ); + ctx.setHeader("Access-Control-Max-Age", "86400"); + + let { body } = ctx; + if (!body) { + throw ctx.error("BAD_REQUEST", { + error_description: "request body not found", + error: "invalid_request", + }); + } + if (body instanceof FormData) { + body = Object.fromEntries(body.entries()); + } + if (!(body instanceof Object)) { + throw new APIError("BAD_REQUEST", { + error_description: "request body is not an object", + error: "invalid_request", + }); + } + let { client_id, client_secret } = body; + const authorization = + ctx.request?.headers.get("authorization") || null; + if ( + authorization && + !client_id && + !client_secret && + authorization.startsWith("Basic ") + ) { + try { + const encoded = authorization.replace("Basic ", ""); + const decoded = new TextDecoder().decode(base64.decode(encoded)); + if (!decoded.includes(":")) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid authorization header format", + error: "invalid_client", + }); + } + const [id, secret] = decoded.split(":"); + if (!id || !secret) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid authorization header format", + error: "invalid_client", + }); + } + client_id = id; + client_secret = secret; + } catch (error) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid authorization header format", + error: "invalid_client", + }); + } + } + const { + grant_type, + code, + redirect_uri, + refresh_token, + code_verifier, + } = body; + if (grant_type === "refresh_token") { + if (!refresh_token) { + throw new APIError("BAD_REQUEST", { + error_description: "refresh_token is required", + error: "invalid_request", + }); + } + const token = await ctx.context.adapter.findOne({ + model: "oauthAccessToken", + where: [ + { + field: "refreshToken", + value: refresh_token.toString(), + }, + ], + }); + if (!token) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid refresh token", + error: "invalid_grant", + }); + } + if (token.clientId !== client_id?.toString()) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid client_id", + error: "invalid_client", + }); + } + if (token.refreshTokenExpiresAt < new Date()) { + throw new APIError("UNAUTHORIZED", { + error_description: "refresh token expired", + error: "invalid_grant", + }); + } + const accessToken = generateRandomString(32, "a-z", "A-Z"); + const newRefreshToken = generateRandomString(32, "a-z", "A-Z"); + const accessTokenExpiresAt = new Date( + Date.now() + opts.accessTokenExpiresIn * 1000, + ); + const refreshTokenExpiresAt = new Date( + Date.now() + opts.refreshTokenExpiresIn * 1000, + ); + await ctx.context.adapter.create({ + model: modelName.oauthAccessToken, + data: { + accessToken, + refreshToken: newRefreshToken, + accessTokenExpiresAt, + refreshTokenExpiresAt, + clientId: client_id.toString(), + userId: token.userId, + scopes: token.scopes, + createdAt: new Date(), + updatedAt: new Date(), + }, + }); + return ctx.json({ + access_token: accessToken, + token_type: "bearer", + expires_in: opts.accessTokenExpiresIn, + refresh_token: newRefreshToken, + scope: token.scopes, + }); + } + + if (!code) { + throw new APIError("BAD_REQUEST", { + error_description: "code is required", + error: "invalid_request", + }); + } + + if (opts.requirePKCE && !code_verifier) { + throw new APIError("BAD_REQUEST", { + error_description: "code verifier is missing", + error: "invalid_request", + }); + } + + /** + * We need to check if the code is valid before we can proceed + * with the rest of the request. + */ + const verificationValue = + await ctx.context.internalAdapter.findVerificationValue( + code.toString(), + ); + if (!verificationValue) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid code", + error: "invalid_grant", + }); + } + if (verificationValue.expiresAt < new Date()) { + throw new APIError("UNAUTHORIZED", { + error_description: "code expired", + error: "invalid_grant", + }); + } + + await ctx.context.internalAdapter.deleteVerificationValue( + verificationValue.id, + ); + if (!client_id || !client_secret) { + throw new APIError("UNAUTHORIZED", { + error_description: "client_id and client_secret are required", + error: "invalid_client", + }); + } + if (!grant_type) { + throw new APIError("BAD_REQUEST", { + error_description: "grant_type is required", + error: "invalid_request", + }); + } + if (grant_type !== "authorization_code") { + throw new APIError("BAD_REQUEST", { + error_description: "grant_type must be 'authorization_code'", + error: "unsupported_grant_type", + }); + } + + if (!redirect_uri) { + throw new APIError("BAD_REQUEST", { + error_description: "redirect_uri is required", + error: "invalid_request", + }); + } + + const client = await ctx.context.adapter + .findOne>({ + model: modelName.oauthClient, + where: [{ field: "clientId", value: client_id.toString() }], + }) + .then((res) => { + if (!res) { + return null; + } + return { + ...res, + redirectURLs: res.redirectURLs.split(","), + metadata: res.metadata ? JSON.parse(res.metadata) : {}, + } as Client; + }); + if (!client) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid client_id", + error: "invalid_client", + }); + } + if (client.disabled) { + throw new APIError("UNAUTHORIZED", { + error_description: "client is disabled", + error: "invalid_client", + }); + } + const isValidSecret = + client.clientSecret === client_secret.toString(); + if (!isValidSecret) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid client_secret", + error: "invalid_client", + }); + } + const value = JSON.parse( + verificationValue.value, + ) as CodeVerificationValue; + if (value.clientId !== client_id.toString()) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid client_id", + error: "invalid_client", + }); + } + if (value.redirectURI !== redirect_uri.toString()) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid redirect_uri", + error: "invalid_client", + }); + } + if (value.codeChallenge && !code_verifier) { + throw new APIError("BAD_REQUEST", { + error_description: "code verifier is missing", + error: "invalid_request", + }); + } + + const challenge = + value.codeChallengeMethod === "plain" + ? code_verifier + : await createHash("SHA-256", "base64urlnopad").digest( + code_verifier, + ); + + if (challenge !== value.codeChallenge) { + throw new APIError("UNAUTHORIZED", { + error_description: "code verification failed", + error: "invalid_request", + }); + } + + const requestedScopes = value.scope; + await ctx.context.internalAdapter.deleteVerificationValue( + verificationValue.id, + ); + const accessToken = generateRandomString(32, "a-z", "A-Z"); + const refreshToken = generateRandomString(32, "A-Z", "a-z"); + const accessTokenExpiresAt = new Date( + Date.now() + opts.accessTokenExpiresIn * 1000, + ); + const refreshTokenExpiresAt = new Date( + Date.now() + opts.refreshTokenExpiresIn * 1000, + ); + await ctx.context.adapter.create({ + model: modelName.oauthAccessToken, + data: { + accessToken, + refreshToken, + accessTokenExpiresAt, + refreshTokenExpiresAt, + clientId: client_id.toString(), + userId: value.userId, + scopes: requestedScopes.join(" "), + createdAt: new Date(), + updatedAt: new Date(), + }, + }); + const user = await ctx.context.internalAdapter.findUserById( + value.userId, + ); + if (!user) { + throw new APIError("UNAUTHORIZED", { + error_description: "user not found", + error: "invalid_grant", + }); + } + let secretKey = { + alg: "HS256", + key: await subtle.generateKey( + { + name: "HMAC", + hash: "SHA-256", + }, + true, + ["sign", "verify"], + ), + }; + const profile = { + given_name: user.name.split(" ")[0], + family_name: user.name.split(" ")[1], + name: user.name, + profile: user.image, + updated_at: user.updatedAt.toISOString(), + }; + const email = { + email: user.email, + email_verified: user.emailVerified, + }; + const userClaims = { + ...(requestedScopes.includes("profile") ? profile : {}), + ...(requestedScopes.includes("email") ? email : {}), + }; + + const additionalUserClaims = opts.getAdditionalUserInfoClaim + ? opts.getAdditionalUserInfoClaim(user, requestedScopes) + : {}; + + const idToken = await new SignJWT({ + sub: user.id, + aud: client_id.toString(), + iat: Date.now(), + auth_time: ctx.context.session?.session.createdAt.getTime(), + nonce: value.nonce, + acr: "urn:mace:incommon:iap:silver", // default to silver - ⚠︎ this should be configurable and should be validated against the client's metadata + ...userClaims, + ...additionalUserClaims, + }) + .setProtectedHeader({ alg: secretKey.alg }) + .setIssuedAt() + .setExpirationTime( + Math.floor(Date.now() / 1000) + opts.accessTokenExpiresIn, + ) + .sign(secretKey.key); + return ctx.json( + { + access_token: accessToken, + token_type: "Bearer", + expires_in: opts.accessTokenExpiresIn, + refresh_token: requestedScopes.includes("offline_access") + ? refreshToken + : undefined, + scope: requestedScopes.join(" "), + id_token: requestedScopes.includes("openid") + ? idToken + : undefined, + }, + { + headers: { + "Cache-Control": "no-store", + Pragma: "no-cache", + }, + }, + ); + }, + ), + registerMcpClient: createAuthEndpoint( + "/mcp/register", + { + method: "POST", + body: z.object({ + redirect_uris: z.array(z.string()), + token_endpoint_auth_method: z + .enum(["none", "client_secret_basic", "client_secret_post"]) + .default("client_secret_basic") + .optional(), + grant_types: z + .array( + z.enum([ + "authorization_code", + "implicit", + "password", + "client_credentials", + "refresh_token", + "urn:ietf:params:oauth:grant-type:jwt-bearer", + "urn:ietf:params:oauth:grant-type:saml2-bearer", + ]), + ) + .default(["authorization_code"]) + .optional(), + response_types: z + .array(z.enum(["code", "token"])) + .default(["code"]) + .optional(), + client_name: z.string().optional(), + client_uri: z.string().optional(), + logo_uri: z.string().optional(), + scope: z.string().optional(), + contacts: z.array(z.string()).optional(), + tos_uri: z.string().optional(), + policy_uri: z.string().optional(), + jwks_uri: z.string().optional(), + jwks: z.record(z.any()).optional(), + metadata: z.record(z.any()).optional(), + software_id: z.string().optional(), + software_version: z.string().optional(), + software_statement: z.string().optional(), + }), + metadata: { + openapi: { + description: "Register an OAuth2 application", + responses: { + "200": { + description: "OAuth2 application registered successfully", + content: { + "application/json": { + schema: { + type: "object", + properties: { + name: { + type: "string", + description: "Name of the OAuth2 application", + }, + icon: { + type: "string", + nullable: true, + description: "Icon URL for the application", + }, + metadata: { + type: "object", + additionalProperties: true, + nullable: true, + description: + "Additional metadata for the application", + }, + clientId: { + type: "string", + description: "Unique identifier for the client", + }, + clientSecret: { + type: "string", + description: "Secret key for the client", + }, + redirectURLs: { + type: "array", + items: { type: "string", format: "uri" }, + description: "List of allowed redirect URLs", + }, + type: { + type: "string", + description: "Type of the client", + enum: ["web"], + }, + authenticationScheme: { + type: "string", + description: + "Authentication scheme used by the client", + enum: ["client_secret"], + }, + disabled: { + type: "boolean", + description: "Whether the client is disabled", + enum: [false], + }, + userId: { + type: "string", + nullable: true, + description: + "ID of the user who registered the client, null if registered anonymously", + }, + createdAt: { + type: "string", + format: "date-time", + description: "Creation timestamp", + }, + updatedAt: { + type: "string", + format: "date-time", + description: "Last update timestamp", + }, + }, + required: [ + "name", + "clientId", + "clientSecret", + "redirectURLs", + "type", + "authenticationScheme", + "disabled", + "createdAt", + "updatedAt", + ], + }, + }, + }, + }, + }, + }, + }, + }, + async (ctx) => { + const body = ctx.body; + const session = await getSessionFromCtx(ctx); + ctx.setHeader("Access-Control-Allow-Origin", "*"); + ctx.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS"); + ctx.setHeader( + "Access-Control-Allow-Headers", + "Content-Type, Authorization", + ); + ctx.setHeader("Access-Control-Max-Age", "86400"); + ctx.headers?.set("Access-Control-Max-Age", "86400"); + if ( + (!body.grant_types || + body.grant_types.includes("authorization_code") || + body.grant_types.includes("implicit")) && + (!body.redirect_uris || body.redirect_uris.length === 0) + ) { + throw new APIError("BAD_REQUEST", { + error: "invalid_redirect_uri", + error_description: + "Redirect URIs are required for authorization_code and implicit grant types", + }); + } + + if (body.grant_types && body.response_types) { + if ( + body.grant_types.includes("authorization_code") && + !body.response_types.includes("code") + ) { + throw new APIError("BAD_REQUEST", { + error: "invalid_client_metadata", + error_description: + "When 'authorization_code' grant type is used, 'code' response type must be included", + }); + } + if ( + body.grant_types.includes("implicit") && + !body.response_types.includes("token") + ) { + throw new APIError("BAD_REQUEST", { + error: "invalid_client_metadata", + error_description: + "When 'implicit' grant type is used, 'token' response type must be included", + }); + } + } + + const clientId = + opts.generateClientId?.() || generateRandomString(32, "a-z", "A-Z"); + const clientSecret = + opts.generateClientSecret?.() || + generateRandomString(32, "a-z", "A-Z"); + + await ctx.context.adapter.create({ + model: modelName.oauthClient, + data: { + name: body.client_name, + icon: body.logo_uri, + metadata: body.metadata ? JSON.stringify(body.metadata) : null, + clientId: clientId, + clientSecret: clientSecret, + redirectURLs: body.redirect_uris.join(","), + type: "web", + authenticationScheme: + body.token_endpoint_auth_method || "client_secret_basic", + disabled: false, + userId: session?.session.userId, + createdAt: new Date(), + updatedAt: new Date(), + }, + }); + + return ctx.json( + { + client_id: clientId, + client_secret: clientSecret, + client_id_issued_at: Math.floor(Date.now() / 1000), + client_secret_expires_at: 0, // 0 means it doesn't expire + redirect_uris: body.redirect_uris, + token_endpoint_auth_method: + body.token_endpoint_auth_method || "client_secret_basic", + grant_types: body.grant_types || ["authorization_code"], + response_types: body.response_types || ["code"], + client_name: body.client_name, + client_uri: body.client_uri, + logo_uri: body.logo_uri, + scope: body.scope, + contacts: body.contacts, + tos_uri: body.tos_uri, + policy_uri: body.policy_uri, + jwks_uri: body.jwks_uri, + jwks: body.jwks, + software_id: body.software_id, + software_version: body.software_version, + software_statement: body.software_statement, + metadata: body.metadata, + }, + { + status: 201, + headers: { + "Cache-Control": "no-store", + Pragma: "no-cache", + }, + }, + ); + }, + ), + getMcpSession: createAuthEndpoint( + "/mcp/get-session", + { + method: "GET", + requireHeaders: true, + }, + async (c) => { + const accessToken = c.headers + ?.get("Authorization") + ?.replace("Bearer ", ""); + if (!accessToken) { + c.headers?.set("WWW-Authenticate", "Bearer"); + return c.json(null); + } + const accessTokenData = + await c.context.adapter.findOne({ + model: modelName.oauthAccessToken, + where: [ + { + field: "accessToken", + value: accessToken, + }, + ], + }); + if (!accessTokenData) { + return c.json(null); + } + return c.json(accessTokenData); + }, + ), + }, + schema, + } satisfies BetterAuthPlugin; +}; + +export const withMcpAuth = < + Auth extends { + api: { + getMcpSession: (...args: any) => Promise; + }; + }, +>( + auth: Auth, + handler: ( + req: Request, + sesssion: OAuthAccessToken, + ) => Response | Promise, +) => { + return async (req: Request) => { + const session = await auth.api.getMcpSession({ + headers: req.headers, + }); + const wwwAuthenticateValue = + "Bearer resource_metadata=http://localhost:3000/api/auth/.well-known/oauth-authorization-server"; + if (!session) { + return Response.json( + { + jsonrpc: "2.0", + error: { + code: -32000, + message: "Unauthorized: Authentication required", + "www-authenticate": wwwAuthenticateValue, + }, + id: null, + }, + { + status: 401, + headers: { + "WWW-Authenticate": wwwAuthenticateValue, + }, + }, + ); + } + return handler(req, session); + }; +}; + +export const oAuthDiscoveryMetadata = < + Auth extends { + api: { + getMcpOAuthConfig: (...args: any) => any; + }; + }, +>( + auth: Auth, +) => { + return async (request: Request) => { + const res = await auth.api.getMcpOAuthConfig(); + return new Response(JSON.stringify(res), { + status: 200, + headers: { + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "POST, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type, Authorization", + "Access-Control-Max-Age": "86400", + }, + }); + }; +}; diff --git a/packages/better-auth/src/plugins/oidc-provider/index.ts b/packages/better-auth/src/plugins/oidc-provider/index.ts index 39afe00f..84c3f28d 100644 --- a/packages/better-auth/src/plugins/oidc-provider/index.ts +++ b/packages/better-auth/src/plugins/oidc-provider/index.ts @@ -23,7 +23,7 @@ import { parseSetCookieHeader } from "../../cookies"; import { createHash } from "@better-auth/utils/hash"; import { base64 } from "@better-auth/utils/base64"; -const getMetadata = ( +export const getMetadata = ( ctx: GenericEndpointContext, options?: OIDCOptions, ): OIDCMetadata => { @@ -50,6 +50,7 @@ const getMetadata = ( "client_secret_basic", "client_secret_post", ], + code_challenge_methods_supported: ["S256"], claims_supported: [ "sub", "iss", diff --git a/packages/better-auth/src/plugins/oidc-provider/types.ts b/packages/better-auth/src/plugins/oidc-provider/types.ts index 22629da9..d6b26c79 100644 --- a/packages/better-auth/src/plugins/oidc-provider/types.ts +++ b/packages/better-auth/src/plugins/oidc-provider/types.ts @@ -513,4 +513,12 @@ export interface OIDCMetadata { * ["sub", "iss", "aud", "exp", "nbf", "iat", "jti", "email", "email_verified", "name"] */ claims_supported: string[]; + /** + * Supported code challenge methods. + * + * only `S256` is supported. + * + * @default ["S256"] + */ + code_challenge_methods_supported: ["S256"]; } diff --git a/packages/cli/package.json b/packages/cli/package.json index a4c259bd..b9a2bb7e 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/cli", - "version": "1.2.8", + "version": "1.2.9-beta.1", "description": "The CLI for Better Auth", "module": "dist/index.mjs", "repository": { diff --git a/packages/expo/package.json b/packages/expo/package.json index 944592f9..a41f2615 100644 --- a/packages/expo/package.json +++ b/packages/expo/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/expo", - "version": "1.2.8", + "version": "1.2.9-beta.1", "description": "", "main": "dist/index.cjs", "module": "dist/index.mjs", diff --git a/packages/stripe/package.json b/packages/stripe/package.json index 22e9c178..53140213 100644 --- a/packages/stripe/package.json +++ b/packages/stripe/package.json @@ -1,7 +1,7 @@ { "name": "@better-auth/stripe", "author": "Bereket Engida", - "version": "1.2.8", + "version": "1.2.9-beta.1", "main": "dist/index.cjs", "license": "MIT", "keywords": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 50e9add1..f40208a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -358,7 +358,7 @@ importers: devDependencies: '@types/bun': specifier: latest - version: 1.2.12 + version: 1.2.13 dev/cloudflare: dependencies: @@ -367,7 +367,7 @@ importers: version: link:../../packages/better-auth drizzle-orm: specifier: ^0.39.3 - version: 0.39.3(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)) + version: 0.39.3(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)) hono: specifier: ^4.7.2 version: 4.7.4 @@ -476,7 +476,7 @@ importers: version: 0.5.15(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0) '@vercel/analytics': specifier: ^1.5.0 - version: 1.5.0(@remix-run/react@2.16.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@sveltejs/kit@2.19.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(svelte@5.22.6)(vue-router@4.5.1(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2)) + version: 1.5.0(@remix-run/react@2.16.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@sveltejs/kit@2.19.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(svelte@5.22.6)(vue-router@4.5.1(vue@3.5.14(typescript@5.8.2)))(vue@3.5.14(typescript@5.8.2)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -731,7 +731,7 @@ importers: devDependencies: '@ianvs/prettier-plugin-sort-imports': specifier: 4.1.1 - version: 4.1.1(@vue/compiler-sfc@3.5.13)(prettier@3.2.4) + version: 4.1.1(@vue/compiler-sfc@3.5.14)(prettier@3.2.4) '@types/chrome': specifier: 0.0.258 version: 0.0.258 @@ -890,11 +890,57 @@ importers: specifier: ^5.7.2 version: 5.8.2 + examples/nextjs-mcp: + dependencies: + '@types/better-sqlite3': + specifier: ^7.6.12 + version: 7.6.12 + '@vercel/mcp-adapter': + specifier: ^0.4.1 + version: 0.4.1(next@15.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1)) + better-auth: + specifier: workspace:^ + version: link:../../packages/better-auth + better-sqlite3: + specifier: ^11.6.0 + version: 11.8.1 + next: + specifier: 15.3.2 + version: 15.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) + react: + specifier: ^19.0.0 + version: 19.0.0 + react-dom: + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) + zod: + specifier: ^3.24.4 + version: 3.24.4 + devDependencies: + '@tailwindcss/postcss': + specifier: ^4 + version: 4.0.12 + '@types/node': + specifier: ^20 + version: 20.17.24 + '@types/react': + specifier: ^19 + version: 19.0.10 + '@types/react-dom': + specifier: ^19 + version: 19.0.4(@types/react@19.0.10) + tailwindcss: + specifier: ^4 + version: 4.0.12 + typescript: + specifier: ^5 + version: 5.8.2 + examples/nuxt-example: dependencies: '@radix-icons/vue': specifier: ^1.0.0 - version: 1.0.0(vue@3.5.13(typescript@5.8.2)) + version: 1.0.0(vue@3.5.14(typescript@5.8.2)) '@types/better-sqlite3': specifier: ^7.6.12 version: 7.6.12 @@ -903,13 +949,13 @@ importers: version: 1.4.3-beta.0 '@unovis/vue': specifier: 1.4.3-beta.0 - version: 1.4.3-beta.0(@unovis/ts@1.4.3-beta.0)(vue@3.5.13(typescript@5.8.2)) + version: 1.4.3-beta.0(@unovis/ts@1.4.3-beta.0)(vue@3.5.14(typescript@5.8.2)) '@vee-validate/zod': specifier: ^4.14.7 - version: 4.15.0(vue@3.5.13(typescript@5.8.2))(zod@3.24.2) + version: 4.15.0(vue@3.5.14(typescript@5.8.2))(zod@3.24.2) '@vueuse/core': specifier: ^11.3.0 - version: 11.3.0(vue@3.5.13(typescript@5.8.2)) + version: 11.3.0(vue@3.5.14(typescript@5.8.2)) better-auth: specifier: workspace:* version: link:../../packages/better-auth @@ -924,13 +970,13 @@ importers: version: 2.1.1 embla-carousel-vue: specifier: ^8.5.1 - version: 8.5.2(vue@3.5.13(typescript@5.8.2)) + version: 8.5.2(vue@3.5.14(typescript@5.8.2)) nuxt: specifier: ^3.14.1592 - version: 3.16.0(yykrlyfgcq7bklxjhifzhuppyq) + version: 3.16.0(kygbndsg3u7xffwrewwioaaldy) radix-vue: specifier: ^1.9.11 - version: 1.9.17(vue@3.5.13(typescript@5.8.2)) + version: 1.9.17(vue@3.5.14(typescript@5.8.2)) shadcn-nuxt: specifier: ^0.10.4 version: 0.10.4(magicast@0.3.5) @@ -942,19 +988,19 @@ importers: version: 1.0.7(tailwindcss@3.4.17) v-calendar: specifier: ^3.1.2 - version: 3.1.2(@popperjs/core@2.11.8)(vue@3.5.13(typescript@5.8.2)) + version: 3.1.2(@popperjs/core@2.11.8)(vue@3.5.14(typescript@5.8.2)) vaul-vue: specifier: ^0.2.0 - version: 0.2.1(radix-vue@1.9.17(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2)) + version: 0.2.1(radix-vue@1.9.17(vue@3.5.14(typescript@5.8.2)))(vue@3.5.14(typescript@5.8.2)) vee-validate: specifier: ^4.14.7 - version: 4.15.0(vue@3.5.13(typescript@5.8.2)) + version: 4.15.0(vue@3.5.14(typescript@5.8.2)) vue: specifier: latest - version: 3.5.13(typescript@5.8.2) + version: 3.5.14(typescript@5.8.2) vue-router: specifier: latest - version: 4.5.1(vue@3.5.13(typescript@5.8.2)) + version: 4.5.1(vue@3.5.14(typescript@5.8.2)) vue-sonner: specifier: ^1.3.0 version: 1.3.0 @@ -1314,7 +1360,7 @@ importers: version: 1.112.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/start': specifier: ^1.86.1 - version: 1.113.0(hcvcmo22cfk2zc45m3egdtrfb4) + version: 1.113.0(umfczj6grv5xwnnilehiba4mti) '@types/ua-parser-js': specifier: ^0.7.39 version: 0.7.39 @@ -1362,7 +1408,7 @@ importers: version: 0.7.40 vinxi: specifier: ^0.4.3 - version: 0.4.3(tbiltmkuca6gwy6wvywbppe5hm) + version: 0.4.3(xigip3pwxsynk4cmajsowrm4re) devDependencies: '@biomejs/biome': specifier: 1.9.4 @@ -1372,7 +1418,7 @@ importers: version: 7.6.12 '@types/bun': specifier: latest - version: 1.2.12 + version: 1.2.13 '@types/node': specifier: ^22.10.1 version: 22.13.10 @@ -1442,13 +1488,13 @@ importers: version: 5.22.0(prisma@5.22.0) '@tanstack/react-start': specifier: ^1.114.34 - version: 1.114.34(lijngnfq54cp5rlnj53jssmkhu) + version: 1.114.34(xdtxozacaptx2f2yoax7hh4is4) '@types/better-sqlite3': specifier: ^7.6.12 version: 7.6.12 '@types/bun': specifier: latest - version: 1.2.12 + version: 1.2.13 '@types/pg': specifier: ^8.11.10 version: 8.11.11 @@ -1466,7 +1512,7 @@ importers: version: 9.1.2 drizzle-orm: specifier: ^0.38.2 - version: 0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0) + version: 0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0) happy-dom: specifier: ^15.11.7 version: 15.11.7 @@ -1565,7 +1611,7 @@ importers: version: 16.4.7 drizzle-orm: specifier: ^0.33.0 - version: 0.33.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@19.0.10)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0) + version: 0.33.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@19.0.10)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0) fs-extra: specifier: ^11.3.0 version: 11.3.0 @@ -1605,7 +1651,7 @@ importers: version: 5.8.2 unbuild: specifier: 'catalog:' - version: 3.5.0(sass@1.85.1)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)) + version: 3.5.0(sass@1.85.1)(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)) vitest: specifier: ^1.6.0 version: 1.6.1(@types/node@22.15.3)(happy-dom@17.4.1)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0) @@ -1645,7 +1691,7 @@ importers: version: 14.0.2(expo@52.0.37(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@expo/metro-runtime@4.0.1(react-native@0.78.0(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@react-native-community/cli-server-api@13.6.9(encoding@0.1.13))(@types/react@19.0.10)(react@19.0.0)))(encoding@0.1.13)(graphql@15.10.1)(react-native@0.78.0(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@react-native-community/cli-server-api@13.6.9(encoding@0.1.13))(@types/react@19.0.10)(react@19.0.0))(react@19.0.0))(react-native@0.78.0(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@react-native-community/cli-server-api@13.6.9(encoding@0.1.13))(@types/react@19.0.10)(react@19.0.0)) unbuild: specifier: ^3.5.0 - version: 3.5.0(sass@1.85.1)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)) + version: 3.5.0(sass@1.85.1)(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)) vitest: specifier: ^1.6.0 version: 1.6.1(@types/node@22.15.3)(happy-dom@17.4.1)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0) @@ -2162,6 +2208,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.27.2': + resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} engines: {node: '>=6.9.0'} @@ -3377,6 +3428,9 @@ packages: '@emnapi/runtime@1.3.1': resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + '@emnapi/wasi-threads@1.0.1': resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} @@ -4933,105 +4987,215 @@ packages: cpu: [arm64] os: [darwin] + '@img/sharp-darwin-arm64@0.34.1': + resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + '@img/sharp-darwin-x64@0.33.5': resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] + '@img/sharp-darwin-x64@0.34.1': + resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + '@img/sharp-libvips-darwin-arm64@1.0.4': resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} cpu: [arm64] os: [darwin] + '@img/sharp-libvips-darwin-arm64@1.1.0': + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + cpu: [arm64] + os: [darwin] + '@img/sharp-libvips-darwin-x64@1.0.4': resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} cpu: [x64] os: [darwin] + '@img/sharp-libvips-darwin-x64@1.1.0': + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + cpu: [x64] + os: [darwin] + '@img/sharp-libvips-linux-arm64@1.0.4': resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} cpu: [arm64] os: [linux] + '@img/sharp-libvips-linux-arm64@1.1.0': + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + cpu: [arm64] + os: [linux] + '@img/sharp-libvips-linux-arm@1.0.5': resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} cpu: [arm] os: [linux] + '@img/sharp-libvips-linux-arm@1.1.0': + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.1.0': + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + '@img/sharp-libvips-linux-s390x@1.0.4': resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} cpu: [s390x] os: [linux] + '@img/sharp-libvips-linux-s390x@1.1.0': + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + cpu: [s390x] + os: [linux] + '@img/sharp-libvips-linux-x64@1.0.4': resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} cpu: [x64] os: [linux] + '@img/sharp-libvips-linux-x64@1.1.0': + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + cpu: [x64] + os: [linux] + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} cpu: [arm64] os: [linux] + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + cpu: [arm64] + os: [linux] + '@img/sharp-libvips-linuxmusl-x64@1.0.4': resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} cpu: [x64] os: [linux] + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + cpu: [x64] + os: [linux] + '@img/sharp-linux-arm64@0.33.5': resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + '@img/sharp-linux-arm64@0.34.1': + resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + '@img/sharp-linux-arm@0.33.5': resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + '@img/sharp-linux-arm@0.34.1': + resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + '@img/sharp-linux-s390x@0.33.5': resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + '@img/sharp-linux-s390x@0.34.1': + resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + '@img/sharp-linux-x64@0.33.5': resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + '@img/sharp-linux-x64@0.34.1': + resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + '@img/sharp-linuxmusl-arm64@0.33.5': resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + '@img/sharp-linuxmusl-arm64@0.34.1': + resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + '@img/sharp-linuxmusl-x64@0.33.5': resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + '@img/sharp-linuxmusl-x64@0.34.1': + resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + '@img/sharp-wasm32@0.33.5': resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] + '@img/sharp-wasm32@0.34.1': + resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + '@img/sharp-win32-ia32@0.33.5': resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] + '@img/sharp-win32-ia32@0.34.1': + resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + '@img/sharp-win32-x64@0.33.5': resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] + '@img/sharp-win32-x64@0.34.1': + resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@internationalized/date@3.5.5': resolution: {integrity: sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ==} @@ -5440,6 +5604,10 @@ packages: resolution: {integrity: sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w==} engines: {node: '>=12.0.0'} + '@modelcontextprotocol/sdk@1.10.2': + resolution: {integrity: sha512-rb6AMp2DR4SN+kc6L1ta2NCpApyA9WYNx3CrTSZvGxq9wH71bRur+zRqPfg0vQ9mjywR7qZdX2RGHOPq3ss+tA==} + engines: {node: '>=18'} + '@mongodb-js/saslprep@1.1.9': resolution: {integrity: sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==} @@ -5505,6 +5673,9 @@ packages: '@next/env@15.2.3': resolution: {integrity: sha512-a26KnbW9DFEUsSxAxKBORR/uD9THoYoKbkpFywMN/AFvboTt94b8+g/07T8J6ACsdLag8/PDU60ov4rPxRAixw==} + '@next/env@15.3.2': + resolution: {integrity: sha512-xURk++7P7qR9JG1jJtLzPzf0qEvqCN0A/T3DXf8IPMKo9/6FfjxtEffRJIIew/bIL4T3C2jLLqBor8B/zVlx6g==} + '@next/eslint-plugin-next@15.0.0-canary.149': resolution: {integrity: sha512-luututuveL0xzHMFfuyVyfctC/7jdNS/iGrVqGbEvHqvW7W4yydwieasELkC4uY10onGoKGxg1PV8QciqMJqWQ==} @@ -5514,48 +5685,96 @@ packages: cpu: [arm64] os: [darwin] + '@next/swc-darwin-arm64@15.3.2': + resolution: {integrity: sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@next/swc-darwin-x64@15.2.3': resolution: {integrity: sha512-pVwKvJ4Zk7h+4hwhqOUuMx7Ib02u3gDX3HXPKIShBi9JlYllI0nU6TWLbPT94dt7FSi6mSBhfc2JrHViwqbOdw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] + '@next/swc-darwin-x64@15.3.2': + resolution: {integrity: sha512-ro/fdqaZWL6k1S/5CLv1I0DaZfDVJkWNaUU3un8Lg6m0YENWlDulmIWzV96Iou2wEYyEsZq51mwV8+XQXqMp3w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@next/swc-linux-arm64-gnu@15.2.3': resolution: {integrity: sha512-50ibWdn2RuFFkOEUmo9NCcQbbV9ViQOrUfG48zHBCONciHjaUKtHcYFiCwBVuzD08fzvzkWuuZkd4AqbvKO7UQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-gnu@15.3.2': + resolution: {integrity: sha512-covwwtZYhlbRWK2HlYX9835qXum4xYZ3E2Mra1mdQ+0ICGoMiw1+nVAn4d9Bo7R3JqSmK1grMq/va+0cdh7bJA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-arm64-musl@15.2.3': resolution: {integrity: sha512-2gAPA7P652D3HzR4cLyAuVYwYqjG0mt/3pHSWTCyKZq/N/dJcUAEoNQMyUmwTZWCJRKofB+JPuDVP2aD8w2J6Q==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-musl@15.3.2': + resolution: {integrity: sha512-KQkMEillvlW5Qk5mtGA/3Yz0/tzpNlSw6/3/ttsV1lNtMuOHcGii3zVeXZyi4EJmmLDKYcTcByV2wVsOhDt/zg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-x64-gnu@15.2.3': resolution: {integrity: sha512-ODSKvrdMgAJOVU4qElflYy1KSZRM3M45JVbeZu42TINCMG3anp7YCBn80RkISV6bhzKwcUqLBAmOiWkaGtBA9w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-gnu@15.3.2': + resolution: {integrity: sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-linux-x64-musl@15.2.3': resolution: {integrity: sha512-ZR9kLwCWrlYxwEoytqPi1jhPd1TlsSJWAc+H/CJHmHkf2nD92MQpSRIURR1iNgA/kuFSdxB8xIPt4p/T78kwsg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-musl@15.3.2': + resolution: {integrity: sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-win32-arm64-msvc@15.2.3': resolution: {integrity: sha512-+G2FrDcfm2YDbhDiObDU/qPriWeiz/9cRR0yMWJeTLGGX6/x8oryO3tt7HhodA1vZ8r2ddJPCjtLcpaVl7TE2Q==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] + '@next/swc-win32-arm64-msvc@15.3.2': + resolution: {integrity: sha512-LLTKmaI5cfD8dVzh5Vt7+OMo+AIOClEdIU/TSKbXXT2iScUTSxOGoBhfuv+FU8R9MLmrkIL1e2fBMkEEjYAtPQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@next/swc-win32-x64-msvc@15.2.3': resolution: {integrity: sha512-gHYS9tc+G2W0ZC8rBL+H6RdtXIyk40uLiaos0yj5US85FNhbFEndMA2nW3z47nzOWiSvXTZ5kBClc3rD0zJg0w==} engines: {node: '>= 10'} cpu: [x64] os: [win32] + '@next/swc-win32-x64-msvc@15.3.2': + resolution: {integrity: sha512-aW5B8wOPioJ4mBdMDXkt5f3j8pUr9W8AnlX0Df35uRWNT1Y6RIybxjnSUe+PhM+M1bwgyY8PHLmXZC6zT1o5tA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@noble/ciphers@0.6.0': resolution: {integrity: sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==} @@ -7874,6 +8093,35 @@ packages: react-native: optional: true + '@redis/bloom@1.2.0': + resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@redis/client@1.6.1': + resolution: {integrity: sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==} + engines: {node: '>=14'} + + '@redis/graph@1.1.1': + resolution: {integrity: sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@redis/json@1.0.7': + resolution: {integrity: sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@redis/search@1.2.0': + resolution: {integrity: sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@redis/time-series@1.1.0': + resolution: {integrity: sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==} + peerDependencies: + '@redis/client': ^1.0.0 + '@redocly/ajv@8.11.2': resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==} @@ -9413,8 +9661,8 @@ packages: '@types/braces@3.0.4': resolution: {integrity: sha512-0WR3b8eaISjEW7RpZnclONaLFDf7buaowRHdqLp4vLj54AsSAYWfh3DRbfiYJY9XDxMgx1B4sE1Afw2PGpuHOA==} - '@types/bun@1.2.12': - resolution: {integrity: sha512-lY/GQTXDGsolT/TiH72p1tuyUORuRrdV7VwOTOjDOt8uTBJQOJc5zz3ufwwDl0VBaoxotSk4LdP0hhjLJ6ypIQ==} + '@types/bun@1.2.13': + resolution: {integrity: sha512-u6vXep/i9VBxoJl3GjZsl/BFIsvML8DfVDO0RYLEwtSZSp981kEO1V5NwRcO1CPJ7AmvpbnDCiMKo3JvbDEjAg==} '@types/canvas-confetti@1.9.0': resolution: {integrity: sha512-aBGj/dULrimR1XDZLtG9JwxX1b4HPRF6CX9Yfwh3NvstZEm1ZL7RBnel4keCPSqs1ANRu1u2Aoz9R+VmtjYuTg==} @@ -9945,6 +10193,11 @@ packages: vue-router: optional: true + '@vercel/mcp-adapter@0.4.1': + resolution: {integrity: sha512-/P1J1KGbQieNT9dKSt4Y+ZrLcnuf6W1cUMR0V+AcWRfQs7ilz64GaLVdpyUIoZFb45VHqRvTVEZ8YmQspEM/Kw==} + peerDependencies: + next: '>=13.0.0' + '@vercel/nft@0.29.2': resolution: {integrity: sha512-A/Si4mrTkQqJ6EXJKv5EYCDQ3NL6nJXxG8VGXePsaiQigsomHYQC9xSpX8qGk7AEZk4b1ssbYIqJ0ISQQ7bfcA==} engines: {node: '>=18'} @@ -10095,24 +10348,36 @@ packages: '@vue/compiler-core@3.5.13': resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + '@vue/compiler-core@3.5.14': + resolution: {integrity: sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==} + '@vue/compiler-dom@3.3.4': resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} '@vue/compiler-dom@3.5.13': resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + '@vue/compiler-dom@3.5.14': + resolution: {integrity: sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==} + '@vue/compiler-sfc@3.3.4': resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} '@vue/compiler-sfc@3.5.13': resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + '@vue/compiler-sfc@3.5.14': + resolution: {integrity: sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==} + '@vue/compiler-ssr@3.3.4': resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} '@vue/compiler-ssr@3.5.13': resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + '@vue/compiler-ssr@3.5.14': + resolution: {integrity: sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==} + '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} @@ -10145,18 +10410,27 @@ packages: '@vue/reactivity@3.5.13': resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + '@vue/reactivity@3.5.14': + resolution: {integrity: sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==} + '@vue/runtime-core@3.3.4': resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} '@vue/runtime-core@3.5.13': resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + '@vue/runtime-core@3.5.14': + resolution: {integrity: sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==} + '@vue/runtime-dom@3.3.4': resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} '@vue/runtime-dom@3.5.13': resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + '@vue/runtime-dom@3.5.14': + resolution: {integrity: sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==} + '@vue/server-renderer@3.3.4': resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} peerDependencies: @@ -10167,12 +10441,20 @@ packages: peerDependencies: vue: 3.5.13 + '@vue/server-renderer@3.5.14': + resolution: {integrity: sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==} + peerDependencies: + vue: 3.5.14 + '@vue/shared@3.3.4': resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} '@vue/shared@3.5.13': resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + '@vue/shared@3.5.14': + resolution: {integrity: sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ==} + '@vueuse/core@10.11.1': resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} @@ -10433,6 +10715,10 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: @@ -10956,6 +11242,10 @@ packages: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + body-parser@2.2.0: + resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + engines: {node: '>=18'} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -11046,8 +11336,8 @@ packages: engines: {node: '>=10'} hasBin: true - bun-types@1.2.12: - resolution: {integrity: sha512-tvWMx5vPqbRXgE8WUZI94iS1xAYs8bkqESR9cxBB1Wi+urvfTrF1uzuDgBHFAdO0+d2lmsbG3HmeKMvUyj6pWA==} + bun-types@1.2.13: + resolution: {integrity: sha512-rRjA1T6n7wto4gxhAO/ErZEtOXyEZEmnIHQfl0Dt1QQSB4QV0iP6BZ9/YB5fZaHFQ2dwHFrmPaRQ9GGMX01k9Q==} bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} @@ -11518,6 +11808,10 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} + content-disposition@1.0.0: + resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} + engines: {node: '>= 0.6'} + content-security-policy-parser@0.4.1: resolution: {integrity: sha512-NNJS8XPnx3OKr/CUOSwDSJw+lWTrZMYnclLKj0Y9CYOfJNJTWLFGPg3u2hYgbXMXKVRkZR2fbyReNQ1mUff/Qg==} engines: {node: '>=8.0.0'} @@ -13117,6 +13411,14 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + eventsource-parser@3.0.2: + resolution: {integrity: sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + exec-async@2.2.0: resolution: {integrity: sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==} @@ -13278,10 +13580,20 @@ packages: exponential-backoff@3.1.2: resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} + express-rate-limit@7.5.0: + resolution: {integrity: sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==} + engines: {node: '>= 16'} + peerDependencies: + express: ^4.11 || 5 || ^5.0.0-beta.1 + express@4.21.1: resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} engines: {node: '>= 0.10.0'} + express@5.1.0: + resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + engines: {node: '>= 18'} + exsolve@1.0.2: resolution: {integrity: sha512-ZEcIMbthn2zeX4/wD/DLxDUjuCltHXT8Htvm/JFlTkdYgWh2+HGppgwwNUnIVxzxP7yJOPtuBAec0dLx6lVY8w==} @@ -13437,6 +13749,10 @@ packages: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} + finalhandler@2.1.0: + resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} + engines: {node: '>= 0.8'} + find-cache-dir@2.1.0: resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} engines: {node: '>=6'} @@ -13583,6 +13899,10 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -13711,6 +14031,10 @@ packages: generic-names@4.0.0: resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} + generic-pool@3.9.0: + resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} + engines: {node: '>= 4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -14566,6 +14890,9 @@ packages: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-property@1.0.2: resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} @@ -15608,6 +15935,10 @@ packages: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} @@ -15627,6 +15958,10 @@ packages: merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-options@3.0.4: resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} engines: {node: '>=10'} @@ -16008,10 +16343,18 @@ packages: resolution: {integrity: sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==} engines: {node: '>= 0.6'} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -16402,6 +16745,27 @@ packages: sass: optional: true + next@15.3.2: + resolution: {integrity: sha512-CA3BatMyHkxZ48sgOCLdVHjFU36N7TF1HhqAHLFOkV6buwZnvMI84Cug8xD56B9mCuKrqXnLn94417GrZ/jjCQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} @@ -16959,6 +17323,10 @@ packages: path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -17080,6 +17448,10 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + pkce-challenge@5.0.0: + resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==} + engines: {node: '>=16.20.0'} + pkg-dir@3.0.0: resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} engines: {node: '>=6'} @@ -17648,6 +18020,10 @@ packages: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + quansync@0.2.8: resolution: {integrity: sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==} @@ -17692,6 +18068,10 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} + raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} + rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} @@ -18061,6 +18441,9 @@ packages: resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} engines: {node: '>=4'} + redis@4.7.1: + resolution: {integrity: sha512-S1bJDnqLftzHXHP8JsT5II/CtHWQrASX5K96REjWjlmWKrviSOLWmM7QnRLstAWsu1VBBV1ffV6DzCvxNP0UJQ==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -18389,6 +18772,10 @@ packages: rou3@0.5.1: resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + run-applescript@7.0.0: resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} engines: {node: '>=18'} @@ -18511,6 +18898,10 @@ packages: resolution: {integrity: sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==} engines: {node: '>= 0.8.0'} + send@1.2.0: + resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + engines: {node: '>= 18'} + seq-queue@0.0.5: resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} @@ -18538,6 +18929,10 @@ packages: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} + serve-static@2.2.0: + resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + engines: {node: '>= 18'} + server-only@0.0.1: resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} @@ -18586,6 +18981,10 @@ packages: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + sharp@0.34.1: + resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -19584,6 +19983,10 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -20623,6 +21026,14 @@ packages: typescript: optional: true + vue@3.5.14: + resolution: {integrity: sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -20990,6 +21401,9 @@ packages: zod@3.24.2: resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + zod@3.24.4: + resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==} + zustand@3.7.2: resolution: {integrity: sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==} engines: {node: '>=12.7.0'} @@ -22070,6 +22484,10 @@ snapshots: dependencies: '@babel/types': 7.27.1 + '@babel/parser@7.27.2': + dependencies: + '@babel/types': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.9)': dependencies: '@babel/core': 7.26.9 @@ -24508,6 +24926,11 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.4.3': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.0.1': dependencies: tslib: 2.8.1 @@ -25677,11 +26100,11 @@ snapshots: '@floating-ui/utils@0.2.9': {} - '@floating-ui/vue@1.1.5(vue@3.5.13(typescript@5.8.2))': + '@floating-ui/vue@1.1.5(vue@3.5.14(typescript@5.8.2))': dependencies: '@floating-ui/dom': 1.6.12 '@floating-ui/utils': 0.2.8 - vue-demi: 0.14.10(vue@3.5.13(typescript@5.8.2)) + vue-demi: 0.14.10(vue@3.5.14(typescript@5.8.2)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -25738,7 +26161,7 @@ snapshots: '@humanwhocodes/retry@0.4.2': {} - '@ianvs/prettier-plugin-sort-imports@4.1.1(@vue/compiler-sfc@3.5.13)(prettier@3.2.4)': + '@ianvs/prettier-plugin-sort-imports@4.1.1(@vue/compiler-sfc@3.5.14)(prettier@3.2.4)': dependencies: '@babel/core': 7.26.9 '@babel/generator': 7.26.9 @@ -25748,7 +26171,7 @@ snapshots: prettier: 3.2.4 semver: 7.7.1 optionalDependencies: - '@vue/compiler-sfc': 3.5.13 + '@vue/compiler-sfc': 3.5.14 transitivePeerDependencies: - supports-color @@ -25757,76 +26180,154 @@ snapshots: '@img/sharp-libvips-darwin-arm64': 1.0.4 optional: true + '@img/sharp-darwin-arm64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 + optional: true + '@img/sharp-darwin-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.0.4 optional: true + '@img/sharp-darwin-x64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 + optional: true + '@img/sharp-libvips-darwin-arm64@1.0.4': optional: true + '@img/sharp-libvips-darwin-arm64@1.1.0': + optional: true + '@img/sharp-libvips-darwin-x64@1.0.4': optional: true + '@img/sharp-libvips-darwin-x64@1.1.0': + optional: true + '@img/sharp-libvips-linux-arm64@1.0.4': optional: true + '@img/sharp-libvips-linux-arm64@1.1.0': + optional: true + '@img/sharp-libvips-linux-arm@1.0.5': optional: true + '@img/sharp-libvips-linux-arm@1.1.0': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.1.0': + optional: true + '@img/sharp-libvips-linux-s390x@1.0.4': optional: true + '@img/sharp-libvips-linux-s390x@1.1.0': + optional: true + '@img/sharp-libvips-linux-x64@1.0.4': optional: true + '@img/sharp-libvips-linux-x64@1.1.0': + optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + optional: true + '@img/sharp-libvips-linuxmusl-x64@1.0.4': optional: true + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + optional: true + '@img/sharp-linux-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.0.4 optional: true + '@img/sharp-linux-arm64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + optional: true + '@img/sharp-linux-arm@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.0.5 optional: true + '@img/sharp-linux-arm@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + optional: true + '@img/sharp-linux-s390x@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.0.4 optional: true + '@img/sharp-linux-s390x@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + optional: true + '@img/sharp-linux-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.0.4 optional: true + '@img/sharp-linux-x64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + optional: true + '@img/sharp-linuxmusl-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 optional: true + '@img/sharp-linuxmusl-arm64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + optional: true + '@img/sharp-linuxmusl-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.0.4 optional: true + '@img/sharp-linuxmusl-x64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + optional: true + '@img/sharp-wasm32@0.33.5': dependencies: '@emnapi/runtime': 1.3.1 optional: true + '@img/sharp-wasm32@0.34.1': + dependencies: + '@emnapi/runtime': 1.4.3 + optional: true + '@img/sharp-win32-ia32@0.33.5': optional: true + '@img/sharp-win32-ia32@0.34.1': + optional: true + '@img/sharp-win32-x64@0.33.5': optional: true + '@img/sharp-win32-x64@0.34.1': + optional: true + '@internationalized/date@3.5.5': dependencies: '@swc/helpers': 0.5.15 @@ -25926,7 +26427,7 @@ snapshots: dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.15.3 + '@types/node': 20.17.24 '@types/yargs': 15.0.19 chalk: 4.1.2 @@ -26340,6 +26841,21 @@ snapshots: '@lezer/lr': 1.4.2 json5: 2.2.3 + '@modelcontextprotocol/sdk@1.10.2': + dependencies: + content-type: 1.0.5 + cors: 2.8.5 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + express: 5.1.0 + express-rate-limit: 7.5.0(express@5.1.0) + pkce-challenge: 5.0.0 + raw-body: 3.0.0 + zod: 3.24.4 + zod-to-json-schema: 3.24.3(zod@3.24.4) + transitivePeerDependencies: + - supports-color + '@mongodb-js/saslprep@1.1.9': dependencies: sparse-bitfield: 3.0.3 @@ -26394,6 +26910,8 @@ snapshots: '@next/env@15.2.3': {} + '@next/env@15.3.2': {} + '@next/eslint-plugin-next@15.0.0-canary.149': dependencies: fast-glob: 3.3.1 @@ -26401,27 +26919,51 @@ snapshots: '@next/swc-darwin-arm64@15.2.3': optional: true + '@next/swc-darwin-arm64@15.3.2': + optional: true + '@next/swc-darwin-x64@15.2.3': optional: true + '@next/swc-darwin-x64@15.3.2': + optional: true + '@next/swc-linux-arm64-gnu@15.2.3': optional: true + '@next/swc-linux-arm64-gnu@15.3.2': + optional: true + '@next/swc-linux-arm64-musl@15.2.3': optional: true + '@next/swc-linux-arm64-musl@15.3.2': + optional: true + '@next/swc-linux-x64-gnu@15.2.3': optional: true + '@next/swc-linux-x64-gnu@15.3.2': + optional: true + '@next/swc-linux-x64-musl@15.2.3': optional: true + '@next/swc-linux-x64-musl@15.3.2': + optional: true + '@next/swc-win32-arm64-msvc@15.2.3': optional: true + '@next/swc-win32-arm64-msvc@15.3.2': + optional: true + '@next/swc-win32-x64-msvc@15.2.3': optional: true + '@next/swc-win32-x64-msvc@15.3.2': + optional: true + '@noble/ciphers@0.6.0': {} '@noble/hashes@1.7.1': {} @@ -26530,12 +27072,12 @@ snapshots: prompts: 2.4.2 semver: 7.7.1 - '@nuxt/devtools@2.2.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@nuxt/devtools@2.2.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2))': dependencies: '@nuxt/devtools-kit': 2.2.1(magicast@0.3.5)(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)) '@nuxt/devtools-wizard': 2.2.1 '@nuxt/kit': 3.16.0(magicast@0.3.5) - '@vue/devtools-core': 7.7.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + '@vue/devtools-core': 7.7.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) '@vue/devtools-kit': 7.7.2 birpc: 2.2.0 consola: 3.4.0 @@ -26562,7 +27104,7 @@ snapshots: tinyglobby: 0.2.12 vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) vite-plugin-inspect: 11.0.0(@nuxt/kit@3.16.0(magicast@0.3.5))(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)) - vite-plugin-vue-tracer: 0.1.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + vite-plugin-vue-tracer: 0.1.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) which: 5.0.0 ws: 8.18.1 transitivePeerDependencies: @@ -26649,12 +27191,12 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/vite-builder@3.16.0(@biomejs/biome@1.9.4)(@types/node@22.15.3)(eslint@9.22.0(jiti@2.4.2))(less@4.2.2)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.38.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0)': + '@nuxt/vite-builder@3.16.0(@biomejs/biome@1.9.4)(@types/node@22.15.3)(eslint@9.22.0(jiti@2.4.2))(less@4.2.2)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.38.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2))(yaml@2.7.0)': dependencies: '@nuxt/kit': 3.16.0(magicast@0.3.5) '@rollup/plugin-replace': 6.0.2(rollup@4.38.0) - '@vitejs/plugin-vue': 5.2.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) - '@vitejs/plugin-vue-jsx': 4.1.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + '@vitejs/plugin-vue': 5.2.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) + '@vitejs/plugin-vue-jsx': 4.1.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) autoprefixer: 10.4.20(postcss@8.5.3) consola: 3.4.0 cssnano: 7.0.6(postcss@8.5.3) @@ -26682,7 +27224,7 @@ snapshots: vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) vite-node: 3.0.8(@types/node@22.15.3)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0) vite-plugin-checker: 0.9.0(@biomejs/biome@1.9.4)(eslint@9.22.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.2)(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)) - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) vue-bundle-renderer: 2.1.1 transitivePeerDependencies: - '@biomejs/biome' @@ -28071,9 +28613,9 @@ snapshots: '@prisma/debug': 6.4.1 optional: true - '@radix-icons/vue@1.0.0(vue@3.5.13(typescript@5.8.2))': + '@radix-icons/vue@1.0.0(vue@3.5.14(typescript@5.8.2))': dependencies: - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) '@radix-ui/number@1.1.0': {} @@ -30808,6 +31350,32 @@ snapshots: transitivePeerDependencies: - '@types/react' + '@redis/bloom@1.2.0(@redis/client@1.6.1)': + dependencies: + '@redis/client': 1.6.1 + + '@redis/client@1.6.1': + dependencies: + cluster-key-slot: 1.1.2 + generic-pool: 3.9.0 + yallist: 4.0.0 + + '@redis/graph@1.1.1(@redis/client@1.6.1)': + dependencies: + '@redis/client': 1.6.1 + + '@redis/json@1.0.7(@redis/client@1.6.1)': + dependencies: + '@redis/client': 1.6.1 + + '@redis/search@1.2.0(@redis/client@1.6.1)': + dependencies: + '@redis/client': 1.6.1 + + '@redis/time-series@1.1.0(@redis/client@1.6.1)': + dependencies: + '@redis/client': 1.6.1 + '@redocly/ajv@8.11.2': dependencies: fast-deep-equal: 3.1.3 @@ -32165,11 +32733,11 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-start-api-routes@1.112.18(aguku5xwh67z542n34jhfwn7wm)': + '@tanstack/react-start-api-routes@1.112.18(do3hc3md4wd7it5bigaqcra2vq)': dependencies: - '@tanstack/react-start-server': 1.112.18(aguku5xwh67z542n34jhfwn7wm) + '@tanstack/react-start-server': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) '@tanstack/router-core': 1.112.18 - vinxi: 0.5.3(5mkccpfbjktkt3otnngqrrcgde) + vinxi: 0.5.3(qmycrikecd3inn5enqnqcdtkym) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -32215,7 +32783,7 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-client@1.112.18(aguku5xwh67z542n34jhfwn7wm)': + '@tanstack/react-start-client@1.112.18(do3hc3md4wd7it5bigaqcra2vq)': dependencies: '@tanstack/react-router': 1.112.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/router-core': 1.112.18 @@ -32225,7 +32793,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - vinxi: 0.5.3(5mkccpfbjktkt3otnngqrrcgde) + vinxi: 0.5.3(qmycrikecd3inn5enqnqcdtkym) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -32269,7 +32837,7 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-client@1.114.34(3rgr7yknbwuqb7flheblwpv2eq)': + '@tanstack/react-start-client@1.114.34(2plvxtj6a7vw55mtbqwukj7brm)': dependencies: '@tanstack/react-router': 1.114.34(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@tanstack/router-core': 1.114.33 @@ -32280,7 +32848,7 @@ snapshots: react-dom: 19.0.0(react@19.0.0) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - vinxi: 0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) + vinxi: 0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -32324,7 +32892,7 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-client@1.114.34(aguku5xwh67z542n34jhfwn7wm)': + '@tanstack/react-start-client@1.114.34(do3hc3md4wd7it5bigaqcra2vq)': dependencies: '@tanstack/react-router': 1.114.34(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/router-core': 1.114.33 @@ -32335,7 +32903,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - vinxi: 0.5.3(5mkccpfbjktkt3otnngqrrcgde) + vinxi: 0.5.3(qmycrikecd3inn5enqnqcdtkym) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -32379,7 +32947,7 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-config@1.114.34(lijngnfq54cp5rlnj53jssmkhu)': + '@tanstack/react-start-config@1.114.34(xdtxozacaptx2f2yoax7hh4is4)': dependencies: '@tanstack/react-start-plugin': 1.114.32(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) '@tanstack/router-core': 1.114.33 @@ -32389,11 +32957,11 @@ snapshots: '@tanstack/start-server-functions-handler': 1.114.33 '@vitejs/plugin-react': 4.3.4(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)) import-meta-resolve: 4.1.0 - nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) + nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) ofetch: 1.4.1 react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - vinxi: 0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) + vinxi: 0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) zod: 3.24.2 transitivePeerDependencies: @@ -32498,11 +33066,11 @@ snapshots: - tsx - yaml - '@tanstack/react-start-router-manifest@1.112.18(5mkccpfbjktkt3otnngqrrcgde)': + '@tanstack/react-start-router-manifest@1.112.18(qmycrikecd3inn5enqnqcdtkym)': dependencies: '@tanstack/router-core': 1.112.18 tiny-invariant: 1.3.3 - vinxi: 0.5.3(5mkccpfbjktkt3otnngqrrcgde) + vinxi: 0.5.3(qmycrikecd3inn5enqnqcdtkym) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -32546,11 +33114,11 @@ snapshots: - xml2js - yaml - ? '@tanstack/react-start-router-manifest@1.114.33(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0)' + ? '@tanstack/react-start-router-manifest@1.114.33(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0)' : dependencies: '@tanstack/router-core': 1.114.33 tiny-invariant: 1.3.3 - vinxi: 0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) + vinxi: 0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -32594,9 +33162,9 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-server-functions-client@1.112.18(fbq2slcpifq65x7m35legngaoq)': + '@tanstack/react-start-server-functions-client@1.112.18(rikohmhqegmq4stnnvkdxooyim)': dependencies: - '@tanstack/react-start-server-functions-fetcher': 1.112.18(aguku5xwh67z542n34jhfwn7wm) + '@tanstack/react-start-server-functions-fetcher': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) '@tanstack/server-functions-plugin': 1.112.18(@types/node@22.13.10)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' @@ -32644,10 +33212,10 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-server-functions-fetcher@1.112.18(aguku5xwh67z542n34jhfwn7wm)': + '@tanstack/react-start-server-functions-fetcher@1.112.18(do3hc3md4wd7it5bigaqcra2vq)': dependencies: '@tanstack/react-router': 1.112.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tanstack/react-start-client': 1.114.34(aguku5xwh67z542n34jhfwn7wm) + '@tanstack/react-start-client': 1.114.34(do3hc3md4wd7it5bigaqcra2vq) '@tanstack/router-core': 1.112.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -32694,11 +33262,11 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-server-functions-handler@1.112.18(aguku5xwh67z542n34jhfwn7wm)': + '@tanstack/react-start-server-functions-handler@1.112.18(do3hc3md4wd7it5bigaqcra2vq)': dependencies: '@tanstack/react-router': 1.112.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tanstack/react-start-client': 1.112.18(aguku5xwh67z542n34jhfwn7wm) - '@tanstack/react-start-server': 1.112.18(aguku5xwh67z542n34jhfwn7wm) + '@tanstack/react-start-client': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) + '@tanstack/react-start-server': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tiny-invariant: 1.3.3 @@ -32745,11 +33313,11 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-server-functions-ssr@1.112.18(fbq2slcpifq65x7m35legngaoq)': + '@tanstack/react-start-server-functions-ssr@1.112.18(rikohmhqegmq4stnnvkdxooyim)': dependencies: - '@tanstack/react-start-client': 1.112.18(aguku5xwh67z542n34jhfwn7wm) - '@tanstack/react-start-server': 1.112.18(aguku5xwh67z542n34jhfwn7wm) - '@tanstack/react-start-server-functions-fetcher': 1.112.18(aguku5xwh67z542n34jhfwn7wm) + '@tanstack/react-start-client': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) + '@tanstack/react-start-server': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) + '@tanstack/react-start-server-functions-fetcher': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) '@tanstack/server-functions-plugin': 1.112.18(@types/node@22.13.10)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) tiny-invariant: 1.3.3 transitivePeerDependencies: @@ -32798,11 +33366,11 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-server@1.112.18(aguku5xwh67z542n34jhfwn7wm)': + '@tanstack/react-start-server@1.112.18(do3hc3md4wd7it5bigaqcra2vq)': dependencies: '@tanstack/history': 1.112.18 '@tanstack/react-router': 1.112.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tanstack/react-start-client': 1.112.18(aguku5xwh67z542n34jhfwn7wm) + '@tanstack/react-start-client': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) '@tanstack/router-core': 1.112.18 h3: 1.13.0 isbot: 5.1.23 @@ -32869,13 +33437,13 @@ snapshots: tiny-warning: 1.0.3 unctx: 2.4.1 - '@tanstack/react-start@1.114.34(lijngnfq54cp5rlnj53jssmkhu)': + '@tanstack/react-start@1.114.34(xdtxozacaptx2f2yoax7hh4is4)': dependencies: - '@tanstack/react-start-client': 1.114.34(3rgr7yknbwuqb7flheblwpv2eq) - '@tanstack/react-start-config': 1.114.34(lijngnfq54cp5rlnj53jssmkhu) - '@tanstack/react-start-router-manifest': 1.114.33(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) + '@tanstack/react-start-client': 1.114.34(2plvxtj6a7vw55mtbqwukj7brm) + '@tanstack/react-start-config': 1.114.34(xdtxozacaptx2f2yoax7hh4is4) + '@tanstack/react-start-router-manifest': 1.114.33(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) '@tanstack/react-start-server': 1.114.34(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@tanstack/start-api-routes': 1.114.33(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) + '@tanstack/start-api-routes': 1.114.33(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) '@tanstack/start-server-functions-client': 1.114.33(@types/node@22.15.3)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) '@tanstack/start-server-functions-handler': 1.114.33 '@tanstack/start-server-functions-server': 1.114.32(@types/node@22.15.3)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) @@ -33096,11 +33664,11 @@ snapshots: - tsx - yaml - '@tanstack/start-api-routes@1.114.33(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0)': + '@tanstack/start-api-routes@1.114.33(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0)': dependencies: '@tanstack/router-core': 1.114.33 '@tanstack/start-server-core': 1.114.33 - vinxi: 0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) + vinxi: 0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33151,21 +33719,21 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/start-config@1.113.0(hcvcmo22cfk2zc45m3egdtrfb4)': + '@tanstack/start-config@1.113.0(umfczj6grv5xwnnilehiba4mti)': dependencies: '@tanstack/react-router': 1.112.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-start-plugin': 1.112.18(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) - '@tanstack/react-start-server-functions-handler': 1.112.18(aguku5xwh67z542n34jhfwn7wm) + '@tanstack/react-start-server-functions-handler': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) '@tanstack/router-generator': 1.113.0(@tanstack/react-router@1.112.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@tanstack/router-plugin': 1.113.0(@tanstack/react-router@1.112.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite-plugin-solid@2.11.6(solid-js@1.9.5)(vite@6.3.4(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(vite@6.3.4(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)) '@tanstack/server-functions-plugin': 1.112.18(@types/node@22.13.10)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) '@vitejs/plugin-react': 4.3.4(vite@6.3.4(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)) import-meta-resolve: 4.1.0 - nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) + nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) ofetch: 1.4.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - vinxi: 0.5.3(5mkccpfbjktkt3otnngqrrcgde) + vinxi: 0.5.3(qmycrikecd3inn5enqnqcdtkym) vite: 6.3.4(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) zod: 3.24.2 transitivePeerDependencies: @@ -33317,16 +33885,16 @@ snapshots: - tsx - yaml - '@tanstack/start@1.113.0(hcvcmo22cfk2zc45m3egdtrfb4)': + '@tanstack/start@1.113.0(umfczj6grv5xwnnilehiba4mti)': dependencies: - '@tanstack/react-start-api-routes': 1.112.18(aguku5xwh67z542n34jhfwn7wm) - '@tanstack/react-start-client': 1.112.18(aguku5xwh67z542n34jhfwn7wm) - '@tanstack/react-start-router-manifest': 1.112.18(5mkccpfbjktkt3otnngqrrcgde) - '@tanstack/react-start-server': 1.112.18(aguku5xwh67z542n34jhfwn7wm) - '@tanstack/react-start-server-functions-client': 1.112.18(fbq2slcpifq65x7m35legngaoq) - '@tanstack/react-start-server-functions-handler': 1.112.18(aguku5xwh67z542n34jhfwn7wm) - '@tanstack/react-start-server-functions-ssr': 1.112.18(fbq2slcpifq65x7m35legngaoq) - '@tanstack/start-config': 1.113.0(hcvcmo22cfk2zc45m3egdtrfb4) + '@tanstack/react-start-api-routes': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) + '@tanstack/react-start-client': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) + '@tanstack/react-start-router-manifest': 1.112.18(qmycrikecd3inn5enqnqcdtkym) + '@tanstack/react-start-server': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) + '@tanstack/react-start-server-functions-client': 1.112.18(rikohmhqegmq4stnnvkdxooyim) + '@tanstack/react-start-server-functions-handler': 1.112.18(do3hc3md4wd7it5bigaqcra2vq) + '@tanstack/react-start-server-functions-ssr': 1.112.18(rikohmhqegmq4stnnvkdxooyim) + '@tanstack/start-config': 1.113.0(umfczj6grv5xwnnilehiba4mti) '@tanstack/start-server-functions-server': 1.112.18(@types/node@22.13.10)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' @@ -33386,10 +33954,10 @@ snapshots: '@tanstack/virtual-file-routes@1.99.0': {} - '@tanstack/vue-virtual@3.10.8(vue@3.5.13(typescript@5.8.2))': + '@tanstack/vue-virtual@3.10.8(vue@3.5.14(typescript@5.8.2))': dependencies: '@tanstack/virtual-core': 3.10.8 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) '@trysound/sax@0.2.0': {} @@ -33437,9 +34005,9 @@ snapshots: '@types/braces@3.0.4': {} - '@types/bun@1.2.12': + '@types/bun@1.2.13': dependencies: - bun-types: 1.2.12 + bun-types: 1.2.13 '@types/canvas-confetti@1.9.0': {} @@ -33610,7 +34178,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 '@types/hammerjs@2.0.46': {} @@ -33628,7 +34196,7 @@ snapshots: '@types/http-proxy@1.17.16': dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 '@types/istanbul-lib-coverage@2.0.6': {} @@ -33651,7 +34219,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 '@types/leaflet@1.7.6': dependencies: @@ -33689,7 +34257,7 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 '@types/node@18.19.87': dependencies: @@ -33714,6 +34282,7 @@ snapshots: '@types/node@22.15.3': dependencies: undici-types: 6.21.0 + optional: true '@types/parse-json@4.0.2': {} @@ -33864,7 +34433,7 @@ snapshots: '@types/ws@8.5.13': dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 '@types/yargs-parser@21.0.3': {} @@ -34042,11 +34611,11 @@ snapshots: hookable: 5.5.3 zhead: 2.2.4 - '@unhead/vue@2.0.0-rc.9(vue@3.5.13(typescript@5.8.2))': + '@unhead/vue@2.0.0-rc.9(vue@3.5.14(typescript@5.8.2))': dependencies: hookable: 5.5.3 unhead: 2.0.0-rc.9 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) '@unovis/dagre-layout@0.8.8-2': dependencies: @@ -34094,10 +34663,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@unovis/vue@1.4.3-beta.0(@unovis/ts@1.4.3-beta.0)(vue@3.5.13(typescript@5.8.2))': + '@unovis/vue@1.4.3-beta.0(@unovis/ts@1.4.3-beta.0)(vue@3.5.14(typescript@5.8.2))': dependencies: '@unovis/ts': 1.4.3-beta.0 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) '@urql/core@5.1.1(graphql@15.10.1)': dependencies: @@ -34163,23 +34732,31 @@ snapshots: '@vanilla-extract/private@1.0.6': {} - '@vee-validate/zod@4.15.0(vue@3.5.13(typescript@5.8.2))(zod@3.24.2)': + '@vee-validate/zod@4.15.0(vue@3.5.14(typescript@5.8.2))(zod@3.24.2)': dependencies: type-fest: 4.26.1 - vee-validate: 4.15.0(vue@3.5.13(typescript@5.8.2)) + vee-validate: 4.15.0(vue@3.5.14(typescript@5.8.2)) zod: 3.24.2 transitivePeerDependencies: - vue - '@vercel/analytics@1.5.0(@remix-run/react@2.16.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@sveltejs/kit@2.19.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(svelte@5.22.6)(vue-router@4.5.1(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))': + '@vercel/analytics@1.5.0(@remix-run/react@2.16.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@sveltejs/kit@2.19.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(svelte@5.22.6)(vue-router@4.5.1(vue@3.5.14(typescript@5.8.2)))(vue@3.5.14(typescript@5.8.2))': optionalDependencies: '@remix-run/react': 2.16.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) '@sveltejs/kit': 2.19.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)))(svelte@5.22.6)(vite@6.3.4(@types/node@22.13.8)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)) next: 15.2.3(@babel/core@7.26.9)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 svelte: 5.22.6 - vue: 3.5.13(typescript@5.8.2) - vue-router: 4.5.1(vue@3.5.13(typescript@5.8.2)) + vue: 3.5.14(typescript@5.8.2) + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.2)) + + '@vercel/mcp-adapter@0.4.1(next@15.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))': + dependencies: + '@modelcontextprotocol/sdk': 1.10.2 + next: 15.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) + redis: 4.7.1 + transitivePeerDependencies: + - supports-color '@vercel/nft@0.29.2(encoding@0.1.13)(rollup@4.38.0)': dependencies: @@ -34257,20 +34834,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.1.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@vitejs/plugin-vue-jsx@4.1.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2))': dependencies: '@babel/core': 7.26.9 '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.9) '@vue/babel-plugin-jsx': 1.3.0(@babel/core@7.26.9) vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@vitejs/plugin-vue@5.2.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2))': dependencies: vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) '@vitest/expect@1.6.1': dependencies: @@ -34412,7 +34989,7 @@ snapshots: '@vscode/l10n@0.0.18': {} - '@vue-macros/common@1.16.1(vue@3.5.13(typescript@5.8.2))': + '@vue-macros/common@1.16.1(vue@3.5.14(typescript@5.8.2))': dependencies: '@vue/compiler-sfc': 3.5.13 ast-kit: 1.4.2 @@ -34421,7 +34998,7 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.2 optionalDependencies: - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) '@vue/babel-helper-vue-transform-on@1.3.0': {} @@ -34461,12 +35038,20 @@ snapshots: '@vue/compiler-core@3.5.13': dependencies: - '@babel/parser': 7.26.9 + '@babel/parser': 7.27.1 '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.1 + '@vue/compiler-core@3.5.14': + dependencies: + '@babel/parser': 7.27.2 + '@vue/shared': 3.5.14 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + '@vue/compiler-dom@3.3.4': dependencies: '@vue/compiler-core': 3.3.4 @@ -34477,6 +35062,11 @@ snapshots: '@vue/compiler-core': 3.5.13 '@vue/shared': 3.5.13 + '@vue/compiler-dom@3.5.14': + dependencies: + '@vue/compiler-core': 3.5.14 + '@vue/shared': 3.5.14 + '@vue/compiler-sfc@3.3.4': dependencies: '@babel/parser': 7.27.1 @@ -34502,6 +35092,18 @@ snapshots: postcss: 8.5.3 source-map-js: 1.2.1 + '@vue/compiler-sfc@3.5.14': + dependencies: + '@babel/parser': 7.27.2 + '@vue/compiler-core': 3.5.14 + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.3 + source-map-js: 1.2.1 + '@vue/compiler-ssr@3.3.4': dependencies: '@vue/compiler-dom': 3.3.4 @@ -34512,13 +35114,18 @@ snapshots: '@vue/compiler-dom': 3.5.13 '@vue/shared': 3.5.13 + '@vue/compiler-ssr@3.5.14': + dependencies: + '@vue/compiler-dom': 3.5.14 + '@vue/shared': 3.5.14 + '@vue/devtools-api@6.6.4': {} '@vue/devtools-api@7.6.2': dependencies: '@vue/devtools-kit': 7.6.2 - '@vue/devtools-core@7.7.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@vue/devtools-core@7.7.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2))': dependencies: '@vue/devtools-kit': 7.7.2 '@vue/devtools-shared': 7.7.2 @@ -34526,7 +35133,7 @@ snapshots: nanoid: 5.1.5 pathe: 2.0.3 vite-hot-client: 0.2.4(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)) - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) transitivePeerDependencies: - vite @@ -34574,6 +35181,10 @@ snapshots: dependencies: '@vue/shared': 3.5.13 + '@vue/reactivity@3.5.14': + dependencies: + '@vue/shared': 3.5.14 + '@vue/runtime-core@3.3.4': dependencies: '@vue/reactivity': 3.3.4 @@ -34584,6 +35195,11 @@ snapshots: '@vue/reactivity': 3.5.13 '@vue/shared': 3.5.13 + '@vue/runtime-core@3.5.14': + dependencies: + '@vue/reactivity': 3.5.14 + '@vue/shared': 3.5.14 + '@vue/runtime-dom@3.3.4': dependencies: '@vue/runtime-core': 3.3.4 @@ -34597,6 +35213,13 @@ snapshots: '@vue/shared': 3.5.13 csstype: 3.1.3 + '@vue/runtime-dom@3.5.14': + dependencies: + '@vue/reactivity': 3.5.14 + '@vue/runtime-core': 3.5.14 + '@vue/shared': 3.5.14 + csstype: 3.1.3 + '@vue/server-renderer@3.3.4(vue@3.3.4)': dependencies: '@vue/compiler-ssr': 3.3.4 @@ -34609,26 +35232,34 @@ snapshots: '@vue/shared': 3.5.13 vue: 3.5.13(typescript@5.8.2) + '@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.8.2))': + dependencies: + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 + vue: 3.5.14(typescript@5.8.2) + '@vue/shared@3.3.4': {} '@vue/shared@3.5.13': {} - '@vueuse/core@10.11.1(vue@3.5.13(typescript@5.8.2))': + '@vue/shared@3.5.14': {} + + '@vueuse/core@10.11.1(vue@3.5.14(typescript@5.8.2))': dependencies: '@types/web-bluetooth': 0.0.20 '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.8.2)) - vue-demi: 0.14.10(vue@3.5.13(typescript@5.8.2)) + '@vueuse/shared': 10.11.1(vue@3.5.14(typescript@5.8.2)) + vue-demi: 0.14.10(vue@3.5.14(typescript@5.8.2)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/core@11.3.0(vue@3.5.13(typescript@5.8.2))': + '@vueuse/core@11.3.0(vue@3.5.14(typescript@5.8.2))': dependencies: '@types/web-bluetooth': 0.0.20 '@vueuse/metadata': 11.3.0 - '@vueuse/shared': 11.3.0(vue@3.5.13(typescript@5.8.2)) - vue-demi: 0.14.10(vue@3.5.13(typescript@5.8.2)) + '@vueuse/shared': 11.3.0(vue@3.5.14(typescript@5.8.2)) + vue-demi: 0.14.10(vue@3.5.14(typescript@5.8.2)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -34637,16 +35268,16 @@ snapshots: '@vueuse/metadata@11.3.0': {} - '@vueuse/shared@10.11.1(vue@3.5.13(typescript@5.8.2))': + '@vueuse/shared@10.11.1(vue@3.5.14(typescript@5.8.2))': dependencies: - vue-demi: 0.14.10(vue@3.5.13(typescript@5.8.2)) + vue-demi: 0.14.10(vue@3.5.14(typescript@5.8.2)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/shared@11.3.0(vue@3.5.13(typescript@5.8.2))': + '@vueuse/shared@11.3.0(vue@3.5.14(typescript@5.8.2))': dependencies: - vue-demi: 0.14.10(vue@3.5.13(typescript@5.8.2)) + vue-demi: 0.14.10(vue@3.5.14(typescript@5.8.2)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -35170,6 +35801,11 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 + accepts@2.0.0: + dependencies: + mime-types: 3.0.1 + negotiator: 1.0.0 + acorn-import-attributes@1.9.5(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -35456,7 +36092,7 @@ snapshots: ast-walker-scope@0.6.2: dependencies: - '@babel/parser': 7.26.9 + '@babel/parser': 7.27.1 ast-kit: 1.4.2 astral-regex@1.0.0: {} @@ -36026,6 +36662,20 @@ snapshots: transitivePeerDependencies: - supports-color + body-parser@2.2.0: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.0(supports-color@9.4.0) + http-errors: 2.0.0 + iconv-lite: 0.6.3 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 3.0.0 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + boolbase@1.0.0: {} boxen@7.1.1: @@ -36151,9 +36801,9 @@ snapshots: transitivePeerDependencies: - magicast - bun-types@1.2.12: + bun-types@1.2.13: dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 bundle-name@4.1.0: dependencies: @@ -36412,7 +37062,7 @@ snapshots: chrome-launcher@0.15.2: dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -36423,7 +37073,7 @@ snapshots: chromium-edge-launcher@0.2.0: dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -36697,6 +37347,10 @@ snapshots: dependencies: safe-buffer: 5.2.1 + content-disposition@1.0.0: + dependencies: + safe-buffer: 5.2.1 + content-security-policy-parser@0.4.1: {} content-type@1.0.5: {} @@ -37213,18 +37867,18 @@ snapshots: dayjs@1.11.13: {} - db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0): + db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0): optionalDependencies: '@libsql/client': 0.14.0 better-sqlite3: 11.8.1 - drizzle-orm: 0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0) + drizzle-orm: 0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0) mysql2: 3.13.0 - db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0): + db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0): optionalDependencies: '@libsql/client': 0.14.0 better-sqlite3: 11.8.1 - drizzle-orm: 0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)) + drizzle-orm: 0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)) mysql2: 3.13.0 debug@2.6.9: @@ -37460,7 +38114,7 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.33.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@19.0.10)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0): + drizzle-orm@0.33.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@19.0.10)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0): optionalDependencies: '@cloudflare/workers-types': 4.20250303.0 '@libsql/client': 0.14.0 @@ -37469,14 +38123,14 @@ snapshots: '@types/pg': 8.11.11 '@types/react': 19.0.10 better-sqlite3: 11.8.1 - bun-types: 1.2.12 + bun-types: 1.2.13 kysely: 0.28.1 mysql2: 3.13.0 pg: 8.13.3 prisma: 5.22.0 react: 19.0.0 - drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0): + drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0): optionalDependencies: '@cloudflare/workers-types': 4.20250303.0 '@libsql/client': 0.14.0 @@ -37486,14 +38140,14 @@ snapshots: '@types/pg': 8.11.11 '@types/react': 18.3.18 better-sqlite3: 11.8.1 - bun-types: 1.2.12 + bun-types: 1.2.13 kysely: 0.28.1 mysql2: 3.13.0 pg: 8.13.3 prisma: 5.22.0 react: 19.0.0 - drizzle-orm@0.39.3(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)): + drizzle-orm@0.39.3(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)): optionalDependencies: '@cloudflare/workers-types': 4.20250303.0 '@libsql/client': 0.14.0 @@ -37502,13 +38156,13 @@ snapshots: '@types/better-sqlite3': 7.6.12 '@types/pg': 8.11.11 better-sqlite3: 11.8.1 - bun-types: 1.2.12 + bun-types: 1.2.13 kysely: 0.28.1 mysql2: 3.13.0 pg: 8.13.3 prisma: 6.4.1(typescript@5.8.2) - drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)): + drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)): optionalDependencies: '@cloudflare/workers-types': 4.20250303.0 '@libsql/client': 0.14.0 @@ -37517,7 +38171,7 @@ snapshots: '@types/better-sqlite3': 7.6.12 '@types/pg': 8.11.11 better-sqlite3: 11.8.1 - bun-types: 1.2.12 + bun-types: 1.2.13 gel: 2.0.1 kysely: 0.28.1 mysql2: 3.13.0 @@ -37599,11 +38253,11 @@ snapshots: embla-carousel-reactive-utils: 8.5.2(embla-carousel@8.5.2) svelte: 4.2.19 - embla-carousel-vue@8.5.2(vue@3.5.13(typescript@5.8.2)): + embla-carousel-vue@8.5.2(vue@3.5.14(typescript@5.8.2)): dependencies: embla-carousel: 8.5.2 embla-carousel-reactive-utils: 8.5.2(embla-carousel@8.5.2) - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) embla-carousel@8.5.2: {} @@ -38581,7 +39235,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 require-like: 0.1.2 event-target-shim@5.0.1: {} @@ -38592,6 +39246,12 @@ snapshots: events@3.3.0: {} + eventsource-parser@3.0.2: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.2 + exec-async@2.2.0: {} execa@1.0.0: @@ -38934,6 +39594,10 @@ snapshots: exponential-backoff@3.1.2: {} + express-rate-limit@7.5.0(express@5.1.0): + dependencies: + express: 5.1.0 + express@4.21.1: dependencies: accepts: 1.3.8 @@ -38970,6 +39634,38 @@ snapshots: transitivePeerDependencies: - supports-color + express@5.1.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.0 + content-disposition: 1.0.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.0(supports-color@9.4.0) + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.0 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + mime-types: 3.0.1 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.0 + serve-static: 2.2.0 + statuses: 2.0.1 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + exsolve@1.0.2: {} extend-shallow@2.0.1: @@ -39146,6 +39842,17 @@ snapshots: transitivePeerDependencies: - supports-color + finalhandler@2.1.0: + dependencies: + debug: 4.4.0(supports-color@9.4.0) + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + find-cache-dir@2.1.0: dependencies: commondir: 1.0.1 @@ -39279,6 +39986,8 @@ snapshots: fresh@0.5.2: {} + fresh@2.0.0: {} + fs-constants@1.0.0: {} fs-extra@10.1.0: @@ -39473,6 +40182,8 @@ snapshots: dependencies: loader-utils: 3.3.1 + generic-pool@3.9.0: {} + gensync@1.0.0-beta.2: {} geojson-vt@3.2.1: {} @@ -40483,6 +41194,8 @@ snapshots: is-plain-object@5.0.0: {} + is-promise@4.0.0: {} + is-property@1.0.2: {} is-reference@1.2.1: @@ -40667,7 +41380,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 22.13.8 + '@types/node': 20.17.24 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -40709,7 +41422,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.15.3 + '@types/node': 20.17.24 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -40726,7 +41439,7 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -40794,7 +41507,7 @@ snapshots: jscodeshift@0.14.0(@babel/preset-env@7.26.9(@babel/core@7.26.9)): dependencies: '@babel/core': 7.26.9 - '@babel/parser': 7.26.9 + '@babel/parser': 7.27.1 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.26.9) '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.26.9) '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.26.9) @@ -40819,7 +41532,7 @@ snapshots: jscodeshift@0.14.0(@babel/preset-env@7.26.9(@babel/core@7.27.1)): dependencies: '@babel/core': 7.26.9 - '@babel/parser': 7.26.9 + '@babel/parser': 7.27.1 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.26.9) '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.26.9) '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.26.9) @@ -41848,6 +42561,8 @@ snapshots: media-typer@0.3.0: {} + media-typer@1.1.0: {} + memoize-one@5.2.1: {} memoize-one@6.0.0: {} @@ -41862,6 +42577,8 @@ snapshots: merge-descriptors@1.0.3: {} + merge-descriptors@2.0.0: {} + merge-options@3.0.4: dependencies: is-plain-obj: 2.1.0 @@ -42258,7 +42975,7 @@ snapshots: '@babel/code-frame': 7.26.2 '@babel/core': 7.26.9 '@babel/generator': 7.26.9 - '@babel/parser': 7.26.9 + '@babel/parser': 7.27.1 '@babel/template': 7.26.9 '@babel/traverse': 7.26.9 '@babel/types': 7.26.9 @@ -42824,10 +43541,16 @@ snapshots: mime-db@1.53.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 + mime-types@3.0.1: + dependencies: + mime-db: 1.54.0 + mime@1.6.0: {} mime@2.6.0: {} @@ -42955,6 +43678,26 @@ snapshots: typescript: 5.8.2 vue: 3.5.13(typescript@5.8.2) + mkdist@2.2.0(sass@1.85.1)(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)): + dependencies: + autoprefixer: 10.4.20(postcss@8.5.3) + citty: 0.1.6 + cssnano: 7.0.6(postcss@8.5.3) + defu: 6.1.4 + esbuild: 0.24.2 + jiti: 1.21.7 + mlly: 1.7.4 + pathe: 1.1.2 + pkg-types: 1.3.1 + postcss: 8.5.3 + postcss-nested: 7.0.2(postcss@8.5.3) + semver: 7.7.1 + tinyglobby: 0.2.12 + optionalDependencies: + sass: 1.85.1 + typescript: 5.8.2 + vue: 3.5.14(typescript@5.8.2) + mlly@1.7.3: dependencies: acorn: 8.14.0 @@ -43199,9 +43942,35 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@15.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1): + dependencies: + '@next/env': 15.3.2 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001707 + postcss: 8.4.31 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + styled-jsx: 5.1.6(@babel/core@7.26.9)(babel-plugin-macros@3.1.0)(react@19.0.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.3.2 + '@next/swc-darwin-x64': 15.3.2 + '@next/swc-linux-arm64-gnu': 15.3.2 + '@next/swc-linux-arm64-musl': 15.3.2 + '@next/swc-linux-x64-gnu': 15.3.2 + '@next/swc-linux-x64-musl': 15.3.2 + '@next/swc-win32-arm64-msvc': 15.3.2 + '@next/swc-win32-x64-msvc': 15.3.2 + sass: 1.85.1 + sharp: 0.34.1 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nice-try@1.0.5: {} - nitropack@2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2): + nitropack@2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2): dependencies: '@cloudflare/kv-asset-handler': 0.3.4 '@netlify/functions': 3.0.0 @@ -43224,7 +43993,7 @@ snapshots: cookie-es: 2.0.0 croner: 9.0.0 crossws: 0.3.4 - db0: 0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0) + db0: 0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0) defu: 6.1.4 destr: 2.0.3 dot-prop: 9.0.0 @@ -43272,7 +44041,7 @@ snapshots: unenv: 2.0.0-rc.12 unimport: 4.1.2 unplugin-utils: 0.2.4 - unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(ioredis@5.6.0) + unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(ioredis@5.6.0) untyped: 2.0.0 unwasm: 0.3.9 youch: 4.1.0-beta.6 @@ -43305,7 +44074,7 @@ snapshots: - typescript - uploadthing - nitropack@2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2): + nitropack@2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2): dependencies: '@cloudflare/kv-asset-handler': 0.3.4 '@netlify/functions': 3.0.0 @@ -43328,7 +44097,7 @@ snapshots: cookie-es: 2.0.0 croner: 9.0.0 crossws: 0.3.4 - db0: 0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0) + db0: 0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0) defu: 6.1.4 destr: 2.0.3 dot-prop: 9.0.0 @@ -43376,7 +44145,7 @@ snapshots: unenv: 2.0.0-rc.12 unimport: 4.1.2 unplugin-utils: 0.2.4 - unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0) + unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0) untyped: 2.0.0 unwasm: 0.3.9 youch: 4.1.0-beta.6 @@ -43549,17 +44318,17 @@ snapshots: dependencies: esm-env: 1.2.1 - nuxt@3.16.0(yykrlyfgcq7bklxjhifzhuppyq): + nuxt@3.16.0(kygbndsg3u7xffwrewwioaaldy): dependencies: '@nuxt/cli': 3.22.5(magicast@0.3.5) '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 2.2.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + '@nuxt/devtools': 2.2.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) '@nuxt/kit': 3.16.0(magicast@0.3.5) '@nuxt/schema': 3.16.0 '@nuxt/telemetry': 2.6.5(magicast@0.3.5) - '@nuxt/vite-builder': 3.16.0(@biomejs/biome@1.9.4)(@types/node@22.15.3)(eslint@9.22.0(jiti@2.4.2))(less@4.2.2)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.38.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0) + '@nuxt/vite-builder': 3.16.0(@biomejs/biome@1.9.4)(@types/node@22.15.3)(eslint@9.22.0(jiti@2.4.2))(less@4.2.2)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.38.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2))(yaml@2.7.0) '@oxc-parser/wasm': 0.56.5 - '@unhead/vue': 2.0.0-rc.9(vue@3.5.13(typescript@5.8.2)) + '@unhead/vue': 2.0.0-rc.9(vue@3.5.14(typescript@5.8.2)) '@vue/shared': 3.5.13 c12: 3.0.2(magicast@0.3.5) chokidar: 4.0.3 @@ -43585,7 +44354,7 @@ snapshots: magic-string: 0.30.17 mlly: 1.7.4 nanotar: 0.2.0 - nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) + nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) nypm: 0.6.0 ofetch: 1.4.1 ohash: 2.0.11 @@ -43607,13 +44376,13 @@ snapshots: unenv: 2.0.0-rc.12 unimport: 4.1.2 unplugin: 2.2.0 - unplugin-vue-router: 0.12.0(vue-router@4.5.1(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2)) - unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0) + unplugin-vue-router: 0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.2)))(vue@3.5.14(typescript@5.8.2)) + unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0) untyped: 2.0.0 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) vue-bundle-renderer: 2.1.1 vue-devtools-stub: 0.1.0 - vue-router: 4.5.1(vue@3.5.13(typescript@5.8.2)) + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.2)) optionalDependencies: '@parcel/watcher': 2.5.1 '@types/node': 22.15.3 @@ -44112,6 +44881,8 @@ snapshots: path-to-regexp@6.3.0: {} + path-to-regexp@8.2.0: {} + path-type@4.0.0: {} path-type@6.0.0: {} @@ -44214,6 +44985,8 @@ snapshots: pirates@4.0.7: {} + pkce-challenge@5.0.0: {} + pkg-dir@3.0.0: dependencies: find-up: 3.0.0 @@ -45027,6 +45800,10 @@ snapshots: dependencies: side-channel: 1.1.0 + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + quansync@0.2.8: {} query-string@7.1.3: @@ -45048,20 +45825,20 @@ snapshots: quickselect@2.0.0: {} - radix-vue@1.9.17(vue@3.5.13(typescript@5.8.2)): + radix-vue@1.9.17(vue@3.5.14(typescript@5.8.2)): dependencies: '@floating-ui/dom': 1.6.12 - '@floating-ui/vue': 1.1.5(vue@3.5.13(typescript@5.8.2)) + '@floating-ui/vue': 1.1.5(vue@3.5.14(typescript@5.8.2)) '@internationalized/date': 3.6.0 '@internationalized/number': 3.5.4 - '@tanstack/vue-virtual': 3.10.8(vue@3.5.13(typescript@5.8.2)) - '@vueuse/core': 10.11.1(vue@3.5.13(typescript@5.8.2)) - '@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.8.2)) + '@tanstack/vue-virtual': 3.10.8(vue@3.5.14(typescript@5.8.2)) + '@vueuse/core': 10.11.1(vue@3.5.14(typescript@5.8.2)) + '@vueuse/shared': 10.11.1(vue@3.5.14(typescript@5.8.2)) aria-hidden: 1.2.4 defu: 6.1.4 fast-deep-equal: 3.1.3 nanoid: 5.0.9 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) transitivePeerDependencies: - '@vue/composition-api' @@ -45080,6 +45857,13 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + raw-body@3.0.0: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + unpipe: 1.0.0 + rc9@2.1.2: dependencies: defu: 6.1.4 @@ -45810,6 +46594,15 @@ snapshots: dependencies: redis-errors: 1.2.0 + redis@4.7.1: + dependencies: + '@redis/bloom': 1.2.0(@redis/client@1.6.1) + '@redis/client': 1.6.1 + '@redis/graph': 1.1.1(@redis/client@1.6.1) + '@redis/json': 1.0.7(@redis/client@1.6.1) + '@redis/search': 1.2.0(@redis/client@1.6.1) + '@redis/time-series': 1.1.0(@redis/client@1.6.1) + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -46310,6 +47103,16 @@ snapshots: rou3@0.5.1: {} + router@2.2.0: + dependencies: + debug: 4.4.0(supports-color@9.4.0) + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.2.0 + transitivePeerDependencies: + - supports-color + run-applescript@7.0.0: {} run-async@3.0.0: {} @@ -46465,6 +47268,22 @@ snapshots: transitivePeerDependencies: - supports-color + send@1.2.0: + dependencies: + debug: 4.4.0(supports-color@9.4.0) + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.0 + mime-types: 3.0.1 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + seq-queue@0.0.5: {} serialize-error@2.1.0: {} @@ -46492,6 +47311,15 @@ snapshots: transitivePeerDependencies: - supports-color + serve-static@2.2.0: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.0 + transitivePeerDependencies: + - supports-color + server-only@0.0.1: {} set-blocking@2.0.0: {} @@ -46579,6 +47407,34 @@ snapshots: '@img/sharp-win32-x64': 0.33.5 optional: true + sharp@0.34.1: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.1 + '@img/sharp-darwin-x64': 0.34.1 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.1 + '@img/sharp-linux-arm64': 0.34.1 + '@img/sharp-linux-s390x': 0.34.1 + '@img/sharp-linux-x64': 0.34.1 + '@img/sharp-linuxmusl-arm64': 0.34.1 + '@img/sharp-linuxmusl-x64': 0.34.1 + '@img/sharp-wasm32': 0.34.1 + '@img/sharp-win32-ia32': 0.34.1 + '@img/sharp-win32-x64': 0.34.1 + optional: true + shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 @@ -47021,7 +47877,7 @@ snapshots: stripe@18.0.0: dependencies: - '@types/node': 22.13.8 + '@types/node': 20.17.24 qs: 6.13.0 striptags@3.2.0: {} @@ -47753,6 +48609,12 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.1 + typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.8 @@ -47885,6 +48747,39 @@ snapshots: - vue - vue-tsc + unbuild@3.5.0(sass@1.85.1)(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)): + dependencies: + '@rollup/plugin-alias': 5.1.1(rollup@4.34.8) + '@rollup/plugin-commonjs': 28.0.2(rollup@4.34.8) + '@rollup/plugin-json': 6.1.0(rollup@4.34.8) + '@rollup/plugin-node-resolve': 16.0.0(rollup@4.34.8) + '@rollup/plugin-replace': 6.0.2(rollup@4.34.8) + '@rollup/pluginutils': 5.1.4(rollup@4.34.8) + citty: 0.1.6 + consola: 3.4.0 + defu: 6.1.4 + esbuild: 0.25.0 + fix-dts-default-cjs-exports: 1.0.0 + hookable: 5.5.3 + jiti: 2.4.2 + magic-string: 0.30.17 + mkdist: 2.2.0(sass@1.85.1)(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)) + mlly: 1.7.4 + pathe: 2.0.3 + pkg-types: 2.0.0 + pretty-bytes: 6.1.1 + rollup: 4.34.8 + rollup-plugin-dts: 6.1.1(rollup@4.34.8)(typescript@5.8.2) + scule: 1.3.0 + tinyglobby: 0.2.12 + untyped: 2.0.0 + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - sass + - vue + - vue-tsc + unconfig@0.6.1: dependencies: '@antfu/utils': 8.1.1 @@ -47913,7 +48808,8 @@ snapshots: undici-types@6.20.0: {} - undici-types@6.21.0: {} + undici-types@6.21.0: + optional: true undici@5.28.5: dependencies: @@ -48095,10 +48991,10 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.2 - unplugin-vue-router@0.12.0(vue-router@4.5.1(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2)): + unplugin-vue-router@0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.2)))(vue@3.5.14(typescript@5.8.2)): dependencies: '@babel/types': 7.26.9 - '@vue-macros/common': 1.16.1(vue@3.5.13(typescript@5.8.2)) + '@vue-macros/common': 1.16.1(vue@3.5.14(typescript@5.8.2)) ast-walker-scope: 0.6.2 chokidar: 4.0.3 fast-glob: 3.3.3 @@ -48113,7 +49009,7 @@ snapshots: unplugin-utils: 0.2.4 yaml: 2.7.0 optionalDependencies: - vue-router: 4.5.1(vue@3.5.13(typescript@5.8.2)) + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.2)) transitivePeerDependencies: - vue @@ -48127,7 +49023,7 @@ snapshots: acorn: 8.14.1 webpack-virtual-modules: 0.6.2 - unstorage@1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(ioredis@5.6.0): + unstorage@1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(ioredis@5.6.0): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -48139,10 +49035,10 @@ snapshots: ufo: 1.5.4 optionalDependencies: '@azure/identity': 4.6.0 - db0: 0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0) + db0: 0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0) ioredis: 5.6.0 - unstorage@1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0): + unstorage@1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -48154,7 +49050,7 @@ snapshots: ufo: 1.5.4 optionalDependencies: '@azure/identity': 4.6.0 - db0: 0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0) + db0: 0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0) ioredis: 5.6.0 untun@0.1.3: @@ -48292,7 +49188,7 @@ snapshots: kleur: 4.1.5 sade: 1.8.1 - v-calendar@3.1.2(@popperjs/core@2.11.8)(vue@3.5.13(typescript@5.8.2)): + v-calendar@3.1.2(@popperjs/core@2.11.8)(vue@3.5.14(typescript@5.8.2)): dependencies: '@popperjs/core': 2.11.8 '@types/lodash': 4.17.13 @@ -48300,8 +49196,8 @@ snapshots: date-fns: 2.30.0 date-fns-tz: 2.0.1(date-fns@2.30.0) lodash: 4.17.21 - vue: 3.5.13(typescript@5.8.2) - vue-screen-utils: 1.0.0-beta.13(vue@3.5.13(typescript@5.8.2)) + vue: 3.5.14(typescript@5.8.2) + vue-screen-utils: 1.0.0-beta.13(vue@3.5.14(typescript@5.8.2)) valibot@0.31.1: optional: true @@ -48334,11 +49230,11 @@ snapshots: bits-ui: 0.21.16(svelte@4.2.19) svelte: 4.2.19 - vaul-vue@0.2.1(radix-vue@1.9.17(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2)): + vaul-vue@0.2.1(radix-vue@1.9.17(vue@3.5.14(typescript@5.8.2)))(vue@3.5.14(typescript@5.8.2)): dependencies: - '@vueuse/core': 10.11.1(vue@3.5.13(typescript@5.8.2)) - radix-vue: 1.9.17(vue@3.5.13(typescript@5.8.2)) - vue: 3.5.13(typescript@5.8.2) + '@vueuse/core': 10.11.1(vue@3.5.14(typescript@5.8.2)) + radix-vue: 1.9.17(vue@3.5.14(typescript@5.8.2)) + vue: 3.5.14(typescript@5.8.2) transitivePeerDependencies: - '@vue/composition-api' @@ -48369,11 +49265,11 @@ snapshots: - '@types/react' - '@types/react-dom' - vee-validate@4.15.0(vue@3.5.13(typescript@5.8.2)): + vee-validate@4.15.0(vue@3.5.14(typescript@5.8.2)): dependencies: '@vue/devtools-api': 7.6.2 type-fest: 4.26.1 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) vfile-location@5.0.3: dependencies: @@ -48419,7 +49315,7 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vinxi@0.4.3(tbiltmkuca6gwy6wvywbppe5hm): + vinxi@0.4.3(xigip3pwxsynk4cmajsowrm4re): dependencies: '@babel/core': 7.26.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) @@ -48441,7 +49337,7 @@ snapshots: hookable: 5.5.3 http-proxy: 1.18.1 micromatch: 4.0.8 - nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) + nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) node-fetch-native: 1.6.6 path-to-regexp: 6.3.0 pathe: 1.1.2 @@ -48452,7 +49348,7 @@ snapshots: ufo: 1.5.4 unctx: 2.4.1 unenv: 1.10.0 - unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0) + unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0) vite: 5.4.19(@types/node@22.13.10)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0) zod: 3.24.2 transitivePeerDependencies: @@ -48496,7 +49392,7 @@ snapshots: - uploadthing - xml2js - vinxi@0.5.3(5mkccpfbjktkt3otnngqrrcgde): + vinxi@0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0): dependencies: '@babel/core': 7.26.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) @@ -48518,7 +49414,7 @@ snapshots: hookable: 5.5.3 http-proxy: 1.18.1 micromatch: 4.0.8 - nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) + nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) node-fetch-native: 1.6.6 path-to-regexp: 6.3.0 pathe: 1.1.2 @@ -48529,8 +49425,8 @@ snapshots: ufo: 1.5.4 unctx: 2.4.1 unenv: 1.10.0 - unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.12)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0) - vite: 6.3.4(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) + unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.13)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(ioredis@5.6.0) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) zod: 3.24.2 transitivePeerDependencies: - '@azure/app-configuration' @@ -48575,7 +49471,7 @@ snapshots: - xml2js - yaml - vinxi@0.5.3(@azure/identity@4.6.0)(@libsql/client@0.14.0)(@types/node@22.15.3)(better-sqlite3@11.8.1)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(ioredis@5.6.0)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(mysql2@3.13.0)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0): + vinxi@0.5.3(qmycrikecd3inn5enqnqcdtkym): dependencies: '@babel/core': 7.26.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) @@ -48597,7 +49493,7 @@ snapshots: hookable: 5.5.3 http-proxy: 1.18.1 micromatch: 4.0.8 - nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) + nitropack: 2.11.5(@azure/identity@4.6.0)(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(encoding@0.1.13)(mysql2@3.13.0)(typescript@5.8.2) node-fetch-native: 1.6.6 path-to-regexp: 6.3.0 pathe: 1.1.2 @@ -48608,8 +49504,8 @@ snapshots: ufo: 1.5.4 unctx: 2.4.1 unenv: 1.10.0 - unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.38.4(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(@types/react@18.3.18)(better-sqlite3@11.8.1)(bun-types@1.2.12)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@5.22.0)(react@19.0.0))(mysql2@3.13.0))(ioredis@5.6.0) - vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) + unstorage: 1.15.0(@azure/identity@4.6.0)(db0@0.3.1(@libsql/client@0.14.0)(better-sqlite3@11.8.1)(drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250303.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@prisma/client@6.4.1(prisma@6.4.1(typescript@5.8.2))(typescript@5.8.2))(@types/better-sqlite3@7.6.12)(@types/pg@8.11.11)(better-sqlite3@11.8.1)(bun-types@1.2.13)(gel@2.0.1)(kysely@0.28.1)(mysql2@3.13.0)(pg@8.13.3)(prisma@6.4.1(typescript@5.8.2)))(mysql2@3.13.0))(ioredis@5.6.0) + vite: 6.3.4(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) zod: 3.24.2 transitivePeerDependencies: - '@azure/app-configuration' @@ -48816,14 +49712,14 @@ snapshots: - supports-color optional: true - vite-plugin-vue-tracer@0.1.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)): + vite-plugin-vue-tracer@0.1.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)): dependencies: estree-walker: 3.0.3 magic-string: 0.30.17 pathe: 2.0.3 source-map-js: 1.2.1 vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) vite-tsconfig-paths@4.3.2(typescript@5.8.2)(vite@5.4.19(@types/node@22.15.3)(less@4.2.2)(lightningcss@1.29.2)(sass@1.85.1)(terser@5.39.0)): dependencies: @@ -49231,20 +50127,20 @@ snapshots: dependencies: ufo: 1.5.4 - vue-demi@0.14.10(vue@3.5.13(typescript@5.8.2)): + vue-demi@0.14.10(vue@3.5.14(typescript@5.8.2)): dependencies: - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) vue-devtools-stub@0.1.0: {} - vue-router@4.5.1(vue@3.5.13(typescript@5.8.2)): + vue-router@4.5.1(vue@3.5.14(typescript@5.8.2)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) - vue-screen-utils@1.0.0-beta.13(vue@3.5.13(typescript@5.8.2)): + vue-screen-utils@1.0.0-beta.13(vue@3.5.14(typescript@5.8.2)): dependencies: - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.14(typescript@5.8.2) vue-sonner@1.3.0: {} @@ -49266,6 +50162,16 @@ snapshots: optionalDependencies: typescript: 5.8.2 + vue@3.5.14(typescript@5.8.2): + dependencies: + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-sfc': 3.5.14 + '@vue/runtime-dom': 3.5.14 + '@vue/server-renderer': 3.5.14(vue@3.5.14(typescript@5.8.2)) + '@vue/shared': 3.5.14 + optionalDependencies: + typescript: 5.8.2 + walker@1.0.8: dependencies: makeerror: 1.0.12 @@ -49634,6 +50540,10 @@ snapshots: dependencies: zod: 3.24.2 + zod-to-json-schema@3.24.3(zod@3.24.4): + dependencies: + zod: 3.24.4 + zod-to-ts@1.2.0(typescript@5.8.2)(zod@3.24.2): dependencies: typescript: 5.8.2 @@ -49643,6 +50553,8 @@ snapshots: zod@3.24.2: {} + zod@3.24.4: {} + zustand@3.7.2(react@19.0.0): optionalDependencies: react: 19.0.0