img:first-child]:pt-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none group/card flex flex-col",
- className,
- )}
- {...props}
- />
- );
+ return (
+
img:first-child]:pt-0 has-data-[slot=card-footer]:pb-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none",
+ className,
+ )}
+ {...props}
+ />
+ );
}
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
+ return (
+
+ );
}
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
+ return (
+
+ );
}
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
+ return (
+
+ );
}
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
+ return (
+
+ );
}
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
+ return (
+
+ );
}
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
+ return (
+
+ );
}
-export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardAction,
+ CardDescription,
+ CardContent,
+};
diff --git a/apps/web/src/components/ui/checkbox.tsx b/apps/web/src/components/ui/checkbox.tsx
index af3f70a..daaee8f 100644
--- a/apps/web/src/components/ui/checkbox.tsx
+++ b/apps/web/src/components/ui/checkbox.tsx
@@ -4,23 +4,23 @@ import { CheckIcon } from "lucide-react";
import { cn } from "@/lib/utils";
function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {
- return (
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+ );
}
export { Checkbox };
diff --git a/apps/web/src/components/ui/dropdown-menu.tsx b/apps/web/src/components/ui/dropdown-menu.tsx
index 234a85d..d60ef75 100644
--- a/apps/web/src/components/ui/dropdown-menu.tsx
+++ b/apps/web/src/components/ui/dropdown-menu.tsx
@@ -1,241 +1,262 @@
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
import { CheckIcon, ChevronRightIcon } from "lucide-react";
-import * as React from "react";
+import type * as React from "react";
import { cn } from "@/lib/utils";
function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {
- return
;
+ return
;
}
function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
- return
;
+ return
;
}
function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {
- return
;
+ return
;
}
function DropdownMenuContent({
- align = "start",
- alignOffset = 0,
- side = "bottom",
- sideOffset = 4,
- className,
- ...props
+ align = "start",
+ alignOffset = 0,
+ side = "bottom",
+ sideOffset = 4,
+ className,
+ ...props
}: MenuPrimitive.Popup.Props &
- Pick
) {
- return (
-
-
-
-
-
- );
+ Pick<
+ MenuPrimitive.Positioner.Props,
+ "align" | "alignOffset" | "side" | "sideOffset"
+ >) {
+ return (
+
+
+
+
+
+ );
}
function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {
- return ;
+ return ;
}
function DropdownMenuLabel({
- className,
- inset,
- ...props
+ className,
+ inset,
+ ...props
}: MenuPrimitive.GroupLabel.Props & {
- inset?: boolean;
+ inset?: boolean;
}) {
- return (
-
- );
+ return (
+
+ );
}
function DropdownMenuItem({
- className,
- inset,
- variant = "default",
- ...props
+ className,
+ inset,
+ variant = "default",
+ ...props
}: MenuPrimitive.Item.Props & {
- inset?: boolean;
- variant?: "default" | "destructive";
+ inset?: boolean;
+ variant?: "default" | "destructive";
}) {
- return (
-
- );
+ return (
+
+ );
}
function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
- return ;
+ return ;
}
function DropdownMenuSubTrigger({
- className,
- inset,
- children,
- ...props
+ className,
+ inset,
+ children,
+ ...props
}: MenuPrimitive.SubmenuTrigger.Props & {
- inset?: boolean;
+ inset?: boolean;
}) {
- return (
-
- {children}
-
-
- );
+ return (
+
+ {children}
+
+
+ );
}
function DropdownMenuSubContent({
- align = "start",
- alignOffset = -3,
- side = "right",
- sideOffset = 0,
- className,
- ...props
+ align = "start",
+ alignOffset = -3,
+ side = "right",
+ sideOffset = 0,
+ className,
+ ...props
}: React.ComponentProps) {
- return (
-
- );
+ return (
+
+ );
}
function DropdownMenuCheckboxItem({
- className,
- children,
- checked,
- ...props
+ className,
+ children,
+ checked,
+ ...props
}: MenuPrimitive.CheckboxItem.Props) {
- return (
-
-
-
-
-
-
- {children}
-
- );
+ return (
+
+
+
+
+
+
+ {children}
+
+ );
}
function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
- return ;
+ return (
+
+ );
}
-function DropdownMenuRadioItem({ className, children, ...props }: MenuPrimitive.RadioItem.Props) {
- return (
-
-
-
-
-
-
- {children}
-
- );
+function DropdownMenuRadioItem({
+ className,
+ children,
+ ...props
+}: MenuPrimitive.RadioItem.Props) {
+ return (
+
+
+
+
+
+
+ {children}
+
+ );
}
-function DropdownMenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {
- return (
-
- );
+function DropdownMenuSeparator({
+ className,
+ ...props
+}: MenuPrimitive.Separator.Props) {
+ return (
+
+ );
}
-function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">) {
- return (
-
- );
+function DropdownMenuShortcut({
+ className,
+ ...props
+}: React.ComponentProps<"span">) {
+ return (
+
+ );
}
export {
- DropdownMenu,
- DropdownMenuPortal,
- DropdownMenuTrigger,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuLabel,
- DropdownMenuItem,
- DropdownMenuCheckboxItem,
- DropdownMenuRadioGroup,
- DropdownMenuRadioItem,
- DropdownMenuSeparator,
- DropdownMenuShortcut,
- DropdownMenuSub,
- DropdownMenuSubTrigger,
- DropdownMenuSubContent,
+ DropdownMenu,
+ DropdownMenuPortal,
+ DropdownMenuTrigger,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuLabel,
+ DropdownMenuItem,
+ DropdownMenuCheckboxItem,
+ DropdownMenuRadioGroup,
+ DropdownMenuRadioItem,
+ DropdownMenuSeparator,
+ DropdownMenuShortcut,
+ DropdownMenuSub,
+ DropdownMenuSubTrigger,
+ DropdownMenuSubContent,
};
diff --git a/apps/web/src/components/ui/input.tsx b/apps/web/src/components/ui/input.tsx
index 3de26af..13657bf 100644
--- a/apps/web/src/components/ui/input.tsx
+++ b/apps/web/src/components/ui/input.tsx
@@ -1,20 +1,20 @@
import { Input as InputPrimitive } from "@base-ui/react/input";
-import * as React from "react";
+import type * as React from "react";
import { cn } from "@/lib/utils";
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
- return (
-
- );
+ return (
+
+ );
}
export { Input };
diff --git a/apps/web/src/components/ui/label.tsx b/apps/web/src/components/ui/label.tsx
index 7ee9a68..7ff92e8 100644
--- a/apps/web/src/components/ui/label.tsx
+++ b/apps/web/src/components/ui/label.tsx
@@ -1,20 +1,21 @@
"use client";
-import * as React from "react";
+import type * as React from "react";
import { cn } from "@/lib/utils";
function Label({ className, ...props }: React.ComponentProps<"label">) {
- return (
-
- );
+ return (
+ // biome-ignore lint/a11y/noLabelWithoutControl: This is a generic Label component - htmlFor will be provided when used
+
+ );
}
export { Label };
diff --git a/apps/web/src/components/ui/skeleton.tsx b/apps/web/src/components/ui/skeleton.tsx
index f1600e8..eff843c 100644
--- a/apps/web/src/components/ui/skeleton.tsx
+++ b/apps/web/src/components/ui/skeleton.tsx
@@ -1,13 +1,16 @@
import { cn } from "@/lib/utils";
-function Skeleton({ className, ...props }: React.HTMLAttributes) {
- return (
-
- );
+function Skeleton({
+ className,
+ ...props
+}: React.HTMLAttributes) {
+ return (
+
+ );
}
export { Skeleton };
diff --git a/apps/web/src/components/ui/sonner.tsx b/apps/web/src/components/ui/sonner.tsx
index 86f24ad..100a0b9 100644
--- a/apps/web/src/components/ui/sonner.tsx
+++ b/apps/web/src/components/ui/sonner.tsx
@@ -1,45 +1,44 @@
-import type { ToasterProps } from "sonner";
-
import {
- CircleCheckIcon,
- InfoIcon,
- Loader2Icon,
- OctagonXIcon,
- TriangleAlertIcon,
+ CircleCheckIcon,
+ InfoIcon,
+ Loader2Icon,
+ OctagonXIcon,
+ TriangleAlertIcon,
} from "lucide-react";
import { useTheme } from "next-themes";
+import type { ToasterProps } from "sonner";
import { Toaster as Sonner } from "sonner";
const Toaster = ({ ...props }: ToasterProps) => {
- const { theme = "system" } = useTheme();
+ const { theme = "system" } = useTheme();
- return (
- ,
- info: ,
- warning: ,
- error: ,
- loading: ,
- }}
- style={
- {
- "--normal-bg": "var(--popover)",
- "--normal-text": "var(--popover-foreground)",
- "--normal-border": "var(--border)",
- "--border-radius": "var(--radius)",
- } as React.CSSProperties
- }
- toastOptions={{
- classNames: {
- toast: "cn-toast",
- },
- }}
- {...props}
- />
- );
+ return (
+ ,
+ info: ,
+ warning: ,
+ error: ,
+ loading: ,
+ }}
+ style={
+ {
+ "--normal-bg": "var(--popover)",
+ "--normal-text": "var(--popover-foreground)",
+ "--normal-border": "var(--border)",
+ "--border-radius": "var(--radius)",
+ } as React.CSSProperties
+ }
+ toastOptions={{
+ classNames: {
+ toast: "cn-toast",
+ },
+ }}
+ {...props}
+ />
+ );
};
export { Toaster };
diff --git a/apps/web/src/functions/get-user.ts b/apps/web/src/functions/get-user.ts
index acf52f8..a2b3362 100644
--- a/apps/web/src/functions/get-user.ts
+++ b/apps/web/src/functions/get-user.ts
@@ -3,7 +3,7 @@ import { createServerFn } from "@tanstack/react-start";
import { authMiddleware } from "@/middleware/auth";
export const getUser = createServerFn({ method: "GET" })
- .middleware([authMiddleware])
- .handler(async ({ context }) => {
- return context.session;
- });
+ .middleware([authMiddleware])
+ .handler(async ({ context }) => {
+ return context.session;
+ });
diff --git a/apps/web/src/index.css b/apps/web/src/index.css
index f1d8c73..3f9164d 100644
--- a/apps/web/src/index.css
+++ b/apps/web/src/index.css
@@ -1 +1,63 @@
@import "tailwindcss";
+@import url("https://fonts.cdnfonts.com/css/intro");
+
+/* Intro font family */
+@font-face {
+ font-family: "Intro";
+ src: local("Intro"), local("Intro Regular");
+ font-weight: 400;
+ font-style: normal;
+}
+
+/* Smooth scrolling for the entire page */
+html {
+ scroll-behavior: smooth;
+}
+
+/* Hide scrollbar but keep functionality */
+html {
+ scrollbar-width: thin;
+ scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
+}
+
+::-webkit-scrollbar {
+ width: 6px;
+}
+
+::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+::-webkit-scrollbar-thumb {
+ background: rgba(0, 0, 0, 0.2);
+ border-radius: 3px;
+}
+
+/* Sticky scroll container with snap points */
+.sticky-scroll-container {
+ height: 400vh; /* 4 sections x 100vh */
+ position: relative;
+}
+
+.sticky-section {
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ width: 100%;
+}
+
+/* Scroll snap for the whole page - mandatory snapping to closest section */
+html {
+ scroll-snap-type: y mandatory;
+ scroll-behavior: smooth;
+}
+
+.snap-section {
+ scroll-snap-align: start;
+ scroll-snap-stop: always;
+}
+
+/* Ensure snap works consistently in both directions */
+.snap-section {
+ scroll-margin-top: 0;
+}
diff --git a/apps/web/src/lib/utils.ts b/apps/web/src/lib/utils.ts
index a5ef193..ac680b3 100644
--- a/apps/web/src/lib/utils.ts
+++ b/apps/web/src/lib/utils.ts
@@ -1,6 +1,6 @@
-import { clsx, type ClassValue } from "clsx";
+import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs));
+ return twMerge(clsx(inputs));
}
diff --git a/apps/web/src/middleware/auth.ts b/apps/web/src/middleware/auth.ts
index 4ea957c..7cb314a 100644
--- a/apps/web/src/middleware/auth.ts
+++ b/apps/web/src/middleware/auth.ts
@@ -1,11 +1,13 @@
import { auth } from "@kk/auth";
import { createMiddleware } from "@tanstack/react-start";
-export const authMiddleware = createMiddleware().server(async ({ next, request }) => {
- const session = await auth.api.getSession({
- headers: request.headers,
- });
- return next({
- context: { session },
- });
-});
+export const authMiddleware = createMiddleware().server(
+ async ({ next, request }) => {
+ const session = await auth.api.getSession({
+ headers: request.headers,
+ });
+ return next({
+ context: { session },
+ });
+ },
+);
diff --git a/apps/web/src/router.tsx b/apps/web/src/router.tsx
index 09c7285..c1394fa 100644
--- a/apps/web/src/router.tsx
+++ b/apps/web/src/router.tsx
@@ -7,22 +7,22 @@ import { routeTree } from "./routeTree.gen";
import { orpc, queryClient } from "./utils/orpc";
export const getRouter = () => {
- const router = createTanStackRouter({
- routeTree,
- scrollRestoration: true,
- defaultPreloadStaleTime: 0,
- context: { orpc, queryClient },
- defaultPendingComponent: () => ,
- defaultNotFoundComponent: () => Not Found
,
- Wrap: ({ children }) => (
- {children}
- ),
- });
- return router;
+ const router = createTanStackRouter({
+ routeTree,
+ scrollRestoration: true,
+ defaultPreloadStaleTime: 0,
+ context: { orpc, queryClient },
+ defaultPendingComponent: () => ,
+ defaultNotFoundComponent: () => Not Found
,
+ Wrap: ({ children }) => (
+ {children}
+ ),
+ });
+ return router;
};
declare module "@tanstack/react-router" {
- interface Register {
- router: ReturnType;
- }
+ interface Register {
+ router: ReturnType;
+ }
}
diff --git a/apps/web/src/routes/api/auth/$.ts b/apps/web/src/routes/api/auth/$.ts
index ff607eb..5c8ae31 100644
--- a/apps/web/src/routes/api/auth/$.ts
+++ b/apps/web/src/routes/api/auth/$.ts
@@ -2,14 +2,14 @@ import { auth } from "@kk/auth";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/api/auth/$")({
- server: {
- handlers: {
- GET: ({ request }) => {
- return auth.handler(request);
- },
- POST: ({ request }) => {
- return auth.handler(request);
- },
- },
- },
+ server: {
+ handlers: {
+ GET: ({ request }) => {
+ return auth.handler(request);
+ },
+ POST: ({ request }) => {
+ return auth.handler(request);
+ },
+ },
+ },
});
diff --git a/apps/web/src/routes/api/rpc/$.ts b/apps/web/src/routes/api/rpc/$.ts
index 969924e..108e0df 100644
--- a/apps/web/src/routes/api/rpc/$.ts
+++ b/apps/web/src/routes/api/rpc/$.ts
@@ -8,51 +8,51 @@ import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
import { createFileRoute } from "@tanstack/react-router";
const rpcHandler = new RPCHandler(appRouter, {
- interceptors: [
- onError((error) => {
- console.error(error);
- }),
- ],
+ interceptors: [
+ onError((error) => {
+ console.error(error);
+ }),
+ ],
});
const apiHandler = new OpenAPIHandler(appRouter, {
- plugins: [
- new OpenAPIReferencePlugin({
- schemaConverters: [new ZodToJsonSchemaConverter()],
- }),
- ],
- interceptors: [
- onError((error) => {
- console.error(error);
- }),
- ],
+ plugins: [
+ new OpenAPIReferencePlugin({
+ schemaConverters: [new ZodToJsonSchemaConverter()],
+ }),
+ ],
+ interceptors: [
+ onError((error) => {
+ console.error(error);
+ }),
+ ],
});
async function handle({ request }: { request: Request }) {
- const rpcResult = await rpcHandler.handle(request, {
- prefix: "/api/rpc",
- context: await createContext({ req: request }),
- });
- if (rpcResult.response) return rpcResult.response;
+ const rpcResult = await rpcHandler.handle(request, {
+ prefix: "/api/rpc",
+ context: await createContext({ req: request }),
+ });
+ if (rpcResult.response) return rpcResult.response;
- const apiResult = await apiHandler.handle(request, {
- prefix: "/api/rpc/api-reference",
- context: await createContext({ req: request }),
- });
- if (apiResult.response) return apiResult.response;
+ const apiResult = await apiHandler.handle(request, {
+ prefix: "/api/rpc/api-reference",
+ context: await createContext({ req: request }),
+ });
+ if (apiResult.response) return apiResult.response;
- return new Response("Not found", { status: 404 });
+ return new Response("Not found", { status: 404 });
}
export const Route = createFileRoute("/api/rpc/$")({
- server: {
- handlers: {
- HEAD: handle,
- GET: handle,
- POST: handle,
- PUT: handle,
- PATCH: handle,
- DELETE: handle,
- },
- },
+ server: {
+ handlers: {
+ HEAD: handle,
+ GET: handle,
+ POST: handle,
+ PUT: handle,
+ PATCH: handle,
+ DELETE: handle,
+ },
+ },
});
diff --git a/apps/web/src/routes/index.tsx b/apps/web/src/routes/index.tsx
index e739619..e778f3c 100644
--- a/apps/web/src/routes/index.tsx
+++ b/apps/web/src/routes/index.tsx
@@ -1,5 +1,6 @@
import { createFileRoute } from "@tanstack/react-router";
+import ArtForms from "@/components/homepage/ArtForms";
import EventRegistrationForm from "@/components/homepage/EventRegistrationForm";
import Footer from "@/components/homepage/Footer";
import Hero from "@/components/homepage/Hero";
@@ -11,11 +12,14 @@ export const Route = createFileRoute("/")({
function HomePage() {
return (
-
-
-
-
-
-
+
);
}
diff --git a/apps/web/src/utils/orpc.ts b/apps/web/src/utils/orpc.ts
index 604bc52..6bc288d 100644
--- a/apps/web/src/utils/orpc.ts
+++ b/apps/web/src/utils/orpc.ts
@@ -1,9 +1,8 @@
-import type { RouterClient } from "@orpc/server";
-
import { createContext } from "@kk/api/context";
import { appRouter } from "@kk/api/routers/index";
import { createORPCClient } from "@orpc/client";
import { RPCLink } from "@orpc/client/fetch";
+import type { RouterClient } from "@orpc/server";
import { createRouterClient } from "@orpc/server";
import { createTanstackQueryUtils } from "@orpc/tanstack-query";
import { QueryCache, QueryClient } from "@tanstack/react-query";
@@ -12,39 +11,39 @@ import { getRequest } from "@tanstack/react-start/server";
import { toast } from "sonner";
export const queryClient = new QueryClient({
- queryCache: new QueryCache({
- onError: (error, query) => {
- toast.error(`Error: ${error.message}`, {
- action: {
- label: "retry",
- onClick: query.invalidate,
- },
- });
- },
- }),
+ queryCache: new QueryCache({
+ onError: (error, query) => {
+ toast.error(`Error: ${error.message}`, {
+ action: {
+ label: "retry",
+ onClick: query.invalidate,
+ },
+ });
+ },
+ }),
});
const getORPCClient = createIsomorphicFn()
- .server(() =>
- createRouterClient(appRouter, {
- context: async () => {
- return createContext({ req: getRequest() });
- },
- }),
- )
- .client((): RouterClient => {
- const link = new RPCLink({
- url: `${window.location.origin}/api/rpc`,
- fetch(url, options) {
- return fetch(url, {
- ...options,
- credentials: "include",
- });
- },
- });
+ .server(() =>
+ createRouterClient(appRouter, {
+ context: async () => {
+ return createContext({ req: getRequest() });
+ },
+ }),
+ )
+ .client((): RouterClient => {
+ const link = new RPCLink({
+ url: `${window.location.origin}/api/rpc`,
+ fetch(url, options) {
+ return fetch(url, {
+ ...options,
+ credentials: "include",
+ });
+ },
+ });
- return createORPCClient(link);
- });
+ return createORPCClient(link);
+ });
export const client: RouterClient = getORPCClient();
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
index fbb99a2..2a6835b 100644
--- a/apps/web/tsconfig.json
+++ b/apps/web/tsconfig.json
@@ -1,28 +1,28 @@
{
- "include": ["**/*.ts", "**/*.tsx"],
- "compilerOptions": {
- "target": "ES2022",
- "jsx": "react-jsx",
- "module": "ESNext",
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
- "types": ["vite/client"],
+ "include": ["**/*.ts", "**/*.tsx"],
+ "compilerOptions": {
+ "target": "ES2022",
+ "jsx": "react-jsx",
+ "module": "ESNext",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "types": ["vite/client"],
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "noEmit": true,
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "noEmit": true,
- /* Linting */
- "skipLibCheck": true,
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true,
- "noUncheckedSideEffectImports": true,
- "baseUrl": ".",
- "paths": {
- "@/*": ["./src/*"]
- }
- }
+ /* Linting */
+ "skipLibCheck": true,
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
}
diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts
index 61efb98..e55389d 100644
--- a/apps/web/vite.config.ts
+++ b/apps/web/vite.config.ts
@@ -6,8 +6,14 @@ import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
- plugins: [tsconfigPaths(), tailwindcss(), tanstackStart(), viteReact(), alchemy()],
- server: {
- port: 3001,
- },
+ plugins: [
+ tsconfigPaths(),
+ tailwindcss(),
+ tanstackStart(),
+ viteReact(),
+ alchemy(),
+ ],
+ server: {
+ port: 3001,
+ },
});
diff --git a/biome.json b/biome.json
index 85f16dc..81a85a2 100644
--- a/biome.json
+++ b/biome.json
@@ -1,76 +1,76 @@
{
- "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
- "vcs": {
- "enabled": false,
- "clientKind": "git",
- "useIgnoreFile": false
- },
- "files": {
- "ignoreUnknown": false,
- "includes": [
- "**",
- "!**/.next",
- "!**/dist",
- "!**/.turbo",
- "!**/dev-dist",
- "!**/.zed",
- "!**/.vscode",
- "!**/routeTree.gen.ts",
- "!**/src-tauri",
- "!**/.nuxt",
- "!bts.jsonc",
- "!**/.expo",
- "!**/.wrangler",
- "!**/.alchemy",
- "!**/.svelte-kit",
- "!**/wrangler.jsonc",
- "!**/.source",
- "!**/convex/_generated"
- ]
- },
- "formatter": {
- "enabled": true,
- "indentStyle": "tab"
- },
- "assist": { "actions": { "source": { "organizeImports": "on" } } },
- "linter": {
- "enabled": true,
- "rules": {
- "recommended": true,
- "correctness": {
- "useExhaustiveDependencies": "info"
- },
- "nursery": {
- "useSortedClasses": {
- "level": "warn",
- "fix": "safe",
- "options": {
- "functions": ["clsx", "cva", "cn"]
- }
- }
- },
- "style": {
- "noParameterAssign": "error",
- "useAsConstAssertion": "error",
- "useDefaultParameterLast": "error",
- "useEnumInitializers": "error",
- "useSelfClosingElements": "error",
- "useSingleVarDeclarator": "error",
- "noUnusedTemplateLiteral": "error",
- "useNumberNamespace": "error",
- "noInferrableTypes": "error",
- "noUselessElse": "error"
- }
- }
- },
- "javascript": {
- "formatter": {
- "quoteStyle": "double"
- }
- },
- "css": {
- "parser": {
- "tailwindDirectives": true
- }
- }
+ "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
+ "vcs": {
+ "enabled": false,
+ "clientKind": "git",
+ "useIgnoreFile": false
+ },
+ "files": {
+ "ignoreUnknown": false,
+ "includes": [
+ "**",
+ "!**/.next",
+ "!**/dist",
+ "!**/.turbo",
+ "!**/dev-dist",
+ "!**/.zed",
+ "!**/.vscode",
+ "!**/routeTree.gen.ts",
+ "!**/src-tauri",
+ "!**/.nuxt",
+ "!bts.jsonc",
+ "!**/.expo",
+ "!**/.wrangler",
+ "!**/.alchemy",
+ "!**/.svelte-kit",
+ "!**/wrangler.jsonc",
+ "!**/.source",
+ "!**/convex/_generated"
+ ]
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab"
+ },
+ "assist": { "actions": { "source": { "organizeImports": "on" } } },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true,
+ "correctness": {
+ "useExhaustiveDependencies": "info"
+ },
+ "nursery": {
+ "useSortedClasses": {
+ "level": "warn",
+ "fix": "safe",
+ "options": {
+ "functions": ["clsx", "cva", "cn"]
+ }
+ }
+ },
+ "style": {
+ "noParameterAssign": "error",
+ "useAsConstAssertion": "error",
+ "useDefaultParameterLast": "error",
+ "useEnumInitializers": "error",
+ "useSelfClosingElements": "error",
+ "useSingleVarDeclarator": "error",
+ "noUnusedTemplateLiteral": "error",
+ "useNumberNamespace": "error",
+ "noInferrableTypes": "error",
+ "noUselessElse": "error"
+ }
+ }
+ },
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "double"
+ }
+ },
+ "css": {
+ "parser": {
+ "tailwindDirectives": true
+ }
+ }
}
diff --git a/bun.lock b/bun.lock
index 5b5e647..a2df046 100644
--- a/bun.lock
+++ b/bun.lock
@@ -31,6 +31,8 @@
"@orpc/server": "catalog:",
"@orpc/tanstack-query": "^1.12.2",
"@orpc/zod": "catalog:",
+ "@react-three/drei": "^10.7.7",
+ "@react-three/fiber": "^9.5.0",
"@tailwindcss/vite": "^4.1.8",
"@tanstack/react-form": "^1.28.0",
"@tanstack/react-query": "^5.80.6",
@@ -51,6 +53,7 @@
"sonner": "^2.0.3",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.3",
+ "three": "^0.183.1",
"tw-animate-css": "^1.2.5",
"vite-tsconfig-paths": "^5.1.4",
"zod": "catalog:",
@@ -64,6 +67,7 @@
"@testing-library/react": "^16.2.0",
"@types/react": "19.2.7",
"@types/react-dom": "19.2.3",
+ "@types/three": "^0.183.1",
"@vitejs/plugin-react": "^5.0.4",
"alchemy": "catalog:",
"jsdom": "^26.0.0",
@@ -356,6 +360,8 @@
"@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.4", "", {}, "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw=="],
+ "@dimforge/rapier3d-compat": ["@dimforge/rapier3d-compat@0.12.0", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="],
+
"@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.52.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.2", "which": "^4.0.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-CaQcc8JvtzQhUSm9877b6V4Tb7HCotkcyud9X2YwdqtQKwgljkMRwU96fVYKnzN3V0Hj74oP7Es+vZ0mS+Aa1w=="],
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="],
@@ -544,8 +550,12 @@
"@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.22", "", { "os": "win32", "cpu": "x64" }, "sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA=="],
+ "@mediapipe/tasks-vision": ["@mediapipe/tasks-vision@0.10.17", "", {}, "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg=="],
+
"@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-qOdO524oPMkUsOJTrsH9vz/HN3B5pKyW+9zIW51A9kDMVe7ON70drz1ouoyoyOcfzc+oxhkQ6jWmbyKnlWmYqA=="],
+ "@monogrid/gainmap-js": ["@monogrid/gainmap-js@3.4.0", "", { "dependencies": { "promise-worker-transferable": "^1.0.4" }, "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg=="],
+
"@mswjs/interceptors": ["@mswjs/interceptors@0.41.3", "", { "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", "@open-draft/until": "^2.0.0", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "strict-event-emitter": "^0.5.1" } }, "sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA=="],
"@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="],
@@ -640,6 +650,10 @@
"@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="],
+ "@react-three/drei": ["@react-three/drei@10.7.7", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mediapipe/tasks-vision": "0.10.17", "@monogrid/gainmap-js": "^3.0.6", "@use-gesture/react": "^10.3.1", "camera-controls": "^3.1.0", "cross-env": "^7.0.3", "detect-gpu": "^5.0.56", "glsl-noise": "^0.0.0", "hls.js": "^1.5.17", "maath": "^0.10.8", "meshline": "^3.3.1", "stats-gl": "^2.2.8", "stats.js": "^0.17.0", "suspend-react": "^0.1.3", "three-mesh-bvh": "^0.8.3", "three-stdlib": "^2.35.6", "troika-three-text": "^0.52.4", "tunnel-rat": "^0.1.2", "use-sync-external-store": "^1.4.0", "utility-types": "^3.11.0", "zustand": "^5.0.1" }, "peerDependencies": { "@react-three/fiber": "^9.0.0", "react": "^19", "react-dom": "^19", "three": ">=0.159" }, "optionalPeers": ["react-dom"] }, "sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ=="],
+
+ "@react-three/fiber": ["@react-three/fiber@9.5.0", "", { "dependencies": { "@babel/runtime": "^7.17.8", "@types/webxr": "*", "base64-js": "^1.5.1", "buffer": "^6.0.3", "its-fine": "^2.0.0", "react-use-measure": "^2.1.7", "scheduler": "^0.27.0", "suspend-react": "^0.1.3", "use-sync-external-store": "^1.4.0", "zustand": "^5.0.3" }, "peerDependencies": { "expo": ">=43.0", "expo-asset": ">=8.4", "expo-file-system": ">=11.0", "expo-gl": ">=11.0", "react": ">=19 <19.3", "react-dom": ">=19 <19.3", "react-native": ">=0.78", "three": ">=0.156" }, "optionalPeers": ["expo", "expo-asset", "expo-file-system", "expo-gl", "react-dom", "react-native"] }, "sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA=="],
+
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="],
@@ -866,7 +880,7 @@
"@tanstack/start-storage-context": ["@tanstack/start-storage-context@1.162.6", "", { "dependencies": { "@tanstack/router-core": "1.162.6" } }, "sha512-Ry/z1tMyEgAearn1dug3Whb/p1X86QErNV+trtDxf+r6Dzt636+eu0biiSuoQxDN7HQe417LB3IUhx4/uFrC2A=="],
- "@tanstack/store": ["@tanstack/store@0.8.1", "", {}, "sha512-PtOisLjUZPz5VyPRSCGjNOlwTvabdTBQ2K80DpVL1chGVr35WRxfeavAPdNq6pm/t7F8GhoR2qtmkkqtCEtHYw=="],
+ "@tanstack/store": ["@tanstack/store@0.9.1", "", {}, "sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg=="],
"@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.161.4", "", {}, "sha512-42WoRePf8v690qG8yGRe/YOh+oHni9vUaUUfoqlS91U2scd3a5rkLtVsc6b7z60w3RogH0I00vdrC5AaeiZ18w=="],
@@ -876,6 +890,8 @@
"@ts-morph/common": ["@ts-morph/common@0.27.0", "", { "dependencies": { "fast-glob": "^3.3.3", "minimatch": "^10.0.1", "path-browserify": "^1.0.1" } }, "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ=="],
+ "@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="],
+
"@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="],
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
@@ -886,22 +902,40 @@
"@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
+ "@types/draco3d": ["@types/draco3d@1.4.10", "", {}, "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw=="],
+
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"@types/node": ["@types/node@22.19.11", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w=="],
+ "@types/offscreencanvas": ["@types/offscreencanvas@2019.7.3", "", {}, "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A=="],
+
"@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
+ "@types/react-reconciler": ["@types/react-reconciler@0.28.9", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="],
+
+ "@types/stats.js": ["@types/stats.js@0.17.4", "", {}, "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="],
+
"@types/statuses": ["@types/statuses@2.0.6", "", {}, "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA=="],
+ "@types/three": ["@types/three@0.183.1", "", { "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": ">=0.5.17", "@webgpu/types": "*", "fflate": "~0.8.2", "meshoptimizer": "~1.0.1" } }, "sha512-f2Pu5Hrepfgavttdye3PsH5RWyY/AvdZQwIVhrc4uNtvF7nOWJacQKcoVJn0S4f0yYbmAE6AR+ve7xDcuYtMGw=="],
+
"@types/validate-npm-package-name": ["@types/validate-npm-package-name@4.0.2", "", {}, "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw=="],
+ "@types/webxr": ["@types/webxr@0.5.24", "", {}, "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg=="],
+
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
+ "@use-gesture/core": ["@use-gesture/core@10.3.1", "", {}, "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw=="],
+
+ "@use-gesture/react": ["@use-gesture/react@10.3.1", "", { "dependencies": { "@use-gesture/core": "10.3.1" }, "peerDependencies": { "react": ">= 16.8.0" } }, "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g=="],
+
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.4", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA=="],
+ "@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="],
+
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
"acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
@@ -934,6 +968,8 @@
"balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
+ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
+
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="],
"before-after-hook": ["before-after-hook@3.0.2", "", {}, "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="],
@@ -942,6 +978,8 @@
"better-call": ["better-call@1.1.8", "", { "dependencies": { "@better-auth/utils": "^0.3.0", "@better-fetch/fetch": "^1.1.4", "rou3": "^0.7.10", "set-cookie-parser": "^2.7.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-XMQ2rs6FNXasGNfMjzbyroSwKwYbZ/T3IxruSS6U2MJRsSYh3wYtG3o6H00ZlKZ/C/UPOAD97tqgQJNsxyeTXw=="],
+ "bidi-js": ["bidi-js@1.0.3", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="],
+
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
"blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="],
@@ -958,6 +996,8 @@
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
+ "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
+
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
"bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
@@ -970,6 +1010,8 @@
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
+ "camera-controls": ["camera-controls@3.1.2", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA=="],
+
"caniuse-lite": ["caniuse-lite@1.0.30001774", "", {}, "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA=="],
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
@@ -1018,6 +1060,8 @@
"cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="],
+ "cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="],
+
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
@@ -1054,6 +1098,8 @@
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
+ "detect-gpu": ["detect-gpu@5.0.70", "", { "dependencies": { "webgl-constants": "^1.1.1" } }, "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w=="],
+
"detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="],
"diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="],
@@ -1070,6 +1116,8 @@
"dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="],
+ "draco3d": ["draco3d@1.5.7", "", {}, "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ=="],
+
"drizzle-kit": ["drizzle-kit@0.31.9", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "esbuild-register": "^3.5.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-GViD3IgsXn7trFyBUUHyTFBpH/FsHTxYJ66qdbVggxef4UBPHRYxQaRzYLTuekYnk9i5FIEL9pbBIwMqX/Uwrg=="],
"drizzle-orm": ["drizzle-orm@0.45.1", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA=="],
@@ -1150,6 +1198,8 @@
"fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="],
+ "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="],
+
"figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="],
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
@@ -1198,6 +1248,8 @@
"globrex": ["globrex@0.1.2", "", {}, "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="],
+ "glsl-noise": ["glsl-noise@0.0.0", "", {}, "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w=="],
+
"goober": ["goober@2.1.18", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
@@ -1216,6 +1268,8 @@
"headers-polyfill": ["headers-polyfill@4.0.3", "", {}, "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ=="],
+ "hls.js": ["hls.js@1.6.15", "", {}, "sha512-E3a5VwgXimGHwpRGV+WxRTKeSp2DW5DI5MWv34ulL3t5UNmyJWCQ1KmLEHbYzcfThfXG8amBL+fCYPneGHC4VA=="],
+
"hono": ["hono@4.12.2", "", {}, "sha512-gJnaDHXKDayjt8ue0n8Gs0A007yKXj4Xzb8+cNjZeYsSzzwKc0Lr+OZgYwVfB0pHfUs17EPoLvrOsEaJ9mj+Tg=="],
"html-encoding-sniffer": ["html-encoding-sniffer@4.0.0", "", { "dependencies": { "whatwg-encoding": "^3.1.1" } }, "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ=="],
@@ -1232,6 +1286,8 @@
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
+
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
@@ -1272,7 +1328,7 @@
"is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="],
- "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
+ "is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="],
"is-regexp": ["is-regexp@3.1.0", "", {}, "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA=="],
@@ -1288,6 +1344,8 @@
"isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="],
+ "its-fine": ["its-fine@2.0.0", "", { "dependencies": { "@types/react-reconciler": "^0.28.9" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng=="],
+
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
@@ -1364,6 +1422,8 @@
"lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="],
+ "maath": ["maath@0.10.8", "", { "peerDependencies": { "@types/three": ">=0.134.0", "three": ">=0.134.0" } }, "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g=="],
+
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
@@ -1376,6 +1436,10 @@
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
+ "meshline": ["meshline@3.3.1", "", { "peerDependencies": { "three": ">=0.137" } }, "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ=="],
+
+ "meshoptimizer": ["meshoptimizer@1.0.1", "", {}, "sha512-Vix+QlA1YYT3FwmBBZ+49cE5y/b+pRrcXKqGpS5ouh33d3lSp2PoTpCw19E0cKDFWalembrHnIaZetf27a+W2g=="],
+
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
@@ -1486,6 +1550,8 @@
"postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+ "potpack": ["potpack@1.0.2", "", {}, "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="],
+
"powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
@@ -1498,6 +1564,8 @@
"promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="],
+ "promise-worker-transferable": ["promise-worker-transferable@1.0.4", "", { "dependencies": { "is-promise": "^2.1.0", "lie": "^3.0.2" } }, "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw=="],
+
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
"proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="],
@@ -1524,6 +1592,8 @@
"react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
+ "react-use-measure": ["react-use-measure@2.1.7", "", { "peerDependencies": { "react": ">=16.13", "react-dom": ">=16.13" }, "optionalPeers": ["react-dom"] }, "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg=="],
+
"readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
@@ -1614,6 +1684,10 @@
"srvx": ["srvx@0.11.7", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-p9qj9wkv/MqG1VoJpOsqXv1QcaVcYRk7ifsC6i3TEwDXFyugdhJN4J3KzQPZq2IJJ2ZCt7ASOB++85pEK38jRw=="],
+ "stats-gl": ["stats-gl@2.4.2", "", { "dependencies": { "@types/three": "*", "three": "^0.170.0" } }, "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ=="],
+
+ "stats.js": ["stats.js@0.17.0", "", {}, "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw=="],
+
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
"stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
@@ -1640,6 +1714,8 @@
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
+ "suspend-react": ["suspend-react@0.1.3", "", { "peerDependencies": { "react": ">=17.0" } }, "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ=="],
+
"symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="],
"tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="],
@@ -1652,6 +1728,12 @@
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
+ "three": ["three@0.183.1", "", {}, "sha512-Psv6bbd3d/M/01MT2zZ+VmD0Vj2dbWTNhfe4CuSg7w5TuW96M3NOyCVuh9SZQ05CpGmD7NEcJhZw4GVjhCYxfQ=="],
+
+ "three-mesh-bvh": ["three-mesh-bvh@0.8.3", "", { "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg=="],
+
+ "three-stdlib": ["three-stdlib@2.36.1", "", { "dependencies": { "@types/draco3d": "^1.4.0", "@types/offscreencanvas": "^2019.6.4", "@types/webxr": "^0.5.2", "draco3d": "^1.4.1", "fflate": "^0.6.9", "potpack": "^1.0.1" }, "peerDependencies": { "three": ">=0.128.0" } }, "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg=="],
+
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
"tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="],
@@ -1672,6 +1754,12 @@
"tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="],
+ "troika-three-text": ["troika-three-text@0.52.4", "", { "dependencies": { "bidi-js": "^1.0.2", "troika-three-utils": "^0.52.4", "troika-worker-utils": "^0.52.0", "webgl-sdf-generator": "1.1.1" }, "peerDependencies": { "three": ">=0.125.0" } }, "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg=="],
+
+ "troika-three-utils": ["troika-three-utils@0.52.4", "", { "peerDependencies": { "three": ">=0.125.0" } }, "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A=="],
+
+ "troika-worker-utils": ["troika-worker-utils@0.52.0", "", {}, "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw=="],
+
"ts-morph": ["ts-morph@26.0.0", "", { "dependencies": { "@ts-morph/common": "~0.27.0", "code-block-writer": "^13.0.3" } }, "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug=="],
"tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="],
@@ -1682,6 +1770,8 @@
"tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="],
+ "tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "^4.3.2" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="],
+
"turbo": ["turbo@2.8.10", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.10", "turbo-darwin-arm64": "2.8.10", "turbo-linux-64": "2.8.10", "turbo-linux-arm64": "2.8.10", "turbo-windows-64": "2.8.10", "turbo-windows-arm64": "2.8.10" }, "bin": { "turbo": "bin/turbo" } }, "sha512-OxbzDES66+x7nnKGg2MwBA1ypVsZoDTLHpeaP4giyiHSixbsiTaMyeJqbEyvBdp5Cm28fc+8GG6RdQtic0ijwQ=="],
"turbo-darwin-64": ["turbo-darwin-64@2.8.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-A03fXh+B7S8mL3PbdhTd+0UsaGrhfyPkODvzBDpKRY7bbeac4MDFpJ7I+Slf2oSkCEeSvHKR7Z4U71uKRUfX7g=="],
@@ -1730,6 +1820,8 @@
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+ "utility-types": ["utility-types@3.11.0", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="],
+
"validate-npm-package-name": ["validate-npm-package-name@7.0.2", "", {}, "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A=="],
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
@@ -1748,6 +1840,10 @@
"web-vitals": ["web-vitals@5.1.0", "", {}, "sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg=="],
+ "webgl-constants": ["webgl-constants@1.1.1", "", {}, "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="],
+
+ "webgl-sdf-generator": ["webgl-sdf-generator@1.1.1", "", {}, "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA=="],
+
"webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
"webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
@@ -1804,6 +1900,8 @@
"zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
+ "zustand": ["zustand@5.0.11", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg=="],
+
"@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
"@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
@@ -1858,9 +1956,11 @@
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+ "@tanstack/form-core/@tanstack/store": ["@tanstack/store@0.8.1", "", {}, "sha512-PtOisLjUZPz5VyPRSCGjNOlwTvabdTBQ2K80DpVL1chGVr35WRxfeavAPdNq6pm/t7F8GhoR2qtmkkqtCEtHYw=="],
+
"@tanstack/react-router/@tanstack/react-store": ["@tanstack/react-store@0.9.1", "", { "dependencies": { "@tanstack/store": "0.9.1", "use-sync-external-store": "^1.6.0" }, "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" } }, "sha512-YzJLnRvy5lIEFTLWBAZmcOjK3+2AepnBv/sr6NZmiqJvq7zTQggyK99Gw8fqYdMdHPQWXjz0epFKJXC+9V2xDA=="],
- "@tanstack/router-core/@tanstack/store": ["@tanstack/store@0.9.1", "", {}, "sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg=="],
+ "@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.8.1", "", {}, "sha512-PtOisLjUZPz5VyPRSCGjNOlwTvabdTBQ2K80DpVL1chGVr35WRxfeavAPdNq6pm/t7F8GhoR2qtmkkqtCEtHYw=="],
"@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
@@ -1932,6 +2032,8 @@
"restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
+ "router/is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
+
"router/path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="],
"shadcn/open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="],
@@ -1944,14 +2046,20 @@
"source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
+ "stats-gl/three": ["three@0.170.0", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="],
+
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
+ "three-stdlib/fflate": ["fflate@0.6.10", "", {}, "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg=="],
+
"tsx/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
+ "tunnel-rat/zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="],
+
"vite/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
"wrangler/@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.14.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "^1.20260218.0" }, "optionalPeers": ["workerd"] }, "sha512-XKAkWhi1nBdNsSEoNG9nkcbyvfUrSjSf+VYVPfOto3gLTZVc3F4g6RASCMh6IixBKCG2yDgZKQIHGKtjcnLnKg=="],
@@ -2046,8 +2154,6 @@
"@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
- "@tanstack/react-router/@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.9.1", "", {}, "sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg=="],
-
"cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
diff --git a/opencode.json b/opencode.json
index e27cda2..34bd115 100644
--- a/opencode.json
+++ b/opencode.json
@@ -1,27 +1,27 @@
{
- "$schema": "https://opencode.ai/config.json",
- "mcp": {
- "context7": {
- "type": "local",
- "command": ["npx", "-y", "@upstash/context7-mcp"],
- "enabled": true,
- "environment": {}
- },
- "cloudflare-docs": {
- "type": "remote",
- "url": "https://docs.mcp.cloudflare.com/sse",
- "enabled": true
- },
- "shadcn": {
- "type": "local",
- "command": ["npx", "-y", "shadcn@latest", "mcp"],
- "enabled": true,
- "environment": {}
- },
- "better-auth": {
- "type": "remote",
- "url": "https://mcp.inkeep.com/better-auth/mcp",
- "enabled": true
- }
- }
+ "$schema": "https://opencode.ai/config.json",
+ "mcp": {
+ "context7": {
+ "type": "local",
+ "command": ["npx", "-y", "@upstash/context7-mcp"],
+ "enabled": true,
+ "environment": {}
+ },
+ "cloudflare-docs": {
+ "type": "remote",
+ "url": "https://docs.mcp.cloudflare.com/sse",
+ "enabled": true
+ },
+ "shadcn": {
+ "type": "local",
+ "command": ["npx", "-y", "shadcn@latest", "mcp"],
+ "enabled": true,
+ "environment": {}
+ },
+ "better-auth": {
+ "type": "remote",
+ "url": "https://mcp.inkeep.com/better-auth/mcp",
+ "enabled": true
+ }
+ }
}
diff --git a/package.json b/package.json
index e5fe403..77b52a3 100644
--- a/package.json
+++ b/package.json
@@ -1,54 +1,54 @@
{
- "name": "kk",
- "private": true,
- "workspaces": {
- "packages": [
- "apps/*",
- "packages/*"
- ],
- "catalog": {
- "dotenv": "^17.2.2",
- "zod": "^4.1.13",
- "typescript": "^5",
- "@types/node": "^22.13.14",
- "@libsql/client": "0.15.15",
- "libsql": "0.5.22",
- "@orpc/server": "^1.12.2",
- "@orpc/client": "^1.12.2",
- "@orpc/openapi": "^1.12.2",
- "@orpc/zod": "^1.12.2",
- "better-auth": "^1.4.18",
- "alchemy": "^0.82.1"
- }
- },
- "type": "module",
- "scripts": {
- "dev": "turbo dev",
- "build": "turbo build",
- "check-types": "turbo check-types",
- "dev:native": "turbo -F native dev",
- "dev:web": "turbo -F web dev",
- "db:push": "turbo -F @kk/db db:push",
- "db:studio": "turbo -F @kk/db db:studio",
- "db:generate": "turbo -F @kk/db db:generate",
- "db:migrate": "turbo -F @kk/db db:migrate",
- "db:local": "turbo -F @kk/db db:local",
- "deploy": "turbo -F @kk/infra deploy",
- "destroy": "turbo -F @kk/infra destroy",
- "check": "biome check --write ."
- },
- "dependencies": {
- "@kk/env": "workspace:*",
- "dotenv": "catalog:",
- "zod": "catalog:"
- },
- "devDependencies": {
- "@biomejs/biome": "^2.2.0",
- "@cloudflare/workers-types": "^4.20251213.0",
- "@kk/config": "workspace:*",
- "@types/node": "catalog:",
- "turbo": "^2.6.3",
- "typescript": "catalog:"
- },
- "packageManager": "bun@1.3.8"
+ "name": "kk",
+ "private": true,
+ "workspaces": {
+ "packages": [
+ "apps/*",
+ "packages/*"
+ ],
+ "catalog": {
+ "dotenv": "^17.2.2",
+ "zod": "^4.1.13",
+ "typescript": "^5",
+ "@types/node": "^22.13.14",
+ "@libsql/client": "0.15.15",
+ "libsql": "0.5.22",
+ "@orpc/server": "^1.12.2",
+ "@orpc/client": "^1.12.2",
+ "@orpc/openapi": "^1.12.2",
+ "@orpc/zod": "^1.12.2",
+ "better-auth": "^1.4.18",
+ "alchemy": "^0.82.1"
+ }
+ },
+ "type": "module",
+ "scripts": {
+ "dev": "turbo dev",
+ "build": "turbo build",
+ "check-types": "turbo check-types",
+ "dev:native": "turbo -F native dev",
+ "dev:web": "turbo -F web dev",
+ "db:push": "turbo -F @kk/db db:push",
+ "db:studio": "turbo -F @kk/db db:studio",
+ "db:generate": "turbo -F @kk/db db:generate",
+ "db:migrate": "turbo -F @kk/db db:migrate",
+ "db:local": "turbo -F @kk/db db:local",
+ "deploy": "turbo -F @kk/infra deploy",
+ "destroy": "turbo -F @kk/infra destroy",
+ "check": "biome check --write ."
+ },
+ "dependencies": {
+ "@kk/env": "workspace:*",
+ "dotenv": "catalog:",
+ "zod": "catalog:"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "^2.2.0",
+ "@cloudflare/workers-types": "^4.20251213.0",
+ "@kk/config": "workspace:*",
+ "@types/node": "catalog:",
+ "turbo": "^2.6.3",
+ "typescript": "catalog:"
+ },
+ "packageManager": "bun@1.3.8"
}
diff --git a/packages/api/package.json b/packages/api/package.json
index 7f45131..8103a74 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -1,28 +1,28 @@
{
- "name": "@kk/api",
- "type": "module",
- "exports": {
- ".": {
- "default": "./src/index.ts"
- },
- "./*": {
- "default": "./src/*.ts"
- }
- },
- "scripts": {},
- "dependencies": {
- "@kk/auth": "workspace:*",
- "@kk/db": "workspace:*",
- "@kk/env": "workspace:*",
- "@orpc/client": "catalog:",
- "@orpc/openapi": "catalog:",
- "@orpc/server": "catalog:",
- "@orpc/zod": "catalog:",
- "dotenv": "catalog:",
- "zod": "catalog:"
- },
- "devDependencies": {
- "@kk/config": "workspace:*",
- "typescript": "catalog:"
- }
+ "name": "@kk/api",
+ "type": "module",
+ "exports": {
+ ".": {
+ "default": "./src/index.ts"
+ },
+ "./*": {
+ "default": "./src/*.ts"
+ }
+ },
+ "scripts": {},
+ "dependencies": {
+ "@kk/auth": "workspace:*",
+ "@kk/db": "workspace:*",
+ "@kk/env": "workspace:*",
+ "@orpc/client": "catalog:",
+ "@orpc/openapi": "catalog:",
+ "@orpc/server": "catalog:",
+ "@orpc/zod": "catalog:",
+ "dotenv": "catalog:",
+ "zod": "catalog:"
+ },
+ "devDependencies": {
+ "@kk/config": "workspace:*",
+ "typescript": "catalog:"
+ }
}
diff --git a/packages/api/src/context.ts b/packages/api/src/context.ts
index df0181a..7971df1 100644
--- a/packages/api/src/context.ts
+++ b/packages/api/src/context.ts
@@ -1,12 +1,12 @@
import { auth } from "@kk/auth";
export async function createContext({ req }: { req: Request }) {
- const session = await auth.api.getSession({
- headers: req.headers,
- });
- return {
- session,
- };
+ const session = await auth.api.getSession({
+ headers: req.headers,
+ });
+ return {
+ session,
+ };
}
export type Context = Awaited>;
diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts
index f1017a5..11d1f33 100644
--- a/packages/api/src/index.ts
+++ b/packages/api/src/index.ts
@@ -7,14 +7,14 @@ export const o = os.$context();
export const publicProcedure = o;
const requireAuth = o.middleware(async ({ context, next }) => {
- if (!context.session?.user) {
- throw new ORPCError("UNAUTHORIZED");
- }
- return next({
- context: {
- session: context.session,
- },
- });
+ if (!context.session?.user) {
+ throw new ORPCError("UNAUTHORIZED");
+ }
+ return next({
+ context: {
+ session: context.session,
+ },
+ });
});
export const protectedProcedure = publicProcedure.use(requireAuth);
diff --git a/packages/api/src/routers/index.ts b/packages/api/src/routers/index.ts
index 65d41dd..9d78fe1 100644
--- a/packages/api/src/routers/index.ts
+++ b/packages/api/src/routers/index.ts
@@ -3,15 +3,15 @@ import type { RouterClient } from "@orpc/server";
import { protectedProcedure, publicProcedure } from "../index";
export const appRouter = {
- healthCheck: publicProcedure.handler(() => {
- return "OK";
- }),
- privateData: protectedProcedure.handler(({ context }) => {
- return {
- message: "This is private",
- user: context.session?.user,
- };
- }),
+ healthCheck: publicProcedure.handler(() => {
+ return "OK";
+ }),
+ privateData: protectedProcedure.handler(({ context }) => {
+ return {
+ message: "This is private",
+ user: context.session?.user,
+ };
+ }),
};
export type AppRouter = typeof appRouter;
export type AppRouterClient = RouterClient;
diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json
index 7f4c489..67533c8 100644
--- a/packages/api/tsconfig.json
+++ b/packages/api/tsconfig.json
@@ -1,10 +1,10 @@
{
- "extends": "@kk/config/tsconfig.base.json",
- "compilerOptions": {
- "declaration": true,
- "declarationMap": true,
- "sourceMap": true,
- "outDir": "dist",
- "composite": true
- }
+ "extends": "@kk/config/tsconfig.base.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "outDir": "dist",
+ "composite": true
+ }
}
diff --git a/packages/auth/package.json b/packages/auth/package.json
index aabc68d..47c19eb 100644
--- a/packages/auth/package.json
+++ b/packages/auth/package.json
@@ -1,24 +1,24 @@
{
- "name": "@kk/auth",
- "type": "module",
- "exports": {
- ".": {
- "default": "./src/index.ts"
- },
- "./*": {
- "default": "./src/*.ts"
- }
- },
- "scripts": {},
- "dependencies": {
- "@kk/db": "workspace:*",
- "@kk/env": "workspace:*",
- "better-auth": "catalog:",
- "dotenv": "catalog:",
- "zod": "catalog:"
- },
- "devDependencies": {
- "@kk/config": "workspace:*",
- "typescript": "catalog:"
- }
+ "name": "@kk/auth",
+ "type": "module",
+ "exports": {
+ ".": {
+ "default": "./src/index.ts"
+ },
+ "./*": {
+ "default": "./src/*.ts"
+ }
+ },
+ "scripts": {},
+ "dependencies": {
+ "@kk/db": "workspace:*",
+ "@kk/env": "workspace:*",
+ "better-auth": "catalog:",
+ "dotenv": "catalog:",
+ "zod": "catalog:"
+ },
+ "devDependencies": {
+ "@kk/config": "workspace:*",
+ "typescript": "catalog:"
+ }
}
diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts
index f349f05..66415b6 100644
--- a/packages/auth/src/index.ts
+++ b/packages/auth/src/index.ts
@@ -6,14 +6,14 @@ import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { tanstackStartCookies } from "better-auth/tanstack-start";
export const auth = betterAuth({
- database: drizzleAdapter(db, {
- provider: "sqlite",
+ database: drizzleAdapter(db, {
+ provider: "sqlite",
- schema: schema,
- }),
- trustedOrigins: [env.CORS_ORIGIN],
- emailAndPassword: {
- enabled: true,
- },
- plugins: [tanstackStartCookies()],
+ schema: schema,
+ }),
+ trustedOrigins: [env.CORS_ORIGIN],
+ emailAndPassword: {
+ enabled: true,
+ },
+ plugins: [tanstackStartCookies()],
});
diff --git a/packages/auth/tsconfig.json b/packages/auth/tsconfig.json
index 7f4c489..67533c8 100644
--- a/packages/auth/tsconfig.json
+++ b/packages/auth/tsconfig.json
@@ -1,10 +1,10 @@
{
- "extends": "@kk/config/tsconfig.base.json",
- "compilerOptions": {
- "declaration": true,
- "declarationMap": true,
- "sourceMap": true,
- "outDir": "dist",
- "composite": true
- }
+ "extends": "@kk/config/tsconfig.base.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "outDir": "dist",
+ "composite": true
+ }
}
diff --git a/packages/config/package.json b/packages/config/package.json
index 3ad8084..27aaf44 100644
--- a/packages/config/package.json
+++ b/packages/config/package.json
@@ -1,5 +1,5 @@
{
- "name": "@kk/config",
- "version": "0.0.0",
- "private": true
+ "name": "@kk/config",
+ "version": "0.0.0",
+ "private": true
}
diff --git a/packages/config/tsconfig.base.json b/packages/config/tsconfig.base.json
index cb7ef83..f8787cd 100644
--- a/packages/config/tsconfig.base.json
+++ b/packages/config/tsconfig.base.json
@@ -1,22 +1,22 @@
{
- "$schema": "https://json.schemastore.org/tsconfig",
- "compilerOptions": {
- "target": "ESNext",
- "module": "ESNext",
- "moduleResolution": "bundler",
- "lib": ["ESNext"],
- "verbatimModuleSyntax": true,
- "strict": true,
- "skipLibCheck": true,
- "resolveJsonModule": true,
- "allowSyntheticDefaultImports": true,
- "esModuleInterop": true,
- "forceConsistentCasingInFileNames": true,
- "isolatedModules": true,
- "noUncheckedIndexedAccess": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true,
- "types": ["node", "@cloudflare/workers-types"]
- }
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "lib": ["ESNext"],
+ "verbatimModuleSyntax": true,
+ "strict": true,
+ "skipLibCheck": true,
+ "resolveJsonModule": true,
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "isolatedModules": true,
+ "noUncheckedIndexedAccess": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "types": ["node", "@cloudflare/workers-types"]
+ }
}
diff --git a/packages/db/drizzle.config.ts b/packages/db/drizzle.config.ts
index 55f9b46..96fc8bb 100644
--- a/packages/db/drizzle.config.ts
+++ b/packages/db/drizzle.config.ts
@@ -2,14 +2,14 @@ import dotenv from "dotenv";
import { defineConfig } from "drizzle-kit";
dotenv.config({
- path: "../../apps/web/.env",
+ path: "../../apps/web/.env",
});
export default defineConfig({
- schema: "./src/schema",
- out: "./src/migrations",
- dialect: "turso",
- dbCredentials: {
- url: process.env.DATABASE_URL || "",
- },
+ schema: "./src/schema",
+ out: "./src/migrations",
+ dialect: "turso",
+ dbCredentials: {
+ url: process.env.DATABASE_URL || "",
+ },
});
diff --git a/packages/db/package.json b/packages/db/package.json
index c2d70e6..1d052a6 100644
--- a/packages/db/package.json
+++ b/packages/db/package.json
@@ -1,32 +1,32 @@
{
- "name": "@kk/db",
- "type": "module",
- "exports": {
- ".": {
- "default": "./src/index.ts"
- },
- "./*": {
- "default": "./src/*.ts"
- }
- },
- "scripts": {
- "db:local": "turso dev --db-file local.db",
- "db:push": "drizzle-kit push",
- "db:generate": "drizzle-kit generate",
- "db:studio": "drizzle-kit studio",
- "db:migrate": "drizzle-kit migrate"
- },
- "dependencies": {
- "@kk/env": "workspace:*",
- "@libsql/client": "catalog:",
- "dotenv": "catalog:",
- "drizzle-orm": "^0.45.1",
- "libsql": "catalog:",
- "zod": "catalog:"
- },
- "devDependencies": {
- "@kk/config": "workspace:*",
- "drizzle-kit": "^0.31.8",
- "typescript": "catalog:"
- }
+ "name": "@kk/db",
+ "type": "module",
+ "exports": {
+ ".": {
+ "default": "./src/index.ts"
+ },
+ "./*": {
+ "default": "./src/*.ts"
+ }
+ },
+ "scripts": {
+ "db:local": "turso dev --db-file local.db",
+ "db:push": "drizzle-kit push",
+ "db:generate": "drizzle-kit generate",
+ "db:studio": "drizzle-kit studio",
+ "db:migrate": "drizzle-kit migrate"
+ },
+ "dependencies": {
+ "@kk/env": "workspace:*",
+ "@libsql/client": "catalog:",
+ "dotenv": "catalog:",
+ "drizzle-orm": "^0.45.1",
+ "libsql": "catalog:",
+ "zod": "catalog:"
+ },
+ "devDependencies": {
+ "@kk/config": "workspace:*",
+ "drizzle-kit": "^0.31.8",
+ "typescript": "catalog:"
+ }
}
diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts
index 1d30f75..601146a 100644
--- a/packages/db/src/index.ts
+++ b/packages/db/src/index.ts
@@ -5,7 +5,7 @@ import { drizzle } from "drizzle-orm/libsql";
import * as schema from "./schema";
const client = createClient({
- url: env.DATABASE_URL,
+ url: env.DATABASE_URL,
});
export const db = drizzle({ client, schema });
diff --git a/packages/db/src/schema/auth.ts b/packages/db/src/schema/auth.ts
index 8dd30b2..30e12e4 100644
--- a/packages/db/src/schema/auth.ts
+++ b/packages/db/src/schema/auth.ts
@@ -1,105 +1,107 @@
import { relations, sql } from "drizzle-orm";
-import { sqliteTable, text, integer, index } from "drizzle-orm/sqlite-core";
+import { index, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
- id: text("id").primaryKey(),
- name: text("name").notNull(),
- email: text("email").notNull().unique(),
- emailVerified: integer("email_verified", { mode: "boolean" }).default(false).notNull(),
- image: text("image"),
- createdAt: integer("created_at", { mode: "timestamp_ms" })
- .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
- .notNull(),
- updatedAt: integer("updated_at", { mode: "timestamp_ms" })
- .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
- .$onUpdate(() => /* @__PURE__ */ new Date())
- .notNull(),
+ id: text("id").primaryKey(),
+ name: text("name").notNull(),
+ email: text("email").notNull().unique(),
+ emailVerified: integer("email_verified", { mode: "boolean" })
+ .default(false)
+ .notNull(),
+ image: text("image"),
+ createdAt: integer("created_at", { mode: "timestamp_ms" })
+ .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
+ .notNull(),
+ updatedAt: integer("updated_at", { mode: "timestamp_ms" })
+ .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
+ .$onUpdate(() => /* @__PURE__ */ new Date())
+ .notNull(),
});
export const session = sqliteTable(
- "session",
- {
- id: text("id").primaryKey(),
- expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
- token: text("token").notNull().unique(),
- createdAt: integer("created_at", { mode: "timestamp_ms" })
- .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
- .notNull(),
- updatedAt: integer("updated_at", { mode: "timestamp_ms" })
- .$onUpdate(() => /* @__PURE__ */ new Date())
- .notNull(),
- ipAddress: text("ip_address"),
- userAgent: text("user_agent"),
- userId: text("user_id")
- .notNull()
- .references(() => user.id, { onDelete: "cascade" }),
- },
- (table) => [index("session_userId_idx").on(table.userId)],
+ "session",
+ {
+ id: text("id").primaryKey(),
+ expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
+ token: text("token").notNull().unique(),
+ createdAt: integer("created_at", { mode: "timestamp_ms" })
+ .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
+ .notNull(),
+ updatedAt: integer("updated_at", { mode: "timestamp_ms" })
+ .$onUpdate(() => /* @__PURE__ */ new Date())
+ .notNull(),
+ ipAddress: text("ip_address"),
+ userAgent: text("user_agent"),
+ userId: text("user_id")
+ .notNull()
+ .references(() => user.id, { onDelete: "cascade" }),
+ },
+ (table) => [index("session_userId_idx").on(table.userId)],
);
export const account = sqliteTable(
- "account",
- {
- id: text("id").primaryKey(),
- accountId: text("account_id").notNull(),
- providerId: text("provider_id").notNull(),
- userId: text("user_id")
- .notNull()
- .references(() => user.id, { onDelete: "cascade" }),
- accessToken: text("access_token"),
- refreshToken: text("refresh_token"),
- idToken: text("id_token"),
- accessTokenExpiresAt: integer("access_token_expires_at", {
- mode: "timestamp_ms",
- }),
- refreshTokenExpiresAt: integer("refresh_token_expires_at", {
- mode: "timestamp_ms",
- }),
- scope: text("scope"),
- password: text("password"),
- createdAt: integer("created_at", { mode: "timestamp_ms" })
- .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
- .notNull(),
- updatedAt: integer("updated_at", { mode: "timestamp_ms" })
- .$onUpdate(() => /* @__PURE__ */ new Date())
- .notNull(),
- },
- (table) => [index("account_userId_idx").on(table.userId)],
+ "account",
+ {
+ id: text("id").primaryKey(),
+ accountId: text("account_id").notNull(),
+ providerId: text("provider_id").notNull(),
+ userId: text("user_id")
+ .notNull()
+ .references(() => user.id, { onDelete: "cascade" }),
+ accessToken: text("access_token"),
+ refreshToken: text("refresh_token"),
+ idToken: text("id_token"),
+ accessTokenExpiresAt: integer("access_token_expires_at", {
+ mode: "timestamp_ms",
+ }),
+ refreshTokenExpiresAt: integer("refresh_token_expires_at", {
+ mode: "timestamp_ms",
+ }),
+ scope: text("scope"),
+ password: text("password"),
+ createdAt: integer("created_at", { mode: "timestamp_ms" })
+ .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
+ .notNull(),
+ updatedAt: integer("updated_at", { mode: "timestamp_ms" })
+ .$onUpdate(() => /* @__PURE__ */ new Date())
+ .notNull(),
+ },
+ (table) => [index("account_userId_idx").on(table.userId)],
);
export const verification = sqliteTable(
- "verification",
- {
- id: text("id").primaryKey(),
- identifier: text("identifier").notNull(),
- value: text("value").notNull(),
- expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
- createdAt: integer("created_at", { mode: "timestamp_ms" })
- .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
- .notNull(),
- updatedAt: integer("updated_at", { mode: "timestamp_ms" })
- .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
- .$onUpdate(() => /* @__PURE__ */ new Date())
- .notNull(),
- },
- (table) => [index("verification_identifier_idx").on(table.identifier)],
+ "verification",
+ {
+ id: text("id").primaryKey(),
+ identifier: text("identifier").notNull(),
+ value: text("value").notNull(),
+ expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
+ createdAt: integer("created_at", { mode: "timestamp_ms" })
+ .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
+ .notNull(),
+ updatedAt: integer("updated_at", { mode: "timestamp_ms" })
+ .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)
+ .$onUpdate(() => /* @__PURE__ */ new Date())
+ .notNull(),
+ },
+ (table) => [index("verification_identifier_idx").on(table.identifier)],
);
export const userRelations = relations(user, ({ many }) => ({
- sessions: many(session),
- accounts: many(account),
+ sessions: many(session),
+ accounts: many(account),
}));
export const sessionRelations = relations(session, ({ one }) => ({
- user: one(user, {
- fields: [session.userId],
- references: [user.id],
- }),
+ user: one(user, {
+ fields: [session.userId],
+ references: [user.id],
+ }),
}));
export const accountRelations = relations(account, ({ one }) => ({
- user: one(user, {
- fields: [account.userId],
- references: [user.id],
- }),
+ user: one(user, {
+ fields: [account.userId],
+ references: [user.id],
+ }),
}));
diff --git a/packages/db/src/schema/index.ts b/packages/db/src/schema/index.ts
index d9d31ea..97ccf76 100644
--- a/packages/db/src/schema/index.ts
+++ b/packages/db/src/schema/index.ts
@@ -1,2 +1 @@
export * from "./auth";
-export {};
diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json
index 7f4c489..67533c8 100644
--- a/packages/db/tsconfig.json
+++ b/packages/db/tsconfig.json
@@ -1,10 +1,10 @@
{
- "extends": "@kk/config/tsconfig.base.json",
- "compilerOptions": {
- "declaration": true,
- "declarationMap": true,
- "sourceMap": true,
- "outDir": "dist",
- "composite": true
- }
+ "extends": "@kk/config/tsconfig.base.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "outDir": "dist",
+ "composite": true
+ }
}
diff --git a/packages/env/package.json b/packages/env/package.json
index 0ddc37a..2718d2c 100644
--- a/packages/env/package.json
+++ b/packages/env/package.json
@@ -1,21 +1,21 @@
{
- "name": "@kk/env",
- "version": "0.0.0",
- "private": true,
- "type": "module",
- "exports": {
- "./server": "./src/server.ts",
- "./web": "./src/web.ts"
- },
- "dependencies": {
- "@t3-oss/env-core": "^0.13.1",
- "dotenv": "catalog:",
- "zod": "catalog:"
- },
- "devDependencies": {
- "@kk/config": "workspace:*",
- "@kk/infra": "workspace:*",
- "@types/node": "catalog:",
- "typescript": "catalog:"
- }
+ "name": "@kk/env",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "exports": {
+ "./server": "./src/server.ts",
+ "./web": "./src/web.ts"
+ },
+ "dependencies": {
+ "@t3-oss/env-core": "^0.13.1",
+ "dotenv": "catalog:",
+ "zod": "catalog:"
+ },
+ "devDependencies": {
+ "@kk/config": "workspace:*",
+ "@kk/infra": "workspace:*",
+ "@types/node": "catalog:",
+ "typescript": "catalog:"
+ }
}
diff --git a/packages/env/src/server.ts b/packages/env/src/server.ts
index 7df2ad1..cee1323 100644
--- a/packages/env/src/server.ts
+++ b/packages/env/src/server.ts
@@ -3,13 +3,15 @@ import { createEnv } from "@t3-oss/env-core";
import { z } from "zod";
export const env = createEnv({
- server: {
- DATABASE_URL: z.string().min(1),
- BETTER_AUTH_SECRET: z.string().min(32),
- BETTER_AUTH_URL: z.url(),
- CORS_ORIGIN: z.url(),
- NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
- },
- runtimeEnv: process.env,
- emptyStringAsUndefined: true,
+ server: {
+ DATABASE_URL: z.string().min(1),
+ BETTER_AUTH_SECRET: z.string().min(32),
+ BETTER_AUTH_URL: z.url(),
+ CORS_ORIGIN: z.url(),
+ NODE_ENV: z
+ .enum(["development", "production", "test"])
+ .default("development"),
+ },
+ runtimeEnv: process.env,
+ emptyStringAsUndefined: true,
});
diff --git a/packages/env/src/web.ts b/packages/env/src/web.ts
index b522469..05d11da 100644
--- a/packages/env/src/web.ts
+++ b/packages/env/src/web.ts
@@ -1,9 +1,9 @@
import { createEnv } from "@t3-oss/env-core";
-import { z } from "zod";
export const env = createEnv({
- clientPrefix: "VITE_",
- client: {},
- runtimeEnv: (import.meta as any).env,
- emptyStringAsUndefined: true,
+ clientPrefix: "VITE_",
+ client: {},
+ // biome-ignore lint/suspicious/noExplicitAny: Vite's import.meta.env doesn't have proper types
+ runtimeEnv: (import.meta as any).env,
+ emptyStringAsUndefined: true,
});
diff --git a/packages/env/tsconfig.json b/packages/env/tsconfig.json
index b0ce18d..27c8ec4 100644
--- a/packages/env/tsconfig.json
+++ b/packages/env/tsconfig.json
@@ -1,3 +1,3 @@
{
- "extends": "@kk/config/tsconfig.base.json"
+ "extends": "@kk/config/tsconfig.base.json"
}
diff --git a/packages/infra/alchemy.run.ts b/packages/infra/alchemy.run.ts
index 5499a9b..d2a849a 100644
--- a/packages/infra/alchemy.run.ts
+++ b/packages/infra/alchemy.run.ts
@@ -7,14 +7,23 @@ config({ path: "../../apps/web/.env" });
const app = await alchemy("kk");
+// Helper function to get required env var
+function getEnvVar(name: string): string {
+ const value = process.env[name];
+ if (!value) {
+ throw new Error(`Missing required environment variable: ${name}`);
+ }
+ return value;
+}
+
export const web = await TanStackStart("web", {
- cwd: "../../apps/web",
- bindings: {
- DATABASE_URL: alchemy.secret.env.DATABASE_URL!,
- CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,
- BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,
- BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!,
- },
+ cwd: "../../apps/web",
+ bindings: {
+ DATABASE_URL: getEnvVar("DATABASE_URL"),
+ CORS_ORIGIN: getEnvVar("CORS_ORIGIN"),
+ BETTER_AUTH_SECRET: getEnvVar("BETTER_AUTH_SECRET"),
+ BETTER_AUTH_URL: getEnvVar("BETTER_AUTH_URL"),
+ },
});
console.log(`Web -> ${web.url}`);
diff --git a/packages/infra/package.json b/packages/infra/package.json
index 7bfc073..d1480e5 100644
--- a/packages/infra/package.json
+++ b/packages/infra/package.json
@@ -1,19 +1,19 @@
{
- "name": "@kk/infra",
- "private": true,
- "type": "module",
- "scripts": {
- "dev": "alchemy dev",
- "deploy": "alchemy deploy",
- "destroy": "alchemy destroy"
- },
- "dependencies": {
- "dotenv": "catalog:",
- "zod": "catalog:"
- },
- "devDependencies": {
- "@kk/config": "workspace:*",
- "alchemy": "catalog:",
- "typescript": "catalog:"
- }
+ "name": "@kk/infra",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "alchemy dev",
+ "deploy": "alchemy deploy",
+ "destroy": "alchemy destroy"
+ },
+ "dependencies": {
+ "dotenv": "catalog:",
+ "zod": "catalog:"
+ },
+ "devDependencies": {
+ "@kk/config": "workspace:*",
+ "alchemy": "catalog:",
+ "typescript": "catalog:"
+ }
}
diff --git a/skills-lock.json b/skills-lock.json
index 9f8287d..2caa06b 100644
--- a/skills-lock.json
+++ b/skills-lock.json
@@ -1,30 +1,30 @@
{
- "version": 1,
- "skills": {
- "better-auth-best-practices": {
- "source": "better-auth/skills",
- "sourceType": "github",
- "computedHash": "a24359053259e55a75972cab4bf0b0e37e1393bac5f3756ec2e3a7b4b3778d2a"
- },
- "turborepo": {
- "source": "vercel/turborepo",
- "sourceType": "github",
- "computedHash": "47e8b1424c901cd0f5530328cb7448c8828b19063997ea4a4b03164bbdc0fd39"
- },
- "vercel-composition-patterns": {
- "source": "vercel-labs/agent-skills",
- "sourceType": "github",
- "computedHash": "f98931159fa9c7fed043bcd18a891a46dcf89ababa38df13a4c5b7b30dc0ce07"
- },
- "vercel-react-best-practices": {
- "source": "vercel-labs/agent-skills",
- "sourceType": "github",
- "computedHash": "4365be772fd3b41994a72ad478472c6d680678e7f3859860ab010e9c46e48ee0"
- },
- "web-design-guidelines": {
- "source": "vercel-labs/agent-skills",
- "sourceType": "github",
- "computedHash": "a6a44d5498f7e8f68289902f3dedfc6f38ae0cee1e96527c80724cf27f727c2a"
- }
- }
+ "version": 1,
+ "skills": {
+ "better-auth-best-practices": {
+ "source": "better-auth/skills",
+ "sourceType": "github",
+ "computedHash": "a24359053259e55a75972cab4bf0b0e37e1393bac5f3756ec2e3a7b4b3778d2a"
+ },
+ "turborepo": {
+ "source": "vercel/turborepo",
+ "sourceType": "github",
+ "computedHash": "47e8b1424c901cd0f5530328cb7448c8828b19063997ea4a4b03164bbdc0fd39"
+ },
+ "vercel-composition-patterns": {
+ "source": "vercel-labs/agent-skills",
+ "sourceType": "github",
+ "computedHash": "f98931159fa9c7fed043bcd18a891a46dcf89ababa38df13a4c5b7b30dc0ce07"
+ },
+ "vercel-react-best-practices": {
+ "source": "vercel-labs/agent-skills",
+ "sourceType": "github",
+ "computedHash": "4365be772fd3b41994a72ad478472c6d680678e7f3859860ab010e9c46e48ee0"
+ },
+ "web-design-guidelines": {
+ "source": "vercel-labs/agent-skills",
+ "sourceType": "github",
+ "computedHash": "a6a44d5498f7e8f68289902f3dedfc6f38ae0cee1e96527c80724cf27f727c2a"
+ }
+ }
}
diff --git a/tsconfig.json b/tsconfig.json
index b0ce18d..27c8ec4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,3 +1,3 @@
{
- "extends": "@kk/config/tsconfig.base.json"
+ "extends": "@kk/config/tsconfig.base.json"
}
diff --git a/turbo.json b/turbo.json
index c687a74..7dc44e0 100644
--- a/turbo.json
+++ b/turbo.json
@@ -1,44 +1,44 @@
{
- "$schema": "https://turbo.build/schema.json",
- "ui": "tui",
- "tasks": {
- "build": {
- "dependsOn": ["^build"],
- "inputs": ["$TURBO_DEFAULT$", ".env*"],
- "outputs": ["dist/**"]
- },
- "lint": {
- "dependsOn": ["^lint"]
- },
- "check-types": {
- "dependsOn": ["^check-types"]
- },
- "dev": {
- "cache": false,
- "persistent": true
- },
- "db:push": {
- "cache": false
- },
- "db:generate": {
- "cache": false
- },
- "db:migrate": {
- "cache": false,
- "persistent": true
- },
- "db:studio": {
- "cache": false,
- "persistent": true
- },
- "db:local": {
- "cache": false
- },
- "deploy": {
- "cache": false
- },
- "destroy": {
- "cache": false
- }
- }
+ "$schema": "https://turbo.build/schema.json",
+ "ui": "tui",
+ "tasks": {
+ "build": {
+ "dependsOn": ["^build"],
+ "inputs": ["$TURBO_DEFAULT$", ".env*"],
+ "outputs": ["dist/**"]
+ },
+ "lint": {
+ "dependsOn": ["^lint"]
+ },
+ "check-types": {
+ "dependsOn": ["^check-types"]
+ },
+ "dev": {
+ "cache": false,
+ "persistent": true
+ },
+ "db:push": {
+ "cache": false
+ },
+ "db:generate": {
+ "cache": false
+ },
+ "db:migrate": {
+ "cache": false,
+ "persistent": true
+ },
+ "db:studio": {
+ "cache": false,
+ "persistent": true
+ },
+ "db:local": {
+ "cache": false
+ },
+ "deploy": {
+ "cache": false
+ },
+ "destroy": {
+ "cache": false
+ }
+ }
}