diff --git a/.gitignore b/.gitignore index 8fa5c69404..42217cf108 100644 --- a/.gitignore +++ b/.gitignore @@ -140,10 +140,12 @@ packages/js/* packages/react/* packages/next/* packages/stack/* +packages/tanstack-start/* !packages/js/package.json !packages/react/package.json !packages/next/package.json !packages/stack/package.json +!packages/tanstack-start/package.json # claude code .claude/scheduled_tasks.lock diff --git a/apps/dashboard/public/tanstack-start-logo.png b/apps/dashboard/public/tanstack-start-logo.png new file mode 100644 index 0000000000..41443b6c22 Binary files /dev/null and b/apps/dashboard/public/tanstack-start-logo.png differ diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/setup-page.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/setup-page.tsx index cab6b61f0e..4f33d133bd 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/setup-page.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/setup-page.tsx @@ -1,7 +1,7 @@ 'use client'; import { CodeBlock } from '@/components/code-block'; -import { APIEnvKeys, NextJsEnvKeys } from '@/components/env-keys'; +import { APIEnvKeys, NextJsEnvKeys, ViteEnvKeys } from '@/components/env-keys'; import { InlineCode } from '@/components/inline-code'; import { StyledLink } from '@/components/link'; import { CopyPromptButton, Tabs, TabsContent, TabsList, TabsTrigger, Typography, cn } from "@/components/ui"; @@ -27,22 +27,58 @@ const nameClasses = "text-green-600 dark:text-green-500"; const INSTALL_COMMAND_BY_FRAMEWORK = { nextjs: 'npx @stackframe/stack-cli@latest init', + tanstackStart: 'npm install @stackframe/tanstack-start', react: 'npm install @stackframe/react', javascript: 'npm install @stackframe/js', python: 'pip install requests', } as const; -const buildInstallPrompt = (command: string) => deindent` +type SetupFramework = keyof typeof INSTALL_COMMAND_BY_FRAMEWORK; + +const TANSTACK_START_SETUP_PROMPT = deindent` + Please set up Stack Auth in my TanStack Start app. + + 1. Install the alpha TanStack Start package: + + npm install @stackframe/tanstack-start + + 2. Configure the app with these environment variables: + + VITE_STACK_PROJECT_ID= + STACK_SECRET_SERVER_KEY= + + 3. Create a StackClientApp using @stackframe/tanstack-start with: + - projectId: import.meta.env.VITE_STACK_PROJECT_ID + - tokenStore: "cookie" + - redirectMethod: "window" + + 4. Wrap the TanStack Start root route with StackProvider and StackTheme. + + 5. Add a /handler/$ route using StackHandler. The handler route must set ssr: false and pass location={pathname} from useLocation(). + + Use only the environment variables listed above. + + After it finishes, verify that the Stack Auth MCP server is registered in your AI client config — name: \`stack-auth\`, transport: \`http\`, URL: \`https://mcp.stack-auth.com/\`. If it is not registered, please add it manually so you have live access to Stack Auth docs and APIs. +`; + +const buildInstallPrompt = (framework: SetupFramework) => { + if (framework === "tanstackStart") { + return TANSTACK_START_SETUP_PROMPT; + } + + const command = INSTALL_COMMAND_BY_FRAMEWORK[framework]; + return deindent` Please run the following command in my project's terminal: ${command} After it finishes, verify that the Stack Auth MCP server is registered in your AI client config — name: \`stack-auth\`, transport: \`http\`, URL: \`https://mcp.stack-auth.com/\`. The command above should handle this automatically; if for any reason it didn't, please add the MCP server manually so you have live access to Stack Auth docs and APIs. `; +}; export default function SetupPage(props: { toMetrics: () => void }) { const adminApp = useAdminApp(); - const [selectedFramework, setSelectedFramework] = useState<'nextjs' | 'react' | 'javascript' | 'python'>('nextjs'); + const [selectedFramework, setSelectedFramework] = useState<'nextjs' | 'tanstackStart' | 'react' | 'javascript' | 'python'>('nextjs'); const [keys, setKeys] = useState<{ projectId: string, publishableClientKey?: string, secretServerKey: string } | null>(null); const projectConfig = adminApp.useProject().useConfig(); const requirePublishableClientKey = projectConfig.project.requirePublishableClientKey; @@ -220,6 +256,142 @@ export default function SetupPage(props: { toMetrics: () => void }) { } ]; + const tanstackStartSteps = [ + { + step: 2, + title: "Install Stack Auth", + content: <> + + In a new or existing TanStack Start project, install the alpha Stack Auth package: + + + npm install @stackframe/tanstack-start + + } + title="Terminal" + icon="terminal" + /> + + }, + { + step: 3, + title: "Create Keys", + content: <> + + Put these keys in your TanStack Start environment file. + + + + }, + { + step: 4, + title: "Create stack/client.ts file", + content: <> + + Create a new file called src/stack/client.ts and initialize Stack Auth with cookie storage. + + + + }, + { + step: 5, + title: "Update the root route", + content: <> + + Wrap your TanStack Start root route with StackProvider and StackTheme. + + + + + + + ); + } + + function RootDocument({ children }: { children: React.ReactNode }) { + return ( + + + + + + {children} + + + + ); + } + `} + title="src/routes/__root.tsx" + icon="code" + /> + + }, + { + step: 6, + title: "Add the handler route", + content: <> + + Create a splat route for Stack Auth's built-in auth pages. + + ; + } + `} + title="src/routes/handler/$.tsx" + icon="code" + /> + + If you start your TanStack Start app and navigate to http://localhost:3000/handler/sign-up, you will see the sign-up page. + + + }, + ]; + const javascriptSteps = [ { step: 2, @@ -480,7 +652,7 @@ export default function SetupPage(props: { toMetrics: () => void }) { Copy prompt @@ -500,6 +672,11 @@ export default function SetupPage(props: { toMetrics: () => void }) { name: 'Next.js', reverseIfDark: true, imgSrc: '/next-logo.svg', + }, { + id: 'tanstackStart', + name: 'TanStack Start', + reverseIfDark: false, + imgSrc: '/tanstack-start-logo.png', }, { id: 'react', name: 'React', @@ -538,6 +715,7 @@ export default function SetupPage(props: { toMetrics: () => void }) { , }, ...(selectedFramework === 'nextjs' ? nextJsSteps : []), + ...(selectedFramework === 'tanstackStart' ? tanstackStartSteps : []), ...(selectedFramework === 'react' ? reactSteps : []), ...(selectedFramework === 'javascript' ? javascriptSteps : []), ...(selectedFramework === 'python' ? pythonSteps : []), @@ -638,7 +816,7 @@ function GlobeIllustrationInner() { function StackAuthKeys(props: { keys: { projectId: string, publishableClientKey?: string, secretServerKey: string } | null, onGenerateKeys: () => Promise, - type: 'next' | 'raw', + type: 'next' | 'vite' | 'raw', }) { return (
@@ -650,6 +828,11 @@ function StackAuthKeys(props: { publishableClientKey={props.keys.publishableClientKey} secretServerKey={props.keys.secretServerKey} /> + ) : props.type === 'vite' ? ( + ) : ( { - router.push(subAppDestinationPath ?? appPath); + if (documentationHref != null) { + window.location.href = documentationHref; + } else { + router.push(subAppDestinationPath ?? appDestination); + } }; const handleDisable = async () => { diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx index 6c395bd636..a7098614a7 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx @@ -58,9 +58,11 @@ type AppSection = { items: { name: string, href: string, + external?: boolean, match: (fullUrl: URL) => boolean, }[], firstItemHref?: string, + firstItemExternal?: boolean, }; type BottomItem = { @@ -209,6 +211,7 @@ function NavItem({ if (isCollapsed) { // For sections, navigate to the first item when collapsed const collapsedHref = isSection && item.firstItemHref ? item.firstItemHref : href; + const collapsedTarget = isSection && item.firstItemExternal ? "_blank" : undefined; return (
@@ -226,7 +229,7 @@ function NavItem({ : "hover:bg-white/40 dark:hover:bg-background/60 text-muted-foreground hover:text-foreground" )} > - + @@ -351,6 +354,7 @@ function NavSubItem({ return ( ({ name: navItem.displayName, href: getItemPath(projectId, navigableFrontend, navItem), + external: navItem.external, match: (fullUrl: URL) => testItemPath(projectId, navigableFrontend, navItem, fullUrl), })); return { @@ -413,6 +418,7 @@ function AppNavItem({ href: getAppPath(projectId, appFrontend), icon: appFrontend.icon, firstItemHref: items[0]?.href, + firstItemExternal: items[0]?.external, }; }, [app.displayName, appId, appFrontend, projectId]); diff --git a/apps/dashboard/src/components/app-square.tsx b/apps/dashboard/src/components/app-square.tsx index 09537c2b72..5758d1ef0a 100644 --- a/apps/dashboard/src/components/app-square.tsx +++ b/apps/dashboard/src/components/app-square.tsx @@ -1,7 +1,7 @@ import { useAdminApp, useProjectId } from "@/app/(main)/(protected)/projects/[projectId]/use-admin-app"; import { useRouter } from "@/components/router"; import { Button, cn, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui"; -import { ALL_APPS_FRONTEND, AppFrontend, getAppPath, isSubApp } from "@/lib/apps-frontend"; +import { ALL_APPS_FRONTEND, AppFrontend, getAppPath, getDocumentationHref, isSubApp } from "@/lib/apps-frontend"; import { isAppEnabled } from "@/lib/apps-utils"; import { useUpdateConfig } from "@/lib/config-update"; import { CheckIcon, DotsThreeVerticalIcon } from "@phosphor-icons/react"; @@ -220,6 +220,7 @@ export function AppListItem({ const isEnabled = isAppEnabled(config.apps.installed, appId); const appPath = getAppPath(project.id, appFrontend); + const appDestinationPath = getDocumentationHref(appFrontend) ?? appPath; const appDetailsPath = `/projects/${project.id}/apps/${appId}`; const router = useRouter(); const parentAppId = isSubApp(appFrontend) ? appFrontend.parentAppId : null; @@ -249,7 +250,7 @@ export function AppListItem({ return ( (null); @@ -154,7 +155,7 @@ export function AppStoreEntry({ className="px-8 bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white font-medium shadow-lg shadow-blue-500/20" > - Open App + {isDocumentationBackedApp ? "Open Docs" : "Open App"} {onDisable && (
); } - diff --git a/examples/tanstack-start-demo/.env.development b/examples/tanstack-start-demo/.env.development new file mode 100644 index 0000000000..881f07c4b1 --- /dev/null +++ b/examples/tanstack-start-demo/.env.development @@ -0,0 +1,3 @@ +VITE_STACK_API_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}02 +VITE_STACK_PROJECT_ID=internal +VITE_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only diff --git a/examples/tanstack-start-demo/.eslintrc.cjs b/examples/tanstack-start-demo/.eslintrc.cjs new file mode 100644 index 0000000000..1a4ae3fdbe --- /dev/null +++ b/examples/tanstack-start-demo/.eslintrc.cjs @@ -0,0 +1,4 @@ +module.exports = { + extends: ["../../configs/eslint/defaults.js"], + ignorePatterns: ["/*", "!/src"], +}; diff --git a/examples/tanstack-start-demo/.gitignore b/examples/tanstack-start-demo/.gitignore new file mode 100644 index 0000000000..d121322a72 --- /dev/null +++ b/examples/tanstack-start-demo/.gitignore @@ -0,0 +1,4 @@ +.output +.tanstack +dist +node_modules diff --git a/examples/tanstack-start-demo/package.json b/examples/tanstack-start-demo/package.json new file mode 100644 index 0000000000..3f735963db --- /dev/null +++ b/examples/tanstack-start-demo/package.json @@ -0,0 +1,40 @@ +{ + "name": "@stackframe/example-tanstack-start-demo", + "version": "2.8.86", + "repository": "https://github.com/stack-auth/stack-auth", + "description": "TanStack Start demo app for Stack Auth", + "private": true, + "type": "module", + "scripts": { + "typecheck": "tsc --noEmit", + "clean": "rimraf .output && rimraf node_modules", + "dev": "vite dev --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}43", + "build": "vite build", + "start": "node .output/server/index.mjs", + "lint": "eslint --ext .ts,.tsx ." + }, + "dependencies": { + "@stackframe/stack-shared": "workspace:*", + "@stackframe/stack-ui": "workspace:*", + "@stackframe/tanstack-start": "workspace:*", + "@tanstack/react-router": "^1.168.23", + "@tanstack/react-start": "^1.167.42", + "nitro": "^3.0.0", + "react": "19.2.1", + "react-dom": "19.2.1" + }, + "devDependencies": { + "@types/node": "^22.13.0", + "@types/react": "19.2.1", + "@types/react-dom": "19.2.1", + "@vitejs/plugin-react": "^5.0.0", + "autoprefixer": "^10.4.20", + "postcss": "^8.4.47", + "rimraf": "^5.0.10", + "tailwindcss": "^3.4.14", + "typescript": "5.9.3", + "vite": "^7.0.0", + "vite-tsconfig-paths": "^4.3.2" + }, + "packageManager": "pnpm@10.23.0" +} diff --git a/examples/tanstack-start-demo/postcss.config.js b/examples/tanstack-start-demo/postcss.config.js new file mode 100644 index 0000000000..2aa7205d4b --- /dev/null +++ b/examples/tanstack-start-demo/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/examples/tanstack-start-demo/src/client.tsx b/examples/tanstack-start-demo/src/client.tsx new file mode 100644 index 0000000000..51b520a484 --- /dev/null +++ b/examples/tanstack-start-demo/src/client.tsx @@ -0,0 +1,12 @@ +import { StartClient } from "@tanstack/react-start/client"; +import { StrictMode, startTransition } from "react"; +import { hydrateRoot } from "react-dom/client"; + +startTransition(() => { + hydrateRoot( + document, + + + , + ); +}); diff --git a/examples/tanstack-start-demo/src/components/header.tsx b/examples/tanstack-start-demo/src/components/header.tsx new file mode 100644 index 0000000000..b8e292cba4 --- /dev/null +++ b/examples/tanstack-start-demo/src/components/header.tsx @@ -0,0 +1,33 @@ +import { Link } from "@tanstack/react-router"; +import { UserButton } from "@stackframe/tanstack-start"; +import { useEffect, useState } from "react"; + +export function Header() { + return ( + <> +
+
+ + +
+
+
+ + ); +} + +function ClientMountedUserButton() { + const [isMounted, setIsMounted] = useState(false); + useEffect(() => { + setIsMounted(true); + }, []); + + return isMounted ? :
; +} diff --git a/examples/tanstack-start-demo/src/routeTree.gen.ts b/examples/tanstack-start-demo/src/routeTree.gen.ts new file mode 100644 index 0000000000..7a987f7e3d --- /dev/null +++ b/examples/tanstack-start-demo/src/routeTree.gen.ts @@ -0,0 +1,104 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as ProtectedRouteImport } from './routes/protected' +import { Route as IndexRouteImport } from './routes/index' +import { Route as HandlerSplatRouteImport } from './routes/handler/$' + +const ProtectedRoute = ProtectedRouteImport.update({ + id: '/protected', + path: '/protected', + getParentRoute: () => rootRouteImport, +} as any) +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) +const HandlerSplatRoute = HandlerSplatRouteImport.update({ + id: '/handler/$', + path: '/handler/$', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/protected': typeof ProtectedRoute + '/handler/$': typeof HandlerSplatRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/protected': typeof ProtectedRoute + '/handler/$': typeof HandlerSplatRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute + '/protected': typeof ProtectedRoute + '/handler/$': typeof HandlerSplatRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' | '/protected' | '/handler/$' + fileRoutesByTo: FileRoutesByTo + to: '/' | '/protected' | '/handler/$' + id: '__root__' | '/' | '/protected' | '/handler/$' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + ProtectedRoute: typeof ProtectedRoute + HandlerSplatRoute: typeof HandlerSplatRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/protected': { + id: '/protected' + path: '/protected' + fullPath: '/protected' + preLoaderRoute: typeof ProtectedRouteImport + parentRoute: typeof rootRouteImport + } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + '/handler/$': { + id: '/handler/$' + path: '/handler/$' + fullPath: '/handler/$' + preLoaderRoute: typeof HandlerSplatRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + ProtectedRoute: ProtectedRoute, + HandlerSplatRoute: HandlerSplatRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + } +} diff --git a/examples/tanstack-start-demo/src/router.tsx b/examples/tanstack-start-demo/src/router.tsx new file mode 100644 index 0000000000..9edcb7fb20 --- /dev/null +++ b/examples/tanstack-start-demo/src/router.tsx @@ -0,0 +1,18 @@ +import { createRouter } from "@tanstack/react-router"; +import { routeTree } from "./routeTree.gen"; + +export function getRouter() { + return createRouter({ + routeTree, + scrollRestoration: true, + defaultNotFoundComponent: () => ( +
+
+

404

+

Page not found

+

This route is not part of the TanStack Start demo.

+
+
+ ), + }); +} diff --git a/examples/tanstack-start-demo/src/routes/__root.tsx b/examples/tanstack-start-demo/src/routes/__root.tsx new file mode 100644 index 0000000000..25adb8163c --- /dev/null +++ b/examples/tanstack-start-demo/src/routes/__root.tsx @@ -0,0 +1,58 @@ +/// +import "../styles.css"; + +import { StackProvider, StackTheme } from "@stackframe/tanstack-start"; +import { createRootRoute, HeadContent, Outlet, Scripts } from "@tanstack/react-router"; +import type { ReactNode } from "react"; +import { Suspense, useMemo } from "react"; +import { Header } from "~/components/header"; +import { createStackApp } from "~/stack"; + +export const Route = createRootRoute({ + head: () => ({ + meta: [ + { charSet: "utf-8" }, + { name: "viewport", content: "width=device-width, initial-scale=1" }, + { title: "Stack Auth TanStack Start Demo" }, + { + name: "description", + content: "TanStack Start demo application using Stack Auth.", + }, + ], + }), + shellComponent: RootDocument, + component: RootComponent, +}); + +function RootDocument({ children }: { children: ReactNode }) { + return ( + + + + + + {children} + + + + ); +} + +function RootComponent() { + const stackApp = useMemo(() => createStackApp(), []); + + return ( + + +
+
+
+ + + +
+
+
+
+ ); +} diff --git a/examples/tanstack-start-demo/src/routes/handler/$.tsx b/examples/tanstack-start-demo/src/routes/handler/$.tsx new file mode 100644 index 0000000000..e3b97ca859 --- /dev/null +++ b/examples/tanstack-start-demo/src/routes/handler/$.tsx @@ -0,0 +1,12 @@ +import { StackHandler } from "@stackframe/tanstack-start"; +import { createFileRoute, useLocation } from "@tanstack/react-router"; + +export const Route = createFileRoute("/handler/$")({ + ssr: false, + component: HandlerPage, +}); + +function HandlerPage() { + const { pathname } = useLocation(); + return ; +} diff --git a/examples/tanstack-start-demo/src/routes/index.tsx b/examples/tanstack-start-demo/src/routes/index.tsx new file mode 100644 index 0000000000..a434dfb08a --- /dev/null +++ b/examples/tanstack-start-demo/src/routes/index.tsx @@ -0,0 +1,76 @@ +import { runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises"; +import { UserAvatar, useStackApp, useUser } from "@stackframe/tanstack-start"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/")({ + component: HomePage, +}); + +function HomePage() { + const user = useUser({ includeRestricted: true }); + const app = useStackApp(); + + if (!user) { + return ( +
+
+

TanStack Start alpha

+

Welcome to the Stack demo app.

+

+ This example uses @stackframe/tanstack-start with file-based routes and Stack Auth handler pages. +

+
+ + +
+
+
+ ); + } + + return ( +
+
+
+ +
+

Signed in as

+

{user.displayName ?? user.primaryEmail ?? user.id}

+ {user.isRestricted && ( + + Restricted + + )} +
+
+ +
+
+
User ID
+
{user.id}
+
+ {user.primaryEmail && ( +
+
Email
+
{user.primaryEmail}
+
+ )} +
+
Restricted
+
{user.isRestricted ? `Yes${user.restrictedReason ? ` (${user.restrictedReason.type})` : ""}` : "No"}
+
+
+ +
+ +
+
+
+ ); +} diff --git a/examples/tanstack-start-demo/src/routes/protected.tsx b/examples/tanstack-start-demo/src/routes/protected.tsx new file mode 100644 index 0000000000..9cceb955eb --- /dev/null +++ b/examples/tanstack-start-demo/src/routes/protected.tsx @@ -0,0 +1,23 @@ +import { useUser } from "@stackframe/tanstack-start"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/protected")({ + ssr: false, + component: ProtectedPage, +}); + +function ProtectedPage() { + const user = useUser({ or: "redirect" }); + + return ( +
+
+

Protected route

+

You can see this because you are signed in.

+

+ TanStack Start rendered this route with Stack Auth session state for {user.displayName ?? user.primaryEmail ?? user.id}. +

+
+
+ ); +} diff --git a/examples/tanstack-start-demo/src/stack.ts b/examples/tanstack-start-demo/src/stack.ts new file mode 100644 index 0000000000..a6b315a362 --- /dev/null +++ b/examples/tanstack-start-demo/src/stack.ts @@ -0,0 +1,29 @@ +import { StackClientApp } from "@stackframe/tanstack-start"; + +function getPortPrefix(): string { + return import.meta.env.NEXT_PUBLIC_STACK_PORT_PREFIX ?? "81"; +} + +function replaceStackPortPrefix(value: string): string { + return value.replace(/\$\{NEXT_PUBLIC_STACK_PORT_PREFIX:-81\}/g, getPortPrefix()); +} + +function getStackApiUrl(): string { + const configured = import.meta.env.VITE_STACK_API_URL as string | undefined; + return configured ? replaceStackPortPrefix(configured) : `http://localhost:${getPortPrefix()}02`; +} + +export function createStackApp() { + return new StackClientApp({ + projectId: import.meta.env.VITE_STACK_PROJECT_ID ?? "internal", + publishableClientKey: import.meta.env.VITE_STACK_PUBLISHABLE_CLIENT_KEY ?? "this-publishable-client-key-is-for-local-development-only", + baseUrl: getStackApiUrl(), + tokenStore: "cookie", + redirectMethod: "window", + urls: { + afterSignIn: "/protected", + afterSignUp: "/protected", + afterSignOut: "/", + }, + }); +} diff --git a/examples/tanstack-start-demo/src/styles.css b/examples/tanstack-start-demo/src/styles.css new file mode 100644 index 0000000000..06b4c37556 --- /dev/null +++ b/examples/tanstack-start-demo/src/styles.css @@ -0,0 +1,24 @@ +/* stylelint-disable scss/at-rule-no-unknown */ +@tailwind base; +@tailwind components; +@tailwind utilities; +/* stylelint-enable scss/at-rule-no-unknown */ + +:root { + color-scheme: light; + background: rgb(244 244 245); +} + +html:has(head > [data-stack-theme="dark"]) { + color-scheme: dark; + background: rgb(9 9 11); +} + +body { + margin: 0; +} + +button, +a { + -webkit-tap-highlight-color: transparent; +} diff --git a/examples/tanstack-start-demo/tailwind.config.js b/examples/tanstack-start-demo/tailwind.config.js new file mode 100644 index 0000000000..4c91f98879 --- /dev/null +++ b/examples/tanstack-start-demo/tailwind.config.js @@ -0,0 +1,12 @@ +/** @type {import('tailwindcss').Config} */ +export default { + darkMode: ["selector", 'html:has(head > [data-stack-theme="dark"])'], + content: [ + "./src/**/*.{js,ts,jsx,tsx}", + "../../packages/stack-ui/src/**/*.{ts,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/examples/tanstack-start-demo/tsconfig.json b/examples/tanstack-start-demo/tsconfig.json new file mode 100644 index 0000000000..8578865f20 --- /dev/null +++ b/examples/tanstack-start-demo/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "target": "ES2022", + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "skipLibCheck": true, + "isolatedModules": true, + "noEmit": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "baseUrl": ".", + "paths": { + "~/*": ["./src/*"] + } + }, + "include": ["src", "vite.config.ts"] +} diff --git a/examples/tanstack-start-demo/vite.config.ts b/examples/tanstack-start-demo/vite.config.ts new file mode 100644 index 0000000000..39c84c2450 --- /dev/null +++ b/examples/tanstack-start-demo/vite.config.ts @@ -0,0 +1,94 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; +import viteReact from "@vitejs/plugin-react"; +import { defineConfig, type Plugin } from "vite"; +import { nitro } from "nitro/vite"; +import tsConfigPaths from "vite-tsconfig-paths"; + +const stackAuthRootPath = fileURLToPath(new URL("../..", import.meta.url)); + +function watchNodeModules(modules: string[]): Plugin { + return { + name: "watch-node-modules", + config() { + return { + server: { + watch: { + ignored: modules.map((moduleName) => `!**/node_modules/${moduleName}/**`), + }, + }, + }; + }, + }; +} + +function waitForWorkspacePackages(packages: string[]): Plugin { + const packageDistEntries = packages.map((pkg) => ({ + name: pkg, + entry: path.resolve(__dirname, "node_modules", pkg, "dist", "esm", "index.js"), + })); + + async function waitForFile(filePath: string, timeoutMs = 60_000): Promise { + if (fs.existsSync(filePath)) return; + const start = performance.now(); + return await new Promise((resolve, reject) => { + const interval = setInterval(() => { + if (fs.existsSync(filePath)) { + clearInterval(interval); + resolve(); + } else if (performance.now() - start > timeoutMs) { + clearInterval(interval); + reject(new Error(`Timed out waiting for ${filePath} to exist`)); + } + }, 500); + }); + } + + return { + name: "wait-for-workspace-packages", + enforce: "pre", + async buildStart() { + const missing = packageDistEntries.filter((pkg) => !fs.existsSync(pkg.entry)); + if (missing.length === 0) return; + console.log(`Waiting for workspace packages to build: ${missing.map((pkg) => pkg.name).join(", ")}`); + await Promise.all(missing.map((pkg) => waitForFile(pkg.entry))); + console.log("All workspace packages are ready."); + }, + }; +} + +export default defineConfig(({ mode }) => { + const isVitest = mode === "test" || process.env.VITEST === "true"; + + return { + server: { + port: Number(`${process.env.NEXT_PUBLIC_STACK_PORT_PREFIX || "81"}43`), + fs: { + allow: [stackAuthRootPath], + }, + }, + resolve: { + dedupe: ["react", "react-dom"], + }, + ssr: { + noExternal: [/^@stackframe\//, /^@radix-ui\//], + }, + optimizeDeps: { + include: ["@stackframe/stack-shared", "@stackframe/stack-shared/config"], + }, + plugins: [ + ...(isVitest ? [] : [ + waitForWorkspacePackages(["@stackframe/tanstack-start", "@stackframe/stack-shared", "@stackframe/stack-ui"]), + watchNodeModules(["@stackframe/tanstack-start", "@stackframe/stack-shared", "@stackframe/stack-ui"]), + ]), + tsConfigPaths(), + ...(isVitest ? [] : [ + tanstackStart(), + nitro(), + ]), + viteReact(), + ], + }; +}); diff --git a/package.json b/package.json index b1557a6104..6b74316c6c 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,8 @@ "db:migrate": "pnpm pre && pnpm run --filter=@stackframe/backend db:migrate", "fern": "pnpm pre && pnpm run --filter=@stackframe/docs fern", "dev:full": "pnpm pre && concurrently -k \"pnpm run generate-sdks:watch\" \"pnpm run generate-setup-prompt-docs:watch\" \"turbo run dev --concurrency 99999\"", - "dev": "pnpm pre && concurrently -k \"pnpm run generate-sdks:watch\" \"pnpm run generate-openapi-docs:watch\" \"pnpm run generate-setup-prompt-docs:watch\" \"turbo run dev --concurrency 99999 --filter=./apps/* --filter=@stackframe/docs-mintlify --filter=@stackframe/stack-docs --filter=./packages/* --filter=./examples/demo \"", - "dev:tui": "pnpm pre && (trap 'kill 0' EXIT; pnpm run generate-sdks:watch & pnpm run generate-openapi-docs:watch & pnpm run generate-setup-prompt-docs:watch & turbo run dev --ui tui --concurrency 99999 --filter=./apps/* --filter=@stackframe/stack-docs --filter=./packages/* --filter=./examples/demo)", + "dev": "pnpm pre && concurrently -k \"pnpm run generate-sdks:watch\" \"pnpm run generate-openapi-docs:watch\" \"pnpm run generate-setup-prompt-docs:watch\" \"turbo run dev --concurrency 99999 --filter=./apps/* --filter=@stackframe/docs-mintlify --filter=@stackframe/stack-docs --filter=./packages/* --filter=./examples/demo --filter=./examples/tanstack-start-demo \"", + "dev:tui": "pnpm pre && (trap 'kill 0' EXIT; pnpm run generate-sdks:watch & pnpm run generate-openapi-docs:watch & pnpm run generate-setup-prompt-docs:watch & turbo run dev --ui tui --concurrency 99999 --filter=./apps/* --filter=@stackframe/stack-docs --filter=./packages/* --filter=./examples/demo --filter=./examples/tanstack-start-demo)", "dev:inspect": "pnpm pre && STACK_BACKEND_DEV_EXTRA_ARGS=\"--inspect\" pnpm run dev", "dev:profile": "pnpm pre && STACK_BACKEND_DEV_EXTRA_ARGS=\"--experimental-cpu-prof\" pnpm run dev", "dev:basic": "pnpm pre && concurrently -k \"pnpm run generate-sdks:watch\" \"turbo run dev --concurrency 99999 --filter=@stackframe/backend --filter=@stackframe/dashboard --filter=@stackframe/mock-oauth-server\"", diff --git a/packages/js/package.json b/packages/js/package.json index cbc838838d..c93f0da227 100644 --- a/packages/js/package.json +++ b/packages/js/package.json @@ -85,4 +85,4 @@ "tsdown": "^0.20.3", "convex": "^1.27.0" } -} \ No newline at end of file +} diff --git a/packages/react/package.json b/packages/react/package.json index bc702a61af..c7004adbfa 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -114,4 +114,4 @@ "tsdown": "^0.20.3", "convex": "^1.27.0" } -} \ No newline at end of file +} diff --git a/packages/stack-shared/src/apps/apps-config.ts b/packages/stack-shared/src/apps/apps-config.ts index 92a5cb9726..63db82190e 100644 --- a/packages/stack-shared/src/apps/apps-config.ts +++ b/packages/stack-shared/src/apps/apps-config.ts @@ -150,6 +150,12 @@ export const ALL_APPS = { tags: ["integration", "developers"], stage: "stable", }, + "tanstack-start": { + displayName: "TanStack Start", + subtitle: "Use Stack Auth in TanStack Start apps", + tags: ["integration", "developers"], + stage: "alpha", + }, "analytics": { displayName: "Analytics", subtitle: "View and explore analytics data", diff --git a/packages/stack/package.json b/packages/stack/package.json index 4766147f96..b3ebc1e49b 100644 --- a/packages/stack/package.json +++ b/packages/stack/package.json @@ -122,4 +122,4 @@ "tsdown": "^0.20.3", "convex": "^1.27.0" } -} \ No newline at end of file +} diff --git a/packages/tanstack-start/package.json b/packages/tanstack-start/package.json new file mode 100644 index 0000000000..a757e33ae3 --- /dev/null +++ b/packages/tanstack-start/package.json @@ -0,0 +1,132 @@ +{ + "//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)", + "name": "@stackframe/tanstack-start", + "version": "2.8.88", + "repository": "https://github.com/stack-auth/stack-auth", + "sideEffects": false, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": { + "default": "./dist/esm/index.js" + }, + "require": { + "default": "./dist/index.js" + } + }, + "./tanstack-start-server-context": { + "types": "./dist/tanstack-start-server-context.combined.d.ts", + "import": { + "browser": "./dist/esm/tanstack-start-server-context.default.js", + "default": "./dist/esm/tanstack-start-server-context.server.js" + }, + "require": { + "browser": "./dist/tanstack-start-server-context.default.js", + "default": "./dist/tanstack-start-server-context.server.js" + } + }, + "./convex.config": { + "types": "./dist/integrations/convex/component/convex.config.d.ts", + "import": { + "default": "./dist/esm/integrations/convex/component/convex.config.js" + }, + "require": { + "default": "./dist/integrations/convex/component/convex.config.js" + } + }, + "./convex-auth.config": { + "types": "./dist/integrations/convex.d.ts", + "import": { + "default": "./dist/esm/integrations/convex.js" + }, + "require": { + "default": "./dist/integrations/convex.js" + } + } + }, + "homepage": "https://stack-auth.com", + "scripts": { + "typecheck": "tsc --noEmit", + "clean": "rimraf dist && rimraf node_modules", + "lint": "eslint --ext .tsx,.ts .", + "build": "rimraf dist && pnpm run css && tsdown", + "dev": "concurrently -n \"build,codegen\" -k \"tsdown --watch\" \"pnpm run codegen:watch\"", + "codegen": "pnpm run css", + "codegen:watch": "pnpm run css:watch", + "css": "pnpm run css-tw && pnpm run css-sc", + "css:watch": "concurrently -n \"tw,sc\" -k \"pnpm run css-tw:watch\" \"pnpm run css-sc:watch\"", + "css-tw:watch": "tailwindcss -i ./src/global.css -o ./src/generated/tailwind.css --watch", + "css-tw": "tailwindcss -i ./src/global.css -o ./src/generated/tailwind.css", + "css-sc": "tsx ./scripts/process-css.ts ./src/generated/tailwind.css ./src/generated/global-css.ts", + "css-sc:watch": "chokidar --silent './src/generated/tailwind.css' -c 'pnpm run css-sc' --throttle 2000" + }, + "files": [ + "README.md", + "dist", + "CHANGELOG.md", + "LICENSE" + ], + "dependencies": { + "@ai-sdk/react": "^3.0.72", + "ai": "^6.0.0", + "@hookform/resolvers": "^5.2.2", + "@stripe/react-stripe-js": "^3.8.1", + "@stripe/stripe-js": "^7.7.0", + "@simplewebauthn/browser": "^13.2.2", + "@stackframe/stack-shared": "workspace:*", + "@stackframe/stack-ui": "workspace:*", + "@tanstack/react-table": "^8.21.3", + "browser-image-compression": "^2.0.2", + "color": "^5.0.3", + "cookie": "^1.1.1", + "jose": "^6.1.3", + "js-cookie": "^3.0.5", + "lucide-react": "^0.378.0", + "oauth4webapi": "^3.8.3", + "@oslojs/otp": "^1.1.0", + "qrcode": "^1.5.4", + "react-easy-crop": "^5.5.6", + "react-hook-form": "^7.70.0", + "tailwindcss-animate": "^1.0.7", + "rrweb": "^1.1.3", + "tsx": "^4.21.0", + "yup": "^1.7.1" + }, + "peerDependencies": { + "@types/react": ">=18.3.0", + "@tanstack/react-router": ">=1.100.0", + "@tanstack/react-start": ">=1.100.0", + "react": ">=18.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, + "devDependencies": { + "@quetzallabs/i18n": "^0.1.19", + "@types/color": "^3.0.6", + "@types/cookie": "^0.6.0", + "@types/js-cookie": "^3.0.6", + "@types/qrcode": "^1.5.5", + "@types/react-avatar-editor": "^13.0.3", + "autoprefixer": "^10.4.17", + "chokidar-cli": "^3.0.0", + "esbuild": "^0.20.2", + "i18next": "^23.14.0", + "i18next-parser": "^9.0.2", + "@tanstack/react-router": "^1.167.4", + "@tanstack/react-start": "^1.166.15", + "postcss": "^8.4.38", + "postcss-nested": "^6.0.1", + "react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "react-dom": "^19.0.0", + "rimraf": "^6.1.2", + "tailwindcss": "^3.4.4", + "tsdown": "^0.20.3", + "convex": "^1.27.0" + } +} diff --git a/packages/template/package-template.json b/packages/template/package-template.json index daed224f6a..bd240c345a 100644 --- a/packages/template/package-template.json +++ b/packages/template/package-template.json @@ -5,6 +5,8 @@ "name": "@stackframe/js", "//": "ELSE_IF_PLATFORM next", "name": "@stackframe/stack", + "//": "ELSE_IF_PLATFORM tanstack-start", + "name": "@stackframe/tanstack-start", "//": "ELSE_IF_PLATFORM react", "name": "@stackframe/react", "//": "END_PLATFORM", @@ -26,6 +28,19 @@ "default": "./dist/index.js" } }, + "//": "IF_PLATFORM tanstack-start", + "./tanstack-start-server-context": { + "types": "./dist/tanstack-start-server-context.combined.d.ts", + "import": { + "browser": "./dist/esm/tanstack-start-server-context.default.js", + "default": "./dist/esm/tanstack-start-server-context.server.js" + }, + "require": { + "browser": "./dist/tanstack-start-server-context.default.js", + "default": "./dist/tanstack-start-server-context.server.js" + } + }, + "//": "END_PLATFORM", "./convex.config": { "types": "./dist/integrations/convex/component/convex.config.d.ts", "import": { @@ -131,6 +146,10 @@ "react-dom": ">=18.3.0", "next": ">=14.1 || >=15.0.0-canary.0 || >=15.0.0-rc.0", "//": "END_PLATFORM", + "//": "IF_PLATFORM tanstack-start", + "@tanstack/react-router": ">=1.100.0", + "@tanstack/react-start": ">=1.100.0", + "//": "END_PLATFORM", "react": ">=18.3.0" }, "//": "END_PLATFORM", @@ -160,6 +179,10 @@ "i18next-parser": "^9.0.2", "//": "NEXT_LINE_PLATFORM next", "next": "^14.2.35", + "//": "NEXT_LINE_PLATFORM template tanstack-start", + "@tanstack/react-router": "^1.167.4", + "//": "NEXT_LINE_PLATFORM template tanstack-start", + "@tanstack/react-start": "^1.166.15", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "react": "^19.0.0", diff --git a/packages/template/package.json b/packages/template/package.json index f065f28341..59f1868cba 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -17,6 +17,17 @@ "default": "./dist/index.js" } }, + "./tanstack-start-server-context": { + "types": "./dist/tanstack-start-server-context.combined.d.ts", + "import": { + "browser": "./dist/esm/tanstack-start-server-context.default.js", + "default": "./dist/esm/tanstack-start-server-context.server.js" + }, + "require": { + "browser": "./dist/tanstack-start-server-context.default.js", + "default": "./dist/tanstack-start-server-context.server.js" + } + }, "./convex.config": { "types": "./dist/integrations/convex/component/convex.config.d.ts", "import": { @@ -94,6 +105,8 @@ "@types/react-dom": ">=18.3.0", "react-dom": ">=18.3.0", "next": ">=14.1 || >=15.0.0-canary.0 || >=15.0.0-rc.0", + "@tanstack/react-router": ">=1.100.0", + "@tanstack/react-start": ">=1.100.0", "react": ">=18.3.0" }, "peerDependenciesMeta": { @@ -117,6 +130,8 @@ "i18next": "^23.14.0", "i18next-parser": "^9.0.2", "next": "^14.2.35", + "@tanstack/react-router": "^1.167.4", + "@tanstack/react-start": "^1.166.15", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "react": "^19.0.0", @@ -127,4 +142,4 @@ "tsdown": "^0.20.3", "convex": "^1.27.0" } -} \ No newline at end of file +} diff --git a/packages/template/src/components-page/stack-handler-client.tsx b/packages/template/src/components-page/stack-handler-client.tsx index 55cfe9fe06..dcb929f96a 100644 --- a/packages/template/src/components-page/stack-handler-client.tsx +++ b/packages/template/src/components-page/stack-handler-client.tsx @@ -236,8 +236,8 @@ export function StackHandlerClient(props: BaseHandlerProps & Partial const navigate = stackApp.useNavigate(); const navigateRef = useRef(navigate); navigateRef.current = navigate; - const currentLocation = props.location ?? window.location.pathname; - const searchParamsSource = new URLSearchParams(window.location.search); + const currentLocation = props.location ?? (typeof window === "undefined" ? new URL(stackApp.urls.handler, placeholderOrigin).pathname : window.location.pathname); + const searchParamsSource = new URLSearchParams(typeof window === "undefined" ? "" : window.location.search); const redirectTargets: (string | undefined)[] = []; END_PLATFORM */ diff --git a/packages/template/src/lib/cookie.ts b/packages/template/src/lib/cookie.ts index 5d7b7a779c..7171731de3 100644 --- a/packages/template/src/lib/cookie.ts +++ b/packages/template/src/lib/cookie.ts @@ -1,6 +1,7 @@ import { cookies as rscCookies, headers as rscHeaders } from '@stackframe/stack-sc/force-react-server'; // THIS_LINE_PLATFORM next import { isBrowserLike } from '@stackframe/stack-shared/dist/utils/env'; import { StackAssertionError } from '@stackframe/stack-shared/dist/utils/errors'; +import * as tanstackStartServerContext from "@stackframe/tanstack-start/tanstack-start-server-context"; // THIS_LINE_PLATFORM tanstack-start import Cookies from "js-cookie"; import { calculatePKCECodeChallenge, generateRandomCodeVerifier, generateRandomState } from "oauth4webapi"; @@ -67,6 +68,49 @@ import { calculatePKCECodeChallenge, generateRandomCodeVerifier, generateRandomS type SetCookieOptions = { maxAge: number | "session", noOpIfServerComponent?: boolean, domain?: string, secure?: boolean }; type DeleteCookieOptions = { noOpIfServerComponent?: boolean, domain?: string }; +// IF_PLATFORM tanstack-start +let tanStackStartCookieHelperPromise: Promise | null = null; + +function getTanStackStartServerContext() { + const { + deleteCookie, + getCookie, + getCookies, + getRequestHeader, + setCookie, + } = tanstackStartServerContext; + if ( + deleteCookie == null + || getCookie == null + || getCookies == null + || getRequestHeader == null + || setCookie == null + ) { + throw new StackAssertionError("TanStack Start server context is only available during server rendering"); + } + return { + deleteCookie, + getCookie, + getCookies, + getRequestHeader, + setCookie, + }; +} + +declare global { + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + interface ImportMetaEnv { + SSR: boolean, + } + + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + interface ImportMeta { + readonly env: ImportMetaEnv, + } +} + +// END_PLATFORM + function ensureClient() { if (!isBrowserLike()) { throw new Error("cookieClient functions can only be called in a browser environment, yet window is undefined"); @@ -95,6 +139,16 @@ export async function createPlaceholderCookieHelper(): Promise { }; } +function requiresSecureAttribute(name: string): boolean { + return name.startsWith("__Host-"); +} + +function validateCookieOptions(name: string, options: DeleteCookieOptions | SetCookieOptions) { + if (requiresSecureAttribute(name) && options.domain !== undefined) { + throw new StackAssertionError("__Host- cookies must not specify a Domain attribute"); + } +} + export async function createCookieHelper(): Promise { if (isBrowserLike()) { return createBrowserCookieHelper(); @@ -104,12 +158,90 @@ export async function createCookieHelper(): Promise { await rscCookies(), await rscHeaders(), ); + // ELSE_IF_PLATFORM tanstack-start + if (import.meta.env.SSR) { + const cookieHelperPromise = tanStackStartCookieHelperPromise + ?? Promise.resolve(createTanStackStartCookieHelper(getTanStackStartServerContext())); + tanStackStartCookieHelperPromise = cookieHelperPromise; + return await cookieHelperPromise; + } + return await createPlaceholderCookieHelper(); // ELSE_PLATFORM return await createPlaceholderCookieHelper(); // END_PLATFORM } } +export function createCookieHelperSync(): CookieHelper { + if (isBrowserLike()) { + return createBrowserCookieHelper(); + } + function throwError(): never { + throw new StackAssertionError("Synchronous server cookie helpers are not available on this platform"); + } + return { + get: throwError, + getAll: throwError, + set: throwError, + setOrDelete: throwError, + delete: throwError, + }; +} + +// IF_PLATFORM tanstack-start +function determineSecureFromTanStackStartContext(api: ReturnType): boolean { + return api.getRequestHeader("x-forwarded-proto") === "https" + || (api.getCookie("stack-is-https") !== undefined); +} + +function refreshTanStackStartIsHttpsCookie(api: ReturnType) { + api.setCookie("stack-is-https", "true", { + secure: true, + maxAge: 60 * 60 * 24 * 365, + sameSite: "lax", + path: "/", + }); +} + +function createTanStackStartCookieHelper(api: ReturnType): CookieHelper { + const helper: CookieHelper = { + get: (name: string) => { + const all = helper.getAll(); + return all[name] ?? null; + }, + getAll: () => { + // set a helper cookie, see comment in `NextCookieHelper.set` below + refreshTanStackStartIsHttpsCookie(api); + return api.getCookies(); + }, + set: (name: string, value: string, options: SetCookieOptions) => { + validateCookieOptions(name, options); + api.setCookie(name, value, { + secure: requiresSecureAttribute(name) || (options.secure ?? determineSecureFromTanStackStartContext(api)), + maxAge: options.maxAge === "session" ? undefined : options.maxAge, + domain: options.domain, + sameSite: "lax", + path: "/", + }); + }, + setOrDelete: (name, value, options) => { + if (value === null) helper.delete(name, options); + else helper.set(name, value, options); + }, + delete: (name: string, options: DeleteCookieOptions) => { + validateCookieOptions(name, options); + const secure = requiresSecureAttribute(name) || determineSecureFromTanStackStartContext(api); + api.deleteCookie(name, { + secure, + domain: options.domain, + path: "/", + }); + }, + }; + return helper; +} +// END_PLATFORM + export function createBrowserCookieHelper(): CookieHelper { return { get: getCookieClient, @@ -166,6 +298,7 @@ function createNextCookieHelper( }, {} as Record); }, set: (name: string, value: string, options: SetCookieOptions) => { + validateCookieOptions(name, options); // Whenever the client is on HTTPS, we want to set the Secure flag on the cookie. // // This is not easy to find out on a Next.js server, so see the algorithm at the top of this file. @@ -177,10 +310,11 @@ function createNextCookieHelper( try { rscCookiesAwaited.set(name, value, { - secure: isSecureCookie, + secure: requiresSecureAttribute(name) || isSecureCookie, maxAge: options.maxAge === "session" ? undefined : options.maxAge, domain: options.domain, sameSite: "lax", + path: "/", }); } catch (e) { handleCookieError(e, options); @@ -195,10 +329,11 @@ function createNextCookieHelper( }, delete(name: string, options: DeleteCookieOptions) { try { + validateCookieOptions(name, options); if (options.domain !== undefined) { - rscCookiesAwaited.delete({ name, domain: options.domain }); + rscCookiesAwaited.delete({ name, domain: options.domain, path: "/" }); } else { - rscCookiesAwaited.delete(name); + rscCookiesAwaited.delete({ name, path: "/" }); } } catch (e) { handleCookieError(e, options); @@ -232,6 +367,10 @@ export async function isSecure(): Promise { } // IF_PLATFORM next return determineSecureFromServerContext(await rscCookies(), await rscHeaders()); + // ELSE_IF_PLATFORM tanstack-start + if (import.meta.env.SSR) { + return determineSecureFromTanStackStartContext(getTanStackStartServerContext()); + } // END_PLATFORM return false; } @@ -299,12 +438,14 @@ function _internalShouldSetPartitionedClient() { } function setCookieClientInternal(name: string, value: string, options: SetCookieOptions) { - const secure = options.secure ?? determineSecureFromClientContext(); + validateCookieOptions(name, options); + const secure = requiresSecureAttribute(name) || (options.secure ?? determineSecureFromClientContext()); const partitioned = shouldSetPartitionedClient(); Cookies.set(name, value, { expires: options.maxAge === "session" ? undefined : new Date(Date.now() + (options.maxAge) * 1000), domain: options.domain, secure, + path: "/", sameSite: "Lax", ...(partitioned ? { partitioned, @@ -314,11 +455,12 @@ function setCookieClientInternal(name: string, value: string, options: SetCookie } function deleteCookieClientInternal(name: string, options: DeleteCookieOptions) { + validateCookieOptions(name, options); for (const partitioned of [true, false]) { if (options.domain !== undefined) { - Cookies.remove(name, { domain: options.domain, secure: determineSecureFromClientContext(), partitioned }); + Cookies.remove(name, { domain: options.domain, secure: determineSecureFromClientContext(), partitioned, path: "/" }); } - Cookies.remove(name, { secure: determineSecureFromClientContext(), partitioned }); + Cookies.remove(name, { secure: requiresSecureAttribute(name) || determineSecureFromClientContext(), partitioned, path: "/" }); } } diff --git a/packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts b/packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts index 8eccf1644f..1f2133b5ea 100644 --- a/packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts +++ b/packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts @@ -36,6 +36,8 @@ import { BotChallengeExecutionFailedError, BotChallengeUserCancelledError, withB import type { TurnstileAction } from "@stackframe/stack-shared/dist/utils/turnstile"; import { isRelative } from "@stackframe/stack-shared/dist/utils/urls"; import { generateUuid } from "@stackframe/stack-shared/dist/utils/uuids"; +import * as tanstackStartServerContext from "@stackframe/tanstack-start/tanstack-start-server-context"; // THIS_LINE_PLATFORM tanstack-start +import * as TanStackRouter from "@tanstack/react-router"; // THIS_LINE_PLATFORM tanstack-start import * as cookie from "cookie"; import * as NextNavigationUnscrambled from "next/navigation"; // import the entire module to get around some static compiler warnings emitted by Next.js in some cases | THIS_LINE_PLATFORM next import React, { useCallback, useMemo } from "react"; // THIS_LINE_PLATFORM react-like @@ -152,6 +154,26 @@ function getHeaderValueFromRequestLikeHeaders(headers: RequestLike["headers"], n return null; } +// IF_PLATFORM tanstack-start +function getTanStackStartRequestHeader(name: string): string | null { + const { getRequestHeader } = tanstackStartServerContext; + if (getRequestHeader == null) { + throw new StackAssertionError("TanStack Start request headers are only available during server rendering"); + } + return getRequestHeader(name) ?? null; +} +// END_PLATFORM + +async function getServerRequestHost(): Promise { + // IF_PLATFORM next + return (await sc.headers?.())?.get("host") ?? null; + // ELSE_IF_PLATFORM tanstack-start + return getTanStackStartRequestHeader("host"); + // ELSE_PLATFORM + return null; + // END_PLATFORM +} + type StackClientAppImplConstructorOptionsResolved = StackClientAppConstructorOptions & { inheritsFrom?: undefined }; export class _StackClientAppImplIncomplete implements StackClientApp { @@ -608,6 +630,7 @@ export class _StackClientAppImplIncomplete { + // IF_PLATFORM tanstack-start + if (!isBrowserLike()) { + return this._getOrCreateTokenStore(use(createCookieHelper()), overrideTokenStoreInit); + } + // END_PLATFORM suspendIfSsr(); const cookieHelper = createBrowserCookieHelper(); const tokenStore = this._getOrCreateTokenStore(cookieHelper, overrideTokenStoreInit); @@ -2520,6 +2550,10 @@ export class _StackClientAppImplIncomplete router.push(to); // END_PLATFORM + // IF_PLATFORM tanstack-start + } else if (this._redirectMethod === "tanstack-start") { + return (to: string) => window.location.assign(to); + // END_PLATFORM } else { return (to: string) => { }; } @@ -2589,6 +2627,20 @@ export class _StackClientAppImplIncomplete>>(); export function useAsyncCache(cache: AsyncCache>, dependencies: D, caller: string): T { // we explicitly don't want to run this hook in SSR + // IF_PLATFORM tanstack-start + if (!isBrowserLike()) { + const result = use(cache.getOrWait(dependencies, "read-write")); + if (result.status === "error") { + throw result.error; + } + return result.data; + } + // ELSE_PLATFORM suspendIfSsr(caller); + // END_PLATFORM // on the dashboard, we do some perf monitoring for pre-fetching which should hook right in here const asyncCacheHooks: any[] = getGlobal("use-async-cache-execution-hooks") ?? []; @@ -220,7 +230,7 @@ export function useAsyncCache(cache: AsyncCache const promise = React.useSyncExternalStore( subscribe, getSnapshot, - () => throwErr(new Error("getServerSnapshot should never be called in useAsyncCache because we restrict to CSR earlier")) + getSnapshot, ); const result = use(promise); diff --git a/packages/template/src/lib/stack-app/common.ts b/packages/template/src/lib/stack-app/common.ts index 293f654ec3..a2f66cbe9d 100644 --- a/packages/template/src/lib/stack-app/common.ts +++ b/packages/template/src/lib/stack-app/common.ts @@ -30,6 +30,7 @@ export type EmailConfig = { export type RedirectMethod = "window" | "nextjs" // THIS_LINE_PLATFORM next + | "tanstack-start" // THIS_LINE_PLATFORM tanstack-start | "none" | { useNavigate: () => (to: string) => void, diff --git a/packages/template/src/providers/stack-provider.tsx b/packages/template/src/providers/stack-provider.tsx index cb985cd318..38f60c7699 100644 --- a/packages/template/src/providers/stack-provider.tsx +++ b/packages/template/src/providers/stack-provider.tsx @@ -31,6 +31,35 @@ function NextStackProvider({ ); } +// ELSE_IF_PLATFORM tanstack-start +function TanStackStartStackProvider({ + children, + app, + lang, + translationOverrides, +}: { + lang?: React.ComponentProps['lang'], + /** + * A mapping of English translations to translated equivalents. + * + * These will take priority over the translations from the language specified in the `lang` property. Note that the + * keys are case-sensitive. + */ + translationOverrides?: Record, + children: React.ReactNode, + // list all three types of apps even though server and admin are subclasses of client so it's clear that you can pass any + app: StackClientApp, +}) { + return ( + + + + {children} + + + + ); +} // ELSE_PLATFORM function ReactStackProvider({ children, @@ -63,6 +92,8 @@ function ReactStackProvider({ // IF_PLATFORM next export default NextStackProvider; -/* ELSE_PLATFORM +/* ELSE_IF_PLATFORM tanstack-start +export default TanStackStartStackProvider; +ELSE_PLATFORM export default ReactStackProvider; END_PLATFORM */ diff --git a/packages/template/src/tanstack-start-server-context.combined.ts b/packages/template/src/tanstack-start-server-context.combined.ts new file mode 100644 index 0000000000..1dfffe7aa3 --- /dev/null +++ b/packages/template/src/tanstack-start-server-context.combined.ts @@ -0,0 +1,8 @@ +import * as browserContext from "./tanstack-start-server-context.default"; +import * as serverContext from "./tanstack-start-server-context.server"; + +export declare const getCookie: typeof serverContext.getCookie | typeof browserContext.getCookie; +export declare const getCookies: typeof serverContext.getCookies | typeof browserContext.getCookies; +export declare const setCookie: typeof serverContext.setCookie | typeof browserContext.setCookie; +export declare const deleteCookie: typeof serverContext.deleteCookie | typeof browserContext.deleteCookie; +export declare const getRequestHeader: typeof serverContext.getRequestHeader | typeof browserContext.getRequestHeader; diff --git a/packages/template/src/tanstack-start-server-context.d.ts b/packages/template/src/tanstack-start-server-context.d.ts new file mode 100644 index 0000000000..e183d95ef6 --- /dev/null +++ b/packages/template/src/tanstack-start-server-context.d.ts @@ -0,0 +1,9 @@ +declare module "@stackframe/tanstack-start/tanstack-start-server-context" { + type TanStackStartServerContext = typeof import("@tanstack/react-start/server"); + + export const deleteCookie: TanStackStartServerContext["deleteCookie"] | undefined; + export const getCookie: TanStackStartServerContext["getCookie"] | undefined; + export const getCookies: TanStackStartServerContext["getCookies"] | undefined; + export const getRequestHeader: TanStackStartServerContext["getRequestHeader"] | undefined; + export const setCookie: TanStackStartServerContext["setCookie"] | undefined; +} diff --git a/packages/template/src/tanstack-start-server-context.default.ts b/packages/template/src/tanstack-start-server-context.default.ts new file mode 100644 index 0000000000..87afea609e --- /dev/null +++ b/packages/template/src/tanstack-start-server-context.default.ts @@ -0,0 +1,5 @@ +export const getCookie = undefined; +export const getCookies = undefined; +export const setCookie = undefined; +export const deleteCookie = undefined; +export const getRequestHeader = undefined; diff --git a/packages/template/src/tanstack-start-server-context.server.ts b/packages/template/src/tanstack-start-server-context.server.ts new file mode 100644 index 0000000000..9ca5b20179 --- /dev/null +++ b/packages/template/src/tanstack-start-server-context.server.ts @@ -0,0 +1,7 @@ +export { + deleteCookie, + getCookie, + getCookies, + getRequestHeader, + setCookie, +} from "@tanstack/react-start/server"; diff --git a/packages/template/vitest.config.ts b/packages/template/vitest.config.ts index e4c46fedeb..890a9e5c0d 100644 --- a/packages/template/vitest.config.ts +++ b/packages/template/vitest.config.ts @@ -1,7 +1,16 @@ +import { fileURLToPath } from 'node:url' // THIS_LINE_PLATFORM template import { defineConfig, mergeConfig } from 'vitest/config' import sharedConfig from '../../vitest.shared' +const tanstackStartServerContextStub = fileURLToPath(new URL('./src/tanstack-start-server-context.default.ts', import.meta.url)) // THIS_LINE_PLATFORM template + export default mergeConfig( sharedConfig, - defineConfig({}), + defineConfig({ + resolve: { + alias: { + "@stackframe/tanstack-start/tanstack-start-server-context": tanstackStartServerContextStub, // THIS_LINE_PLATFORM template + }, + }, + }), ) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 482352d2f2..dc088df11b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,7 +71,7 @@ importers: version: 14.2.17(eslint@8.57.1)(typescript@5.9.3) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + version: 2.31.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) eslint-plugin-node: specifier: ^11.1.0 version: 11.1.0(eslint@8.57.1) @@ -749,7 +749,7 @@ importers: version: 1.166.6(crossws@0.4.4(srvx@0.8.16)) nitro: specifier: ^3.0.0 - version: 3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2) + version: 3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(rolldown@1.0.0-rc.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2) react: specifier: 19.2.1 version: 19.2.1 @@ -1568,10 +1568,10 @@ importers: version: link:../../packages/stack '@supabase/ssr': specifier: latest - version: 0.10.0(@supabase/supabase-js@2.102.1) + version: 0.10.2(@supabase/supabase-js@2.104.0) '@supabase/supabase-js': specifier: latest - version: 2.102.1 + version: 2.104.0 jose: specifier: ^5.2.2 version: 5.6.3 @@ -1598,6 +1598,67 @@ importers: specifier: 5.9.3 version: 5.9.3 + examples/tanstack-start-demo: + dependencies: + '@stackframe/stack-shared': + specifier: workspace:* + version: link:../../packages/stack-shared + '@stackframe/stack-ui': + specifier: workspace:* + version: link:../../packages/stack-ui + '@stackframe/tanstack-start': + specifier: workspace:* + version: link:../../packages/tanstack-start + '@tanstack/react-router': + specifier: ^1.168.23 + version: 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/react-start': + specifier: ^1.167.42 + version: 1.167.42(crossws@0.4.4(srvx@0.8.16))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0) + nitro: + specifier: ^3.0.0 + version: 3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2) + react: + specifier: 19.2.1 + version: 19.2.1 + react-dom: + specifier: 19.2.1 + version: 19.2.1(react@19.2.1) + devDependencies: + '@types/node': + specifier: ^22.13.0 + version: 22.19.0 + '@types/react': + specifier: ^18.2.0 + version: 18.3.12 + '@types/react-dom': + specifier: ^18.2.0 + version: 18.3.1 + '@vitejs/plugin-react': + specifier: ^5.0.0 + version: 5.1.4(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + autoprefixer: + specifier: ^10.4.20 + version: 10.4.21(postcss@8.5.6) + postcss: + specifier: ^8.4.47 + version: 8.5.6 + rimraf: + specifier: ^5.0.10 + version: 5.0.10 + tailwindcss: + specifier: ^3.4.14 + version: 3.4.18(tsx@4.21.0)(yaml@2.8.0) + typescript: + specifier: 5.9.3 + version: 5.9.3 + vite: + specifier: ^7.0.0 + version: 7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + vite-tsconfig-paths: + specifier: ^4.3.2 + version: 4.3.2(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + packages/dashboard-ui-components: dependencies: '@dnd-kit/core': @@ -2396,6 +2457,151 @@ importers: specifier: ^6.1.2 version: 6.1.2 + packages/tanstack-start: + dependencies: + '@ai-sdk/react': + specifier: ^3.0.72 + version: 3.0.143(react@19.2.3)(zod@4.3.6) + '@hookform/resolvers': + specifier: ^5.2.2 + version: 5.2.2(react-hook-form@7.70.0(react@19.2.3)) + '@oslojs/otp': + specifier: ^1.1.0 + version: 1.1.0 + '@simplewebauthn/browser': + specifier: ^13.2.2 + version: 13.2.2 + '@stackframe/stack-shared': + specifier: workspace:* + version: link:../stack-shared + '@stackframe/stack-ui': + specifier: workspace:* + version: link:../stack-ui + '@stripe/react-stripe-js': + specifier: ^3.8.1 + version: 3.8.1(@stripe/stripe-js@7.7.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@stripe/stripe-js': + specifier: ^7.7.0 + version: 7.7.0 + '@tanstack/react-table': + specifier: ^8.21.3 + version: 8.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@types/react': + specifier: ^18.2.0 + version: 18.3.12 + ai: + specifier: ^6.0.0 + version: 6.0.141(zod@4.3.6) + browser-image-compression: + specifier: ^2.0.2 + version: 2.0.2 + color: + specifier: ^5.0.3 + version: 5.0.3 + cookie: + specifier: ^1.1.1 + version: 1.1.1 + jose: + specifier: ^6.1.3 + version: 6.1.3 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + lucide-react: + specifier: ^0.378.0 + version: 0.378.0(react@19.2.3) + oauth4webapi: + specifier: ^3.8.3 + version: 3.8.5 + qrcode: + specifier: ^1.5.4 + version: 1.5.4 + react-easy-crop: + specifier: ^5.5.6 + version: 5.5.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react-hook-form: + specifier: ^7.70.0 + version: 7.70.0(react@19.2.3) + rrweb: + specifier: ^1.1.3 + version: 1.1.3 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.0)) + tsx: + specifier: ^4.21.0 + version: 4.21.0 + yup: + specifier: ^1.7.1 + version: 1.7.1 + devDependencies: + '@quetzallabs/i18n': + specifier: ^0.1.19 + version: 0.1.19(next@16.2.2(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@tanstack/react-router': + specifier: ^1.167.4 + version: 1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start': + specifier: ^1.166.15 + version: 1.167.42(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@types/color': + specifier: ^3.0.6 + version: 3.0.6 + '@types/cookie': + specifier: ^0.6.0 + version: 0.6.0 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/qrcode': + specifier: ^1.5.5 + version: 1.5.5 + '@types/react-avatar-editor': + specifier: ^13.0.3 + version: 13.0.3 + '@types/react-dom': + specifier: ^18.2.0 + version: 18.3.1 + autoprefixer: + specifier: ^10.4.17 + version: 10.4.21(postcss@8.5.6) + chokidar-cli: + specifier: ^3.0.0 + version: 3.0.0 + convex: + specifier: ^1.27.0 + version: 1.27.0(react@19.2.3) + esbuild: + specifier: ^0.20.2 + version: 0.20.2 + i18next: + specifier: ^23.14.0 + version: 23.14.0 + i18next-parser: + specifier: ^9.0.2 + version: 9.0.2 + postcss: + specifier: ^8.4.38 + version: 8.5.6 + postcss-nested: + specifier: ^6.0.1 + version: 6.2.0(postcss@8.5.6) + react: + specifier: ^19.0.0 + version: 19.2.3 + react-dom: + specifier: ^19.0.0 + version: 19.2.3(react@19.2.3) + rimraf: + specifier: ^6.1.2 + version: 6.1.2 + tailwindcss: + specifier: ^3.4.4 + version: 3.4.18(tsx@4.21.0)(yaml@2.8.0) + tsdown: + specifier: ^0.20.3 + version: 0.20.3(typescript@5.9.3) + packages/template: dependencies: '@ai-sdk/react': @@ -2480,6 +2686,12 @@ importers: '@quetzallabs/i18n': specifier: ^0.1.19 version: 0.1.19(next@14.2.35(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)) + '@tanstack/react-router': + specifier: ^1.167.4 + version: 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/react-start': + specifier: ^1.166.15 + version: 1.167.42(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) '@types/color': specifier: ^3.0.6 version: 3.0.6 @@ -9891,36 +10103,36 @@ packages: resolution: {integrity: sha512-SXuhqhuR5FXaYgKTXzZJeqtVA6JKb9IZWaGeEUxHHiOcFy2p51wccO72bYpXwoK4D5pzQOIYLTuAc7etxyMmwg==} engines: {node: '>=12.16'} - '@supabase/auth-js@2.102.1': - resolution: {integrity: sha512-2uH2WB0H98TOGDtaFWhxIcR42Dro/VB7VDZanz/4bVJsqioIue1m3TUqu3xciDm2W9r+1LXQvYNsYbQfWmD+uQ==} + '@supabase/auth-js@2.104.0': + resolution: {integrity: sha512-Vs0ndL+s5an7rOmXtS/nbYnGXL8m+KXlCSrPIcw9bR96ma6qyLYILnE6syuM+rpDnf+Tg4PVNxNB2+oDwoy6mA==} engines: {node: '>=20.0.0'} - '@supabase/functions-js@2.102.1': - resolution: {integrity: sha512-UcrcKTPnAIo+Yp9Jjq9XXwFbsmgRYY637mwka9ZjmTIWcX/xr1pote4OVvaGQycVY1KTiQgjMvpC0Q0yJhRq3w==} + '@supabase/functions-js@2.104.0': + resolution: {integrity: sha512-O8EyEz/RT1kfWhyJNpVc/VbLeBsohHGBVif/CI83zoMB+Iul/t/NIekH1/7RsH6kuO+b2D4wJhfiaW8Qr47sRg==} engines: {node: '>=20.0.0'} '@supabase/phoenix@0.4.0': resolution: {integrity: sha512-RHSx8bHS02xwfHdAbX5Lpbo6PXbgyf7lTaXTlwtFDPwOIw64NnVRwFAXGojHhjtVYI+PEPNSWwkL90f4agN3bw==} - '@supabase/postgrest-js@2.102.1': - resolution: {integrity: sha512-InLvXKAYf8BIqiv9jWOYudWB3rU8A9uMbcip5BQ5sLLNPrbO1Ekkr79OvlhZBgMNSppxVyC7wPPGzLxMcTZhlA==} + '@supabase/postgrest-js@2.104.0': + resolution: {integrity: sha512-ynylEq6wduQEycj6pL3P+/yIfDQ+CTnBC5I6p+PzcAO2ybj9coAITVtMfboi+g/dacgMslN5MH73rXsRMB29+Q==} engines: {node: '>=20.0.0'} - '@supabase/realtime-js@2.102.1': - resolution: {integrity: sha512-h2fCumib/v6u7XMwSPgxnpfimjX4xCEayUHrxWLC7UurfQjUZJ0pmJDgm6yj80DnUerxuulRghwm5zXYysFG/Q==} + '@supabase/realtime-js@2.104.0': + resolution: {integrity: sha512-9fUVDoTVAhn7a79+AmEx+asUlRtf2yBrji7TQckcKn/WK4hvAA9Lia9er+lnhuz3WNiF1x6kkA4x7bRCJrU+KA==} engines: {node: '>=20.0.0'} - '@supabase/ssr@0.10.0': - resolution: {integrity: sha512-36jIu+DuKzg5EgA3fnH+zHvwASvpKcL4zPgmHoZaULroS5Q4mzeHcM69zJ0sXUHddO5IcHjQNZJ9Vyhl/DdbRw==} + '@supabase/ssr@0.10.2': + resolution: {integrity: sha512-JFbchN63CXLFHJRNT7udec4/RoD9PmXkSGko3QSO6vUuqGBtSzdmxR7FPfQNr7SuFd65I7Xv46q66ALjEN1cgQ==} peerDependencies: - '@supabase/supabase-js': ^2.100.1 + '@supabase/supabase-js': ^2.102.1 - '@supabase/storage-js@2.102.1': - resolution: {integrity: sha512-eCL9T4Xpe40nmKlkUJ7Zq/hk34db1xPiT0WL3Iv5MbJqHuCAe5TxhV8Rjqd6DNZrzjtfYObZtYl9jKJaHrivqw==} + '@supabase/storage-js@2.104.0': + resolution: {integrity: sha512-s2NHtuAWb9nldJ/fS62WnJE6edvCWn31rrO+FJKlAohs99qdVgtLegUReTU2H9WnZiQlVqaBtu386wt6/6lrRw==} engines: {node: '>=20.0.0'} - '@supabase/supabase-js@2.102.1': - resolution: {integrity: sha512-bChxPVeLDnYN9M2d/u4fXsvylwSQG5grAl+HN8f+ZD9a9PuVU+Ru+xGmEsk+b9Iz3rJC9ZQnQUJYQ28fApdWYA==} + '@supabase/supabase-js@2.104.0': + resolution: {integrity: sha512-hILwhIjCB53G31jlHUe73NDEmrXudcjcYlVRuvNfEhzf0gyFQaFf7j6rd1UGmYZkFMOg//DFE8Iy9ZbNEgosVw==} engines: {node: '>=20.0.0'} '@sveltejs/sv-utils@0.0.3': @@ -10040,6 +10252,10 @@ packages: resolution: {integrity: sha512-Kp/WSt411ZWYvgXy6uiv5RmhHrz9cAml05AQPrtdAp7eUqvIDbMGPnML25OKbzR3RJ1q4wgENxDTvlGPa9+Mww==} engines: {node: '>=20.19'} + '@tanstack/history@1.161.6': + resolution: {integrity: sha512-NaOGLRrddszbQj9upGat6HG/4TKvXLvu+osAIgfxPYA+eIvYKv8GKDJOrY2D3/U9MRnKfMWD7bU4jeD4xmqyIg==} + engines: {node: '>=20.19'} + '@tanstack/query-core@5.90.7': resolution: {integrity: sha512-6PN65csiuTNfBMXqQUxQhCNdtm1rV+9kC9YwWAIKcaxAauq3Wu7p18j3gQY3YIBJU70jT/wzCCZ2uqto/vQgiQ==} @@ -10055,6 +10271,20 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-router@1.168.23': + resolution: {integrity: sha512-+GblieDnutG6oipJJPNtRJjrWF8QTZEG/l0532+BngFkVK48oHNOcvIkSoAFYftK1egAwM7KBxXsb0Ou+X6/MQ==} + engines: {node: '>=20.19'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-start-client@1.166.40': + resolution: {integrity: sha512-ynjRe8YjaPfcQNEaQ3nE2/zIZNCdyVGew0pHK5lCorqEy3z/YuiKlj5ZXPmel7XGw0XoKsDIH2eXnUtTbIwpjg==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-start-client@1.166.6': resolution: {integrity: sha512-RG+aFN/JdJXArcTBbsJUCrCMzxqMA1YDkdm50Qg2P7H2e3T7Tmqf7mzopXP0b8oMCxbdvjY0leer4t4/KndnjQ==} engines: {node: '>=22.12.0'} @@ -10062,6 +10292,24 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-start-rsc@0.0.21': + resolution: {integrity: sha512-Q7T8HIGgCIrbMkdep5bmh/uPRK/3OZQ11FODZoMOvyrgTho/MA4kuUFSREvz2LdlXYrz3WxhSSLJnAtpPKJn5w==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@vitejs/plugin-rsc': '>=0.5.20' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + peerDependenciesMeta: + '@vitejs/plugin-rsc': + optional: true + + '@tanstack/react-start-server@1.166.41': + resolution: {integrity: sha512-Z0kyOeraz5nHE7DYh4brYetYoXvh3wjNNI3fJZ0+OzGODfNUgZtEQg/f1g1f1kj64irgWIuWTVPi3rOwiPSzYw==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-start-server@1.166.6': resolution: {integrity: sha512-L1aUZW1Q6NU08/MDbQTUJw9yIKr5l3Kg8XWZvB2bpFahN3N+yy2KJehWRMZHTUfnIcV2IjGk3FMEwbLiI20DtA==} engines: {node: '>=22.12.0'} @@ -10077,12 +10325,31 @@ packages: react-dom: '>=18.0.0 || >=19.0.0' vite: '>=7.0.0' + '@tanstack/react-start@1.167.42': + resolution: {integrity: sha512-zobCIyeChagJg/dwWOWYofseucV618++DOIT/HB6tfnKKKnCw15vO9jhkGD5c+SBUNLyG4km+Y4ynvTIkaseVg==} + engines: {node: '>=22.12.0'} + hasBin: true + peerDependencies: + '@vitejs/plugin-rsc': '*' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + vite: '>=7.0.0' + peerDependenciesMeta: + '@vitejs/plugin-rsc': + optional: true + '@tanstack/react-store@0.9.2': resolution: {integrity: sha512-Vt5usJE5sHG/cMechQfmwvwne6ktGCELe89Lmvoxe3LKRoFrhPa8OCKWs0NliG8HTJElEIj7PLtaBQIcux5pAQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/react-store@0.9.3': + resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/react-table@8.20.5': resolution: {integrity: sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==} engines: {node: '>=12'} @@ -10107,6 +10374,15 @@ packages: resolution: {integrity: sha512-SwVPMQxjoY4jwiNgD9u5kDFp/iSaf3wgf1t93xRCC6qDHmv/xLaawhvwEPNIJaPepWuSYRpywpJWH9hGlBqVbw==} engines: {node: '>=20.19'} + '@tanstack/router-core@1.168.15': + resolution: {integrity: sha512-Wr0424NDtD8fT/uALobMZ9DdcfsTyXtW5IPR++7zvW8/7RaIOeaqXpVDId8ywaGtqPWLWOfaUg2zUtYtukoXYA==} + engines: {node: '>=20.19'} + hasBin: true + + '@tanstack/router-generator@1.166.32': + resolution: {integrity: sha512-VuusKwEXcgKq+myq1JQfZogY8scTXIIeFls50dJ/UXgCXWp5n14iFreYNlg41wURcak2oA3M+t2TVfD0xUUD6g==} + engines: {node: '>=20.19'} + '@tanstack/router-generator@1.166.6': resolution: {integrity: sha512-D7Z6oLP2IfflXUzOOxIgeCD8v3/SXU//cgBon0pbF13HkKdf9Zlt97kQqcaOkbnruJJ6i5xtUIsoAQbMmj+EsQ==} engines: {node: '>=20.19'} @@ -10132,28 +10408,78 @@ packages: webpack: optional: true + '@tanstack/router-plugin@1.167.22': + resolution: {integrity: sha512-wYPzIvBK8bcmXVUpZfSgGBXOrfBAdF4odKevz6rejio5rEd947NtKDF5R7eYdwlAOmRqYpLJnJ1QHkc5t8bY4w==} + engines: {node: '>=20.19'} + hasBin: true + peerDependencies: + '@rsbuild/core': '>=1.0.2' + '@tanstack/react-router': ^1.168.21 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@tanstack/react-router': + optional: true + vite: + optional: true + vite-plugin-solid: + optional: true + webpack: + optional: true + '@tanstack/router-utils@1.161.4': resolution: {integrity: sha512-r8TpjyIZoqrXXaf2DDyjd44gjGBoyE+/oEaaH68yLI9ySPO1gUWmQENZ1MZnmBnpUGN24NOZxdjDLc8npK0SAw==} engines: {node: '>=20.19'} + '@tanstack/router-utils@1.161.6': + resolution: {integrity: sha512-nRcYw+w2OEgK6VfjirYvGyPLOK+tZQz1jkYcmH5AjMamQ9PycnlxZF2aEZtPpNoUsaceX2bHptn6Ub5hGXqNvw==} + engines: {node: '>=20.19'} + '@tanstack/start-client-core@1.166.6': resolution: {integrity: sha512-fnSkRaL6pI3RRdWSeJFg5Vg88Cn9GuuOvmOBP0IgWTNHqywjFm/b1dPGemphD5cmJLhMPAkqGwbK4oPzzdnB9A==} engines: {node: '>=22.12.0'} + '@tanstack/start-client-core@1.167.17': + resolution: {integrity: sha512-3ZnpQ0LPnhrm/GX+HT7XfRxTcqnmBE1KJd7LtaJNuN13NH0C4ZOWchKLPEed2/gluhgsT6UgWm+Ec0kEFtxSaw==} + engines: {node: '>=22.12.0'} + hasBin: true + '@tanstack/start-fn-stubs@1.161.4': resolution: {integrity: sha512-b8s6iSQ+ny0P4lGK0n3DKaL6EI7SECG0/89svDeYieVw2+MaFOJVcQo3rU3BUvmuOcIkgkE5IhdzkmzPXH6yfA==} engines: {node: '>=22.12.0'} + '@tanstack/start-fn-stubs@1.161.6': + resolution: {integrity: sha512-Y6QSlGiLga8cHfvxGGaonXIlt2bIUTVdH6AMjmpMp7+ANNCp+N96GQbjjhLye3JkaxDfP68x5iZA8NK4imgRig==} + engines: {node: '>=22.12.0'} + '@tanstack/start-plugin-core@1.166.6': resolution: {integrity: sha512-/VlfJYOnVyzGlyEATCFxhgPC2AF5pt5MEO+cjvguu9q9+hE/zceSY33Y9gmg7keybVGOz+cmRrSbUaBPMQ+aNw==} engines: {node: '>=22.12.0'} peerDependencies: vite: '>=7.0.0' + '@tanstack/start-plugin-core@1.167.35': + resolution: {integrity: sha512-Ww511KfsXd7TbPYzjiUDCMUI5VbO0chmrTgFi1oOUT0jmk5U0Xh9WVIun1cvRmaq+KBZwvWGvmeIn0UwO3mHEA==} + engines: {node: '>=22.12.0'} + peerDependencies: + vite: '>=7.0.0' + '@tanstack/start-server-core@1.166.6': resolution: {integrity: sha512-nekpa3zFx1SFBURwVbqNunJlLcxvx8vu+Mbnv/nYw4JLfeBmhNNGMZjxmB2K5PRBwIzcKRpLIwgtzyWWzaHKPw==} engines: {node: '>=22.12.0'} + '@tanstack/start-server-core@1.167.19': + resolution: {integrity: sha512-wzOdfzLsK91CnjoywnEjXSlVlaRVK99HJhyVijNU1TECBI2JEKvW9S6d14YfS4gD4fFH4V86tFYhkcLPe6nzWg==} + engines: {node: '>=22.12.0'} + hasBin: true + + '@tanstack/start-storage-context@1.166.29': + resolution: {integrity: sha512-KrJYudc1nbnTY43jdN+hQFMYkhz7+3T+hkgBoGnIP1OspSe6vGQaYGDB4EUXYnkLfyQp+iUuKubgS8hSKeJ0ng==} + engines: {node: '>=22.12.0'} + '@tanstack/start-storage-context@1.166.6': resolution: {integrity: sha512-FLu+bHWS0VFz/KTOPEQnhDxzxToca4giVoUZ3DYfYcQNky+FrIeKYvlwurFNVuLkSCY1Jqr1O2xVnD9dEqBAag==} engines: {node: '>=22.12.0'} @@ -10161,6 +10487,9 @@ packages: '@tanstack/store@0.9.2': resolution: {integrity: sha512-K013lUJEFJK2ofFQ/hZKJUmCnpcV00ebLyOyFOWQvyQHUOZp/iYO84BM6aOGiV81JzwbX0APTVmW8YI7yiG5oA==} + '@tanstack/store@0.9.3': + resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} + '@tanstack/table-core@8.20.5': resolution: {integrity: sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==} engines: {node: '>=12'} @@ -10176,6 +10505,11 @@ packages: resolution: {integrity: sha512-42WoRePf8v690qG8yGRe/YOh+oHni9vUaUUfoqlS91U2scd3a5rkLtVsc6b7z60w3RogH0I00vdrC5AaeiZ18w==} engines: {node: '>=20.19'} + '@tanstack/virtual-file-routes@1.161.7': + resolution: {integrity: sha512-olW33+Cn+bsCsZKPwEGhlkqS6w3M2slFv11JIobdnCFKMLG97oAI2kWKdx5/zsywTL8flpnoIgaZZPlQTFYhdQ==} + engines: {node: '>=20.19'} + hasBin: true + '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} @@ -12023,6 +12357,9 @@ packages: cookie-es@2.0.0: resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} @@ -13936,6 +14273,16 @@ packages: crossws: optional: true + h3@2.0.1-rc.20: + resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + hachure-fill@0.5.2: resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} @@ -15138,6 +15485,9 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magic-string@0.30.8: resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} engines: {node: '>=12'} @@ -17791,6 +18141,11 @@ packages: resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} engines: {node: '>= 0.6'} + srvx@0.11.15: + resolution: {integrity: sha512-iXsux0UcOjdvs0LCMa2Ws3WwcDUozA3JN3BquNXkaFPP7TpRqgunKdEgoZ/uwb1J6xaYHfxtz9Twlh6yzwM6Tg==} + engines: {node: '>=20.16.0'} + hasBin: true + srvx@0.11.9: resolution: {integrity: sha512-97wWJS6F0KTKAhDlHVmBzMvlBOp5FiNp3XrLoodIgYJpXxgG5tE9rX4Pg7s46n2shI4wtEsMATTS1+rI3/ubzA==} engines: {node: '>=20.16.0'} @@ -18849,6 +19204,7 @@ packages: uuid@10.0.0: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true uuid@11.1.0: @@ -18857,6 +19213,7 @@ packages: uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true uzip@0.20201231.0: @@ -19630,6 +19987,16 @@ snapshots: transitivePeerDependencies: - zod + '@ai-sdk/react@3.0.143(react@19.2.3)(zod@4.3.6)': + dependencies: + '@ai-sdk/provider-utils': 4.0.21(zod@4.3.6) + ai: 6.0.141(zod@4.3.6) + react: 19.2.3 + swr: 2.3.4(react@19.2.3) + throttleit: 2.1.0 + transitivePeerDependencies: + - zod + '@ai-sdk/react@3.0.83(react@18.3.1)(zod@3.25.76)': dependencies: '@ai-sdk/provider-utils': 4.0.14(zod@3.25.76) @@ -20847,7 +21214,7 @@ snapshots: '@babel/helper-annotate-as-pure@7.24.7': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-compilation-targets@7.25.9': dependencies: @@ -20881,7 +21248,7 @@ snapshots: '@babel/helper-optimise-call-expression': 7.24.7 '@babel/helper-replace-supers': 7.25.0(@babel/core@7.29.0) '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -20890,29 +21257,29 @@ snapshots: '@babel/helper-member-expression-to-functions@7.24.8': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.24.7': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -20952,7 +21319,7 @@ snapshots: '@babel/helper-optimise-call-expression@7.24.7': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.27.1': {} @@ -20963,14 +21330,14 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-member-expression-to-functions': 7.24.8 '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.24.7': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -20989,7 +21356,7 @@ snapshots: '@babel/helpers@7.26.0': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helpers@7.28.4': dependencies: @@ -21003,7 +21370,7 @@ snapshots: '@babel/parser@7.25.6': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/parser@7.28.5': dependencies: @@ -21032,6 +21399,11 @@ snapshots: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 @@ -21042,6 +21414,11 @@ snapshots: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -21084,9 +21461,9 @@ snapshots: '@babel/template@7.25.9': dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.29.0 '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/template@7.27.2': dependencies: @@ -21102,11 +21479,11 @@ snapshots: '@babel/traverse@7.25.6': dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.29.0 '@babel/generator': 7.28.5 '@babel/parser': 7.28.5 '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 debug: 4.4.3 globals: 11.12.0 transitivePeerDependencies: @@ -22369,6 +22746,11 @@ snapshots: '@standard-schema/utils': 0.3.0 react-hook-form: 7.70.0(react@19.2.1) + '@hookform/resolvers@5.2.2(react-hook-form@7.70.0(react@19.2.3))': + dependencies: + '@standard-schema/utils': 0.3.0 + react-hook-form: 7.70.0(react@19.2.3) + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -25215,6 +25597,23 @@ snapshots: - next - supports-color + '@quetzallabs/i18n@0.1.19(next@16.2.2(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@babel/parser': 7.25.6 + '@babel/traverse': 7.25.6 + axios: 1.7.4 + dotenv: 10.0.0 + i18next: 21.10.0 + i18next-parser: 9.0.2 + next-intl: 3.19.1(next@16.2.2(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@18.3.1) + path: 0.12.7 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - debug + - next + - supports-color + '@radix-ui/number@1.1.0': {} '@radix-ui/number@1.1.1': {} @@ -28176,7 +28575,7 @@ snapshots: '@sentry/bundler-plugin-core@4.3.0(encoding@0.1.13)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@sentry/babel-plugin-component-annotate': 4.3.0 '@sentry/cli': 2.53.0(encoding@0.1.13) dotenv: 16.6.1 @@ -29473,21 +29872,21 @@ snapshots: '@stripe/stripe-js@7.7.0': {} - '@supabase/auth-js@2.102.1': + '@supabase/auth-js@2.104.0': dependencies: tslib: 2.8.1 - '@supabase/functions-js@2.102.1': + '@supabase/functions-js@2.104.0': dependencies: tslib: 2.8.1 '@supabase/phoenix@0.4.0': {} - '@supabase/postgrest-js@2.102.1': + '@supabase/postgrest-js@2.104.0': dependencies: tslib: 2.8.1 - '@supabase/realtime-js@2.102.1': + '@supabase/realtime-js@2.104.0': dependencies: '@supabase/phoenix': 0.4.0 '@types/ws': 8.18.1 @@ -29497,23 +29896,23 @@ snapshots: - bufferutil - utf-8-validate - '@supabase/ssr@0.10.0(@supabase/supabase-js@2.102.1)': + '@supabase/ssr@0.10.2(@supabase/supabase-js@2.104.0)': dependencies: - '@supabase/supabase-js': 2.102.1 + '@supabase/supabase-js': 2.104.0 cookie: 1.0.2 - '@supabase/storage-js@2.102.1': + '@supabase/storage-js@2.104.0': dependencies: iceberg-js: 0.8.1 tslib: 2.8.1 - '@supabase/supabase-js@2.102.1': + '@supabase/supabase-js@2.104.0': dependencies: - '@supabase/auth-js': 2.102.1 - '@supabase/functions-js': 2.102.1 - '@supabase/postgrest-js': 2.102.1 - '@supabase/realtime-js': 2.102.1 - '@supabase/storage-js': 2.102.1 + '@supabase/auth-js': 2.104.0 + '@supabase/functions-js': 2.104.0 + '@supabase/postgrest-js': 2.104.0 + '@supabase/realtime-js': 2.104.0 + '@supabase/storage-js': 2.104.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -29614,6 +30013,8 @@ snapshots: '@tanstack/history@1.161.4': {} + '@tanstack/history@1.161.6': {} + '@tanstack/query-core@5.90.7': {} '@tanstack/react-query@5.90.7(react@18.3.1)': @@ -29638,6 +30039,40 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 + '@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': + dependencies: + '@tanstack/history': 1.161.6 + '@tanstack/react-store': 0.9.3(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/router-core': 1.168.15 + isbot: 5.1.35 + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + + '@tanstack/react-router@1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/history': 1.161.6 + '@tanstack/react-store': 0.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.168.15 + isbot: 5.1.35 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@tanstack/react-start-client@1.166.40(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': + dependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/router-core': 1.168.15 + '@tanstack/start-client-core': 1.167.17 + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + + '@tanstack/react-start-client@1.166.40(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.168.15 + '@tanstack/start-client-core': 1.167.17 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + '@tanstack/react-start-client@1.166.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: '@tanstack/react-router': 1.166.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -29648,6 +30083,108 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 + '@tanstack/react-start-rsc@0.0.21(crossws@0.4.4(srvx@0.8.16))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0)': + dependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/react-start-server': 1.166.41(crossws@0.4.4(srvx@0.8.16))(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/router-core': 1.168.15 + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-fn-stubs': 1.161.6 + '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(crossws@0.4.4(srvx@0.8.16))(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0) + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.8.16)) + '@tanstack/start-storage-context': 1.166.29 + pathe: 2.0.3 + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + transitivePeerDependencies: + - '@rsbuild/core' + - crossws + - supports-color + - vite + - vite-plugin-solid + - webpack + + '@tanstack/react-start-rsc@0.0.21(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/react-start-server': 1.166.41(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/router-core': 1.168.15 + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-fn-stubs': 1.161.6 + '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.11.15)) + '@tanstack/start-storage-context': 1.166.29 + pathe: 2.0.3 + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + transitivePeerDependencies: + - '@rsbuild/core' + - crossws + - supports-color + - vite + - vite-plugin-solid + - webpack + + '@tanstack/react-start-rsc@0.0.21(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-server': 1.166.41(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.168.15 + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-fn-stubs': 1.161.6 + '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.11.15)) + '@tanstack/start-storage-context': 1.166.29 + pathe: 2.0.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + transitivePeerDependencies: + - '@rsbuild/core' + - crossws + - supports-color + - vite + - vite-plugin-solid + - webpack + + '@tanstack/react-start-server@1.166.41(crossws@0.4.4(srvx@0.8.16))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': + dependencies: + '@tanstack/history': 1.161.6 + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/router-core': 1.168.15 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.8.16)) + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + transitivePeerDependencies: + - crossws + + '@tanstack/react-start-server@1.166.41(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': + dependencies: + '@tanstack/history': 1.161.6 + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/router-core': 1.168.15 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.11.15)) + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + transitivePeerDependencies: + - crossws + + '@tanstack/react-start-server@1.166.41(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/history': 1.161.6 + '@tanstack/react-router': 1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.168.15 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.11.15)) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + transitivePeerDependencies: + - crossws + '@tanstack/react-start-server@1.166.6(crossws@0.4.4(srvx@0.8.16))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: '@tanstack/history': 1.161.4 @@ -29680,6 +30217,69 @@ snapshots: - vite-plugin-solid - webpack + '@tanstack/react-start@1.167.42(crossws@0.4.4(srvx@0.8.16))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0)': + dependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/react-start-client': 1.166.40(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/react-start-rsc': 0.0.21(crossws@0.4.4(srvx@0.8.16))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0) + '@tanstack/react-start-server': 1.166.41(crossws@0.4.4(srvx@0.8.16))(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(crossws@0.4.4(srvx@0.8.16))(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0) + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.8.16)) + pathe: 2.0.3 + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + vite: 7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + transitivePeerDependencies: + - '@rsbuild/core' + - crossws + - supports-color + - vite-plugin-solid + - webpack + + '@tanstack/react-start@1.167.42(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/react-start-client': 1.166.40(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/react-start-rsc': 0.0.21(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@tanstack/react-start-server': 1.166.41(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.11.15)) + pathe: 2.0.3 + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + vite: 7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + transitivePeerDependencies: + - '@rsbuild/core' + - crossws + - supports-color + - vite-plugin-solid + - webpack + + '@tanstack/react-start@1.167.42(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-client': 1.166.40(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-rsc': 0.0.21(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@tanstack/react-start-server': 1.166.41(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.11.15)) + pathe: 2.0.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + vite: 7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + transitivePeerDependencies: + - '@rsbuild/core' + - crossws + - supports-color + - vite-plugin-solid + - webpack + '@tanstack/react-store@0.9.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: '@tanstack/store': 0.9.2 @@ -29687,6 +30287,20 @@ snapshots: react-dom: 19.2.1(react@19.2.1) use-sync-external-store: 1.6.0(react@19.2.1) + '@tanstack/react-store@0.9.3(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': + dependencies: + '@tanstack/store': 0.9.3 + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + use-sync-external-store: 1.6.0(react@19.2.1) + + '@tanstack/react-store@0.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/store': 0.9.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/react-table@8.20.5(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: '@tanstack/table-core': 8.20.5 @@ -29711,6 +30325,12 @@ snapshots: react: 19.2.1 react-dom: 19.2.3(react@19.2.1) + '@tanstack/react-table@8.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/table-core': 8.21.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + '@tanstack/react-virtual@3.13.18(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/virtual-core': 3.13.18 @@ -29727,6 +30347,26 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 + '@tanstack/router-core@1.168.15': + dependencies: + '@tanstack/history': 1.161.6 + cookie-es: 3.1.1 + seroval: 1.5.1 + seroval-plugins: 1.5.1(seroval@1.5.1) + + '@tanstack/router-generator@1.166.32': + dependencies: + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-utils': 1.161.6 + '@tanstack/virtual-file-routes': 1.161.7 + magic-string: 0.30.21 + prettier: 3.5.3 + tsx: 4.21.0 + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + '@tanstack/router-generator@1.166.6': dependencies: '@tanstack/router-core': 1.166.6 @@ -29762,6 +30402,70 @@ snapshots: transitivePeerDependencies: - supports-color + '@tanstack/router-plugin@1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-generator': 1.166.32 + '@tanstack/router-utils': 1.161.6 + '@tanstack/virtual-file-routes': 1.161.7 + chokidar: 3.6.0 + unplugin: 2.3.11 + zod: 3.25.76 + optionalDependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + vite: 7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + webpack: 5.92.0 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-plugin@1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-generator': 1.166.32 + '@tanstack/router-utils': 1.161.6 + '@tanstack/virtual-file-routes': 1.161.7 + chokidar: 3.6.0 + unplugin: 2.3.11 + zod: 3.25.76 + optionalDependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + vite: 7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + + '@tanstack/router-plugin@1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-generator': 1.166.32 + '@tanstack/router-utils': 1.161.6 + '@tanstack/virtual-file-routes': 1.161.7 + chokidar: 3.6.0 + unplugin: 2.3.11 + zod: 3.25.76 + optionalDependencies: + '@tanstack/react-router': 1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + vite: 7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + '@tanstack/router-utils@1.161.4': dependencies: '@babel/core': 7.28.5 @@ -29776,6 +30480,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@tanstack/router-utils@1.161.6': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + ansis: 4.2.0 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.3 + pathe: 2.0.3 + tinyglobby: 0.2.15 + transitivePeerDependencies: + - supports-color + '@tanstack/start-client-core@1.166.6': dependencies: '@tanstack/router-core': 1.166.6 @@ -29785,8 +30503,17 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 + '@tanstack/start-client-core@1.167.17': + dependencies: + '@tanstack/router-core': 1.168.15 + '@tanstack/start-fn-stubs': 1.161.6 + '@tanstack/start-storage-context': 1.166.29 + seroval: 1.5.1 + '@tanstack/start-fn-stubs@1.161.4': {} + '@tanstack/start-fn-stubs@1.161.6': {} + '@tanstack/start-plugin-core@1.166.6(@tanstack/react-router@1.166.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(crossws@0.4.4(srvx@0.8.16))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))': dependencies: '@babel/code-frame': 7.27.1 @@ -29819,6 +30546,105 @@ snapshots: - vite-plugin-solid - webpack + '@tanstack/start-plugin-core@1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(crossws@0.4.4(srvx@0.8.16))(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0)': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.29.0 + '@babel/types': 7.29.0 + '@rolldown/pluginutils': 1.0.0-beta.40 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-generator': 1.166.32 + '@tanstack/router-plugin': 1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0) + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.8.16)) + cheerio: 1.0.0 + exsolve: 1.0.8 + pathe: 2.0.3 + picomatch: 4.0.3 + seroval: 1.5.1 + source-map: 0.7.6 + srvx: 0.11.15 + tinyglobby: 0.2.15 + ufo: 1.6.3 + vite: 7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + vitefu: 1.1.2(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + xmlbuilder2: 4.0.3 + zod: 3.25.76 + transitivePeerDependencies: + - '@rsbuild/core' + - '@tanstack/react-router' + - crossws + - supports-color + - vite-plugin-solid + - webpack + + '@tanstack/start-plugin-core@1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.29.0 + '@babel/types': 7.29.0 + '@rolldown/pluginutils': 1.0.0-beta.40 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-generator': 1.166.32 + '@tanstack/router-plugin': 1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.11.15)) + cheerio: 1.0.0 + exsolve: 1.0.8 + pathe: 2.0.3 + picomatch: 4.0.3 + seroval: 1.5.1 + source-map: 0.7.6 + srvx: 0.11.15 + tinyglobby: 0.2.15 + ufo: 1.6.3 + vite: 7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + vitefu: 1.1.2(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + xmlbuilder2: 4.0.3 + zod: 3.25.76 + transitivePeerDependencies: + - '@rsbuild/core' + - '@tanstack/react-router' + - crossws + - supports-color + - vite-plugin-solid + - webpack + + '@tanstack/start-plugin-core@1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.29.0 + '@babel/types': 7.29.0 + '@rolldown/pluginutils': 1.0.0-beta.40 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-generator': 1.166.32 + '@tanstack/router-plugin': 1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + '@tanstack/router-utils': 1.161.6 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-server-core': 1.167.19(crossws@0.4.4(srvx@0.11.15)) + cheerio: 1.0.0 + exsolve: 1.0.8 + pathe: 2.0.3 + picomatch: 4.0.3 + seroval: 1.5.1 + source-map: 0.7.6 + srvx: 0.11.15 + tinyglobby: 0.2.15 + ufo: 1.6.3 + vite: 7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + vitefu: 1.1.2(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)) + xmlbuilder2: 4.0.3 + zod: 3.25.76 + transitivePeerDependencies: + - '@rsbuild/core' + - '@tanstack/react-router' + - crossws + - supports-color + - vite-plugin-solid + - webpack + '@tanstack/start-server-core@1.166.6(crossws@0.4.4(srvx@0.8.16))': dependencies: '@tanstack/history': 1.161.4 @@ -29831,12 +30657,40 @@ snapshots: transitivePeerDependencies: - crossws + '@tanstack/start-server-core@1.167.19(crossws@0.4.4(srvx@0.11.15))': + dependencies: + '@tanstack/history': 1.161.6 + '@tanstack/router-core': 1.168.15 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-storage-context': 1.166.29 + h3-v2: h3@2.0.1-rc.20(crossws@0.4.4(srvx@0.11.15)) + seroval: 1.5.1 + transitivePeerDependencies: + - crossws + + '@tanstack/start-server-core@1.167.19(crossws@0.4.4(srvx@0.8.16))': + dependencies: + '@tanstack/history': 1.161.6 + '@tanstack/router-core': 1.168.15 + '@tanstack/start-client-core': 1.167.17 + '@tanstack/start-storage-context': 1.166.29 + h3-v2: h3@2.0.1-rc.20(crossws@0.4.4(srvx@0.8.16)) + seroval: 1.5.1 + transitivePeerDependencies: + - crossws + + '@tanstack/start-storage-context@1.166.29': + dependencies: + '@tanstack/router-core': 1.168.15 + '@tanstack/start-storage-context@1.166.6': dependencies: '@tanstack/router-core': 1.166.6 '@tanstack/store@0.9.2': {} + '@tanstack/store@0.9.3': {} + '@tanstack/table-core@8.20.5': {} '@tanstack/table-core@8.21.3': {} @@ -29845,6 +30699,8 @@ snapshots: '@tanstack/virtual-file-routes@1.161.4': {} + '@tanstack/virtual-file-routes@1.161.7': {} + '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.27.1 @@ -30636,13 +31492,6 @@ snapshots: optionalDependencies: '@aws-sdk/credential-provider-web-identity': 3.972.27 - '@vercel/mcp-adapter@1.0.0(@modelcontextprotocol/sdk@1.17.2)(next@15.5.10(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': - dependencies: - '@modelcontextprotocol/sdk': 1.17.2 - mcp-handler: 1.0.1(@modelcontextprotocol/sdk@1.17.2)(next@15.5.10(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - optionalDependencies: - next: 15.5.10(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@vercel/mcp-adapter@1.0.0(@modelcontextprotocol/sdk@1.17.2)(next@16.1.7(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: '@modelcontextprotocol/sdk': 1.17.2 @@ -30712,6 +31561,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.3 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))': dependencies: '@babel/core': 7.29.0 @@ -31296,7 +32157,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/parser': 7.28.5 '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -32078,6 +32939,8 @@ snapshots: cookie-es@2.0.0: {} + cookie-es@3.1.1: {} + cookie-signature@1.0.6: {} cookie-signature@1.2.2: {} @@ -32159,6 +33022,11 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crossws@0.4.4(srvx@0.11.15): + optionalDependencies: + srvx: 0.11.15 + optional: true + crossws@0.4.4(srvx@0.8.16): optionalDependencies: srvx: 0.8.16 @@ -33373,7 +34241,7 @@ snapshots: debug: 4.4.3 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.3 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -33398,7 +34266,7 @@ snapshots: is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node @@ -33416,7 +34284,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -33438,16 +34306,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - eslint-plugin-es@3.0.1(eslint@8.57.1): dependencies: eslint: 8.57.1 @@ -33494,7 +34352,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -33541,35 +34399,6 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.8 - array.prototype.findlastindex: 1.2.5 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) - hasown: 2.0.2 - is-core-module: 2.15.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.0 - semver: 6.3.1 - string.prototype.trimend: 1.0.8 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): dependencies: aria-query: 5.3.2 @@ -34846,7 +35675,7 @@ snapshots: h3@2.0.1-rc.16(crossws@0.4.4(srvx@0.8.16)): dependencies: rou3: 0.8.1 - srvx: 0.11.9 + srvx: 0.11.15 optionalDependencies: crossws: 0.4.4(srvx@0.8.16) @@ -34859,6 +35688,20 @@ snapshots: optionalDependencies: crossws: 0.4.4(srvx@0.8.16) + h3@2.0.1-rc.20(crossws@0.4.4(srvx@0.11.15)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.15 + optionalDependencies: + crossws: 0.4.4(srvx@0.11.15) + + h3@2.0.1-rc.20(crossws@0.4.4(srvx@0.8.16)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.15 + optionalDependencies: + crossws: 0.4.4(srvx@0.8.16) + hachure-fill@0.5.2: {} handlebars@4.7.8: @@ -36190,6 +37033,10 @@ snapshots: dependencies: react: 19.2.1 + lucide-react@0.378.0(react@19.2.3): + dependencies: + react: 19.2.3 + lucide-react@0.462.0(react@18.3.1): dependencies: react: 18.3.1 @@ -36212,6 +37059,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.8: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -36229,15 +37080,6 @@ snapshots: math-intrinsics@1.1.0: {} - mcp-handler@1.0.1(@modelcontextprotocol/sdk@1.17.2)(next@15.5.10(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): - dependencies: - '@modelcontextprotocol/sdk': 1.17.2 - chalk: 5.6.2 - commander: 11.1.0 - redis: 4.7.1 - optionalDependencies: - next: 15.5.10(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - mcp-handler@1.0.1(@modelcontextprotocol/sdk@1.17.2)(next@16.1.7(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)): dependencies: '@modelcontextprotocol/sdk': 1.17.2 @@ -36936,14 +37778,14 @@ snapshots: acorn: 8.15.0 pathe: 1.1.2 pkg-types: 1.2.1 - ufo: 1.5.4 + ufo: 1.6.3 mlly@1.7.4: dependencies: acorn: 8.15.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.5.4 + ufo: 1.6.3 module-details-from-path@1.0.3: {} @@ -37036,6 +37878,14 @@ snapshots: react: 18.3.1 use-intl: 3.19.1(react@18.3.1) + next-intl@3.19.1(next@16.2.2(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@18.3.1): + dependencies: + '@formatjs/intl-localematcher': 0.5.4 + negotiator: 0.6.4 + next: 16.2.2(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 18.3.1 + use-intl: 3.19.1(react@18.3.1) + next-mdx-remote-client@1.1.7(@types/react@18.3.12)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(unified@11.0.5): dependencies: '@babel/code-frame': 7.29.0 @@ -37328,6 +38178,31 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@16.2.2(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@next/env': 16.2.2 + '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.10.16 + caniuse-lite: 1.0.30001751 + postcss: 8.4.31 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + styled-jsx: 5.1.6(@babel/core@7.26.0)(react@19.2.3) + optionalDependencies: + '@next/swc-darwin-arm64': 16.2.2 + '@next/swc-darwin-x64': 16.2.2 + '@next/swc-linux-arm64-gnu': 16.2.2 + '@next/swc-linux-arm64-musl': 16.2.2 + '@next/swc-linux-x64-gnu': 16.2.2 + '@next/swc-linux-x64-musl': 16.2.2 + '@next/swc-win32-arm64-msvc': 16.2.2 + '@next/swc-win32-x64-msvc': 16.2.2 + '@opentelemetry/api': 1.9.0 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + next@16.2.2(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1): dependencies: '@next/env': 16.2.2 @@ -37367,7 +38242,7 @@ snapshots: jsonpath-plus: 10.4.0 lodash.topath: 4.5.2 - nitro@3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2): + nitro@3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(rolldown@1.0.0-rc.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2): dependencies: consola: 3.4.2 cookie-es: 2.0.0 @@ -37387,6 +38262,7 @@ snapshots: unenv: 2.0.0-rc.21 unstorage: 2.0.0-alpha.3(chokidar@4.0.3)(db0@0.3.4(@electric-sql/pglite@0.3.2)(mysql2@3.15.3))(lru-cache@11.2.2)(ofetch@1.5.1) optionalDependencies: + rolldown: 1.0.0-rc.3 vite: 7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) xml2js: 0.6.2 transitivePeerDependencies: @@ -37418,6 +38294,57 @@ snapshots: - sqlite3 - uploadthing + nitro@3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2): + dependencies: + consola: 3.4.2 + cookie-es: 2.0.0 + crossws: 0.4.4(srvx@0.8.16) + db0: 0.3.4(@electric-sql/pglite@0.3.2)(mysql2@3.15.3) + esbuild: 0.25.11 + fetchdts: 0.1.7 + h3: 2.0.1-rc.2(crossws@0.4.4(srvx@0.8.16)) + jiti: 2.6.1 + nf3: 0.1.12 + ofetch: 1.5.1 + ohash: 2.0.11 + rendu: 0.0.6 + rollup: 4.57.1 + srvx: 0.8.16 + undici: 7.18.2 + unenv: 2.0.0-rc.21 + unstorage: 2.0.0-alpha.3(chokidar@4.0.3)(db0@0.3.4(@electric-sql/pglite@0.3.2)(mysql2@3.15.3))(lru-cache@11.2.2)(ofetch@1.5.1) + optionalDependencies: + vite: 7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + xml2js: 0.6.2 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - chokidar + - drizzle-orm + - idb-keyval + - ioredis + - lru-cache + - mongodb + - mysql2 + - sqlite3 + - uploadthing + nlcst-to-string@4.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -37813,7 +38740,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.29.0 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -38507,6 +39434,13 @@ snapshots: react-dom: 19.2.1(react@19.2.1) tslib: 2.8.1 + react-easy-crop@5.5.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + normalize-wheel: 1.0.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + tslib: 2.8.1 + react-globe.gl@2.28.2(react@19.2.3): dependencies: globe.gl: 2.34.2 @@ -38530,6 +39464,10 @@ snapshots: dependencies: react: 19.2.1 + react-hook-form@7.70.0(react@19.2.3): + dependencies: + react: 19.2.3 + react-icons@5.2.1(react@18.3.1): dependencies: react: 18.3.1 @@ -40058,6 +40996,8 @@ snapshots: sqlstring@2.3.3: {} + srvx@0.11.15: {} + srvx@0.11.9: {} srvx@0.8.16: {} @@ -40632,6 +41572,16 @@ snapshots: optionalDependencies: esbuild: 0.24.2 + terser-webpack-plugin@5.3.14(webpack@5.92.0): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + terser: 5.44.0 + webpack: 5.92.0 + optional: true + terser@5.44.0: dependencies: '@jridgewell/source-map': 0.3.11 @@ -41458,7 +42408,7 @@ snapshots: vite-tsconfig-paths@4.3.2(typescript@5.9.3)(vite@7.3.1(@types/node@20.17.6)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.19.3)(yaml@2.6.0)): dependencies: - debug: 4.4.0 + debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.5(typescript@5.9.3) optionalDependencies: @@ -41467,9 +42417,20 @@ snapshots: - supports-color - typescript + vite-tsconfig-paths@4.3.2(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)): + dependencies: + debug: 4.4.3 + globrex: 0.1.2 + tsconfck: 3.1.5(typescript@5.9.3) + optionalDependencies: + vite: 7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + - typescript + vite-tsconfig-paths@4.3.2(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)): dependencies: - debug: 4.4.0 + debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.5(typescript@5.9.3) optionalDependencies: @@ -41556,6 +42517,23 @@ snapshots: tsx: 4.19.3 yaml: 2.6.0 + vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0): + dependencies: + esbuild: 0.27.1 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.57.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.0 + fsevents: 2.3.3 + jiti: 1.21.7 + lightningcss: 1.30.1 + terser: 5.44.0 + tsx: 4.21.0 + yaml: 2.8.0 + vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0): dependencies: esbuild: 0.27.1 @@ -41573,10 +42551,35 @@ snapshots: tsx: 4.21.0 yaml: 2.8.0 + vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0): + dependencies: + esbuild: 0.27.1 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.57.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.9.2 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.1 + terser: 5.44.0 + tsx: 4.21.0 + yaml: 2.8.0 + + vitefu@1.1.2(vite@7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)): + optionalDependencies: + vite: 7.3.1(@types/node@22.19.0)(jiti@1.21.7)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + vitefu@1.1.2(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)): optionalDependencies: vite: 7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + vitefu@1.1.2(vite@7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)): + optionalDependencies: + vite: 7.3.1(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0) + vitest@1.6.0(@types/node@20.17.6)(jsdom@24.1.3)(lightningcss@1.30.1)(terser@5.44.0): dependencies: '@vitest/expect': 1.6.0 @@ -41679,6 +42682,38 @@ snapshots: webpack-virtual-modules@0.6.2: {} + webpack@5.92.0: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + browserslist: 4.27.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.3 + es-module-lexer: 1.7.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.14(webpack@5.92.0) + watchpack: 2.4.4 + webpack-sources: 3.3.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + optional: true + webpack@5.92.0(esbuild@0.24.2): dependencies: '@types/eslint-scope': 3.7.7 diff --git a/scripts/generate-sdks.ts b/scripts/generate-sdks.ts index ad6eed7ec6..864ccbcb70 100644 --- a/scripts/generate-sdks.ts +++ b/scripts/generate-sdks.ts @@ -54,7 +54,7 @@ function generateFromTemplate(options: { // If the resulting file is package.json, add a comment field to the JSON. if (path.basename(relativePath) === "package.json") { const jsonObj = JSON.parse(newContent); - newContent = JSON.stringify({ "//": COMMENT_LINE, ...jsonObj }, null, 2); + newContent = JSON.stringify({ "//": COMMENT_LINE, ...jsonObj }, null, 2) + "\n"; } return newContent; @@ -109,7 +109,7 @@ function processPackageJson(path: string, content: string) { } catch (error) { throw new Error(`Failed to parse package.json at ${path}`, { cause: error }); } - return JSON.stringify({ "//": `${COMMENT_LINE} (FOR package.json FILES, PLEASE EDIT package-template.json)`, ...jsonObj }, null, 2); + return JSON.stringify({ "//": `${COMMENT_LINE} (FOR package.json FILES, PLEASE EDIT package-template.json)`, ...jsonObj }, null, 2) + "\n"; } function baseEditFn(options: { @@ -131,6 +131,14 @@ function baseEditFn(options: { withGeneratorLock(async () => { const baseDir = path.resolve(__dirname, "..", "packages"); const srcDir = path.resolve(baseDir, "template"); + const tanstackStartOnlyTemplateFiles = new Set([ + "src/tanstack-start-server-context.combined.ts", + "src/tanstack-start-server-context.default.ts", + "src/tanstack-start-server-context.server.ts", + ]); + const templateOnlyFiles = new Set([ + "src/tanstack-start-server-context.d.ts", + ]); // Copy package-template.json to package.json in the template, // applying macros and adding a comment field. @@ -168,7 +176,9 @@ withGeneratorLock(async () => { "src/global.d.ts", ]; - if (ignores.some((ignorePath) => relativePath.startsWith(ignorePath)) || relativePath.endsWith(".tsx")) { + if (tanstackStartOnlyTemplateFiles.has(relativePath) || templateOnlyFiles.has(relativePath)) { + return false; + } else if (ignores.some((ignorePath) => relativePath.startsWith(ignorePath)) || relativePath.endsWith(".tsx")) { return false; } else { return true; @@ -182,6 +192,7 @@ withGeneratorLock(async () => { editFn: (relativePath, content) => { return baseEditFn({ relativePath, content, platforms: PLATFORMS["next"] }); }, + filterFn: (relativePath) => !tanstackStartOnlyTemplateFiles.has(relativePath), }); generateFromTemplate({ @@ -190,6 +201,16 @@ withGeneratorLock(async () => { editFn: (relativePath, content) => { return baseEditFn({ relativePath, content, platforms: PLATFORMS["react"] }); }, + filterFn: (relativePath) => !tanstackStartOnlyTemplateFiles.has(relativePath), + }); + + generateFromTemplate({ + src: srcDir, + dest: path.resolve(baseDir, "tanstack-start"), + editFn: (relativePath, content) => { + return baseEditFn({ relativePath, content, platforms: PLATFORMS["tanstack-start"] }); + }, + filterFn: (relativePath) => !templateOnlyFiles.has(relativePath), }); }).catch((error) => { console.error(error); diff --git a/scripts/utils.ts b/scripts/utils.ts index 3e33e5428b..72e05c995a 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -9,7 +9,8 @@ export const PLATFORMS = { "next": ['next', 'react-like', 'js-like'], "js": ['js', 'js-like'], "react": ['react', 'react-like', 'js-like'], - "template": ['template', 'react-like', 'next', 'js', 'js-like', 'python-like'], + "tanstack-start": ['tanstack-start', 'react', 'react-like', 'js-like'], + "template": ['template', 'react-like', 'next', 'js', 'js-like', 'python-like', 'tanstack-start'], "python": ['python', 'python-like'], } diff --git a/turbo.json b/turbo.json index 6e882d284d..5a392d98cc 100644 --- a/turbo.json +++ b/turbo.json @@ -4,6 +4,7 @@ "STACK_*", "CRON_SECRET", "NEXT_PUBLIC_*", + "VITE_*", "NEXT_PUBLIC_SENTRY_*", "SENTRY_*", "VERCEL_GIT_COMMIT_SHA",