diff --git a/.github/workflows/build-and-deploy_devresults-xdev.yml b/.github/workflows/build-and-deploy_devresults-xdev.yml
index 55688c05..129042a6 100644
--- a/.github/workflows/build-and-deploy_devresults-xdev.yml
+++ b/.github/workflows/build-and-deploy_devresults-xdev.yml
@@ -21,7 +21,7 @@ jobs:
- name: Set up Node.js version
uses: actions/setup-node@v4
with:
- node-version: "18.x"
+ node-version: "20.x"
- uses: pnpm/action-setup@v3
with:
diff --git a/.gitignore b/.gitignore
index 437e23de..1901d45e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,4 +51,5 @@ test-results
typings
yarn-debug.log*
yarn-error.log*
-.copilotcontext
\ No newline at end of file
+.copilotcontext
+.react-router/
\ No newline at end of file
diff --git a/app/ErrorBoundary.tsx b/app/ErrorBoundary.tsx
index 7a8fdb5f..e8d51e7e 100644
--- a/app/ErrorBoundary.tsx
+++ b/app/ErrorBoundary.tsx
@@ -1,4 +1,4 @@
-import { useRouteError } from "@remix-run/react"
+import { useRouteError } from "react-router"
import { ErrorScreen } from "ui/ErrorScreen"
export function ErrorBoundary() {
diff --git a/app/context/Auth/AuthContextProvider.tsx b/app/context/Auth/AuthContextProvider.tsx
index b56e019b..6c112571 100644
--- a/app/context/Auth/AuthContextProvider.tsx
+++ b/app/context/Auth/AuthContextProvider.tsx
@@ -2,7 +2,7 @@ import type { Repo } from "@automerge/automerge-repo"
import { RepoContext } from "@automerge/automerge-repo-react-hooks"
import type * as Auth from "@localfirst/auth"
import { type AuthProvider } from "@localfirst/auth-provider-automerge-repo"
-import { useNavigate } from "@remix-run/react"
+import { useNavigate } from "react-router"
import { initializeAuthRepo } from "context/Auth/initializeAuthRepo"
import { useLocalState } from "hooks/useLocalState"
import { useSignOut } from "hooks/useSignOut"
@@ -42,7 +42,7 @@ export function AuthContextProvider({ children }: { children: React.ReactNode })
switch (scenario) {
case "FIRST_LOAD": {
// start the auth flow
- navigate("/auth/begin")
+ void navigate("/auth/begin")
break
}
@@ -66,7 +66,7 @@ export function AuthContextProvider({ children }: { children: React.ReactNode })
const signOutIfNotAMember = (team: Auth.Team) => {
if (user && team.memberWasRemoved(user.userId)) {
signOut()
- navigate("/")
+ void navigate("/")
}
}
diff --git a/app/entry.client.tsx b/app/entry.client.tsx
deleted file mode 100644
index 405f591a..00000000
--- a/app/entry.client.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { RemixBrowser } from "@remix-run/react"
-import { startTransition } from "react"
-import { hydrateRoot } from "react-dom/client"
-
-startTransition(() => {
- hydrateRoot(document.querySelector("#app")!, )
-})
diff --git a/app/entry.server.tsx b/app/entry.server.tsx
deleted file mode 100644
index 9c45a851..00000000
--- a/app/entry.server.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import fs from "node:fs"
-import path from "node:path"
-import type { EntryContext } from "@remix-run/node"
-import { RemixServer } from "@remix-run/react"
-import { renderToString } from "react-dom/server"
-
-export default function handleRequest(
- request: Request,
- responseStatusCode: number,
- _responseHeaders: Headers,
- remixContext: EntryContext,
-) {
- const shellHtml = fs.readFileSync(path.join(process.cwd(), "app/index.html")).toString()
- const appHtml = renderToString()
- const html = shellHtml.replace("", appHtml)
-
- return new Response(html, {
- headers: { "Content-Type": "text/html" },
- status: responseStatusCode,
- })
-}
diff --git a/app/hooks/useNavigationHotkey.tsx b/app/hooks/useNavigationHotkey.tsx
index fde93f4a..f9c80742 100644
--- a/app/hooks/useNavigationHotkey.tsx
+++ b/app/hooks/useNavigationHotkey.tsx
@@ -1,10 +1,10 @@
-import { useNavigate } from "@remix-run/react"
+import { useNavigate } from "react-router"
import { useHotkeys } from "react-hotkeys-hook"
export function useNavigationHotkey(keys: string, path: string) {
const navigate = useNavigate()
useHotkeys(keys, e => {
e.preventDefault()
- navigate(path, { relative: "path" })
+ void navigate(path, { relative: "path" })
})
}
diff --git a/app/hooks/useRedirect.tsx b/app/hooks/useRedirect.tsx
index e65c8ae4..3ee5f2ac 100644
--- a/app/hooks/useRedirect.tsx
+++ b/app/hooks/useRedirect.tsx
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ // state is any
-import { useLocation, useNavigate } from "@remix-run/react"
+import { useLocation, useNavigate } from "react-router"
import { useEffect } from "react"
export function useRedirect({ from, to, condition = true }: Params) {
@@ -10,11 +10,11 @@ export function useRedirect({ from, to, condition = true }: Params) {
if (!condition) return
if (typeof from === "string" && pathname === from) {
console.log(`redirecting from ${from} to ${to}`)
- navigate(to, { state })
+ void navigate(to, { state })
} else if (from instanceof RegExp && from.test(pathname)) {
const newTo = pathname.replace(from, to)
console.log(`redirecting from ${from} to ${newTo}`)
- navigate(newTo, { state })
+ void navigate(newTo, { state })
}
}, [pathname])
}
diff --git a/app/hooks/useSelectedWeek.tsx b/app/hooks/useSelectedWeek.tsx
index 1c0aabc2..e92cc917 100644
--- a/app/hooks/useSelectedWeek.tsx
+++ b/app/hooks/useSelectedWeek.tsx
@@ -1,5 +1,5 @@
import { LocalDate } from "@js-joda/core"
-import { useParams } from "@remix-run/react"
+import { useParams } from "react-router"
import { getWeek } from "lib/getWeek"
export function useSelectedWeek() {
diff --git a/app/hooks/useSelectedYear.tsx b/app/hooks/useSelectedYear.tsx
index 0074a1ed..3677a4ae 100644
--- a/app/hooks/useSelectedYear.tsx
+++ b/app/hooks/useSelectedYear.tsx
@@ -1,4 +1,4 @@
-import { useParams } from "react-router-dom"
+import { useParams } from "react-router"
import { getCurrentYear } from "lib/getCurrentYear"
import { yearFromString } from "lib/yearFromString"
diff --git a/app/index.html b/app/index.html
deleted file mode 100644
index 3f32f93b..00000000
--- a/app/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- XDev
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/root.tsx b/app/root.tsx
index fae68182..f8fe07b7 100644
--- a/app/root.tsx
+++ b/app/root.tsx
@@ -1,5 +1,5 @@
import "@ibm/plex/css/ibm-plex.css"
-import { Links, Outlet, Scripts, ScrollRestoration } from "@remix-run/react"
+import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router"
import { Loading } from "ui/Loading"
import "./index.css"
@@ -14,11 +14,24 @@ export default function App() {
export function Layout({ children }: { children: React.ReactNode }) {
return (
- <>
- {children}
-
-
- >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {children}
+
+
+
+
)
}
diff --git a/app/routes.ts b/app/routes.ts
new file mode 100644
index 00000000..cfbfaec3
--- /dev/null
+++ b/app/routes.ts
@@ -0,0 +1,16 @@
+import { remixRoutesOptionAdapter } from "@react-router/remix-routes-option-adapter"
+import { flatRoutes } from "remix-flat-routes"
+
+const routes = remixRoutesOptionAdapter(defineRoutes => {
+ return flatRoutes("routes", defineRoutes, {
+ ignoredRouteFiles: ["**/.*"], // Ignore dot files (like .DS_Store)
+ // appDir: 'app',
+ // routeDir: 'routes',
+ // basePath: '/',
+ // paramPrefixChar: '$',
+ // nestedDirectoryChar: '+',
+ // routeRegex: /((\${nestedDirectoryChar}[\/\\][^\/\\:?*]+)|[\/\\]((index|route|layout|page)|(_[^\/\\:?*]+)|([^\/\\:?*]+\.route)))\.(ts|tsx|js|jsx|md|mdx)$$/,
+ })
+})
+
+export default routes
diff --git a/app/routes/_private+/_private.tsx b/app/routes/_private+/_private.tsx
index fc6c4706..b2cd8a9b 100644
--- a/app/routes/_private+/_private.tsx
+++ b/app/routes/_private+/_private.tsx
@@ -1,4 +1,4 @@
-import { Outlet } from "@remix-run/react"
+import { Outlet } from "react-router"
import { AuthContextProvider } from "context/Auth/AuthContextProvider"
import { DatabaseContextProvider } from "context/Database/DatabaseContextProvider"
import { useTeam } from "hooks/useTeam"
diff --git a/app/routes/_private+/devtools+/_devtools.tsx b/app/routes/_private+/devtools+/_devtools.tsx
index 4ab17600..34603f70 100644
--- a/app/routes/_private+/devtools+/_devtools.tsx
+++ b/app/routes/_private+/devtools+/_devtools.tsx
@@ -1,4 +1,4 @@
-import { Outlet } from "react-router-dom"
+import { Outlet } from "react-router"
import { PageLayout } from "ui/layouts/PageLayout"
import { SecondaryNav } from "ui/SecondaryNav"
diff --git a/app/routes/_private+/dones+/_dones.tsx b/app/routes/_private+/dones+/_dones.tsx
index 6b79c96c..bbd173be 100644
--- a/app/routes/_private+/dones+/_dones.tsx
+++ b/app/routes/_private+/dones+/_dones.tsx
@@ -1,4 +1,4 @@
-import { Outlet } from "@remix-run/react"
+import { Outlet } from "react-router"
import { useRedirect } from "hooks/useRedirect"
import { getSunday } from "lib/getSunday"
diff --git a/app/routes/_private+/hours+/_hours.tsx b/app/routes/_private+/hours+/_hours.tsx
index 458160cd..a4b9843d 100644
--- a/app/routes/_private+/hours+/_hours.tsx
+++ b/app/routes/_private+/hours+/_hours.tsx
@@ -1,4 +1,4 @@
-import { Outlet } from "@remix-run/react"
+import { Outlet } from "react-router"
import { useRedirect } from "hooks/useRedirect"
import { getCurrentYear } from "lib/getCurrentYear"
diff --git a/app/routes/_private+/myweek+/_myweek.tsx b/app/routes/_private+/myweek+/_myweek.tsx
index 84b04848..7a36aa00 100644
--- a/app/routes/_private+/myweek+/_myweek.tsx
+++ b/app/routes/_private+/myweek+/_myweek.tsx
@@ -1,4 +1,4 @@
-import { Outlet } from "@remix-run/react"
+import { Outlet } from "react-router"
import { useRedirect } from "hooks/useRedirect"
import { getSunday } from "lib/getSunday"
diff --git a/app/routes/_private+/settings+/_settings.tsx b/app/routes/_private+/settings+/_settings.tsx
index 12f3e0a9..5d480cbd 100644
--- a/app/routes/_private+/settings+/_settings.tsx
+++ b/app/routes/_private+/settings+/_settings.tsx
@@ -1,4 +1,4 @@
-import { Outlet } from "react-router-dom"
+import { Outlet } from "react-router"
import { SecondaryNav } from "ui/SecondaryNav"
import { PageLayout } from "ui/layouts/PageLayout"
diff --git a/app/routes/_private+/settings+/devices+/_devices.tsx b/app/routes/_private+/settings+/devices+/_devices.tsx
index 52f2e1f4..6fd87d0a 100644
--- a/app/routes/_private+/settings+/devices+/_devices.tsx
+++ b/app/routes/_private+/settings+/devices+/_devices.tsx
@@ -1,5 +1,5 @@
import { useTeam } from "hooks/useTeam"
-import { Outlet } from "react-router-dom"
+import { Outlet } from "react-router"
import { Devices } from "ui/Devices"
export default function DevicesPage() {
diff --git a/app/routes/_private+/settings+/devices+/invite.tsx b/app/routes/_private+/settings+/devices+/invite.tsx
index a293bfdb..b1ba4dfe 100644
--- a/app/routes/_private+/settings+/devices+/invite.tsx
+++ b/app/routes/_private+/settings+/devices+/invite.tsx
@@ -1,4 +1,4 @@
-import { useNavigate } from "@remix-run/react"
+import { useNavigate } from "react-router"
import { useDeviceInvitationGenerator } from "hooks/useDeviceInvitationGenerator"
import { useTeam } from "hooks/useTeam"
import { InviteDeviceDialog } from "ui/InviteDeviceDialog"
@@ -15,7 +15,7 @@ export default function DevicesInvitePage() {
return (
navigate("..")}
+ onClose={async () => navigate("..")}
invitationCode={invitationCode}
/>
)
diff --git a/app/routes/_private+/team+/_team.tsx b/app/routes/_private+/team+/_team.tsx
index e9224c38..f51366ce 100644
--- a/app/routes/_private+/team+/_team.tsx
+++ b/app/routes/_private+/team+/_team.tsx
@@ -1,4 +1,4 @@
-import { Outlet } from "react-router-dom"
+import { Outlet } from "react-router"
import { SecondaryNav } from "ui/SecondaryNav"
import { PageLayout } from "ui/layouts/PageLayout"
diff --git a/app/routes/_private+/team+/members+/_members.tsx b/app/routes/_private+/team+/members+/_members.tsx
index ff207f7f..5ae13e27 100644
--- a/app/routes/_private+/team+/members+/_members.tsx
+++ b/app/routes/_private+/team+/members+/_members.tsx
@@ -1,5 +1,5 @@
import { useTeam } from "hooks/useTeam"
-import { Outlet } from "react-router-dom"
+import { Outlet } from "react-router"
import { Members } from "ui/Members"
export default function MembersPage() {
diff --git a/app/routes/_private+/team+/members+/invite.tsx b/app/routes/_private+/team+/members+/invite.tsx
index 252144ae..f7721c70 100644
--- a/app/routes/_private+/team+/members+/invite.tsx
+++ b/app/routes/_private+/team+/members+/invite.tsx
@@ -1,7 +1,7 @@
import { useDatabase } from "hooks/useDatabase"
import { useMemberInvitationGenerator } from "hooks/useMemberInvitationGenerator"
import { useTeam } from "hooks/useTeam"
-import { useLocation, useNavigate } from "react-router-dom"
+import { useLocation, useNavigate } from "react-router"
import { type ContactId } from "schema/Contact"
import { InviteMemberDialog } from "ui/InviteMemberDialog"
@@ -26,7 +26,7 @@ export default function MembersInvitePage() {
return (
navigate("..")}
+ onClose={async () => navigate("..")}
contact={contact}
invitationCode={invitationCode}
/>
diff --git a/app/routes/_private+/team+/members+/remove.tsx b/app/routes/_private+/team+/members+/remove.tsx
index 86761628..52fb5bde 100644
--- a/app/routes/_private+/team+/members+/remove.tsx
+++ b/app/routes/_private+/team+/members+/remove.tsx
@@ -1,6 +1,6 @@
import { useDatabase } from "hooks/useDatabase"
import { useTeam } from "hooks/useTeam"
-import { useLocation, useNavigate } from "react-router-dom"
+import { useLocation, useNavigate } from "react-router"
import type { ContactId } from "schema/Contact"
import { RemoveMemberDialog } from "ui/RemoveMemberDialog"
@@ -21,7 +21,7 @@ export default function RemovePage() {
return (
navigate("..")}
+ onClose={async () => navigate("..")}
contact={contact}
remove={() => {
team.remove(contact.id)
diff --git a/app/routes/_private+/team+/members+/revoke.tsx b/app/routes/_private+/team+/members+/revoke.tsx
index cf8aa13a..50179f92 100644
--- a/app/routes/_private+/team+/members+/revoke.tsx
+++ b/app/routes/_private+/team+/members+/revoke.tsx
@@ -1,6 +1,6 @@
import { useInvitation } from "hooks/useInvitation"
import { useTeam } from "hooks/useTeam"
-import { useLocation, useNavigate } from "react-router-dom"
+import { useLocation, useNavigate } from "react-router"
import type { ContactId } from "schema/Contact"
import { RevokeInvitationDialog } from "ui/RevokeInvitationDialog"
@@ -23,7 +23,7 @@ export default function RevokeInvitationPage() {
return (
navigate("..")}
+ onClose={async () => navigate("..")}
contact={contact}
invitation={invitation}
revoke={revoke}
diff --git a/app/routes/auth+/_auth.tsx b/app/routes/auth+/_auth.tsx
index 401b25e5..5ac20f5d 100644
--- a/app/routes/auth+/_auth.tsx
+++ b/app/routes/auth+/_auth.tsx
@@ -1,4 +1,4 @@
-import { Outlet } from "react-router-dom"
+import { Outlet } from "react-router"
import { CenteredLayout } from "ui/layouts/CenteredLayout"
export default function AuthLayout() {
diff --git a/app/routes/auth+/begin.tsx b/app/routes/auth+/begin.tsx
index b50caedc..bebc4f62 100644
--- a/app/routes/auth+/begin.tsx
+++ b/app/routes/auth+/begin.tsx
@@ -1,4 +1,4 @@
-import { useNavigate } from "@remix-run/react"
+import { useNavigate } from "react-router"
import { useLocalState } from "hooks/useLocalState"
import { UserNameForm } from "ui/UserNameForm"
@@ -11,7 +11,7 @@ export default function AuthBeginPage() {
userName={userName}
onSubmit={({ n: userName }) => {
update({ userName })
- navigate("/auth/setup")
+ void navigate("/auth/setup")
}}
/>
)
diff --git a/app/routes/auth+/setup+/_.create.tsx b/app/routes/auth+/setup+/_.create.tsx
index daf83b21..d2c39e94 100644
--- a/app/routes/auth+/setup+/_.create.tsx
+++ b/app/routes/auth+/setup+/_.create.tsx
@@ -4,7 +4,7 @@
import { createUser } from "@localfirst/auth"
import { getShareId } from "@localfirst/auth-provider-automerge-repo"
-import { useNavigate } from "@remix-run/react"
+import { useNavigate } from "react-router"
import { createDevice, type UserInfo } from "context/Auth/createDevice"
import { getInitialContacts } from "context/Auth/getInitialContacts"
import { initializeAuthRepo } from "context/Auth/initializeAuthRepo"
@@ -26,7 +26,7 @@ export default function AuthCreatePage() {
// hooks ↑
if (!userName) {
- navigate("/auth/begin")
+ void navigate("/auth/begin")
return null
}
@@ -68,7 +68,7 @@ export default function AuthCreatePage() {
update({ user, device, rootDocumentId, shareId })
// Navigate to the app
- navigate("/")
+ void navigate("/")
}}
/>
)
diff --git a/app/routes/auth+/setup+/_.join.($code).tsx b/app/routes/auth+/setup+/_.join.($code).tsx
index 5c8f7d6a..4975abc2 100644
--- a/app/routes/auth+/setup+/_.join.($code).tsx
+++ b/app/routes/auth+/setup+/_.join.($code).tsx
@@ -5,7 +5,7 @@ import { eventPromise } from "@herbcaudill/eventemitter42"
import * as Auth from "@localfirst/auth"
import { createUser } from "@localfirst/auth"
import { type AuthErrorType } from "@localfirst/auth-provider-automerge-repo"
-import { useNavigate, useParams } from "@remix-run/react"
+import { useNavigate, useParams } from "react-router"
import { createDevice, type UserInfo } from "context/Auth/createDevice"
import { getRootDocumentIdFromTeam } from "context/Auth/getRootDocumentIdFromTeam"
import { initializeAuthRepo } from "context/Auth/initializeAuthRepo"
@@ -95,7 +95,7 @@ export default function AuthJoinPage() {
// Save our user info etc. to local storage
update({ user, device, rootDocumentId, shareId })
- navigate("/")
+ void navigate("/")
}
return invitationCodeFromUrl ?
diff --git a/app/routes/auth+/setup+/_.link.($code).tsx b/app/routes/auth+/setup+/_.link.($code).tsx
index 42905774..da8db54d 100644
--- a/app/routes/auth+/setup+/_.link.($code).tsx
+++ b/app/routes/auth+/setup+/_.link.($code).tsx
@@ -1,5 +1,5 @@
import { eventPromise } from "@herbcaudill/eventemitter42"
-import { useNavigate } from "@remix-run/react"
+import { useNavigate } from "react-router"
import { createDevice } from "context/Auth/createDevice"
import { getRootDocumentIdFromTeam } from "context/Auth/getRootDocumentIdFromTeam"
import { initializeAuthRepo } from "context/Auth/initializeAuthRepo"
@@ -30,7 +30,7 @@ export default function AuthLinkPage() {
const rootDocumentId = getRootDocumentIdFromTeam(team)
update({ user, device, rootDocumentId, shareId })
- navigate("/")
+ void navigate("/")
}}
/>
)
diff --git a/app/routes/auth+/setup+/_setup.tsx b/app/routes/auth+/setup+/_setup.tsx
index 0378aee6..6aeb69f9 100644
--- a/app/routes/auth+/setup+/_setup.tsx
+++ b/app/routes/auth+/setup+/_setup.tsx
@@ -1,11 +1,11 @@
-import { useNavigate } from "@remix-run/react"
+import { useNavigate } from "react-router"
import { useLocalState } from "hooks/useLocalState"
import { SetupOptions } from "ui/SetupOptions"
export default function AuthSetupPage() {
const { userName } = useLocalState()
const navigate = useNavigate()
- if (!userName) navigate("/auth/begin")
+ if (!userName) void navigate("/auth/begin")
return
}
diff --git a/app/ui/Devices.tsx b/app/ui/Devices.tsx
index 4d459776..edafce36 100644
--- a/app/ui/Devices.tsx
+++ b/app/ui/Devices.tsx
@@ -1,5 +1,5 @@
import type { Device, DeviceWithSecrets, UnixTimestamp } from "@localfirst/auth"
-import { Link } from "@remix-run/react"
+import { Link } from "react-router"
import { Button } from "@ui/button"
import { cx } from "lib/cx"
import { getBrowserIcon, getDeviceIcon, getOsIcon } from "lib/getDeviceIcon"
diff --git a/app/ui/ErrorScreen.tsx b/app/ui/ErrorScreen.tsx
index bc3d33ad..b7b02f2b 100644
--- a/app/ui/ErrorScreen.tsx
+++ b/app/ui/ErrorScreen.tsx
@@ -1,5 +1,5 @@
import { Card, CardContent, CardHeader, CardTitle } from "@ui/card"
-import { type ErrorResponse } from "react-router-dom"
+import { type ErrorResponse } from "react-router"
import { CenteredLayout } from "./layouts/CenteredLayout"
const isRouteErrorResponse = (e: Error | ErrorResponse): e is ErrorResponse => {
diff --git a/app/ui/Members.tsx b/app/ui/Members.tsx
index 67754679..b75862bb 100644
--- a/app/ui/Members.tsx
+++ b/app/ui/Members.tsx
@@ -1,4 +1,4 @@
-import { Link } from "@remix-run/react"
+import { Link } from "react-router"
import { Button } from "@ui/button"
import { by } from "lib/by"
import { cx } from "lib/cx"
diff --git a/app/ui/SecondaryNav.tsx b/app/ui/SecondaryNav.tsx
index 20c331dc..a2a3b8ac 100644
--- a/app/ui/SecondaryNav.tsx
+++ b/app/ui/SecondaryNav.tsx
@@ -1,6 +1,6 @@
import { useRedirect } from "hooks/useRedirect"
import { cx } from "lib/cx"
-import { NavLink } from "react-router-dom"
+import { NavLink } from "react-router"
export function SecondaryNav({ heading, items = [], parent: parentPath }: Props) {
const [firstItem] = items
diff --git a/app/ui/SetupOptions.tsx b/app/ui/SetupOptions.tsx
index 96c13483..2175ca42 100644
--- a/app/ui/SetupOptions.tsx
+++ b/app/ui/SetupOptions.tsx
@@ -2,7 +2,7 @@ import { Card, CardContent, CardHeader } from "@ui/card"
import { Button } from "ui/shadcn/button"
import { cx } from "lib/cx"
import { Fragment } from "react/jsx-runtime"
-import { Link } from "react-router-dom"
+import { Link } from "react-router"
export const SetupOptions = () => {
const options = [
diff --git a/app/ui/Sidebar.tsx b/app/ui/Sidebar.tsx
index 2bc7cdb2..1f1f2803 100644
--- a/app/ui/Sidebar.tsx
+++ b/app/ui/Sidebar.tsx
@@ -1,4 +1,4 @@
-import { NavLink } from "@remix-run/react"
+import { NavLink } from "react-router"
import { cx } from "lib/cx"
import { type ExtendedContact } from "schema/Contact"
import { type NavItem } from "types/types"
diff --git a/app/ui/Signout.tsx b/app/ui/Signout.tsx
index b2fe3846..a4cb8d60 100644
--- a/app/ui/Signout.tsx
+++ b/app/ui/Signout.tsx
@@ -1,6 +1,6 @@
import { Button } from "@ui/button"
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@ui/card"
-import { Link } from "@remix-run/react"
+import { Link } from "react-router"
export const Signout = ({ confirmed = false, onConfirm = () => {} }: Props) => {
const warning = (
diff --git a/app/ui/WeekNav.tsx b/app/ui/WeekNav.tsx
index 3d69d04a..3cfe34ba 100644
--- a/app/ui/WeekNav.tsx
+++ b/app/ui/WeekNav.tsx
@@ -1,4 +1,4 @@
-import { Link, useLocation, useParams } from "@remix-run/react"
+import { Link, useLocation, useParams } from "react-router"
import { useNavigationHotkey } from "hooks/useNavigationHotkey"
import { useSelectedWeek } from "hooks/useSelectedWeek"
import { formatDateRange } from "lib/formatDateRange"
diff --git a/app/ui/YearNav.tsx b/app/ui/YearNav.tsx
index bac4d67c..0901cb2d 100644
--- a/app/ui/YearNav.tsx
+++ b/app/ui/YearNav.tsx
@@ -1,4 +1,4 @@
-import { Link, useLocation } from "@remix-run/react"
+import { Link, useLocation } from "react-router"
import { useNavigationHotkey } from "hooks/useNavigationHotkey"
import { useRedirect } from "hooks/useRedirect"
import { useSelectedYear } from "hooks/useSelectedYear"
diff --git a/package.json b/package.json
index 38c4c8e3..65d858a5 100644
--- a/package.json
+++ b/package.json
@@ -5,12 +5,12 @@
"type": "module",
"scripts": {
"benchmark": "vitest bench",
- "build": "remix vite:build",
+ "build": "react-router build",
"build:storybook": "storybook build",
"build:icons": "node ./scripts/generate-icon-types.js",
"dev": "run-p dev:open dev:syncserver",
"dev:open": "pnpm dev:start --open",
- "dev:start": "remix vite:dev --port 3000 --host",
+ "dev:start": "react-router dev --port 3000 --host",
"dev:syncserver": "cross-env DEBUG=localfirst* NODE_ENV=development node ./scripts/syncserver.js",
"icon-types": "node ./scripts/generate-icon-types.js",
"context": "node ./scripts/populate-context.js",
@@ -62,8 +62,8 @@
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.6",
- "@remix-run/node": "^2.8.1",
- "@remix-run/react": "^2.8.1",
+ "@react-router/node": "^7.0.0",
+ "@react-router/remix-routes-option-adapter": "^7.2.0",
"@storybook/manager-api": "^8.4.6",
"@svgr/core": "^8.1.0",
"@svgr/plugin-jsx": "^8.1.0",
@@ -74,13 +74,14 @@
"csv-parse": "^5.5.5",
"debug": "^4.3.4",
"effect": "^3.5.7",
+ "isbot": "^5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.3",
"react-hotkeys-hook": "^4.5.0",
"react-json-view-lite": "^2.0.1",
"react-qr-code": "^2.0.12",
- "react-router-dom": "^6.22.3",
+ "react-router": "^7.0.0",
"react-textarea-autosize": "^8.5.3",
"remix-flat-routes": "^0.6.4",
"tailwind-merge": "^2.2.1",
@@ -99,7 +100,7 @@
},
"devDependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
- "@remix-run/dev": "^2.8.1",
+ "@react-router/dev": "^7.0.0",
"@storybook/addon-essentials": "^8.4.6",
"@storybook/addon-interactions": "^8.4.6",
"@storybook/addon-links": "^8.4.6",
@@ -143,7 +144,7 @@
"xo": "^0.58.0"
},
"engines": {
- "node": ">=18.0.0"
+ "node": ">=20"
},
"pnpm": {
"overrides": {
diff --git a/playwright.config.ts b/playwright.config.ts
index cdfee765..3d743c92 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -71,7 +71,7 @@ export default defineConfig({
[]
: [
{
- command: "pnpm remix vite:dev --port 3001",
+ command: "pnpm react-router dev --port 3001",
env: { VITE_SYNC_SERVER_PORT: "3031" },
url: "http://localhost:3001",
reuseExistingServer: false,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c95294dd..ddf8fcdb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -106,12 +106,12 @@ importers:
'@radix-ui/react-tooltip':
specifier: ^1.1.6
version: 1.1.6(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@remix-run/node':
- specifier: ^2.8.1
- version: 2.8.1(typescript@5.6.3)
- '@remix-run/react':
- specifier: ^2.8.1
- version: 2.8.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.6.3)
+ '@react-router/node':
+ specifier: ^7.0.0
+ version: 7.2.0(react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(typescript@5.6.3)
+ '@react-router/remix-routes-option-adapter':
+ specifier: ^7.2.0
+ version: 7.2.0(@react-router/dev@7.2.0(@types/node@20.11.27)(react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(terser@5.36.0)(typescript@5.6.3)(vite@5.1.4(@types/node@20.11.27)(terser@5.36.0)))(typescript@5.6.3)
'@storybook/manager-api':
specifier: ^8.4.6
version: 8.4.6(storybook@8.4.6(prettier@3.2.5))
@@ -142,6 +142,9 @@ importers:
effect:
specifier: ^3.5.7
version: 3.5.7
+ isbot:
+ specifier: ^5
+ version: 5.1.23
react:
specifier: ^18.2.0
version: 18.2.0
@@ -160,9 +163,9 @@ importers:
react-qr-code:
specifier: ^2.0.12
version: 2.0.12(react@18.2.0)
- react-router-dom:
- specifier: ^6.22.3
- version: 6.22.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ react-router:
+ specifier: ^7.0.0
+ version: 7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
react-textarea-autosize:
specifier: ^8.5.3
version: 8.5.3(@types/react@18.2.66)(react@18.2.0)
@@ -212,9 +215,9 @@ importers:
'@esbuild-plugins/node-globals-polyfill':
specifier: ^0.2.3
version: 0.2.3(esbuild@0.20.1)
- '@remix-run/dev':
- specifier: ^2.8.1
- version: 2.8.1(@types/node@20.11.27)(terser@5.36.0)(ts-node@10.9.2(@types/node@20.11.27)(typescript@5.6.3))(typescript@5.6.3)(vite@5.1.4(@types/node@20.11.27)(terser@5.36.0))
+ '@react-router/dev':
+ specifier: ^7.0.0
+ version: 7.2.0(@types/node@20.11.27)(react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(terser@5.36.0)(typescript@5.6.3)(vite@5.1.4(@types/node@20.11.27)(terser@5.36.0))
'@storybook/addon-essentials':
specifier: ^8.4.6
version: 8.4.6(@types/react@18.2.66)(storybook@8.4.6(prettier@3.2.5))
@@ -427,10 +430,6 @@ packages:
resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==}
engines: {node: '>=6.9.0'}
- '@babel/helper-annotate-as-pure@7.22.5':
- resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
- engines: {node: '>=6.9.0'}
-
'@babel/helper-annotate-as-pure@7.25.9':
resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==}
engines: {node: '>=6.9.0'}
@@ -447,12 +446,6 @@ packages:
resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==}
engines: {node: '>=6.9.0'}
- '@babel/helper-create-class-features-plugin@7.24.0':
- resolution: {integrity: sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0
-
'@babel/helper-create-class-features-plugin@7.25.9':
resolution: {integrity: sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==}
engines: {node: '>=6.9.0'}
@@ -482,10 +475,6 @@ packages:
resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
engines: {node: '>=6.9.0'}
- '@babel/helper-member-expression-to-functions@7.23.0':
- resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==}
- engines: {node: '>=6.9.0'}
-
'@babel/helper-member-expression-to-functions@7.25.9':
resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==}
engines: {node: '>=6.9.0'}
@@ -510,10 +499,6 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0
- '@babel/helper-optimise-call-expression@7.22.5':
- resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
- engines: {node: '>=6.9.0'}
-
'@babel/helper-optimise-call-expression@7.25.9':
resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==}
engines: {node: '>=6.9.0'}
@@ -532,12 +517,6 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0
- '@babel/helper-replace-supers@7.22.20':
- resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0
-
'@babel/helper-replace-supers@7.25.9':
resolution: {integrity: sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==}
engines: {node: '>=6.9.0'}
@@ -552,10 +531,6 @@ packages:
resolution: {integrity: sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==}
engines: {node: '>=6.9.0'}
- '@babel/helper-skip-transparent-expression-wrappers@7.22.5':
- resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==}
- engines: {node: '>=6.9.0'}
-
'@babel/helper-skip-transparent-expression-wrappers@7.25.9':
resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==}
engines: {node: '>=6.9.0'}
@@ -824,12 +799,6 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-modules-commonjs@7.23.3':
- resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
'@babel/plugin-transform-modules-commonjs@7.25.9':
resolution: {integrity: sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==}
engines: {node: '>=6.9.0'}
@@ -1422,6 +1391,9 @@ packages:
'@types/react': '>=16'
react: '>=16'
+ '@mjackson/node-fetch-server@0.2.0':
+ resolution: {integrity: sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng==}
+
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2':
resolution: {integrity: sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==}
cpu: [arm64]
@@ -2070,6 +2042,44 @@ packages:
peerDependencies:
react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0
+ '@react-router/dev@7.2.0':
+ resolution: {integrity: sha512-GzSNGeWuhx6sMsnidCQAlCAephibUMC61xIAdsc6hBXWCJe/T9wUrvtnh2Xbcpr7BRZJtJN4UhI472ZURA6m9w==}
+ engines: {node: '>=20.0.0'}
+ hasBin: true
+ peerDependencies:
+ '@react-router/serve': ^7.2.0
+ react-router: ^7.2.0
+ typescript: ^5.1.0
+ vite: ^5.1.0 || ^6.0.0
+ wrangler: ^3.28.2
+ peerDependenciesMeta:
+ '@react-router/serve':
+ optional: true
+ typescript:
+ optional: true
+ wrangler:
+ optional: true
+
+ '@react-router/node@7.2.0':
+ resolution: {integrity: sha512-CqBHLwvvV4BB8htmaSwT+SOwX9B4RVOIiEdTlaIp12sNVCGSYDIEGbv3T4Wxeq8p5ynNfhNcdBeXtZ6ZPWVozA==}
+ engines: {node: '>=20.0.0'}
+ peerDependencies:
+ react-router: 7.2.0
+ typescript: ^5.1.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@react-router/remix-routes-option-adapter@7.2.0':
+ resolution: {integrity: sha512-y5LH81y4JMP392FUVdjH+JbT/Q/vzKVA5t/HBb/JIUFjh/KN5bKt4zIoWY7sbr95A61RSIBr4ZDLH/VZrxL35A==}
+ engines: {node: '>=20.0.0'}
+ peerDependencies:
+ '@react-router/dev': ^7.2.0
+ typescript: ^5.1.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
'@react-stately/utils@3.9.1':
resolution: {integrity: sha512-yzw75GE0iUWiyps02BOAPTrybcsMIxEJlzXqtvllAb01O9uX5n0i3X+u2eCpj2UoDF4zS08Ps0jPgWxg8xEYtA==}
peerDependencies:
@@ -2108,17 +2118,6 @@ packages:
typescript:
optional: true
- '@remix-run/react@2.8.1':
- resolution: {integrity: sha512-HTPm1U8+xz2jPaVjZnssrckfmFMA8sUZUdaWnoF5lmLWdReqcQv+XlBhIrQQ3jO9L8iYYdnzaSZZcRFYSdpTYg==}
- engines: {node: '>=18.0.0'}
- peerDependencies:
- react: ^18.0.0
- react-dom: ^18.0.0
- typescript: ^5.1.0
- peerDependenciesMeta:
- typescript:
- optional: true
-
'@remix-run/router@1.15.3':
resolution: {integrity: sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==}
engines: {node: '>=14.0.0'}
@@ -3152,6 +3151,9 @@ packages:
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
engines: {node: '>= 0.4'}
+ babel-dead-code-elimination@1.0.9:
+ resolution: {integrity: sha512-JLIhax/xullfInZjtu13UJjaLHDeTzt3vOeomaSUdO/nAMEL/pWC/laKrSvWylXMnVWyL5bpmG9njqBZlUQOdg==}
+
babel-plugin-polyfill-corejs2@0.4.11:
resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==}
peerDependencies:
@@ -3333,6 +3335,10 @@ packages:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
@@ -3448,6 +3454,10 @@ packages:
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
engines: {node: '>= 0.6'}
+ cookie@1.0.2:
+ resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
+ engines: {node: '>=18'}
+
core-js-compat@3.36.1:
resolution: {integrity: sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==}
@@ -3558,9 +3568,26 @@ packages:
supports-color:
optional: true
+ debug@4.4.0:
+ resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
decode-named-character-reference@1.0.2:
resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==}
+ dedent@1.5.3:
+ resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==}
+ peerDependencies:
+ babel-plugin-macros: ^3.1.0
+ peerDependenciesMeta:
+ babel-plugin-macros:
+ optional: true
+
deep-eql@4.1.3:
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
engines: {node: '>=6'}
@@ -3748,9 +3775,6 @@ packages:
resolution: {integrity: sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==}
engines: {node: '>= 0.4'}
- es-module-lexer@1.4.1:
- resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==}
-
es-module-lexer@1.5.4:
resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
@@ -4743,6 +4767,10 @@ packages:
isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+ isbot@5.1.23:
+ resolution: {integrity: sha512-ie3ehy2iXdkuzaZx32SoKb9b8l9Cm8cqQ1lJjQXnq8GRTrk/Jx7IUDcB4mhlw6H3gWaMqGYoWeV0lPv1P/20Ig==}
+ engines: {node: '>=18'}
+
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
@@ -5995,6 +6023,16 @@ packages:
peerDependencies:
react: '>=16.8'
+ react-router@7.2.0:
+ resolution: {integrity: sha512-fXyqzPgCPZbqhrk7k3hPcCpYIlQ2ugIXDboHUzhJISFVy2DEPsmHgN588MyGmkIOv3jDgNfUE3kJi83L28s/LQ==}
+ engines: {node: '>=20.0.0'}
+ peerDependencies:
+ react: '>=18'
+ react-dom: '>=18'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+
react-style-singleton@2.2.1:
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
engines: {node: '>=10'}
@@ -6056,6 +6094,10 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
recast@0.23.6:
resolution: {integrity: sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ==}
engines: {node: '>= 4'}
@@ -6731,6 +6773,9 @@ packages:
tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
+ turbo-stream@2.4.0:
+ resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==}
+
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
@@ -6811,6 +6856,10 @@ packages:
undici-types@6.19.8:
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+ undici@6.21.1:
+ resolution: {integrity: sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==}
+ engines: {node: '>=18.17'}
+
unicode-canonical-property-names-ecmascript@2.0.1:
resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==}
engines: {node: '>=4'}
@@ -7020,6 +7069,14 @@ packages:
v8-compile-cache-lib@3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+ valibot@0.41.0:
+ resolution: {integrity: sha512-igDBb8CTYr8YTQlOKgaN9nSS0Be7z+WRuaeYqGf3Cjz3aKmSnqEmYnkfVjzIuumGqfHpa3fLIvMEAfhrpqN8ng==}
+ peerDependencies:
+ typescript: '>=5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
validate-npm-package-license@3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
@@ -7043,16 +7100,16 @@ packages:
vfile@5.3.7:
resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==}
- vite-node@1.3.1:
- resolution: {integrity: sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==}
- engines: {node: ^18.0.0 || >=20.0.0}
- hasBin: true
-
vite-node@1.5.0:
resolution: {integrity: sha512-tV8h6gMj6vPzVCa7l+VGq9lwoJjW8Y79vst8QZZGiuRAfijU+EEWuc0kFpmndQrWhMMhet1jdSF+40KSZUqIIw==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
+ vite-node@3.0.0-beta.2:
+ resolution: {integrity: sha512-ofTf6cfRdL30Wbl9n/BX81EyIR5s4PReLmSurrxQ+koLaWUNOEo8E0lCM53OJkb8vpa2URM2nSrxZsIFyvY1rg==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+
vite-plugin-pwa@0.19.3:
resolution: {integrity: sha512-ajY7Vn39hFbkWyqkyoJT40hPJcfU9AAfCugARJ3AdqK258z3mi3dmG88PB0+1WqJwUsedRRPkScH5HnQBzmRMQ==}
engines: {node: '>=16.0.0'}
@@ -7520,10 +7577,6 @@ snapshots:
'@jridgewell/trace-mapping': 0.3.25
jsesc: 3.0.2
- '@babel/helper-annotate-as-pure@7.22.5':
- dependencies:
- '@babel/types': 7.24.0
-
'@babel/helper-annotate-as-pure@7.25.9':
dependencies:
'@babel/types': 7.26.0
@@ -7551,19 +7604,6 @@ snapshots:
lru-cache: 5.1.1
semver: 6.3.1
- '@babel/helper-create-class-features-plugin@7.24.0(@babel/core@7.24.0)':
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-annotate-as-pure': 7.22.5
- '@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-function-name': 7.23.0
- '@babel/helper-member-expression-to-functions': 7.23.0
- '@babel/helper-optimise-call-expression': 7.22.5
- '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
- '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
- '@babel/helper-split-export-declaration': 7.22.6
- semver: 6.3.1
-
'@babel/helper-create-class-features-plugin@7.25.9(@babel/core@7.24.5)':
dependencies:
'@babel/core': 7.24.5
@@ -7589,7 +7629,7 @@ snapshots:
'@babel/core': 7.24.5
'@babel/helper-compilation-targets': 7.25.9
'@babel/helper-plugin-utils': 7.25.9
- debug: 4.3.7
+ debug: 4.4.0
lodash.debounce: 4.0.8
resolve: 1.22.8
transitivePeerDependencies:
@@ -7606,10 +7646,6 @@ snapshots:
dependencies:
'@babel/types': 7.24.0
- '@babel/helper-member-expression-to-functions@7.23.0':
- dependencies:
- '@babel/types': 7.24.0
-
'@babel/helper-member-expression-to-functions@7.25.9':
dependencies:
'@babel/traverse': 7.25.9
@@ -7646,10 +7682,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/helper-optimise-call-expression@7.22.5':
- dependencies:
- '@babel/types': 7.24.0
-
'@babel/helper-optimise-call-expression@7.25.9':
dependencies:
'@babel/types': 7.26.0
@@ -7667,13 +7699,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/helper-replace-supers@7.22.20(@babel/core@7.24.0)':
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-member-expression-to-functions': 7.23.0
- '@babel/helper-optimise-call-expression': 7.22.5
-
'@babel/helper-replace-supers@7.25.9(@babel/core@7.24.5)':
dependencies:
'@babel/core': 7.24.5
@@ -7694,10 +7719,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/helper-skip-transparent-expression-wrappers@7.22.5':
- dependencies:
- '@babel/types': 7.24.0
-
'@babel/helper-skip-transparent-expression-wrappers@7.25.9':
dependencies:
'@babel/traverse': 7.25.9
@@ -7795,10 +7816,10 @@ snapshots:
dependencies:
'@babel/core': 7.24.5
- '@babel/plugin-syntax-decorators@7.24.0(@babel/core@7.24.0)':
+ '@babel/plugin-syntax-decorators@7.24.0(@babel/core@7.24.5)':
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.24.0
+ '@babel/core': 7.24.5
+ '@babel/helper-plugin-utils': 7.25.9
'@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.24.5)':
dependencies:
@@ -7810,15 +7831,15 @@ snapshots:
'@babel/core': 7.24.5
'@babel/helper-plugin-utils': 7.25.9
- '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.0)':
+ '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.5)':
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.24.0
+ '@babel/core': 7.24.5
+ '@babel/helper-plugin-utils': 7.25.9
- '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.0)':
+ '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.5)':
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.24.0
+ '@babel/core': 7.24.5
+ '@babel/helper-plugin-utils': 7.25.9
'@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.5)':
dependencies:
@@ -7978,13 +7999,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.24.0)':
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
- '@babel/helper-plugin-utils': 7.24.0
- '@babel/helper-simple-access': 7.22.5
-
'@babel/plugin-transform-modules-commonjs@7.25.9(@babel/core@7.24.5)':
dependencies:
'@babel/core': 7.24.5
@@ -8143,13 +8157,15 @@ snapshots:
'@babel/core': 7.24.5
'@babel/helper-plugin-utils': 7.25.9
- '@babel/plugin-transform-typescript@7.23.6(@babel/core@7.24.0)':
+ '@babel/plugin-transform-typescript@7.23.6(@babel/core@7.24.5)':
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-annotate-as-pure': 7.22.5
- '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
- '@babel/helper-plugin-utils': 7.24.0
- '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0)
+ '@babel/core': 7.24.5
+ '@babel/helper-annotate-as-pure': 7.25.9
+ '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.24.5)
+ '@babel/helper-plugin-utils': 7.25.9
+ '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.5)
+ transitivePeerDependencies:
+ - supports-color
'@babel/plugin-transform-unicode-escapes@7.25.9(@babel/core@7.24.5)':
dependencies:
@@ -8256,14 +8272,16 @@ snapshots:
'@babel/types': 7.26.0
esutils: 2.0.3
- '@babel/preset-typescript@7.23.3(@babel/core@7.24.0)':
+ '@babel/preset-typescript@7.23.3(@babel/core@7.24.5)':
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.24.0
- '@babel/helper-validator-option': 7.23.5
- '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.24.0)
+ '@babel/core': 7.24.5
+ '@babel/helper-plugin-utils': 7.25.9
+ '@babel/helper-validator-option': 7.25.9
+ '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.5)
+ '@babel/plugin-transform-modules-commonjs': 7.25.9(@babel/core@7.24.5)
+ '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.24.5)
+ transitivePeerDependencies:
+ - supports-color
'@babel/runtime@7.24.0':
dependencies:
@@ -8714,6 +8732,8 @@ snapshots:
'@types/react': 18.2.66
react: 18.2.0
+ '@mjackson/node-fetch-server@0.2.0': {}
+
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2':
optional: true
@@ -8748,7 +8768,7 @@ snapshots:
'@npmcli/fs@3.1.0':
dependencies:
- semver: 7.6.0
+ semver: 7.6.3
'@npmcli/git@4.1.0':
dependencies:
@@ -8758,7 +8778,7 @@ snapshots:
proc-log: 3.0.0
promise-inflight: 1.0.1
promise-retry: 2.0.1
- semver: 7.6.0
+ semver: 7.6.3
which: 3.0.1
transitivePeerDependencies:
- bluebird
@@ -8771,7 +8791,7 @@ snapshots:
json-parse-even-better-errors: 3.0.1
normalize-package-data: 5.0.0
proc-log: 3.0.0
- semver: 7.6.0
+ semver: 7.6.3
transitivePeerDependencies:
- bluebird
@@ -9318,6 +9338,69 @@ snapshots:
clsx: 2.1.0
react: 18.2.0
+ '@react-router/dev@7.2.0(@types/node@20.11.27)(react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(terser@5.36.0)(typescript@5.6.3)(vite@5.1.4(@types/node@20.11.27)(terser@5.36.0))':
+ dependencies:
+ '@babel/core': 7.24.5
+ '@babel/generator': 7.26.2
+ '@babel/parser': 7.26.2
+ '@babel/plugin-syntax-decorators': 7.24.0(@babel/core@7.24.5)
+ '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.5)
+ '@babel/preset-typescript': 7.23.3(@babel/core@7.24.5)
+ '@babel/traverse': 7.25.9
+ '@babel/types': 7.26.0
+ '@npmcli/package-json': 4.0.1
+ '@react-router/node': 7.2.0(react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(typescript@5.6.3)
+ arg: 5.0.2
+ babel-dead-code-elimination: 1.0.9
+ chokidar: 4.0.3
+ dedent: 1.5.3
+ es-module-lexer: 1.5.4
+ exit-hook: 2.2.1
+ fs-extra: 10.1.0
+ gunzip-maybe: 1.4.2
+ jsesc: 3.0.2
+ lodash: 4.17.21
+ pathe: 1.1.2
+ picocolors: 1.1.1
+ picomatch: 2.3.1
+ prettier: 2.8.8
+ react-refresh: 0.14.0
+ react-router: 7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ semver: 7.6.3
+ set-cookie-parser: 2.6.0
+ valibot: 0.41.0(typescript@5.6.3)
+ vite: 5.1.4(@types/node@20.11.27)(terser@5.36.0)
+ vite-node: 3.0.0-beta.2(@types/node@20.11.27)(terser@5.36.0)
+ optionalDependencies:
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - '@types/node'
+ - babel-plugin-macros
+ - bluebird
+ - less
+ - lightningcss
+ - sass
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+
+ '@react-router/node@7.2.0(react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(typescript@5.6.3)':
+ dependencies:
+ '@mjackson/node-fetch-server': 0.2.0
+ react-router: 7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ source-map-support: 0.5.21
+ stream-slice: 0.1.2
+ undici: 6.21.1
+ optionalDependencies:
+ typescript: 5.6.3
+
+ '@react-router/remix-routes-option-adapter@7.2.0(@react-router/dev@7.2.0(@types/node@20.11.27)(react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(terser@5.36.0)(typescript@5.6.3)(vite@5.1.4(@types/node@20.11.27)(terser@5.36.0)))(typescript@5.6.3)':
+ dependencies:
+ '@react-router/dev': 7.2.0(@types/node@20.11.27)(react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(terser@5.36.0)(typescript@5.6.3)(vite@5.1.4(@types/node@20.11.27)(terser@5.36.0))
+ optionalDependencies:
+ typescript: 5.6.3
+
'@react-stately/utils@3.9.1(react@18.2.0)':
dependencies:
'@swc/helpers': 0.5.9
@@ -9329,14 +9412,14 @@ snapshots:
'@remix-run/dev@2.8.1(@types/node@20.11.27)(terser@5.36.0)(ts-node@10.9.2(@types/node@20.11.27)(typescript@5.6.3))(typescript@5.6.3)(vite@5.1.4(@types/node@20.11.27)(terser@5.36.0))':
dependencies:
- '@babel/core': 7.24.0
- '@babel/generator': 7.23.6
- '@babel/parser': 7.24.0
- '@babel/plugin-syntax-decorators': 7.24.0(@babel/core@7.24.0)
- '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0)
- '@babel/preset-typescript': 7.23.3(@babel/core@7.24.0)
- '@babel/traverse': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/core': 7.24.5
+ '@babel/generator': 7.26.2
+ '@babel/parser': 7.26.2
+ '@babel/plugin-syntax-decorators': 7.24.0(@babel/core@7.24.5)
+ '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.5)
+ '@babel/preset-typescript': 7.23.3(@babel/core@7.24.5)
+ '@babel/traverse': 7.25.9
+ '@babel/types': 7.26.0
'@mdx-js/mdx': 2.3.0
'@npmcli/package-json': 4.0.1
'@remix-run/node': 2.8.1(typescript@5.6.3)
@@ -9350,7 +9433,7 @@ snapshots:
chokidar: 3.6.0
cross-spawn: 7.0.3
dotenv: 16.4.5
- es-module-lexer: 1.4.1
+ es-module-lexer: 1.5.4
esbuild: 0.20.1
esbuild-plugins-node-modules-polyfill: 1.6.3(esbuild@0.20.1)
execa: 5.1.1
@@ -9363,9 +9446,9 @@ snapshots:
json5: 2.2.3
lodash: 4.17.21
lodash.debounce: 4.0.8
- minimatch: 9.0.3
+ minimatch: 9.0.4
ora: 5.4.1
- picocolors: 1.0.0
+ picocolors: 1.1.1
picomatch: 2.3.1
pidtree: 0.6.0
postcss: 8.4.35
@@ -9377,7 +9460,7 @@ snapshots:
react-refresh: 0.14.0
remark-frontmatter: 4.0.1
remark-mdx-frontmatter: 1.1.1
- semver: 7.6.0
+ semver: 7.6.3
set-cookie-parser: 2.6.0
tar-fs: 2.1.1
tsconfig-paths: 4.2.0
@@ -9412,17 +9495,6 @@ snapshots:
optionalDependencies:
typescript: 5.6.3
- '@remix-run/react@2.8.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.6.3)':
- dependencies:
- '@remix-run/router': 1.15.3
- '@remix-run/server-runtime': 2.8.1(typescript@5.6.3)
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- react-router: 6.22.3(react@18.2.0)
- react-router-dom: 6.22.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- optionalDependencies:
- typescript: 5.6.3
-
'@remix-run/router@1.15.3': {}
'@remix-run/router@1.15.3-pre.0': {}
@@ -9981,7 +10053,7 @@ snapshots:
'@types/acorn@4.0.6':
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
'@types/aria-query@5.0.4': {}
@@ -10031,7 +10103,7 @@ snapshots:
'@types/estree-jsx@1.0.5':
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
'@types/estree@0.0.39': {}
@@ -10234,7 +10306,7 @@ snapshots:
'@vanilla-extract/babel-plugin-debug-ids@1.0.5':
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.24.5
transitivePeerDependencies:
- supports-color
@@ -10254,8 +10326,8 @@ snapshots:
'@vanilla-extract/integration@6.5.0(@types/node@20.11.27)(terser@5.36.0)':
dependencies:
- '@babel/core': 7.24.0
- '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0)
+ '@babel/core': 7.24.5
+ '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.5)
'@vanilla-extract/babel-plugin-debug-ids': 1.0.5
'@vanilla-extract/css': 1.14.1
esbuild: 0.20.1
@@ -10266,7 +10338,7 @@ snapshots:
mlly: 1.6.1
outdent: 0.8.0
vite: 5.1.4(@types/node@20.11.27)(terser@5.36.0)
- vite-node: 1.3.1(@types/node@20.11.27)(terser@5.36.0)
+ vite-node: 1.5.0(@types/node@20.11.27)(terser@5.36.0)
transitivePeerDependencies:
- '@types/node'
- less
@@ -10453,6 +10525,10 @@ snapshots:
dependencies:
acorn: 8.11.3
+ acorn-jsx@5.3.2(acorn@8.14.0):
+ dependencies:
+ acorn: 8.14.0
+
acorn-walk@8.3.2: {}
acorn@8.11.3: {}
@@ -10645,6 +10721,15 @@ snapshots:
dependencies:
possible-typed-array-names: 1.0.0
+ babel-dead-code-elimination@1.0.9:
+ dependencies:
+ '@babel/core': 7.24.5
+ '@babel/parser': 7.26.2
+ '@babel/traverse': 7.25.9
+ '@babel/types': 7.26.0
+ transitivePeerDependencies:
+ - supports-color
+
babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.5):
dependencies:
'@babel/compat-data': 7.26.2
@@ -10880,6 +10965,10 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
chownr@1.1.4: {}
chownr@2.0.0: {}
@@ -10960,6 +11049,8 @@ snapshots:
cookie@0.6.0: {}
+ cookie@1.0.2: {}
+
core-js-compat@3.36.1:
dependencies:
browserslist: 4.23.0
@@ -11052,10 +11143,16 @@ snapshots:
dependencies:
ms: 2.1.3
+ debug@4.4.0:
+ dependencies:
+ ms: 2.1.3
+
decode-named-character-reference@1.0.2:
dependencies:
character-entities: 2.0.2
+ dedent@1.5.3: {}
+
deep-eql@4.1.3:
dependencies:
type-detect: 4.0.8
@@ -11309,8 +11406,6 @@ snapshots:
iterator.prototype: 1.1.2
safe-array-concat: 1.1.2
- es-module-lexer@1.4.1: {}
-
es-module-lexer@1.5.4: {}
es-object-atoms@1.0.0:
@@ -11716,7 +11811,7 @@ snapshots:
estree-util-attach-comments@2.1.1:
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
estree-util-build-jsx@2.2.2:
dependencies:
@@ -11757,7 +11852,7 @@ snapshots:
eval@0.1.8:
dependencies:
- '@types/node': 20.11.27
+ '@types/node': 20.17.6
require-like: 0.1.2
event-target-shim@5.0.1: {}
@@ -12125,7 +12220,7 @@ snapshots:
hast-util-to-estree@2.3.3:
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
'@types/estree-jsx': 1.0.5
'@types/hast': 2.3.10
'@types/unist': 2.0.10
@@ -12353,7 +12448,7 @@ snapshots:
is-reference@3.0.2:
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
is-regex@1.1.4:
dependencies:
@@ -12425,6 +12520,8 @@ snapshots:
isarray@2.0.5: {}
+ isbot@5.1.23: {}
+
isexe@2.0.0: {}
isomorphic-ws@5.0.0(ws@8.16.0):
@@ -12765,7 +12862,7 @@ snapshots:
media-query-parser@2.0.2:
dependencies:
- '@babel/runtime': 7.24.4
+ '@babel/runtime': 7.26.0
media-typer@0.3.0: {}
@@ -12817,7 +12914,7 @@ snapshots:
micromark-extension-mdx-expression@1.0.8:
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
micromark-factory-mdx-expression: 1.0.9
micromark-factory-space: 1.1.0
micromark-util-character: 1.2.0
@@ -12829,7 +12926,7 @@ snapshots:
micromark-extension-mdx-jsx@1.0.5:
dependencies:
'@types/acorn': 4.0.6
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
estree-util-is-identifier-name: 2.1.0
micromark-factory-mdx-expression: 1.0.9
micromark-factory-space: 1.1.0
@@ -12845,7 +12942,7 @@ snapshots:
micromark-extension-mdxjs-esm@1.0.5:
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
micromark-core-commonmark: 1.1.0
micromark-util-character: 1.2.0
micromark-util-events-to-acorn: 1.2.3
@@ -12857,8 +12954,8 @@ snapshots:
micromark-extension-mdxjs@1.0.1:
dependencies:
- acorn: 8.11.3
- acorn-jsx: 5.3.2(acorn@8.11.3)
+ acorn: 8.14.0
+ acorn-jsx: 5.3.2(acorn@8.14.0)
micromark-extension-mdx-expression: 1.0.8
micromark-extension-mdx-jsx: 1.0.5
micromark-extension-mdx-md: 1.0.1
@@ -12881,7 +12978,7 @@ snapshots:
micromark-factory-mdx-expression@1.0.9:
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
micromark-util-character: 1.2.0
micromark-util-events-to-acorn: 1.2.3
micromark-util-symbol: 1.1.0
@@ -12945,7 +13042,7 @@ snapshots:
micromark-util-events-to-acorn@1.2.3:
dependencies:
'@types/acorn': 4.0.6
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
'@types/unist': 2.0.10
estree-util-visit: 1.2.1
micromark-util-symbol: 1.1.0
@@ -12983,7 +13080,7 @@ snapshots:
micromark@3.2.0:
dependencies:
'@types/debug': 4.1.12
- debug: 4.3.7
+ debug: 4.4.0
decode-named-character-reference: 1.0.2
micromark-core-commonmark: 1.1.0
micromark-factory-space: 1.1.0
@@ -13155,7 +13252,7 @@ snapshots:
dependencies:
hosted-git-info: 6.1.1
is-core-module: 2.13.1
- semver: 7.6.0
+ semver: 7.6.3
validate-npm-package-license: 3.0.4
normalize-path@3.0.0: {}
@@ -13164,7 +13261,7 @@ snapshots:
npm-install-checks@6.3.0:
dependencies:
- semver: 7.6.0
+ semver: 7.6.3
npm-normalize-package-bin@3.0.1: {}
@@ -13172,7 +13269,7 @@ snapshots:
dependencies:
hosted-git-info: 6.1.1
proc-log: 3.0.0
- semver: 7.6.0
+ semver: 7.6.3
validate-npm-package-name: 5.0.0
npm-pick-manifest@8.0.2:
@@ -13180,7 +13277,7 @@ snapshots:
npm-install-checks: 6.3.0
npm-normalize-package-bin: 3.0.1
npm-package-arg: 10.1.0
- semver: 7.6.0
+ semver: 7.6.3
npm-run-all@4.1.5:
dependencies:
@@ -13412,7 +13509,7 @@ snapshots:
periscopic@3.1.0:
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.6
estree-walker: 3.0.3
is-reference: 3.0.2
@@ -13750,6 +13847,16 @@ snapshots:
'@remix-run/router': 1.15.3
react: 18.2.0
+ react-router@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
+ dependencies:
+ '@types/cookie': 0.6.0
+ cookie: 1.0.2
+ react: 18.2.0
+ set-cookie-parser: 2.6.0
+ turbo-stream: 2.4.0
+ optionalDependencies:
+ react-dom: 18.2.0(react@18.2.0)
+
react-style-singleton@2.2.1(@types/react@18.2.66)(react@18.2.0):
dependencies:
get-nonce: 1.0.1
@@ -13827,6 +13934,8 @@ snapshots:
dependencies:
picomatch: 2.3.1
+ readdirp@4.1.2: {}
+
recast@0.23.6:
dependencies:
ast-types: 0.16.1
@@ -14610,6 +14719,8 @@ snapshots:
tslib@2.6.2: {}
+ turbo-stream@2.4.0: {}
+
type-check@0.4.0:
dependencies:
prelude-ls: 1.2.1
@@ -14693,6 +14804,8 @@ snapshots:
undici-types@6.19.8: {}
+ undici@6.21.1: {}
+
unicode-canonical-property-names-ecmascript@2.0.1: {}
unicode-match-property-ecmascript@2.0.0:
@@ -14905,6 +15018,10 @@ snapshots:
v8-compile-cache-lib@3.0.1: {}
+ valibot@0.41.0(typescript@5.6.3):
+ optionalDependencies:
+ typescript: 5.6.3
+
validate-npm-package-license@3.0.4:
dependencies:
spdx-correct: 3.2.0
@@ -14937,7 +15054,7 @@ snapshots:
unist-util-stringify-position: 3.0.3
vfile-message: 3.1.4
- vite-node@1.3.1(@types/node@20.11.27)(terser@5.36.0):
+ vite-node@1.5.0(@types/node@20.11.27)(terser@5.36.0):
dependencies:
cac: 6.7.14
debug: 4.3.4
@@ -14954,12 +15071,12 @@ snapshots:
- supports-color
- terser
- vite-node@1.5.0(@types/node@20.11.27)(terser@5.36.0):
+ vite-node@3.0.0-beta.2(@types/node@20.11.27)(terser@5.36.0):
dependencies:
cac: 6.7.14
- debug: 4.3.4
+ debug: 4.4.0
+ es-module-lexer: 1.5.4
pathe: 1.1.2
- picocolors: 1.0.0
vite: 5.1.4(@types/node@20.11.27)(terser@5.36.0)
transitivePeerDependencies:
- '@types/node'
diff --git a/react-router.config.ts b/react-router.config.ts
new file mode 100644
index 00000000..c945f66b
--- /dev/null
+++ b/react-router.config.ts
@@ -0,0 +1,7 @@
+import type { Config } from "@react-router/dev/config"
+
+export default {
+ // Config options...
+ // SPA mode to get our redirects working (also because we eventually want a SPA)
+ ssr: false,
+} satisfies Config
diff --git a/tsconfig.json b/tsconfig.json
index 1e304b25..5aa610d4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,7 +11,8 @@
"skipLibCheck": true,
"strict": true,
"target": "ESNext",
- "types": ["vite/client"]
+ "types": ["@react-router/node", "vite/client"],
+ "rootDirs": [".", "./.react-router/types"]
},
"include": ["*.ts", "test/**/*.ts"]
}
diff --git a/vite.config.ts b/vite.config.ts
index fa4cf336..ff11c81f 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,6 +1,5 @@
import { NodeGlobalsPolyfillPlugin as nodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill"
-import { vitePlugin as remix, type VitePluginConfig } from "@remix-run/dev"
-import { flatRoutes } from "remix-flat-routes"
+import { reactRouter } from "@react-router/dev/vite"
import { type Options as AutoImportOptions } from "unplugin-auto-import/types"
import autoImport from "unplugin-auto-import/vite"
import iconsResolver from "unplugin-icons/resolver"
@@ -11,19 +10,6 @@ import wasm from "vite-plugin-wasm"
import tsconfigPaths from "vite-tsconfig-paths"
import { defineConfig } from "vitest/config"
-const remixOptions: VitePluginConfig = {
- // SPA mode https://remix.run/docs/en/main/future/spa-mode
- ssr: false,
-
- // see https://github.com/kiliman/remix-flat-routes
- ignoredRouteFiles: ["**/*"],
- routes: async defineRoutes =>
- flatRoutes("routes", defineRoutes, {
- // allow colocating route modules with their components
- ignoredRouteFiles: ["**/lib/*", "**/hooks/*", "**/context/*", "**/ui/*"],
- }),
-}
-
const pwaOptions: Partial = {
includeAssets: ["favicon.ico"],
srcDir: "app",
@@ -66,7 +52,7 @@ const isStorybook = process.argv[1].includes("storybook")
export default defineConfig({
plugins: [
- !isStorybook && remix(remixOptions),
+ !isStorybook && reactRouter(),
tsconfigPaths(),
wasm() as Plugin,
vitePWA(pwaOptions),