diff --git a/.env.example b/.env.example index 8afe26f..1a596de 100644 --- a/.env.example +++ b/.env.example @@ -38,8 +38,8 @@ BACKEND_URL=http://localhost:1284 TRUSTED_ORIGINS=http://localhost:3000 # URLs for Next.js client side -NEXT_PUBLIC_BACKEND_URL=http://localhost:1284 -NEXT_PUBLIC_FRONTEND_URL=http://localhost:3000 +VITE_PUBLIC_BACKEND_URL=http://localhost:1284 +VITE_PUBLIC_FRONTEND_URL=http://localhost:3000 # Database. Make sure the user, password, and database name match the ones in the url DATABASE_URL=postgres://postgres:postgres@localhost:5432/nimbus diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index e151057..cc44724 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -175,8 +175,8 @@ jobs: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} NODE_ENV: ${{ secrets.NODE_ENV }} - NEXT_PUBLIC_BACKEND_URL: ${{ secrets.NEXT_PUBLIC_BACKEND_URL }} - NEXT_PUBLIC_FRONTEND_URL: ${{ secrets.NEXT_PUBLIC_FRONTEND_URL }} + VITE_PUBLIC_BACKEND_URL: ${{ secrets.VITE_PUBLIC_BACKEND_URL }} + VITE_PUBLIC_FRONTEND_URL: ${{ secrets.VITE_PUBLIC_FRONTEND_URL }} run: | cd apps/web bun run cf:build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a62ded..89e0d49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,8 +58,8 @@ jobs: env: NODE_ENV: production DATABASE_URL: postgres://postgres:postgres@localhost:5432/nimbus-test - NEXT_PUBLIC_BACKEND_URL: http://localhost:1284 - NEXT_PUBLIC_FRONTEND_URL: http://localhost:3000 + VITE_PUBLIC_BACKEND_URL: http://localhost:1284 + VITE_PUBLIC_FRONTEND_URL: http://localhost:3000 run: bun run build - name: Create coverage badge diff --git a/.rules/GENERAL.md b/.rules/GENERAL.md index c74ec3f..6ba679e 100644 --- a/.rules/GENERAL.md +++ b/.rules/GENERAL.md @@ -1 +1,2 @@ - Only do the minimum required changes to accomplish the stated task. +- Do not write up a document at the end of your process diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index eb7fe68..2787647 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -40,8 +40,8 @@ Nimbus requires the following environment variables to work, some will be pre-fi - `WEB_PORT` - `BACKEND_URL` - `TRUSTED_ORIGINS` -- `NEXT_PUBLIC_BACKEND_URL` -- `NEXT_PUBLIC_FRONTEND_URL` +- `VITE_PUBLIC_BACKEND_URL` +- `VITE_PUBLIC_FRONTEND_URL` - `DATABASE_URL` - `DATABASE_HOST` - `POSTGRES_PORT` @@ -57,8 +57,8 @@ Nimbus requires the following environment variables to work, some will be pre-fi - `EMAIL_FROM` - `RESEND_API_KEY` -- `NEXT_PUBLIC_POSTHOG_KEY` -- `NEXT_PUBLIC_POSTHOG_HOST` +- `VITE_PUBLIC_POSTHOG_KEY` +- `VITE_PUBLIC_POSTHOG_HOST` ### 3. Start Services diff --git a/apps/server/src/utils/encryption.ts b/apps/server/src/utils/encryption.ts index bb54409..076196b 100644 --- a/apps/server/src/utils/encryption.ts +++ b/apps/server/src/utils/encryption.ts @@ -1,7 +1,8 @@ import { createCipheriv, createDecipheriv, randomBytes, createHash } from "crypto"; +import { env } from "@nimbus/env/server"; const ENCRYPTION_ALGORITHM = "aes-256-cbc"; -const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY; +const ENCRYPTION_KEY = env.ENCRYPTION_KEY; function deriveKey(): Buffer { if (!ENCRYPTION_KEY) { diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 12e74ee..628ee64 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -2,11 +2,11 @@ FROM oven/bun AS builder WORKDIR /app -ARG NEXT_PUBLIC_BACKEND_URL -ARG NEXT_PUBLIC_FRONTEND_URL +ARG VITE_PUBLIC_BACKEND_URL +ARG VITE_PUBLIC_FRONTEND_URL -ENV NEXT_PUBLIC_BACKEND_URL=${NEXT_PUBLIC_BACKEND_URL} -ENV NEXT_PUBLIC_FRONTEND_URL=${NEXT_PUBLIC_FRONTEND_URL} +ENV VITE_PUBLIC_BACKEND_URL=${VITE_PUBLIC_BACKEND_URL} +ENV VITE_PUBLIC_FRONTEND_URL=${VITE_PUBLIC_FRONTEND_URL} # Copy package files for dependency installation COPY package.json bun.lock ./ @@ -36,8 +36,8 @@ WORKDIR /app # Set environment variables ENV NODE_ENV=production ENV PORT=3000 -ENV NEXT_PUBLIC_BACKEND_URL=${NEXT_PUBLIC_BACKEND_URL} -ENV NEXT_PUBLIC_FRONTEND_URL=${NEXT_PUBLIC_FRONTEND_URL} +ENV VITE_PUBLIC_BACKEND_URL=${VITE_PUBLIC_BACKEND_URL} +ENV VITE_PUBLIC_FRONTEND_URL=${VITE_PUBLIC_FRONTEND_URL} # Create non-root user RUN groupadd -r nodejs && useradd -r -g nodejs nodejs diff --git a/apps/web/package.json b/apps/web/package.json index cdf3984..83d941e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -33,6 +33,7 @@ "@radix-ui/react-tabs": "^1.1.12", "@radix-ui/react-tooltip": "^1.2.7", "@t3-oss/env-core": "^0.13.8", + "@tailwindcss/postcss": "^4.1.14", "@tanstack/react-query": "^5.83.0", "@tanstack/react-query-devtools": "^5.84.1", "@tanstack/react-router-devtools": "^1.133.0", diff --git a/apps/web/src/components/auth/verify-email-content.tsx b/apps/web/src/components/auth/verify-email-content.tsx index 2e58a28..2727b69 100644 --- a/apps/web/src/components/auth/verify-email-content.tsx +++ b/apps/web/src/components/auth/verify-email-content.tsx @@ -23,7 +23,7 @@ export function VerifyEmailContent({ ...props }: ComponentProps<"div">) { if (!token) return; setIsLoading(true); try { - await axios.get(`${env.NEXT_PUBLIC_BACKEND_URL}/api/auth/verify-email`, { + await axios.get(`${env.VITE_PUBLIC_BACKEND_URL}/api/auth/verify-email`, { withCredentials: true, params: { token, diff --git a/apps/web/src/components/providers/posthog-provider.tsx b/apps/web/src/components/providers/posthog-provider.tsx index d9229d6..588376d 100644 --- a/apps/web/src/components/providers/posthog-provider.tsx +++ b/apps/web/src/components/providers/posthog-provider.tsx @@ -7,8 +7,8 @@ import posthog from "posthog-js"; export function PHProvider({ children }: { children: ReactNode }) { useEffect(() => { - posthog.init(env.NEXT_PUBLIC_POSTHOG_KEY!, { - api_host: env.NEXT_PUBLIC_POSTHOG_HOST, + posthog.init(env.VITE_PUBLIC_POSTHOG_KEY, { + api_host: env.VITE_PUBLIC_POSTHOG_HOST, capture_pageview: false, // Disable automatic pageview capture, as we capture manually defaults: "2025-05-24", }); diff --git a/apps/web/src/components/settings/s3-account-form.tsx b/apps/web/src/components/settings/s3-account-form.tsx index ba5848a..fbd81e6 100644 --- a/apps/web/src/components/settings/s3-account-form.tsx +++ b/apps/web/src/components/settings/s3-account-form.tsx @@ -9,6 +9,7 @@ import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Loader2 } from "lucide-react"; +import env from "@nimbus/env/client"; import { useState } from "react"; type S3AccountFormProps = { @@ -46,7 +47,7 @@ export function S3AccountForm({ onSuccess, onCancel }: S3AccountFormProps) { nickname: formData.nickname || null, // Ensure null for empty nickname }; - const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL; + const backendUrl = env.VITE_PUBLIC_BACKEND_URL; if (!backendUrl) { throw new Error("Backend URL is not configured"); } diff --git a/apps/web/src/hooks/useAuth.ts b/apps/web/src/hooks/useAuth.ts index 5abf454..b8cd675 100644 --- a/apps/web/src/hooks/useAuth.ts +++ b/apps/web/src/hooks/useAuth.ts @@ -24,13 +24,13 @@ interface AuthState { const signInWithProvider = async (provider: DriveProvider) => { return authClient.signIn.social({ provider, - callbackURL: `${env.NEXT_PUBLIC_FRONTEND_URL}/dashboard`, + callbackURL: `${env.VITE_PUBLIC_FRONTEND_URL}/dashboard`, }); }; const linkSessionWithProvider = async ( provider: DriveProvider, - callbackURL: string = `${env.NEXT_PUBLIC_FRONTEND_URL}/dashboard` + callbackURL: string = `${env.VITE_PUBLIC_FRONTEND_URL}/dashboard` ) => { return authClient.linkSocial({ provider, @@ -200,7 +200,7 @@ export const useSignUp = () => { name: fullName, email: data.email, password: data.password, - callbackURL: `${env.NEXT_PUBLIC_FRONTEND_URL}/dashboard`, + callbackURL: `${env.VITE_PUBLIC_FRONTEND_URL}/dashboard`, }); redirectToDashboard(); }, diff --git a/apps/web/src/lib/utils.ts b/apps/web/src/lib/utils.ts index 3d6f916..1df5dd4 100644 --- a/apps/web/src/lib/utils.ts +++ b/apps/web/src/lib/utils.ts @@ -13,7 +13,7 @@ export function cn(...inputs: ClassValue[]) { * Gets the base URL for the frontend */ export const getBaseUrl = () => { - return env.NEXT_PUBLIC_FRONTEND_URL; + return env.VITE_PUBLIC_FRONTEND_URL; }; /** diff --git a/apps/web/src/routeTree.gen.ts b/apps/web/src/routeTree.gen.ts index 647c7e7..a01512c 100644 --- a/apps/web/src/routeTree.gen.ts +++ b/apps/web/src/routeTree.gen.ts @@ -8,381 +8,390 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -import { Route as ProtectedDashboardProviderSlugAccountIdRouteImport } from "./routes/_protected/dashboard/$providerSlug.$accountId"; -import { Route as ProtectedDashboardSettingsRouteImport } from "./routes/_protected/dashboard/settings"; -import { Route as ProtectedDashboardIndexRouteImport } from "./routes/_protected/dashboard/index"; -import { Route as PublicForgotPasswordRouteImport } from "./routes/_public/forgot-password"; -import { Route as PublicResetPasswordRouteImport } from "./routes/_public/reset-password"; -import { Route as PublicContributorsRouteImport } from "./routes/_public/contributors"; -import { Route as ProtectedDashboardRouteImport } from "./routes/_protected/dashboard"; -import { Route as PublicVerifyEmailRouteImport } from "./routes/_public/verify-email"; -import { Route as PublicPrivacyRouteImport } from "./routes/_public/privacy"; -import { Route as PublicSignupRouteImport } from "./routes/_public/signup"; -import { Route as PublicSigninRouteImport } from "./routes/_public/signin"; -import { Route as PublicTermsRouteImport } from "./routes/_public/terms"; -import { Route as ProtectedRouteImport } from "./routes/_protected"; -import { Route as PublicRouteImport } from "./routes/_public"; -import { Route as rootRouteImport } from "./routes/__root"; -import { Route as IndexRouteImport } from "./routes/index"; -import { Route as DebugRouteImport } from "./routes/debug"; +import { Route as rootRouteImport } from "./routes/__root" +import { Route as DebugRouteImport } from "./routes/debug" +import { Route as PublicRouteImport } from "./routes/_public" +import { Route as ProtectedRouteImport } from "./routes/_protected" +import { Route as IndexRouteImport } from "./routes/index" +import { Route as PublicVerifyEmailRouteImport } from "./routes/_public/verify-email" +import { Route as PublicTermsRouteImport } from "./routes/_public/terms" +import { Route as PublicSignupRouteImport } from "./routes/_public/signup" +import { Route as PublicSigninRouteImport } from "./routes/_public/signin" +import { Route as PublicResetPasswordRouteImport } from "./routes/_public/reset-password" +import { Route as PublicPrivacyRouteImport } from "./routes/_public/privacy" +import { Route as PublicForgotPasswordRouteImport } from "./routes/_public/forgot-password" +import { Route as PublicContributorsRouteImport } from "./routes/_public/contributors" +import { Route as ProtectedDashboardRouteImport } from "./routes/_protected/dashboard" +import { Route as ProtectedDashboardIndexRouteImport } from "./routes/_protected/dashboard/index" +import { Route as ProtectedDashboardSettingsRouteImport } from "./routes/_protected/dashboard/settings" +import { Route as ProtectedDashboardProviderSlugAccountIdRouteImport } from "./routes/_protected/dashboard/$providerSlug.$accountId" const DebugRoute = DebugRouteImport.update({ - id: "/debug", - path: "/debug", - getParentRoute: () => rootRouteImport, -} as any); + id: "/debug", + path: "/debug", + getParentRoute: () => rootRouteImport, +} as any) const PublicRoute = PublicRouteImport.update({ - id: "/_public", - getParentRoute: () => rootRouteImport, -} as any); + id: "/_public", + getParentRoute: () => rootRouteImport, +} as any) const ProtectedRoute = ProtectedRouteImport.update({ - id: "/_protected", - getParentRoute: () => rootRouteImport, -} as any); + id: "/_protected", + getParentRoute: () => rootRouteImport, +} as any) const IndexRoute = IndexRouteImport.update({ - id: "/", - path: "/", - getParentRoute: () => rootRouteImport, -} as any); + id: "/", + path: "/", + getParentRoute: () => rootRouteImport, +} as any) const PublicVerifyEmailRoute = PublicVerifyEmailRouteImport.update({ - id: "/verify-email", - path: "/verify-email", - getParentRoute: () => PublicRoute, -} as any); + id: "/verify-email", + path: "/verify-email", + getParentRoute: () => PublicRoute, +} as any) const PublicTermsRoute = PublicTermsRouteImport.update({ - id: "/terms", - path: "/terms", - getParentRoute: () => PublicRoute, -} as any); + id: "/terms", + path: "/terms", + getParentRoute: () => PublicRoute, +} as any) const PublicSignupRoute = PublicSignupRouteImport.update({ - id: "/signup", - path: "/signup", - getParentRoute: () => PublicRoute, -} as any); + id: "/signup", + path: "/signup", + getParentRoute: () => PublicRoute, +} as any) const PublicSigninRoute = PublicSigninRouteImport.update({ - id: "/signin", - path: "/signin", - getParentRoute: () => PublicRoute, -} as any); + id: "/signin", + path: "/signin", + getParentRoute: () => PublicRoute, +} as any) const PublicResetPasswordRoute = PublicResetPasswordRouteImport.update({ - id: "/reset-password", - path: "/reset-password", - getParentRoute: () => PublicRoute, -} as any); + id: "/reset-password", + path: "/reset-password", + getParentRoute: () => PublicRoute, +} as any) const PublicPrivacyRoute = PublicPrivacyRouteImport.update({ - id: "/privacy", - path: "/privacy", - getParentRoute: () => PublicRoute, -} as any); + id: "/privacy", + path: "/privacy", + getParentRoute: () => PublicRoute, +} as any) const PublicForgotPasswordRoute = PublicForgotPasswordRouteImport.update({ - id: "/forgot-password", - path: "/forgot-password", - getParentRoute: () => PublicRoute, -} as any); + id: "/forgot-password", + path: "/forgot-password", + getParentRoute: () => PublicRoute, +} as any) const PublicContributorsRoute = PublicContributorsRouteImport.update({ - id: "/contributors", - path: "/contributors", - getParentRoute: () => PublicRoute, -} as any); + id: "/contributors", + path: "/contributors", + getParentRoute: () => PublicRoute, +} as any) const ProtectedDashboardRoute = ProtectedDashboardRouteImport.update({ - id: "/dashboard", - path: "/dashboard", - getParentRoute: () => ProtectedRoute, -} as any); + id: "/dashboard", + path: "/dashboard", + getParentRoute: () => ProtectedRoute, +} as any) const ProtectedDashboardIndexRoute = ProtectedDashboardIndexRouteImport.update({ - id: "/", - path: "/", - getParentRoute: () => ProtectedDashboardRoute, -} as any); -const ProtectedDashboardSettingsRoute = ProtectedDashboardSettingsRouteImport.update({ - id: "/settings", - path: "/settings", - getParentRoute: () => ProtectedDashboardRoute, -} as any); -const ProtectedDashboardProviderSlugAccountIdRoute = ProtectedDashboardProviderSlugAccountIdRouteImport.update({ - id: "/$providerSlug/$accountId", - path: "/$providerSlug/$accountId", - getParentRoute: () => ProtectedDashboardRoute, -} as any); + id: "/", + path: "/", + getParentRoute: () => ProtectedDashboardRoute, +} as any) +const ProtectedDashboardSettingsRoute = + ProtectedDashboardSettingsRouteImport.update({ + id: "/settings", + path: "/settings", + getParentRoute: () => ProtectedDashboardRoute, + } as any) +const ProtectedDashboardProviderSlugAccountIdRoute = + ProtectedDashboardProviderSlugAccountIdRouteImport.update({ + id: "/$providerSlug/$accountId", + path: "/$providerSlug/$accountId", + getParentRoute: () => ProtectedDashboardRoute, + } as any) export interface FileRoutesByFullPath { - "/": typeof IndexRoute; - "/debug": typeof DebugRoute; - "/dashboard": typeof ProtectedDashboardRouteWithChildren; - "/contributors": typeof PublicContributorsRoute; - "/forgot-password": typeof PublicForgotPasswordRoute; - "/privacy": typeof PublicPrivacyRoute; - "/reset-password": typeof PublicResetPasswordRoute; - "/signin": typeof PublicSigninRoute; - "/signup": typeof PublicSignupRoute; - "/terms": typeof PublicTermsRoute; - "/verify-email": typeof PublicVerifyEmailRoute; - "/dashboard/settings": typeof ProtectedDashboardSettingsRoute; - "/dashboard/": typeof ProtectedDashboardIndexRoute; - "/dashboard/$providerSlug/$accountId": typeof ProtectedDashboardProviderSlugAccountIdRoute; + "/": typeof IndexRoute + "/debug": typeof DebugRoute + "/dashboard": typeof ProtectedDashboardRouteWithChildren + "/contributors": typeof PublicContributorsRoute + "/forgot-password": typeof PublicForgotPasswordRoute + "/privacy": typeof PublicPrivacyRoute + "/reset-password": typeof PublicResetPasswordRoute + "/signin": typeof PublicSigninRoute + "/signup": typeof PublicSignupRoute + "/terms": typeof PublicTermsRoute + "/verify-email": typeof PublicVerifyEmailRoute + "/dashboard/settings": typeof ProtectedDashboardSettingsRoute + "/dashboard/": typeof ProtectedDashboardIndexRoute + "/dashboard/$providerSlug/$accountId": typeof ProtectedDashboardProviderSlugAccountIdRoute } export interface FileRoutesByTo { - "/": typeof IndexRoute; - "/debug": typeof DebugRoute; - "/contributors": typeof PublicContributorsRoute; - "/forgot-password": typeof PublicForgotPasswordRoute; - "/privacy": typeof PublicPrivacyRoute; - "/reset-password": typeof PublicResetPasswordRoute; - "/signin": typeof PublicSigninRoute; - "/signup": typeof PublicSignupRoute; - "/terms": typeof PublicTermsRoute; - "/verify-email": typeof PublicVerifyEmailRoute; - "/dashboard/settings": typeof ProtectedDashboardSettingsRoute; - "/dashboard": typeof ProtectedDashboardIndexRoute; - "/dashboard/$providerSlug/$accountId": typeof ProtectedDashboardProviderSlugAccountIdRoute; + "/": typeof IndexRoute + "/debug": typeof DebugRoute + "/contributors": typeof PublicContributorsRoute + "/forgot-password": typeof PublicForgotPasswordRoute + "/privacy": typeof PublicPrivacyRoute + "/reset-password": typeof PublicResetPasswordRoute + "/signin": typeof PublicSigninRoute + "/signup": typeof PublicSignupRoute + "/terms": typeof PublicTermsRoute + "/verify-email": typeof PublicVerifyEmailRoute + "/dashboard/settings": typeof ProtectedDashboardSettingsRoute + "/dashboard": typeof ProtectedDashboardIndexRoute + "/dashboard/$providerSlug/$accountId": typeof ProtectedDashboardProviderSlugAccountIdRoute } export interface FileRoutesById { - __root__: typeof rootRouteImport; - "/": typeof IndexRoute; - "/_protected": typeof ProtectedRouteWithChildren; - "/_public": typeof PublicRouteWithChildren; - "/debug": typeof DebugRoute; - "/_protected/dashboard": typeof ProtectedDashboardRouteWithChildren; - "/_public/contributors": typeof PublicContributorsRoute; - "/_public/forgot-password": typeof PublicForgotPasswordRoute; - "/_public/privacy": typeof PublicPrivacyRoute; - "/_public/reset-password": typeof PublicResetPasswordRoute; - "/_public/signin": typeof PublicSigninRoute; - "/_public/signup": typeof PublicSignupRoute; - "/_public/terms": typeof PublicTermsRoute; - "/_public/verify-email": typeof PublicVerifyEmailRoute; - "/_protected/dashboard/settings": typeof ProtectedDashboardSettingsRoute; - "/_protected/dashboard/": typeof ProtectedDashboardIndexRoute; - "/_protected/dashboard/$providerSlug/$accountId": typeof ProtectedDashboardProviderSlugAccountIdRoute; + __root__: typeof rootRouteImport + "/": typeof IndexRoute + "/_protected": typeof ProtectedRouteWithChildren + "/_public": typeof PublicRouteWithChildren + "/debug": typeof DebugRoute + "/_protected/dashboard": typeof ProtectedDashboardRouteWithChildren + "/_public/contributors": typeof PublicContributorsRoute + "/_public/forgot-password": typeof PublicForgotPasswordRoute + "/_public/privacy": typeof PublicPrivacyRoute + "/_public/reset-password": typeof PublicResetPasswordRoute + "/_public/signin": typeof PublicSigninRoute + "/_public/signup": typeof PublicSignupRoute + "/_public/terms": typeof PublicTermsRoute + "/_public/verify-email": typeof PublicVerifyEmailRoute + "/_protected/dashboard/settings": typeof ProtectedDashboardSettingsRoute + "/_protected/dashboard/": typeof ProtectedDashboardIndexRoute + "/_protected/dashboard/$providerSlug/$accountId": typeof ProtectedDashboardProviderSlugAccountIdRoute } export interface FileRouteTypes { - fileRoutesByFullPath: FileRoutesByFullPath; - fullPaths: - | "/" - | "/debug" - | "/dashboard" - | "/contributors" - | "/forgot-password" - | "/privacy" - | "/reset-password" - | "/signin" - | "/signup" - | "/terms" - | "/verify-email" - | "/dashboard/settings" - | "/dashboard/" - | "/dashboard/$providerSlug/$accountId"; - fileRoutesByTo: FileRoutesByTo; - to: - | "/" - | "/debug" - | "/contributors" - | "/forgot-password" - | "/privacy" - | "/reset-password" - | "/signin" - | "/signup" - | "/terms" - | "/verify-email" - | "/dashboard/settings" - | "/dashboard" - | "/dashboard/$providerSlug/$accountId"; - id: - | "__root__" - | "/" - | "/_protected" - | "/_public" - | "/debug" - | "/_protected/dashboard" - | "/_public/contributors" - | "/_public/forgot-password" - | "/_public/privacy" - | "/_public/reset-password" - | "/_public/signin" - | "/_public/signup" - | "/_public/terms" - | "/_public/verify-email" - | "/_protected/dashboard/settings" - | "/_protected/dashboard/" - | "/_protected/dashboard/$providerSlug/$accountId"; - fileRoutesById: FileRoutesById; + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + | "/" + | "/debug" + | "/dashboard" + | "/contributors" + | "/forgot-password" + | "/privacy" + | "/reset-password" + | "/signin" + | "/signup" + | "/terms" + | "/verify-email" + | "/dashboard/settings" + | "/dashboard/" + | "/dashboard/$providerSlug/$accountId" + fileRoutesByTo: FileRoutesByTo + to: + | "/" + | "/debug" + | "/contributors" + | "/forgot-password" + | "/privacy" + | "/reset-password" + | "/signin" + | "/signup" + | "/terms" + | "/verify-email" + | "/dashboard/settings" + | "/dashboard" + | "/dashboard/$providerSlug/$accountId" + id: + | "__root__" + | "/" + | "/_protected" + | "/_public" + | "/debug" + | "/_protected/dashboard" + | "/_public/contributors" + | "/_public/forgot-password" + | "/_public/privacy" + | "/_public/reset-password" + | "/_public/signin" + | "/_public/signup" + | "/_public/terms" + | "/_public/verify-email" + | "/_protected/dashboard/settings" + | "/_protected/dashboard/" + | "/_protected/dashboard/$providerSlug/$accountId" + fileRoutesById: FileRoutesById } export interface RootRouteChildren { - IndexRoute: typeof IndexRoute; - ProtectedRoute: typeof ProtectedRouteWithChildren; - PublicRoute: typeof PublicRouteWithChildren; - DebugRoute: typeof DebugRoute; + IndexRoute: typeof IndexRoute + ProtectedRoute: typeof ProtectedRouteWithChildren + PublicRoute: typeof PublicRouteWithChildren + DebugRoute: typeof DebugRoute } declare module "@tanstack/react-router" { - interface FileRoutesByPath { - "/debug": { - id: "/debug"; - path: "/debug"; - fullPath: "/debug"; - preLoaderRoute: typeof DebugRouteImport; - parentRoute: typeof rootRouteImport; - }; - "/_public": { - id: "/_public"; - path: ""; - fullPath: ""; - preLoaderRoute: typeof PublicRouteImport; - parentRoute: typeof rootRouteImport; - }; - "/_protected": { - id: "/_protected"; - path: ""; - fullPath: ""; - preLoaderRoute: typeof ProtectedRouteImport; - parentRoute: typeof rootRouteImport; - }; - "/": { - id: "/"; - path: "/"; - fullPath: "/"; - preLoaderRoute: typeof IndexRouteImport; - parentRoute: typeof rootRouteImport; - }; - "/_public/verify-email": { - id: "/_public/verify-email"; - path: "/verify-email"; - fullPath: "/verify-email"; - preLoaderRoute: typeof PublicVerifyEmailRouteImport; - parentRoute: typeof PublicRoute; - }; - "/_public/terms": { - id: "/_public/terms"; - path: "/terms"; - fullPath: "/terms"; - preLoaderRoute: typeof PublicTermsRouteImport; - parentRoute: typeof PublicRoute; - }; - "/_public/signup": { - id: "/_public/signup"; - path: "/signup"; - fullPath: "/signup"; - preLoaderRoute: typeof PublicSignupRouteImport; - parentRoute: typeof PublicRoute; - }; - "/_public/signin": { - id: "/_public/signin"; - path: "/signin"; - fullPath: "/signin"; - preLoaderRoute: typeof PublicSigninRouteImport; - parentRoute: typeof PublicRoute; - }; - "/_public/reset-password": { - id: "/_public/reset-password"; - path: "/reset-password"; - fullPath: "/reset-password"; - preLoaderRoute: typeof PublicResetPasswordRouteImport; - parentRoute: typeof PublicRoute; - }; - "/_public/privacy": { - id: "/_public/privacy"; - path: "/privacy"; - fullPath: "/privacy"; - preLoaderRoute: typeof PublicPrivacyRouteImport; - parentRoute: typeof PublicRoute; - }; - "/_public/forgot-password": { - id: "/_public/forgot-password"; - path: "/forgot-password"; - fullPath: "/forgot-password"; - preLoaderRoute: typeof PublicForgotPasswordRouteImport; - parentRoute: typeof PublicRoute; - }; - "/_public/contributors": { - id: "/_public/contributors"; - path: "/contributors"; - fullPath: "/contributors"; - preLoaderRoute: typeof PublicContributorsRouteImport; - parentRoute: typeof PublicRoute; - }; - "/_protected/dashboard": { - id: "/_protected/dashboard"; - path: "/dashboard"; - fullPath: "/dashboard"; - preLoaderRoute: typeof ProtectedDashboardRouteImport; - parentRoute: typeof ProtectedRoute; - }; - "/_protected/dashboard/": { - id: "/_protected/dashboard/"; - path: "/"; - fullPath: "/dashboard/"; - preLoaderRoute: typeof ProtectedDashboardIndexRouteImport; - parentRoute: typeof ProtectedDashboardRoute; - }; - "/_protected/dashboard/settings": { - id: "/_protected/dashboard/settings"; - path: "/settings"; - fullPath: "/dashboard/settings"; - preLoaderRoute: typeof ProtectedDashboardSettingsRouteImport; - parentRoute: typeof ProtectedDashboardRoute; - }; - "/_protected/dashboard/$providerSlug/$accountId": { - id: "/_protected/dashboard/$providerSlug/$accountId"; - path: "/$providerSlug/$accountId"; - fullPath: "/dashboard/$providerSlug/$accountId"; - preLoaderRoute: typeof ProtectedDashboardProviderSlugAccountIdRouteImport; - parentRoute: typeof ProtectedDashboardRoute; - }; - } + interface FileRoutesByPath { + "/debug": { + id: "/debug" + path: "/debug" + fullPath: "/debug" + preLoaderRoute: typeof DebugRouteImport + parentRoute: typeof rootRouteImport + } + "/_public": { + id: "/_public" + path: "" + fullPath: "" + preLoaderRoute: typeof PublicRouteImport + parentRoute: typeof rootRouteImport + } + "/_protected": { + id: "/_protected" + path: "" + fullPath: "" + preLoaderRoute: typeof ProtectedRouteImport + parentRoute: typeof rootRouteImport + } + "/": { + id: "/" + path: "/" + fullPath: "/" + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + "/_public/verify-email": { + id: "/_public/verify-email" + path: "/verify-email" + fullPath: "/verify-email" + preLoaderRoute: typeof PublicVerifyEmailRouteImport + parentRoute: typeof PublicRoute + } + "/_public/terms": { + id: "/_public/terms" + path: "/terms" + fullPath: "/terms" + preLoaderRoute: typeof PublicTermsRouteImport + parentRoute: typeof PublicRoute + } + "/_public/signup": { + id: "/_public/signup" + path: "/signup" + fullPath: "/signup" + preLoaderRoute: typeof PublicSignupRouteImport + parentRoute: typeof PublicRoute + } + "/_public/signin": { + id: "/_public/signin" + path: "/signin" + fullPath: "/signin" + preLoaderRoute: typeof PublicSigninRouteImport + parentRoute: typeof PublicRoute + } + "/_public/reset-password": { + id: "/_public/reset-password" + path: "/reset-password" + fullPath: "/reset-password" + preLoaderRoute: typeof PublicResetPasswordRouteImport + parentRoute: typeof PublicRoute + } + "/_public/privacy": { + id: "/_public/privacy" + path: "/privacy" + fullPath: "/privacy" + preLoaderRoute: typeof PublicPrivacyRouteImport + parentRoute: typeof PublicRoute + } + "/_public/forgot-password": { + id: "/_public/forgot-password" + path: "/forgot-password" + fullPath: "/forgot-password" + preLoaderRoute: typeof PublicForgotPasswordRouteImport + parentRoute: typeof PublicRoute + } + "/_public/contributors": { + id: "/_public/contributors" + path: "/contributors" + fullPath: "/contributors" + preLoaderRoute: typeof PublicContributorsRouteImport + parentRoute: typeof PublicRoute + } + "/_protected/dashboard": { + id: "/_protected/dashboard" + path: "/dashboard" + fullPath: "/dashboard" + preLoaderRoute: typeof ProtectedDashboardRouteImport + parentRoute: typeof ProtectedRoute + } + "/_protected/dashboard/": { + id: "/_protected/dashboard/" + path: "/" + fullPath: "/dashboard/" + preLoaderRoute: typeof ProtectedDashboardIndexRouteImport + parentRoute: typeof ProtectedDashboardRoute + } + "/_protected/dashboard/settings": { + id: "/_protected/dashboard/settings" + path: "/settings" + fullPath: "/dashboard/settings" + preLoaderRoute: typeof ProtectedDashboardSettingsRouteImport + parentRoute: typeof ProtectedDashboardRoute + } + "/_protected/dashboard/$providerSlug/$accountId": { + id: "/_protected/dashboard/$providerSlug/$accountId" + path: "/$providerSlug/$accountId" + fullPath: "/dashboard/$providerSlug/$accountId" + preLoaderRoute: typeof ProtectedDashboardProviderSlugAccountIdRouteImport + parentRoute: typeof ProtectedDashboardRoute + } + } } interface ProtectedDashboardRouteChildren { - ProtectedDashboardSettingsRoute: typeof ProtectedDashboardSettingsRoute; - ProtectedDashboardIndexRoute: typeof ProtectedDashboardIndexRoute; - ProtectedDashboardProviderSlugAccountIdRoute: typeof ProtectedDashboardProviderSlugAccountIdRoute; + ProtectedDashboardSettingsRoute: typeof ProtectedDashboardSettingsRoute + ProtectedDashboardIndexRoute: typeof ProtectedDashboardIndexRoute + ProtectedDashboardProviderSlugAccountIdRoute: typeof ProtectedDashboardProviderSlugAccountIdRoute } const ProtectedDashboardRouteChildren: ProtectedDashboardRouteChildren = { - ProtectedDashboardSettingsRoute: ProtectedDashboardSettingsRoute, - ProtectedDashboardIndexRoute: ProtectedDashboardIndexRoute, - ProtectedDashboardProviderSlugAccountIdRoute: ProtectedDashboardProviderSlugAccountIdRoute, -}; + ProtectedDashboardSettingsRoute: ProtectedDashboardSettingsRoute, + ProtectedDashboardIndexRoute: ProtectedDashboardIndexRoute, + ProtectedDashboardProviderSlugAccountIdRoute: + ProtectedDashboardProviderSlugAccountIdRoute, +} -const ProtectedDashboardRouteWithChildren = ProtectedDashboardRoute._addFileChildren(ProtectedDashboardRouteChildren); +const ProtectedDashboardRouteWithChildren = + ProtectedDashboardRoute._addFileChildren(ProtectedDashboardRouteChildren) interface ProtectedRouteChildren { - ProtectedDashboardRoute: typeof ProtectedDashboardRouteWithChildren; + ProtectedDashboardRoute: typeof ProtectedDashboardRouteWithChildren } const ProtectedRouteChildren: ProtectedRouteChildren = { - ProtectedDashboardRoute: ProtectedDashboardRouteWithChildren, -}; + ProtectedDashboardRoute: ProtectedDashboardRouteWithChildren, +} -const ProtectedRouteWithChildren = ProtectedRoute._addFileChildren(ProtectedRouteChildren); +const ProtectedRouteWithChildren = ProtectedRoute._addFileChildren( + ProtectedRouteChildren, +) interface PublicRouteChildren { - PublicContributorsRoute: typeof PublicContributorsRoute; - PublicForgotPasswordRoute: typeof PublicForgotPasswordRoute; - PublicPrivacyRoute: typeof PublicPrivacyRoute; - PublicResetPasswordRoute: typeof PublicResetPasswordRoute; - PublicSigninRoute: typeof PublicSigninRoute; - PublicSignupRoute: typeof PublicSignupRoute; - PublicTermsRoute: typeof PublicTermsRoute; - PublicVerifyEmailRoute: typeof PublicVerifyEmailRoute; + PublicContributorsRoute: typeof PublicContributorsRoute + PublicForgotPasswordRoute: typeof PublicForgotPasswordRoute + PublicPrivacyRoute: typeof PublicPrivacyRoute + PublicResetPasswordRoute: typeof PublicResetPasswordRoute + PublicSigninRoute: typeof PublicSigninRoute + PublicSignupRoute: typeof PublicSignupRoute + PublicTermsRoute: typeof PublicTermsRoute + PublicVerifyEmailRoute: typeof PublicVerifyEmailRoute } const PublicRouteChildren: PublicRouteChildren = { - PublicContributorsRoute: PublicContributorsRoute, - PublicForgotPasswordRoute: PublicForgotPasswordRoute, - PublicPrivacyRoute: PublicPrivacyRoute, - PublicResetPasswordRoute: PublicResetPasswordRoute, - PublicSigninRoute: PublicSigninRoute, - PublicSignupRoute: PublicSignupRoute, - PublicTermsRoute: PublicTermsRoute, - PublicVerifyEmailRoute: PublicVerifyEmailRoute, -}; + PublicContributorsRoute: PublicContributorsRoute, + PublicForgotPasswordRoute: PublicForgotPasswordRoute, + PublicPrivacyRoute: PublicPrivacyRoute, + PublicResetPasswordRoute: PublicResetPasswordRoute, + PublicSigninRoute: PublicSigninRoute, + PublicSignupRoute: PublicSignupRoute, + PublicTermsRoute: PublicTermsRoute, + PublicVerifyEmailRoute: PublicVerifyEmailRoute, +} -const PublicRouteWithChildren = PublicRoute._addFileChildren(PublicRouteChildren); +const PublicRouteWithChildren = + PublicRoute._addFileChildren(PublicRouteChildren) const rootRouteChildren: RootRouteChildren = { - IndexRoute: IndexRoute, - ProtectedRoute: ProtectedRouteWithChildren, - PublicRoute: PublicRouteWithChildren, - DebugRoute: DebugRoute, -}; -export const routeTree = rootRouteImport._addFileChildren(rootRouteChildren)._addFileTypes(); + IndexRoute: IndexRoute, + ProtectedRoute: ProtectedRouteWithChildren, + PublicRoute: PublicRouteWithChildren, + DebugRoute: DebugRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() diff --git a/apps/web/src/routes/__root.tsx b/apps/web/src/routes/__root.tsx index 2500ae2..c5faf5c 100644 --- a/apps/web/src/routes/__root.tsx +++ b/apps/web/src/routes/__root.tsx @@ -1,9 +1,9 @@ import { createRootRoute, Outlet, ErrorComponent } from "@tanstack/react-router"; import { ReactQueryProvider } from "@/components/providers/query-provider"; +import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"; import { ThemeProvider } from "@/components/providers/theme-provider"; import { AppProviders } from "@/components/providers/app-providers"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; -import { TanStackRouterDevtools } from "@tanstack/router-devtools"; import { geistSans, geistMono, manrope } from "@/utils/fonts"; import { Toaster } from "sonner"; import { Suspense } from "react"; diff --git a/apps/web/src/routes/_protected/dashboard/settings.tsx b/apps/web/src/routes/_protected/dashboard/settings.tsx index 4b1fb50..ee1949e 100644 --- a/apps/web/src/routes/_protected/dashboard/settings.tsx +++ b/apps/web/src/routes/_protected/dashboard/settings.tsx @@ -60,7 +60,7 @@ function SettingsPage() { if (user?.email !== email) { await authClient.changeEmail({ newEmail: email, - callbackURL: `${env.NEXT_PUBLIC_FRONTEND_URL}/verify-email`, + callbackURL: `${env.VITE_PUBLIC_FRONTEND_URL}/verify-email`, }); isUpdated = true; } diff --git a/apps/web/src/utils/client.ts b/apps/web/src/utils/client.ts index 4a9d33d..d5a99b3 100644 --- a/apps/web/src/utils/client.ts +++ b/apps/web/src/utils/client.ts @@ -4,10 +4,10 @@ import env from "@nimbus/env/client"; import { hc } from "hono/client"; const createClient = (options?: ClientRequestOptions) => { - if (!env.NEXT_PUBLIC_BACKEND_URL) { - throw new Error("NEXT_PUBLIC_BACKEND_URL is not configured"); + if (!env.VITE_PUBLIC_BACKEND_URL) { + throw new Error("VITE_PUBLIC_BACKEND_URL is not configured"); } - return hc(env.NEXT_PUBLIC_BACKEND_URL, options); + return hc(env.VITE_PUBLIC_BACKEND_URL, options); }; export const publicClient = createClient(); diff --git a/apps/web/src/utils/site-config.ts b/apps/web/src/utils/site-config.ts index 09aa985..a57a40f 100644 --- a/apps/web/src/utils/site-config.ts +++ b/apps/web/src/utils/site-config.ts @@ -3,6 +3,6 @@ import env from "@nimbus/env/client"; export const siteConfig = { name: "Nimbus", description: "A better cloud storage solution.", - url: env.NEXT_PUBLIC_FRONTEND_URL, + url: env.VITE_PUBLIC_FRONTEND_URL, twitterHandle: "@nimbusdotcloud", } as const; diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index c53773c..d3a0ae2 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -7,6 +7,8 @@ import path from "path"; export default defineConfig({ plugins: [ tanstackRouter({ + target: "react", + autoCodeSplitting: true, routesDirectory: "./src/routes", generatedRouteTree: "./src/routeTree.gen.ts", routeFileIgnorePrefix: "-", diff --git a/bun.lock b/bun.lock index 4e92821..1cf10a2 100644 --- a/bun.lock +++ b/bun.lock @@ -76,12 +76,12 @@ "@radix-ui/react-tabs": "^1.1.12", "@radix-ui/react-tooltip": "^1.2.7", "@t3-oss/env-core": "^0.13.8", + "@tailwindcss/postcss": "^4.1.14", "@tanstack/react-query": "^5.83.0", "@tanstack/react-query-devtools": "^5.84.1", "@tanstack/react-router-devtools": "^1.133.0", "@tanstack/react-table": "^8.21.3", "@tanstack/router": "^0.0.1-beta.53", - "@tanstack/router-devtools": "^1.94.4", "axios": "^1.11.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -166,6 +166,8 @@ }, }, "packages": { + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + "@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="], "@aws-crypto/crc32c": ["@aws-crypto/crc32c@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag=="], @@ -482,6 +484,8 @@ "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], + "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], @@ -848,6 +852,36 @@ "@t3-oss/env-core": ["@t3-oss/env-core@0.13.8", "", { "peerDependencies": { "arktype": "^2.1.0", "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0 || ^4.0.0-beta.0" }, "optionalPeers": ["arktype", "typescript", "valibot", "zod"] }, "sha512-L1inmpzLQyYu4+Q1DyrXsGJYCXbtXjC4cICw1uAKv0ppYPQv656lhZPU91Qd1VS6SO/bou1/q5ufVzBGbNsUpw=="], + "@tailwindcss/node": ["@tailwindcss/node@4.1.14", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.0", "lightningcss": "1.30.1", "magic-string": "^0.30.19", "source-map-js": "^1.2.1", "tailwindcss": "4.1.14" } }, "sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw=="], + + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.14", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.5.1" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.14", "@tailwindcss/oxide-darwin-arm64": "4.1.14", "@tailwindcss/oxide-darwin-x64": "4.1.14", "@tailwindcss/oxide-freebsd-x64": "4.1.14", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.14", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.14", "@tailwindcss/oxide-linux-arm64-musl": "4.1.14", "@tailwindcss/oxide-linux-x64-gnu": "4.1.14", "@tailwindcss/oxide-linux-x64-musl": "4.1.14", "@tailwindcss/oxide-wasm32-wasi": "4.1.14", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.14", "@tailwindcss/oxide-win32-x64-msvc": "4.1.14" } }, "sha512-23yx+VUbBwCg2x5XWdB8+1lkPajzLmALEfMb51zZUBYaYVPDQvBSD/WYDqiVyBIo2BZFa3yw1Rpy3G2Jp+K0dw=="], + + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.14", "", { "os": "android", "cpu": "arm64" }, "sha512-a94ifZrGwMvbdeAxWoSuGcIl6/DOP5cdxagid7xJv6bwFp3oebp7y2ImYsnZBMTwjn5Ev5xESvS3FFYUGgPODQ=="], + + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HkFP/CqfSh09xCnrPJA7jud7hij5ahKyWomrC3oiO2U9i0UjP17o9pJbxUN0IJ471GTQQmzwhp0DEcpbp4MZTA=="], + + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-eVNaWmCgdLf5iv6Qd3s7JI5SEFBFRtfm6W0mphJYXgvnDEAZ5sZzqmI06bK6xo0IErDHdTA5/t7d4eTfWbWOFw=="], + + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.14", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QWLoRXNikEuqtNb0dhQN6wsSVVjX6dmUFzuuiL09ZeXju25dsei2uIPl71y2Ic6QbNBsB4scwBoFnlBfabHkEw=="], + + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.14", "", { "os": "linux", "cpu": "arm" }, "sha512-VB4gjQni9+F0VCASU+L8zSIyjrLLsy03sjcR3bM0V2g4SNamo0FakZFKyUQ96ZVwGK4CaJsc9zd/obQy74o0Fw=="], + + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-qaEy0dIZ6d9vyLnmeg24yzA8XuEAD9WjpM5nIM1sUgQ/Zv7cVkharPDQcmm/t/TvXoKo/0knI3me3AGfdx6w1w=="], + + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-ISZjT44s59O8xKsPEIesiIydMG/sCXoMBCqsphDm/WcbnuWLxxb+GcvSIIA5NjUw6F8Tex7s5/LM2yDy8RqYBQ=="], + + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.14", "", { "os": "linux", "cpu": "x64" }, "sha512-02c6JhLPJj10L2caH4U0zF8Hji4dOeahmuMl23stk0MU1wfd1OraE7rOloidSF8W5JTHkFdVo/O7uRUJJnUAJg=="], + + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.14", "", { "os": "linux", "cpu": "x64" }, "sha512-TNGeLiN1XS66kQhxHG/7wMeQDOoL0S33x9BgmydbrWAb9Qw0KYdd8o1ifx4HOGDWhVmJ+Ul+JQ7lyknQFilO3Q=="], + + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.14", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.5", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-uZYAsaW/jS/IYkd6EWPJKW/NlPNSkWkBlaeVBi/WsFQNP05/bzkebUL8FH1pdsqx4f2fH/bWFcUABOM9nfiJkQ=="], + + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-Az0RnnkcvRqsuoLH2Z4n3JfAef0wElgzHD5Aky/e+0tBUxUhIeIqFBTMNQvmMRSP15fWwmvjBxZ3Q8RhsDnxAA=="], + + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.14", "", { "os": "win32", "cpu": "x64" }, "sha512-ttblVGHgf68kEE4om1n/n44I0yGPkCPbLsqzjvybhpwa6mKKtgFfAzy6btc3HRmuW7nHe0OOrSeNP9sQmmH9XA=="], + + "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.14", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.14", "@tailwindcss/oxide": "4.1.14", "postcss": "^8.4.41", "tailwindcss": "4.1.14" } }, "sha512-BdMjIxy7HUNThK87C7BC8I1rE8BVUsfNQSI5siQ4JK3iIa3w0XyVvVL9SXLWO//CtYTcp1v7zci0fYwJOjB+Zg=="], + "@tanstack/history": ["@tanstack/history@1.132.31", "", {}, "sha512-UCHM2uS0t/uSszqPEo+SBSSoQVeQ+LlOWAVBl5SA7+AedeAbKafIPjFn8huZCXNLAYb0WKV2+wETr7lDK9uz7g=="], "@tanstack/query-core": ["@tanstack/query-core@5.85.5", "", {}, "sha512-KO0WTob4JEApv69iYp1eGvfMSUkgw//IpMnq+//cORBzXf0smyRwPLrUvEe5qtAEGjwZTXrjxg+oJNP/C00t6w=="], @@ -870,8 +904,6 @@ "@tanstack/router-core": ["@tanstack/router-core@1.132.47", "", { "dependencies": { "@tanstack/history": "1.132.31", "@tanstack/store": "^0.7.0", "cookie-es": "^2.0.0", "seroval": "^1.3.2", "seroval-plugins": "^1.3.2", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-8YKFHmG6VUqXaWAJzEqjyW6w31dARS2USd2mtI5ZeZcihqMbskK28N4iotBXNn+sSKJnPRjc7A4jTnnEf8Mn8Q=="], - "@tanstack/router-devtools": ["@tanstack/router-devtools@1.133.0", "", { "dependencies": { "@tanstack/react-router-devtools": "1.133.0", "clsx": "^2.1.1", "goober": "^2.1.16", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/react-router": "^1.132.47", "csstype": "^3.0.10", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["csstype"] }, "sha512-TJ4mykqur/U31sOiHIIBdA5xLUyyOUi0H7wl1TLd4mJsD1hwZCRCewhpXpWLInlDU+4OuFYX5atnD6iu5fAIug=="], - "@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.133.0", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/router-core": "^1.132.47", "csstype": "^3.0.10", "solid-js": ">=1.9.5", "tiny-invariant": "^1.3.3" }, "optionalPeers": ["csstype"] }, "sha512-0ZTsKxKEjQsQjnskygflTtbcVktXPOhBE2ofMOaSM+jMTUpNoiul/1BVPIvN61TfUTLeuXvvXDGi58pf20VQUg=="], "@tanstack/router-generator": ["@tanstack/router-generator@1.132.51", "", { "dependencies": { "@tanstack/router-core": "1.132.47", "@tanstack/router-utils": "1.132.51", "@tanstack/virtual-file-routes": "1.132.31", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-iAGz2IZ2rr38o+7cgE33qPyNFJFx7PcPOvUXk5kcX1TtXeyTgVLoe7vqQzKYbungZmht2V8xSFmy6kakUJhxOA=="], @@ -1038,6 +1070,8 @@ "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + "ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], @@ -1152,6 +1186,8 @@ "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + "enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="], + "enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="], "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], @@ -1480,6 +1516,8 @@ "lucide-react": ["lucide-react@0.534.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-4Bz7rujQ/mXHqCwjx09ih/Q9SCizz9CjBV5repw9YSHZZZaop9/Oj0RgCDt6WdEaeAPfbcZ8l2b4jzApStqgNw=="], + "magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "merge-options": ["merge-options@3.0.4", "", { "dependencies": { "is-plain-obj": "^2.1.0" } }, "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ=="], @@ -1500,6 +1538,8 @@ "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + "minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + "motion": ["motion@12.23.12", "", { "dependencies": { "framer-motion": "^12.23.12", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-8jCD8uW5GD1csOoqh1WhH1A6j5APHVE15nuBkFeRiMzYBdRwyAHmSP/oXSuW0WJPZRXTFdBoG4hY9TFWNhhwng=="], "motion-dom": ["motion-dom@12.23.12", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw=="], @@ -1802,6 +1842,10 @@ "tailwindcss": ["tailwindcss@4.1.12", "", {}, "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA=="], + "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], + + "tar": ["tar@7.5.1", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g=="], + "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="], "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], @@ -1904,7 +1948,7 @@ "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], - "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], "yaml": ["yaml@2.8.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="], @@ -1984,14 +2028,30 @@ "@manypkg/get-packages/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + "@tailwindcss/node/jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + + "@tailwindcss/node/tailwindcss": ["tailwindcss@4.1.14", "", {}, "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.5.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="], + + "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + + "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "@tailwindcss/postcss/tailwindcss": ["tailwindcss@4.1.14", "", {}, "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA=="], + "@tanstack/react-router-devtools/vite": ["vite@7.1.9", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="], "@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="], "@tanstack/router-core/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="], - "@tanstack/router-devtools/vite": ["vite@7.1.9", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="], - "@tanstack/router-devtools-core/vite": ["vite@7.1.9", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="], "@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -2088,6 +2148,8 @@ "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], + "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "@changesets/parse/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="], @@ -2144,8 +2206,6 @@ "@tanstack/router-devtools-core/vite/tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], - "@tanstack/router-devtools/vite/tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], - "@types/node-fetch/@types/node/undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="], "@types/pg/@types/node/undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="], diff --git a/docker-compose.yml b/docker-compose.yml index ac8a563..64670f6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -93,15 +93,15 @@ services: # dockerfile: apps/web/Dockerfile # target: runner # args: - # NEXT_PUBLIC_BACKEND_URL: ${NEXT_PUBLIC_BACKEND_URL} - # NEXT_PUBLIC_FRONTEND_URL: ${NEXT_PUBLIC_FRONTEND_URL} + # VITE_PUBLIC_BACKEND_URL: ${VITE_PUBLIC_BACKEND_URL} + # VITE_PUBLIC_FRONTEND_URL: ${VITE_PUBLIC_FRONTEND_URL} # container_name: nimbus-web # restart: unless-stopped # env_file: .env # environment: # NODE_ENV: production - # NEXT_PUBLIC_BACKEND_URL: ${NEXT_PUBLIC_BACKEND_URL} - # NEXT_PUBLIC_FRONTEND_URL: ${NEXT_PUBLIC_FRONTEND_URL} + # VITE_PUBLIC_BACKEND_URL: ${VITE_PUBLIC_BACKEND_URL} + # VITE_PUBLIC_FRONTEND_URL: ${VITE_PUBLIC_FRONTEND_URL} # ports: # - "3000:3000" # depends_on: diff --git a/lint-staged.config.js b/lint-staged.config.js index ea8556f..d82a55f 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -4,9 +4,6 @@ * @type {import('lint-staged').Configuration} */ const config = { - // Lint and fix Next.js files - "apps/web/**/*.{ts,tsx,js,jsx}": () => "bun run --cwd=apps/web lint --fix", - // Lint and fix TypeScript and JavaScript files "**/*.{ts,tsx,js,jsx}": ["oxlint --fix", "prettier --write --list-different"], diff --git a/packages/auth/src/auth-client.ts b/packages/auth/src/auth-client.ts index 59887b2..e5b70a2 100644 --- a/packages/auth/src/auth-client.ts +++ b/packages/auth/src/auth-client.ts @@ -4,8 +4,8 @@ import { createAuthClient } from "better-auth/react"; import env from "@nimbus/env/client"; export const authClient = createAuthClient({ - baseURL: env.NEXT_PUBLIC_BACKEND_URL, - callbackUrl: `${env.NEXT_PUBLIC_FRONTEND_URL}/dashboard`, + baseURL: env.VITE_PUBLIC_BACKEND_URL, + callbackUrl: `${env.VITE_PUBLIC_FRONTEND_URL}/dashboard`, plugins: [ genericOAuthClient(), stripeClient({ diff --git a/packages/db/drizzle.config.ts b/packages/db/drizzle.config.ts index 272678d..70d8cf1 100644 --- a/packages/db/drizzle.config.ts +++ b/packages/db/drizzle.config.ts @@ -1,14 +1,10 @@ import { defineConfig } from "drizzle-kit"; -if (!process.env.DATABASE_URL) { - throw new Error("Missing environment variables. DATABASE_URL is not defined"); -} - export default defineConfig({ out: "./drizzle", schema: "./schema.ts", dialect: "postgresql", dbCredentials: { - url: process.env.DATABASE_URL, + url: process.env.DATABASE_URL!, }, }); diff --git a/packages/env/client.ts b/packages/env/client.ts index 608f630..84fbaa9 100644 --- a/packages/env/client.ts +++ b/packages/env/client.ts @@ -3,19 +3,19 @@ import { z } from "zod"; const env = createEnv({ runtimeEnv: { - NEXT_PUBLIC_BACKEND_URL: process.env.NEXT_PUBLIC_BACKEND_URL, - NEXT_PUBLIC_FRONTEND_URL: process.env.NEXT_PUBLIC_FRONTEND_URL, - NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY, - NEXT_PUBLIC_POSTHOG_HOST: process.env.NEXT_PUBLIC_POSTHOG_HOST, + VITE_PUBLIC_BACKEND_URL: import.meta.env.VITE_PUBLIC_BACKEND_URL, + VITE_PUBLIC_FRONTEND_URL: import.meta.env.VITE_PUBLIC_FRONTEND_URL, + VITE_PUBLIC_POSTHOG_KEY: import.meta.env.VITE_PUBLIC_POSTHOG_KEY, + VITE_PUBLIC_POSTHOG_HOST: import.meta.env.VITE_PUBLIC_POSTHOG_HOST, }, - clientPrefix: "NEXT_PUBLIC_", + clientPrefix: "VITE_PUBLIC_", client: { // Client-side environment variables - NEXT_PUBLIC_BACKEND_URL: z.url(), - NEXT_PUBLIC_FRONTEND_URL: z.url(), - NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(), - NEXT_PUBLIC_POSTHOG_HOST: z.string().optional(), + VITE_PUBLIC_BACKEND_URL: z.url(), + VITE_PUBLIC_FRONTEND_URL: z.url(), + VITE_PUBLIC_POSTHOG_KEY: z.string().optional(), + VITE_PUBLIC_POSTHOG_HOST: z.string().optional(), }, }); diff --git a/packages/env/server.ts b/packages/env/server.ts index 6a7b019..fe63491 100644 --- a/packages/env/server.ts +++ b/packages/env/server.ts @@ -70,6 +70,8 @@ export const env = createEnv({ // Stripe STRIPE_SECRET_KEY: z.string(), STRIPE_WEBHOOK_SECRET: z.string(), + + ENCRYPTION_KEY: z.string(), }, runtimeEnv: process.env,