@@ -571,7 +571,7 @@ function MapMarkerTooltip({ children, className, ...popupOptions }: MapMarkerToo
return createPortal(
@@ -918,7 +918,7 @@ function MapPopup({
return createPortal(
diff --git a/apps/web/hooks/use-calendar-feed.test.tsx b/apps/web/hooks/use-calendar-feed.test.tsx
index d12e1f94..e4984e0c 100644
--- a/apps/web/hooks/use-calendar-feed.test.tsx
+++ b/apps/web/hooks/use-calendar-feed.test.tsx
@@ -14,7 +14,7 @@ vi.mock("sonner", () => ({
},
}));
-import { createTestQueryClient, renderHook, waitFor } from "@/mocks/react";
+import { createTestQueryClient, renderHook } from "@/mocks/react";
import {
CALENDAR_FEED_QUERY_KEY,
CALENDAR_FEED_ROTATED_URL,
@@ -40,12 +40,12 @@ function getFeed(queryClient: ReturnType) {
return queryClient.getQueryData(CALENDAR_FEED_QUERY_KEY);
}
-function renderCalendarFeed(feed: CalendarFeedData = { enabled: false }) {
+async function renderCalendarFeed(feed: CalendarFeedData = { enabled: false }) {
const queryClient = createTestQueryClient();
setCalendarFeedState(feed);
queryClient.setQueryData(CALENDAR_FEED_QUERY_KEY, feed);
- const view = renderHook(() => useCalendarFeed(), {
+ const view = await renderHook(() => useCalendarFeed(), {
wrapper: ({ children }) => (
{children}
),
@@ -66,11 +66,11 @@ describe("useCalendarFeed", () => {
});
it("enables the feed and writes the new URL into cache", async () => {
- const { result, queryClient } = renderCalendarFeed();
+ const { result, queryClient } = await renderCalendarFeed();
result.current.enable();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(getFeed(queryClient)).toEqual({
enabled: true,
feedUrl: CALENDAR_FEED_URL,
@@ -84,22 +84,22 @@ describe("useCalendarFeed", () => {
it("toasts when enable fails", async () => {
enableCalendarFeedMutation.mockRejectedValueOnce(new Error("nope"));
- const { result } = renderCalendarFeed();
+ const { result } = await renderCalendarFeed();
result.current.enable();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to enable calendar feed");
});
expect(result.current.isEnabled).toBe(false);
});
it("disables the feed optimistically", async () => {
- const { result, queryClient } = renderCalendarFeed(enabledFeed);
+ const { result, queryClient } = await renderCalendarFeed(enabledFeed);
result.current.disable();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(getFeed(queryClient)?.enabled).toBe(false);
});
expect(result.current.isEnabled).toBe(false);
@@ -109,11 +109,11 @@ describe("useCalendarFeed", () => {
it("rolls back and toasts when disable fails", async () => {
disableCalendarFeedMutation.mockRejectedValueOnce(new Error("nope"));
- const { result, queryClient } = renderCalendarFeed(enabledFeed);
+ const { result, queryClient } = await renderCalendarFeed(enabledFeed);
result.current.disable();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to disable calendar feed");
});
expect(getFeed(queryClient)).toEqual(enabledFeed);
@@ -121,11 +121,11 @@ describe("useCalendarFeed", () => {
});
it("rotates the token and invalidates to the new URL", async () => {
- const { result, queryClient } = renderCalendarFeed(enabledFeed);
+ const { result, queryClient } = await renderCalendarFeed(enabledFeed);
result.current.rotate.mutate();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(getFeed(queryClient)).toEqual({
enabled: true,
feedUrl: CALENDAR_FEED_ROTATED_URL,
@@ -138,22 +138,22 @@ describe("useCalendarFeed", () => {
it("toasts when rotate fails", async () => {
rotateCalendarFeedTokenMutation.mockRejectedValueOnce(new Error("nope"));
- const { result, queryClient } = renderCalendarFeed(enabledFeed);
+ const { result, queryClient } = await renderCalendarFeed(enabledFeed);
result.current.rotate.mutate();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to regenerate URL");
});
expect(getFeed(queryClient)).toEqual(enabledFeed);
});
it("deletes the feed optimistically", async () => {
- const { result, queryClient } = renderCalendarFeed(enabledFeed);
+ const { result, queryClient } = await renderCalendarFeed(enabledFeed);
result.current.deleteFeed.mutate();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(getFeed(queryClient)).toEqual({ enabled: false });
});
expect(result.current.isEnabled).toBe(false);
@@ -163,11 +163,11 @@ describe("useCalendarFeed", () => {
it("rolls back and toasts when delete fails", async () => {
deleteCalendarFeedMutation.mockRejectedValueOnce(new Error("nope"));
- const { result, queryClient } = renderCalendarFeed(enabledFeed);
+ const { result, queryClient } = await renderCalendarFeed(enabledFeed);
result.current.deleteFeed.mutate();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to disable calendar feed");
});
expect(getFeed(queryClient)).toEqual(enabledFeed);
diff --git a/apps/web/hooks/use-dashboard-mutations.test.tsx b/apps/web/hooks/use-dashboard-mutations.test.tsx
index de7fd006..0a655c8b 100644
--- a/apps/web/hooks/use-dashboard-mutations.test.tsx
+++ b/apps/web/hooks/use-dashboard-mutations.test.tsx
@@ -20,7 +20,7 @@ import {
makeDashboardDomains,
makeTrackedDomain,
} from "@/components/dashboard/test-fixtures";
-import { createTestQueryClient, renderHook, waitFor } from "@/mocks/react";
+import { createTestQueryClient, renderHook } from "@/mocks/react";
import {
bulkArchiveDomainsMutation,
bulkRemoveDomainsMutation,
@@ -69,7 +69,7 @@ function getSubscription(queryClient: ReturnType)
return queryClient.getQueryData(SUBSCRIPTION_QUERY_KEY);
}
-function renderDashboardMutations(options?: {
+async function renderDashboardMutations(options?: {
domains?: TrackedDomainWithDetails[];
subscription?: SubscriptionCache;
}) {
@@ -80,7 +80,7 @@ function renderDashboardMutations(options?: {
queryClient.setQueryData(DOMAINS_QUERY_KEY, domains);
queryClient.setQueryData(SUBSCRIPTION_QUERY_KEY, subscription);
- const view = renderHook(() => useDashboardMutations(), {
+ const view = await renderHook(() => useDashboardMutations(), {
wrapper: ({ children }) => (
{children}
),
@@ -102,13 +102,13 @@ describe("useDashboardMutations", () => {
});
it("removes a domain and decrements active count", async () => {
- const { result, queryClient } = renderDashboardMutations({
+ const { result, queryClient } = await renderDashboardMutations({
subscription: defaultSubscription({ planQuota: 4, canAddMore: false }),
});
result.current.remove("domain-alpha");
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(getDomains(queryClient).map((d) => d.id)).not.toContain("domain-alpha");
});
expect(getSubscription(queryClient)).toMatchObject({
@@ -121,11 +121,11 @@ describe("useDashboardMutations", () => {
});
it("archives a domain and moves it from active to archived counts", async () => {
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
result.current.archive("domain-alpha");
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(
getDomains(queryClient).find((d) => d.id === "domain-alpha")?.archivedAt,
).toBeInstanceOf(Date);
@@ -139,11 +139,11 @@ describe("useDashboardMutations", () => {
});
it("unarchives a domain and reverses the counts", async () => {
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
result.current.unarchive("domain-archived");
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(
getDomains(queryClient).find((d) => d.id === "domain-archived")?.archivedAt,
).toBeNull();
@@ -157,25 +157,25 @@ describe("useDashboardMutations", () => {
});
it("mutes a domain without touching subscription cache", async () => {
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
const subscriptionBefore = getSubscription(queryClient);
result.current.setMuted("domain-alpha", true);
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(getDomains(queryClient).find((d) => d.id === "domain-alpha")?.muted).toBe(true);
});
expect(getSubscription(queryClient)).toEqual(subscriptionBefore);
expect(toast.success).toHaveBeenCalledWith("Domain muted");
result.current.setMuted("domain-alpha", false);
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.success).toHaveBeenCalledWith("Domain unmuted");
});
});
it("bulk-archives only non-archived ids when counting subscription changes", async () => {
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
await result.current.bulkArchive(["domain-alpha", "domain-archived"]);
@@ -194,7 +194,7 @@ describe("useDashboardMutations", () => {
it("toasts requested count when some ids were already archived", async () => {
bulkArchiveDomainsMutation.mockResolvedValueOnce({ successCount: 1, failedCount: 0 });
- const { result } = renderDashboardMutations();
+ const { result } = await renderDashboardMutations();
await result.current.bulkArchive(["domain-alpha", "domain-archived"]);
@@ -203,7 +203,7 @@ describe("useDashboardMutations", () => {
it("toasts a warning when bulk archive only partially succeeds", async () => {
bulkArchiveDomainsMutation.mockResolvedValueOnce({ successCount: 1, failedCount: 1 });
- const { result } = renderDashboardMutations();
+ const { result } = await renderDashboardMutations();
await result.current.bulkArchive(["domain-alpha", "domain-beta"]);
@@ -212,7 +212,7 @@ describe("useDashboardMutations", () => {
});
it("toasts a singular success when one domain is archived", async () => {
- const { result } = renderDashboardMutations();
+ const { result } = await renderDashboardMutations();
await result.current.bulkArchive(["domain-alpha"]);
@@ -220,7 +220,7 @@ describe("useDashboardMutations", () => {
});
it("bulk-deletes ids and decrements active and archived counts by lifecycle state", async () => {
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
await result.current.bulkDelete(["domain-alpha", "domain-archived"]);
@@ -238,7 +238,7 @@ describe("useDashboardMutations", () => {
});
it("bulk-mutes ids across listDomains cache variants without touching subscription", async () => {
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
const archivedListKey = [...DOMAINS_QUERY_KEY, { includeArchived: true }] as const;
queryClient.setQueryData(archivedListKey, getDomains(queryClient));
const subscriptionBefore = getSubscription(queryClient);
@@ -260,7 +260,7 @@ describe("useDashboardMutations", () => {
});
it("toasts unmute success and a warning when bulk mute only partially succeeds", async () => {
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
await result.current.bulkSetMuted(["domain-alpha"], false);
expect(getDomains(queryClient).find((d) => d.id === "domain-alpha")?.muted).toBe(false);
@@ -273,12 +273,12 @@ describe("useDashboardMutations", () => {
it("rolls back muted flags when bulk mute fails", async () => {
bulkSetMutedMutation.mockRejectedValueOnce(new Error("nope"));
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
const domainsBefore = getDomains(queryClient);
await expect(result.current.bulkSetMuted(["domain-alpha"], true)).rejects.toThrow("nope");
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to mute domains");
});
expect(getDomains(queryClient)).toEqual(domainsBefore);
@@ -286,7 +286,7 @@ describe("useDashboardMutations", () => {
it("toasts a warning when bulk delete only partially succeeds", async () => {
bulkRemoveDomainsMutation.mockResolvedValueOnce({ successCount: 1, failedCount: 1 });
- const { result } = renderDashboardMutations();
+ const { result } = await renderDashboardMutations();
await result.current.bulkDelete(["domain-alpha", "domain-beta"]);
@@ -296,13 +296,13 @@ describe("useDashboardMutations", () => {
it("rolls back domains and subscription when remove fails", async () => {
removeDomainMutation.mockRejectedValueOnce(new Error("nope"));
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
const domainsBefore = getDomains(queryClient);
const subscriptionBefore = getSubscription(queryClient);
result.current.remove("domain-alpha");
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to remove domain");
});
expect(getDomains(queryClient)).toEqual(domainsBefore);
@@ -311,13 +311,13 @@ describe("useDashboardMutations", () => {
it("rolls back and toasts when bulk archive fails", async () => {
bulkArchiveDomainsMutation.mockRejectedValueOnce(new Error("nope"));
- const { result, queryClient } = renderDashboardMutations();
+ const { result, queryClient } = await renderDashboardMutations();
const domainsBefore = getDomains(queryClient);
const subscriptionBefore = getSubscription(queryClient);
await expect(result.current.bulkArchive(["domain-alpha"])).rejects.toThrow("nope");
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to archive domains");
});
expect(getDomains(queryClient)).toEqual(domainsBefore);
diff --git a/apps/web/hooks/use-hydrated-now.test.tsx b/apps/web/hooks/use-hydrated-now.test.tsx
index 28392713..d21fd102 100644
--- a/apps/web/hooks/use-hydrated-now.test.tsx
+++ b/apps/web/hooks/use-hydrated-now.test.tsx
@@ -5,11 +5,13 @@ import { renderHook } from "@/mocks/react";
describe("useHydratedNow", () => {
it("stays null on the first render after resetHydratedNow(null)", async () => {
vi.resetModules();
+ const raf = vi.spyOn(window, "requestAnimationFrame").mockImplementation(() => 0);
const { resetHydratedNow, useHydratedNow } = await import("./use-hydrated-now");
resetHydratedNow(null);
- const { result } = renderHook(() => useHydratedNow());
+ const { result } = await renderHook(() => useHydratedNow());
expect(result.current).toBeNull();
+ raf.mockRestore();
});
});
diff --git a/apps/web/hooks/use-notifications-data.test.tsx b/apps/web/hooks/use-notifications-data.test.tsx
index 5ffe70c0..47b2fed1 100644
--- a/apps/web/hooks/use-notifications-data.test.tsx
+++ b/apps/web/hooks/use-notifications-data.test.tsx
@@ -18,7 +18,7 @@ import {
makeNotification,
makeNotificationsInfiniteData,
} from "@/components/notifications/test-fixtures";
-import { createTestQueryClient, renderHook, waitFor } from "@/mocks/react";
+import { createTestQueryClient, renderHook } from "@/mocks/react";
import {
listNotificationsQuery,
markAllReadMutation,
@@ -57,7 +57,7 @@ function pageItems(
return data?.pages.flatMap((page) => page.items) ?? [];
}
-function renderNotificationsData(options?: {
+async function renderNotificationsData(options?: {
items?: NotificationData[];
filter?: "unread" | "read";
enabled?: boolean;
@@ -82,7 +82,7 @@ function renderNotificationsData(options?: {
);
}
- const view = renderHook(
+ const view = await renderHook(
() =>
useNotificationsData({
filter: options?.filter ?? "unread",
@@ -110,21 +110,21 @@ describe("useNotificationsData", () => {
});
it("does not fetch the list when the popover is closed", async () => {
- const { result } = renderNotificationsData({ enabled: false, items: [unreadAlpha] });
+ const { result } = await renderNotificationsData({ enabled: false, items: [unreadAlpha] });
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(result.current.count).toBe(1);
});
expect(listNotificationsQuery).not.toHaveBeenCalled();
});
it("fetches the read list via listNotificationsQuery", async () => {
- const { result } = renderNotificationsData({
+ const { result } = await renderNotificationsData({
filter: "read",
seedReadList: false,
});
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(result.current.notifications.map((item) => item.id)).toContain("notif-gamma");
});
expect(listNotificationsQuery).toHaveBeenCalledWith(
@@ -133,11 +133,11 @@ describe("useNotificationsData", () => {
});
it("markRead moves the item from inbox to archive and decrements the count", async () => {
- const { result, queryClient } = renderNotificationsData();
+ const { result, queryClient } = await renderNotificationsData();
result.current.markRead.mutate({ id: "notif-alpha" });
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(pageItems(queryClient, "unread").map((item) => item.id)).toEqual(["notif-beta"]);
});
const archived = pageItems(queryClient, "read");
@@ -149,11 +149,11 @@ describe("useNotificationsData", () => {
it("rolls back and toasts when markRead fails", async () => {
markReadMutation.mockRejectedValueOnce(new Error("nope"));
- const { result, queryClient } = renderNotificationsData();
+ const { result, queryClient } = await renderNotificationsData();
result.current.markRead.mutate({ id: "notif-alpha" });
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to mark notification as read");
});
expect(pageItems(queryClient, "unread").map((item) => item.id)).toEqual([
@@ -165,11 +165,11 @@ describe("useNotificationsData", () => {
});
it("markAllRead clears inbox and prepends those items onto archive", async () => {
- const { result, queryClient } = renderNotificationsData();
+ const { result, queryClient } = await renderNotificationsData();
result.current.markAllRead.mutate();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(pageItems(queryClient, "unread")).toEqual([]);
});
expect(pageItems(queryClient, "read").map((item) => item.id)).toEqual([
@@ -183,11 +183,11 @@ describe("useNotificationsData", () => {
it("rolls back and toasts when markAllRead fails", async () => {
markAllReadMutation.mockRejectedValueOnce(new Error("nope"));
- const { result, queryClient } = renderNotificationsData();
+ const { result, queryClient } = await renderNotificationsData();
result.current.markAllRead.mutate();
- await waitFor(() => {
+ await vi.waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to mark notifications as read");
});
expect(pageItems(queryClient, "unread").map((item) => item.id)).toEqual([
diff --git a/apps/web/mocks/react.tsx b/apps/web/mocks/react.tsx
index 219106a5..ba3ad8cd 100644
--- a/apps/web/mocks/react.tsx
+++ b/apps/web/mocks/react.tsx
@@ -1,7 +1,8 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
-import { type RenderOptions, render } from "@testing-library/react";
import { Provider as JotaiProvider } from "jotai";
import { useHydrateAtoms } from "jotai/utils";
+import { LazyMotion, MotionConfig, domMax } from "motion/react";
+import { type ComponentRenderOptions, render as baseRender } from "vitest-browser-react";
/**
* Creates a QueryClient configured for testing.
@@ -46,22 +47,27 @@ function HydrateAtoms({
}
/**
- * Test wrapper that provides QueryClientProvider and JotaiProvider with fresh
- * instances for each test. Ensures test isolation.
+ * Test wrapper that provides QueryClient, Jotai, and Motion with a fresh
+ * instance for each test. `reducedMotion="always"` skips enter/exit so
+ * `m.*` components don't stay stuck at `opacity: 0`.
*/
function createWrapper(queryClient: QueryClient, initialAtomValues: AtomTuple[] = []) {
return function Wrapper({ children }: { children: React.ReactNode }) {
return (
- {children}
+
+
+ {children}
+
+
);
};
}
-interface CustomRenderOptions extends Omit {
+interface CustomRenderOptions extends Omit {
/**
* Optional QueryClient instance. If not provided, a new one will be created
* using createTestQueryClient().
@@ -79,41 +85,33 @@ interface CustomRenderOptions extends Omit {
*
* Usage:
* ```tsx
- * import { render, screen } from '@/lib/test-utils'
+ * import { page } from "vitest/browser"
+ * import { render } from "@/mocks/react"
*
- * it('renders component with React Query', () => {
- * render()
- * expect(screen.getByText('Hello')).toBeInTheDocument()
- * })
- *
- * // With custom QueryClient
- * it('uses prefilled cache', () => {
- * const queryClient = createTestQueryClient()
- * queryClient.setQueryData(['key'], { data: 'value' })
- * render(, { queryClient })
+ * it("renders component with React Query", async () => {
+ * await render()
+ * await expect.element(page.getByText("Hello")).toBeInTheDocument()
* })
* ```
*
* @see https://tanstack.com/query/latest/docs/framework/react/guides/testing
*/
-function customRender(ui: React.ReactElement, options?: CustomRenderOptions) {
+export async function render(ui: React.ReactNode, options?: CustomRenderOptions) {
const {
queryClient = createTestQueryClient(),
initialAtomValues = [],
...renderOptions
} = options ?? {};
+ const screen = await baseRender(ui, {
+ wrapper: createWrapper(queryClient, initialAtomValues),
+ ...renderOptions,
+ });
+
return {
- ...render(ui, {
- wrapper: createWrapper(queryClient, initialAtomValues),
- ...renderOptions,
- }),
+ ...screen,
queryClient,
};
}
-// Re-export everything from @testing-library/react
-export * from "@testing-library/react";
-
-// Override render with our custom version
-export { customRender as render };
+export { renderHook } from "vitest-browser-react";
diff --git a/apps/web/package.json b/apps/web/package.json
index facab45f..095a1e53 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -83,24 +83,21 @@
"@domainstack/typescript-config": "workspace:*",
"@tailwindcss/postcss": "^4.3.3",
"@tailwindcss/typography": "^0.5.20",
- "@testing-library/dom": "10.4.1",
- "@testing-library/jest-dom": "7.0.1",
- "@testing-library/react": "16.3.3",
- "@testing-library/user-event": "14.6.7",
"@types/node": "catalog:",
"@types/react": "19.2.18",
"@types/react-dom": "19.2.7",
"@types/ws": "^8.18.1",
"@vitejs/plugin-react": "^6.1.1",
- "@vitest/browser": "^4.1.11",
- "@vitest/browser-playwright": "^4.1.11",
- "@vitest/coverage-v8": "^4.1.11",
+ "@vitest/browser": "^5.0.0",
+ "@vitest/browser-playwright": "^5.0.0",
+ "@vitest/coverage-v8": "^5.0.0",
"babel-plugin-react-compiler": "1.0.0",
"bufferutil": "^4.1.0",
"msw": "^2.15.0",
"playwright": "^1.63.0",
"tailwindcss": "^4.3.3",
"tw-animate-css": "^1.4.0",
- "vitest": "catalog:"
+ "vitest": "catalog:",
+ "vitest-browser-react": "^2.3.0"
}
}
diff --git a/apps/web/postcss.config.mjs b/apps/web/postcss.config.mjs
index c7bcb4b1..61e36849 100644
--- a/apps/web/postcss.config.mjs
+++ b/apps/web/postcss.config.mjs
@@ -1,5 +1,7 @@
const config = {
- plugins: ["@tailwindcss/postcss"],
+ plugins: {
+ "@tailwindcss/postcss": {},
+ },
};
export default config;
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
index 8bb16608..c38222d6 100644
--- a/apps/web/tsconfig.json
+++ b/apps/web/tsconfig.json
@@ -2,7 +2,7 @@
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@domainstack/typescript-config/nextjs.json",
"compilerOptions": {
- "types": ["@testing-library/jest-dom", "vitest/globals"],
+ "types": ["vitest/globals", "vitest/browser"],
"paths": {
"@/*": ["./*"]
}
diff --git a/apps/web/vitest.browser.css b/apps/web/vitest.browser.css
new file mode 100644
index 00000000..1dc96760
--- /dev/null
+++ b/apps/web/vitest.browser.css
@@ -0,0 +1,4 @@
+/* Skip rendering virtualization so hover/a11y queries see real layout. */
+[class*="[content-visibility:auto]"] {
+ content-visibility: visible !important;
+}
diff --git a/apps/web/vitest.config.ts b/apps/web/vitest.config.ts
index 487affdd..fc9b8c4e 100644
--- a/apps/web/vitest.config.ts
+++ b/apps/web/vitest.config.ts
@@ -12,10 +12,10 @@ export default defineConfig({
"next/link": fileURLToPath(new URL("./mocks/next-link.ts", import.meta.url)),
},
tsconfigPaths: true,
- dedupe: ["react", "react-dom", "nuqs"],
+ dedupe: ["react", "react-dom", "nuqs", "@base-ui/react"],
},
optimizeDeps: {
- include: ["nuqs", "nuqs/adapters/testing"],
+ include: ["nuqs", "nuqs/adapters/testing", "react", "react-dom", "react/jsx-runtime"],
},
define: {
"process.env.NEXT_PUBLIC_BASE_URL": JSON.stringify("https://test.domainstack.io"),
@@ -49,7 +49,11 @@ export default defineConfig({
include: ["**/*.test.tsx"],
browser: {
enabled: true,
- provider: playwright(),
+ provider: playwright({
+ contextOptions: {
+ reducedMotion: "reduce",
+ },
+ }),
headless: true,
instances: [
{
diff --git a/apps/web/vitest.setup.browser.ts b/apps/web/vitest.setup.browser.ts
index 3e6b0888..0420fdda 100644
--- a/apps/web/vitest.setup.browser.ts
+++ b/apps/web/vitest.setup.browser.ts
@@ -5,8 +5,11 @@ globalThis.process = {
cwd: () => "/",
};
-import "@testing-library/jest-dom/vitest";
import { vi } from "vitest";
+import "vitest-browser-react";
+
+import "./app/globals.css";
+import "./vitest.browser.css";
// Mock fetch to prevent network requests
globalThis.fetch = vi.fn(() => {
diff --git a/packages/ui/src/components/alert-dialog.tsx b/packages/ui/src/components/alert-dialog.tsx
index 2d697188..64dd09bd 100644
--- a/packages/ui/src/components/alert-dialog.tsx
+++ b/packages/ui/src/components/alert-dialog.tsx
@@ -24,6 +24,7 @@ function AlertDialogOverlay({ className, ...props }: AlertDialogPrimitive.Backdr
"fixed inset-0 isolate z-50 bg-black/10 backdrop-blur-xs dark:bg-black/50",
"data-open:animate-in data-open:duration-200 data-open:fade-in-0",
"data-closed:animate-out data-closed:duration-200 data-closed:fade-out-0",
+ "motion-reduce:animate-none motion-reduce:transition-none",
// iOS 26+: ensure backdrops cover the visual viewport
"supports-[-webkit-touch-callout:none]:absolute",
className,
@@ -44,6 +45,7 @@ function AlertDialogContent({ className, ...props }: AlertDialogPrimitive.Popup.
"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border bg-background p-5 text-foreground shadow-lg outline-hidden sm:max-w-lg",
"data-open:animate-in data-open:duration-200 data-open:fade-in-0 data-open:zoom-in-95",
"data-closed:animate-out data-closed:duration-200 data-closed:fade-out-0 data-closed:zoom-out-95",
+ "motion-reduce:animate-none motion-reduce:transition-none",
// Nested dialog styling: Dim the parent popup
"data-[nested-dialog-open]:after:absolute data-[nested-dialog-open]:after:inset-0 data-[nested-dialog-open]:after:z-50 data-[nested-dialog-open]:after:rounded-[inherit] data-[nested-dialog-open]:after:bg-black/10 data-[nested-dialog-open]:after:content-['']",
// Prevent interaction with parent dialog when nested dialog is open
diff --git a/packages/ui/src/components/alert.tsx b/packages/ui/src/components/alert.tsx
index 2db9c015..8d87a698 100644
--- a/packages/ui/src/components/alert.tsx
+++ b/packages/ui/src/components/alert.tsx
@@ -4,7 +4,7 @@ import { useRender } from "@base-ui/react/use-render";
import { cn, cva, type VariantProps } from "../utils";
const alertVariants = cva({
- base: "relative grid w-full animate-in grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border bg-card/40 px-4 py-3 text-sm backdrop-blur-lg duration-200 fade-in-0 slide-in-from-top-2 has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-2 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
+ base: "relative grid w-full animate-in grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border bg-card/40 px-4 py-3 text-sm backdrop-blur-lg duration-200 fade-in-0 slide-in-from-top-2 has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-2 motion-reduce:animate-none motion-reduce:transition-none [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
variants: {
variant: {
default: "text-card-foreground",
diff --git a/packages/ui/src/components/combobox.tsx b/packages/ui/src/components/combobox.tsx
index caacb7ef..0f57f390 100644
--- a/packages/ui/src/components/combobox.tsx
+++ b/packages/ui/src/components/combobox.tsx
@@ -105,7 +105,7 @@ function ComboboxContent({
"origin-[var(--transform-origin)] overflow-hidden rounded-lg duration-100",
"data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95",
"data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
- "motion-reduce:animate-none",
+ "motion-reduce:animate-none motion-reduce:transition-none",
"data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
"*:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none",
className,
diff --git a/packages/ui/src/components/context-menu.tsx b/packages/ui/src/components/context-menu.tsx
index a77e86ae..21b9bfac 100644
--- a/packages/ui/src/components/context-menu.tsx
+++ b/packages/ui/src/components/context-menu.tsx
@@ -99,6 +99,7 @@ function ContextMenuContent({
"max-h-[var(--available-height)] origin-[var(--transform-origin)] overflow-x-hidden overflow-y-auto duration-100",
"data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95",
"data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
+ "motion-reduce:animate-none motion-reduce:transition-none",
"data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
diff --git a/packages/ui/src/components/dialog.tsx b/packages/ui/src/components/dialog.tsx
index fea14498..55d4aa8f 100644
--- a/packages/ui/src/components/dialog.tsx
+++ b/packages/ui/src/components/dialog.tsx
@@ -40,6 +40,7 @@ function DialogOverlay({ className, ...props }: DialogPrimitive.Backdrop.Props)
"fixed inset-0 isolate z-50 bg-black/10 backdrop-blur-xs dark:bg-black/50",
"data-open:animate-in data-open:duration-200 data-open:fade-in-0",
"data-closed:animate-out data-closed:duration-200 data-closed:fade-out-0",
+ "motion-reduce:animate-none motion-reduce:transition-none",
// iOS 26+: ensure backdrops cover the visual viewport
"supports-[-webkit-touch-callout:none]:absolute",
className,
@@ -69,6 +70,7 @@ function DialogContent({
"gap-4 rounded-lg border bg-background p-5 text-foreground shadow-lg outline-hidden",
"data-open:animate-in data-open:duration-200 data-open:fade-in-0 data-open:zoom-in-95",
"data-closed:animate-out data-closed:duration-200 data-closed:fade-out-0 data-closed:zoom-out-95",
+ "motion-reduce:animate-none motion-reduce:transition-none",
// Nested dialog styling: Dim the parent popup
"data-[nested-dialog-open]:after:absolute data-[nested-dialog-open]:after:inset-0 data-[nested-dialog-open]:after:z-50 data-[nested-dialog-open]:after:rounded-[inherit] data-[nested-dialog-open]:after:bg-black/10 data-[nested-dialog-open]:after:content-['']",
// Prevent interaction with parent dialog when nested dialog is open
diff --git a/packages/ui/src/components/drawer.tsx b/packages/ui/src/components/drawer.tsx
index c1c7ab4c..185752b9 100644
--- a/packages/ui/src/components/drawer.tsx
+++ b/packages/ui/src/components/drawer.tsx
@@ -25,7 +25,7 @@ function DrawerOverlay({ className, ...props }: DrawerPrimitive.Backdrop.Props)
({
"origin-[var(--transform-origin)]",
"data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95",
"data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
+ "motion-reduce:animate-none motion-reduce:transition-none",
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
popoverWidth,
)}
diff --git a/packages/ui/src/components/navigation-menu.tsx b/packages/ui/src/components/navigation-menu.tsx
index 9adbd415..2d908ab0 100644
--- a/packages/ui/src/components/navigation-menu.tsx
+++ b/packages/ui/src/components/navigation-menu.tsx
@@ -79,6 +79,7 @@ function NavigationMenuContent({ className, ...props }: NavigationMenuPrimitive.
"top-0 left-0 w-full p-2 pr-2.5 md:absolute md:w-auto",
"data-open:animate-in data-open:fade-in-0",
"data-closed:animate-out data-closed:fade-out-0",
+ "motion-reduce:animate-none motion-reduce:transition-none",
className,
)}
{...props}
@@ -94,7 +95,7 @@ function NavigationMenuViewport({ className, ...props }: NavigationMenuPrimitive
sideOffset={10}
collisionPadding={{ top: 5, bottom: 5, left: 20, right: 20 }}
className={cn(
- "z-50 w-[var(--positioner-width)] max-w-[var(--available-width)] transition-[top,left,right,bottom] duration-200 ease-out will-change-[top,left,right,bottom]",
+ "z-50 w-[var(--positioner-width)] max-w-[var(--available-width)] transition-[top,left,right,bottom] duration-200 ease-out will-change-[top,left,right,bottom] motion-reduce:transition-none",
)}
>
=22'}
@@ -1072,6 +1060,9 @@ packages:
'@better-fetch/fetch@1.3.1':
resolution: {integrity: sha512-ABkD1WhyfPZprKRQI3bhATjeiFuNWC9PXhfGWqL+sg/gKrM977oFrYkdb4msM3hgUGonr7KlOsOFT5TU2rht9g==}
+ '@blazediff/core@1.10.0':
+ resolution: {integrity: sha512-AOQff0zgR7cGsZL+4E7hVkmujoPUpm0J9xzWGWZj5wCjd3gmxESXAPfKyuzs93VdpQNFhHlBhfOjrcZ+XTERtQ==}
+
'@blazediff/core@1.9.1':
resolution: {integrity: sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA==}
@@ -3152,41 +3143,6 @@ packages:
resolution: {integrity: sha512-GwdDyGGr6UXAtubF14yAwcXvdaogqfsQgIk89Suebjxob/Rjq2xvfmXsjDF1rQmKmhHsJm9TOY7myxv3i6geJw==}
engines: {node: '>=20'}
- '@testing-library/dom@10.4.1':
- resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==}
- engines: {node: '>=18'}
-
- '@testing-library/jest-dom@7.0.1':
- resolution: {integrity: sha512-oMDTC3oA+6CXSO2JZnvOI7CA6oVub6kij5ggk9ohwye5slmkwxYDXcPOVxgMw/RQlticjtO0C1RZkR97HgrWMw==}
- engines: {node: '>=22', npm: '>=6', yarn: '>=1'}
- peerDependencies:
- '@testing-library/dom': '>=10 <11'
- vitest: '>= 0.32'
- peerDependenciesMeta:
- vitest:
- optional: true
-
- '@testing-library/react@16.3.3':
- resolution: {integrity: sha512-Uo193NgQbPMz6lrrhtRQQFcMC6Re/ELLFbbuVL30WDlZxlpZf9/lMHTAVxPRLw1q1iu9OJmR1c2BLiENRstdBg==}
- engines: {node: '>=18'}
- peerDependencies:
- '@testing-library/dom': ^10.0.0
- '@types/react': 19.2.18
- '@types/react-dom': 19.2.7
- react: 19.2.8
- react-dom: 19.2.8
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
- '@testing-library/user-event@14.6.7':
- resolution: {integrity: sha512-MPCpX8bxe8zS+JmmTwLp8jd0dy1rAm60Te/SL8JrQM3qvQJcBOs1d7IefJMyZzqM3EWBrDn/LWDt1BCGu4ASfg==}
- engines: {node: '>=12', npm: '>=6'}
- peerDependencies:
- '@testing-library/dom': '>=7.21.4'
-
'@tokenizer/inflate@0.4.1':
resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==}
engines: {node: '>=18'}
@@ -3247,9 +3203,6 @@ packages:
cpu: [arm64]
os: [win32]
- '@types/aria-query@5.0.4':
- resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
-
'@types/chai@5.2.3':
resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
@@ -3536,11 +3489,22 @@ packages:
playwright: '*'
vitest: 4.1.11
+ '@vitest/browser-playwright@5.0.0':
+ resolution: {integrity: sha512-N+gED9y4/8pypaHjz/x0ah3CjoBr+N0hWWT+Gq4VXtMzyB+rUIdHni0ulzpD1j4H77iWy5Jg8PRMlVn6kjxo6g==}
+ peerDependencies:
+ playwright: '*'
+ vitest: 5.0.0
+
'@vitest/browser@4.1.11':
resolution: {integrity: sha512-bwMovvAeuTFOK5kIFevw4VEf+1gVEICv4SYK4k3knJOxl6b1zEWud8mYKD73e1B0odAn174h1MofURy2TPWf3w==}
peerDependencies:
vitest: 4.1.11
+ '@vitest/browser@5.0.0':
+ resolution: {integrity: sha512-JC9FG5xIRxPHXJPcdCaluIJcEoeM0IwGQ3xneuJk09LXKHRNs40BqWDWymQikbb20yOpYvzpKzmYgPRuSzKmvg==}
+ peerDependencies:
+ vitest: 5.0.0
+
'@vitest/coverage-v8@4.1.11':
resolution: {integrity: sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==}
peerDependencies:
@@ -3550,9 +3514,26 @@ packages:
'@vitest/browser':
optional: true
+ '@vitest/coverage-v8@5.0.0':
+ resolution: {integrity: sha512-toMg6PZGCIa/lQNCDoASrfb1ly4hsUKXFtFYC9kD4t78o5Y6LyNJU7AENt8eHPr3quYdxaxK7hj2mnbFfUk9NA==}
+ peerDependencies:
+ '@vitest/browser': 5.0.0
+ vitest: 5.0.0
+ peerDependenciesMeta:
+ '@vitest/browser':
+ optional: true
+
'@vitest/expect@4.1.11':
resolution: {integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==}
+ '@vitest/istanbul-lib-coverage@1.0.1':
+ resolution: {integrity: sha512-k3DJZ8LhMBK9NS4SclF1ASD3OgXEWDorbIcPTRDK0/Zae6fRvu+fJRxtFdLfHsa9Y24beCdPnoNZ4LviTNstfA==}
+ engines: {node: '>=22'}
+
+ '@vitest/istanbul-lib-report@1.0.1':
+ resolution: {integrity: sha512-1EOLRfsTMnyAr3+kEAsP4o9dhaDlGPpD7H5iLBBeq//YpNB1VIahkPhB+eRp9N2Dkfw8oySROjE3yf9XDeaIkQ==}
+ engines: {node: '>=22'}
+
'@vitest/mocker@4.1.11':
resolution: {integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==}
peerDependencies:
@@ -3564,9 +3545,23 @@ packages:
vite:
optional: true
+ '@vitest/mocker@5.0.0':
+ resolution: {integrity: sha512-66PGTMIiVJP3t4a5yxU9qPtf7MdTBs8jmToMvy+HVflB3Yy13WJZTtPePdvU+wjRV02SKK5doLbSA6o9pwOmiA==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
'@vitest/pretty-format@4.1.11':
resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==}
+ '@vitest/pretty-format@5.0.0':
+ resolution: {integrity: sha512-PVRNuB3wpReb4SQEs4zTKM4KWFhQ5pw3spE8naoDJNB5T5aWRzGKHwXcLUllr0WeOTXpB6bSr3CJLo5+7XQSSQ==}
+
'@vitest/runner@4.1.11':
resolution: {integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==}
@@ -3576,9 +3571,20 @@ packages:
'@vitest/spy@4.1.11':
resolution: {integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==}
+ '@vitest/spy@5.0.0':
+ resolution: {integrity: sha512-uy+luWBAPw9XfthoHi5AkfHUnuPYEESjl0p/r+meoBnU8bxg5GDQ3Ey8MjcJ6sqahkL4PFyrvfMJJBw7LbU06g==}
+
+ '@vitest/ui@5.0.0':
+ resolution: {integrity: sha512-h2FIFwggCY2GxUd2UdQoYNVQkOIqEQLPhNREcl3FUiRsdzQep7NWwYbSmhGEA9nFLPDq5pXzRMcBZQU8Py83sg==}
+ peerDependencies:
+ vitest: 5.0.0
+
'@vitest/utils@4.1.11':
resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==}
+ '@vitest/utils@5.0.0':
+ resolution: {integrity: sha512-dO++xL3vDfvhTAVimfkuQUA3k+JClIF1i1vAkPqpcGAthRmeWnXmHB7YPViPvgCwviX8u7Y5W1u2N//AaQr3fw==}
+
'@webassemblyjs/ast@1.14.1':
resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==}
@@ -3837,10 +3843,6 @@ packages:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
- ansi-styles@5.2.0:
- resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
- engines: {node: '>=10'}
-
ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
@@ -3853,13 +3855,6 @@ packages:
resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
engines: {node: '>=10'}
- aria-query@5.3.0:
- resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
-
- aria-query@5.3.2:
- resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
- engines: {node: '>= 0.4'}
-
assertion-error@2.0.1:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
@@ -4354,9 +4349,6 @@ packages:
resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
engines: {node: '>= 6'}
- css.escape@1.5.1:
- resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
-
cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
@@ -4467,12 +4459,6 @@ packages:
devtools-protocol@0.0.1624250:
resolution: {integrity: sha512-YFAat/lOiIk0ARmBweG+ygrEcbZrq5B9urRyUoeQKp53MlidHXE2TmTbxKcaXoQj7u/aX+jebDO4BW55rs0WwA==}
- dom-accessibility-api@0.5.16:
- resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
-
- dom-accessibility-api@0.6.3:
- resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
-
dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
@@ -4825,6 +4811,9 @@ packages:
fflate@0.4.9:
resolution: {integrity: sha512-zdxgIEddhfsyCaWpJ2SdXEP8ZMrKJ6+5jl4OupODcywU0IhRk6gdXuVGcPICyfx2H97hVK7xmJtRLPjkxAX8Vw==}
+ fflate@0.8.3:
+ resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==}
+
figures@6.1.0:
resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
engines: {node: '>=18'}
@@ -4864,6 +4853,9 @@ packages:
resolution: {integrity: sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==}
engines: {node: '>=18'}
+ flatted@3.4.4:
+ resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==}
+
form-data-encoder@4.1.0:
resolution: {integrity: sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==}
engines: {node: '>= 18'}
@@ -5530,13 +5522,12 @@ packages:
resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==}
engines: {node: 20 || >=22}
- lz-string@1.5.0:
- resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
- hasBin: true
-
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+ magic-string@1.2.3:
+ resolution: {integrity: sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==}
+
magicast@0.5.4:
resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==}
@@ -5766,10 +5757,6 @@ packages:
resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- min-indent@1.0.1:
- resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
- engines: {node: '>=4'}
-
minimatch@10.2.6:
resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==}
engines: {node: 18 || 20 || >=22}
@@ -6363,10 +6350,6 @@ packages:
engines: {node: '>=14'}
hasBin: true
- pretty-format@27.5.1:
- resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
- engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
-
pretty-ms@9.3.1:
resolution: {integrity: sha512-HzMy3Geq23nVALD/M2LliU+F+M+gVNsvkQWWqeBZ8HDiCgzo6YPJ/Omrmtq24EFrIsk0a3EkQGEd7bDOo+IhGA==}
engines: {node: '>=18'}
@@ -6474,9 +6457,6 @@ packages:
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
- react-is@17.0.2:
- resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
-
react-remove-scroll-bar@2.3.8:
resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
engines: {node: '>=10'}
@@ -6530,10 +6510,6 @@ packages:
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
engines: {node: '>= 0.10'}
- redent@3.0.0:
- resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
- engines: {node: '>=8'}
-
reflect-metadata@0.2.2:
resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
@@ -6912,10 +6888,6 @@ packages:
resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==}
engines: {node: '>=18'}
- strip-indent@3.0.0:
- resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
- engines: {node: '>=8'}
-
strip-json-comments@5.0.3:
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
engines: {node: '>=14.16'}
@@ -7042,6 +7014,14 @@ packages:
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+ tinybench@6.1.4:
+ resolution: {integrity: sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==}
+ engines: {node: '>=20.0.0'}
+
+ tinyexec@1.3.0:
+ resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==}
+ engines: {node: '>=18'}
+
tinyexec@1.3.1:
resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==}
engines: {node: '>=18'}
@@ -7332,6 +7312,20 @@ packages:
yaml:
optional: true
+ vitest-browser-react@2.3.0:
+ resolution: {integrity: sha512-S5vdGHHA93j2Z6dbmIJI1wtxT3AXPTRlmC1Meo+ekG011yNnEutMAnHrwyj8qFlGhgBYA8ENGK6+o1Q+vnFz6A==}
+ peerDependencies:
+ '@types/react': 19.2.18
+ '@types/react-dom': 19.2.7
+ react: 19.2.8
+ react-dom: 19.2.8
+ vitest: ^4.0.0 || ^5.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
vitest@4.1.11:
resolution: {integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==}
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
@@ -7373,6 +7367,47 @@ packages:
jsdom:
optional: true
+ vitest@5.0.0:
+ resolution: {integrity: sha512-gpsMNoRhMjMktVxPtstOH4/PJuPyovVaMDr4oDilXaGH1EcqM2OE96SoHT2VIQ6fTGtTjqmHDrEu2X9RQiXf8Q==}
+ engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@opentelemetry/api': ^1.9.0
+ '@types/node': ^22.0.0 || >=24.0.0
+ '@vitest/browser-playwright': 5.0.0
+ '@vitest/browser-preview': 5.0.0
+ '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0
+ '@vitest/coverage-istanbul': 5.0.0
+ '@vitest/coverage-v8': 5.0.0
+ '@vitest/ui': 5.0.0
+ happy-dom: '*'
+ jsdom: '*'
+ vite: ^6.4.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@opentelemetry/api':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/browser-preview':
+ optional: true
+ '@vitest/browser-webdriverio':
+ optional: true
+ '@vitest/coverage-istanbul':
+ optional: true
+ '@vitest/coverage-v8':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
watchpack@2.5.2:
resolution: {integrity: sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==}
engines: {node: '>=10.13.0'}
@@ -7574,8 +7609,6 @@ packages:
snapshots:
- '@adobe/css-tools@4.5.0': {}
-
'@ai-sdk/gateway@4.0.75(zod@4.5.4)':
dependencies:
'@ai-sdk/provider': 4.0.10
@@ -7832,7 +7865,10 @@ snapshots:
'@better-fetch/fetch@1.3.1': {}
- '@blazediff/core@1.9.1': {}
+ '@blazediff/core@1.10.0': {}
+
+ '@blazediff/core@1.9.1':
+ optional: true
'@borewit/text-codec@0.2.2': {}
@@ -8808,11 +8844,11 @@ snapshots:
'@pinojs/redact@0.4.0': {}
- '@polar-sh/better-auth@1.8.4(@polar-sh/sdk@0.47.1)(@stripe/react-stripe-js@4.0.2(@stripe/stripe-js@7.9.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@stripe/stripe-js@7.9.0)(better-auth@1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(@upstash/redis@1.38.4)(kysely@0.29.5)(pg@8.23.0))(next@16.3.4(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(pg@8.23.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@4.1.11))(react@19.2.8)(zod@4.5.4)':
+ '@polar-sh/better-auth@1.8.4(@polar-sh/sdk@0.47.1)(@stripe/react-stripe-js@4.0.2(@stripe/stripe-js@7.9.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@stripe/stripe-js@7.9.0)(better-auth@1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(@upstash/redis@1.38.4)(kysely@0.29.5)(pg@8.23.0))(next@16.3.4(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(pg@8.23.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.0))(react@19.2.8)(zod@4.5.4)':
dependencies:
'@polar-sh/checkout': 0.2.1(@stripe/react-stripe-js@4.0.2(@stripe/stripe-js@7.9.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@stripe/stripe-js@7.9.0)(react@19.2.8)
'@polar-sh/sdk': 0.47.1
- better-auth: 1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(@upstash/redis@1.38.4)(kysely@0.29.5)(pg@8.23.0))(next@16.3.4(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(pg@8.23.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@4.1.11)
+ better-auth: 1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(@upstash/redis@1.38.4)(kysely@0.29.5)(pg@8.23.0))(next@16.3.4(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(pg@8.23.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.0)
zod: 4.5.4
transitivePeerDependencies:
- '@stripe/react-stripe-js'
@@ -9362,43 +9398,6 @@ snapshots:
dependencies:
'@tanstack/store': 0.11.1
- '@testing-library/dom@10.4.1':
- dependencies:
- '@babel/code-frame': 7.29.7
- '@babel/runtime': 7.29.7
- '@types/aria-query': 5.0.4
- aria-query: 5.3.0
- dom-accessibility-api: 0.5.16
- lz-string: 1.5.0
- picocolors: 1.1.1
- pretty-format: 27.5.1
-
- '@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.1)(vitest@4.1.11)':
- dependencies:
- '@adobe/css-tools': 4.5.0
- '@testing-library/dom': 10.4.1
- aria-query: 5.3.2
- css.escape: 1.5.1
- dom-accessibility-api: 0.6.3
- picocolors: 1.1.1
- redent: 3.0.0
- optionalDependencies:
- vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@4.1.11)(@vitest/coverage-v8@4.1.11)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
-
- '@testing-library/react@16.3.3(@testing-library/dom@10.4.1)(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
- dependencies:
- '@babel/runtime': 7.29.7
- '@testing-library/dom': 10.4.1
- react: 19.2.8
- react-dom: 19.2.8(react@19.2.8)
- optionalDependencies:
- '@types/react': 19.2.18
- '@types/react-dom': 19.2.7(@types/react@19.2.18)
-
- '@testing-library/user-event@14.6.7(@testing-library/dom@10.4.1)':
- dependencies:
- '@testing-library/dom': 10.4.1
-
'@tokenizer/inflate@0.4.1(supports-color@10.2.2)':
dependencies:
debug: 4.4.3(supports-color@10.2.2)
@@ -9450,8 +9449,6 @@ snapshots:
'@turbo/windows-arm64@2.10.12':
optional: true
- '@types/aria-query@5.0.4': {}
-
'@types/chai@5.2.3':
dependencies:
'@types/deep-eql': 4.0.2
@@ -9680,14 +9677,28 @@ snapshots:
- msw
- utf-8-validate
- vite
+ optional: true
- '@vitest/browser-playwright@4.1.11(bufferutil@4.1.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(playwright@1.63.0)(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@4.1.11)':
+ '@vitest/browser-playwright@5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.63.0)(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)':
dependencies:
- '@vitest/browser': 4.1.11(bufferutil@4.1.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@4.1.11)
- '@vitest/mocker': 4.1.11(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ '@vitest/browser': 5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)
+ '@vitest/mocker': 5.0.0(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
playwright: 1.63.0
tinyrainbow: 3.1.1
- vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.4.1)(@vitest/browser-playwright@4.1.11)(@vitest/coverage-v8@4.1.11)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ vitest: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ transitivePeerDependencies:
+ - bufferutil
+ - msw
+ - utf-8-validate
+ - vite
+
+ '@vitest/browser-playwright@5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(playwright@1.63.0)(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)':
+ dependencies:
+ '@vitest/browser': 5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)
+ '@vitest/mocker': 5.0.0(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ playwright: 1.63.0
+ tinyrainbow: 3.1.1
+ vitest: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@26.4.1)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
transitivePeerDependencies:
- bufferutil
- msw
@@ -9711,17 +9722,37 @@ snapshots:
- msw
- utf-8-validate
- vite
+ optional: true
- '@vitest/browser@4.1.11(bufferutil@4.1.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@4.1.11)':
+ '@vitest/browser@5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)':
dependencies:
- '@blazediff/core': 1.9.1
- '@vitest/mocker': 4.1.11(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
- '@vitest/utils': 4.1.11
- magic-string: 0.30.21
+ '@blazediff/core': 1.10.0
+ '@vitest/mocker': 5.0.0(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ '@vitest/ui': 5.0.0(vitest@5.0.0)
+ '@vitest/utils': 5.0.0
+ magic-string: 1.2.3
pngjs: 7.0.0
sirv: 3.0.2
tinyrainbow: 3.1.1
- vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.4.1)(@vitest/browser-playwright@4.1.11)(@vitest/coverage-v8@4.1.11)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ vitest: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ ws: 8.21.3(bufferutil@4.1.0)
+ transitivePeerDependencies:
+ - bufferutil
+ - msw
+ - utf-8-validate
+ - vite
+
+ '@vitest/browser@5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)':
+ dependencies:
+ '@blazediff/core': 1.10.0
+ '@vitest/mocker': 5.0.0(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ '@vitest/ui': 5.0.0(vitest@5.0.0)
+ '@vitest/utils': 5.0.0
+ magic-string: 1.2.3
+ pngjs: 7.0.0
+ sirv: 3.0.2
+ tinyrainbow: 3.1.1
+ vitest: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@26.4.1)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
ws: 8.21.3(bufferutil@4.1.0)
transitivePeerDependencies:
- bufferutil
@@ -9745,6 +9776,21 @@ snapshots:
vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@4.1.11)(@vitest/coverage-v8@4.1.11)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
optionalDependencies:
'@vitest/browser': 4.1.11(bufferutil@4.1.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@4.1.11)
+ optional: true
+
+ '@vitest/coverage-v8@5.0.0(@vitest/browser@5.0.0)(vitest@5.0.0)':
+ dependencies:
+ '@bcoe/v8-coverage': 1.0.2
+ '@vitest/istanbul-lib-coverage': 1.0.1
+ '@vitest/istanbul-lib-report': 1.0.1
+ ast-v8-to-istanbul: 1.0.5
+ magicast: 0.5.4
+ obug: 2.1.4
+ std-env: 4.2.0
+ tinyrainbow: 3.1.1
+ vitest: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ optionalDependencies:
+ '@vitest/browser': 5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)
'@vitest/expect@4.1.11':
dependencies:
@@ -9754,6 +9800,13 @@ snapshots:
'@vitest/utils': 4.1.11
chai: 6.2.2
tinyrainbow: 3.1.1
+ optional: true
+
+ '@vitest/istanbul-lib-coverage@1.0.1': {}
+
+ '@vitest/istanbul-lib-report@1.0.1':
+ dependencies:
+ '@vitest/istanbul-lib-coverage': 1.0.1
'@vitest/mocker@4.1.11(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))':
dependencies:
@@ -9763,12 +9816,24 @@ snapshots:
optionalDependencies:
msw: 2.15.0(@types/node@24.13.3)(typescript@7.0.2)
vite: 8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)
+ optional: true
- '@vitest/mocker@4.1.11(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))':
+ '@vitest/mocker@5.0.0(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))':
dependencies:
- '@vitest/spy': 4.1.11
+ '@jridgewell/trace-mapping': 0.3.31
+ '@vitest/spy': 5.0.0
estree-walker: 3.0.3
- magic-string: 0.30.21
+ magic-string: 1.2.3
+ optionalDependencies:
+ msw: 2.15.0(@types/node@24.13.3)(typescript@7.0.2)
+ vite: 8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)
+
+ '@vitest/mocker@5.0.0(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))':
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.31
+ '@vitest/spy': 5.0.0
+ estree-walker: 3.0.3
+ magic-string: 1.2.3
optionalDependencies:
msw: 2.15.0(@types/node@26.4.1)(typescript@7.0.2)
vite: 8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)
@@ -9776,11 +9841,17 @@ snapshots:
'@vitest/pretty-format@4.1.11':
dependencies:
tinyrainbow: 3.1.1
+ optional: true
+
+ '@vitest/pretty-format@5.0.0':
+ dependencies:
+ tinyrainbow: 3.1.1
'@vitest/runner@4.1.11':
dependencies:
'@vitest/utils': 4.1.11
pathe: 2.0.3
+ optional: true
'@vitest/snapshot@4.1.11':
dependencies:
@@ -9788,14 +9859,35 @@ snapshots:
'@vitest/utils': 4.1.11
magic-string: 0.30.21
pathe: 2.0.3
+ optional: true
- '@vitest/spy@4.1.11': {}
+ '@vitest/spy@4.1.11':
+ optional: true
+
+ '@vitest/spy@5.0.0': {}
+
+ '@vitest/ui@5.0.0(vitest@5.0.0)':
+ dependencies:
+ '@vitest/utils': 5.0.0
+ fflate: 0.8.3
+ flatted: 3.4.4
+ pathe: 2.0.3
+ sirv: 3.0.2
+ tinyrainbow: 3.1.1
+ vitest: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
'@vitest/utils@4.1.11':
dependencies:
'@vitest/pretty-format': 4.1.11
convert-source-map: 2.0.0
tinyrainbow: 3.1.1
+ optional: true
+
+ '@vitest/utils@5.0.0':
+ dependencies:
+ '@vitest/pretty-format': 5.0.0
+ convert-source-map: 2.0.0
+ tinyrainbow: 3.1.1
'@webassemblyjs/ast@1.14.1':
dependencies:
@@ -10328,8 +10420,6 @@ snapshots:
dependencies:
color-convert: 2.0.1
- ansi-styles@5.2.0: {}
-
ansi-styles@6.2.3: {}
ansis@3.17.0: {}
@@ -10338,12 +10428,6 @@ snapshots:
dependencies:
tslib: 2.8.1
- aria-query@5.3.0:
- dependencies:
- dequal: 2.0.3
-
- aria-query@5.3.2: {}
-
assertion-error@2.0.1: {}
ast-v8-to-istanbul@1.0.5:
@@ -10447,6 +10531,37 @@ snapshots:
- '@cloudflare/workers-types'
- '@opentelemetry/api'
+ better-auth@1.7.2(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(@upstash/redis@1.38.4)(kysely@0.29.5)(pg@8.23.0))(next@16.3.4(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(pg@8.23.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.0):
+ dependencies:
+ '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.11)(kysely@0.29.5)(nanostores@1.5.3)
+ '@better-auth/drizzle-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.11)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(@upstash/redis@1.38.4)(kysely@0.29.5)(pg@8.23.0))
+ '@better-auth/kysely-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.11)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(kysely@0.29.5)
+ '@better-auth/memory-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.11)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)
+ '@better-auth/mongo-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.11)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)
+ '@better-auth/prisma-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.11)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)
+ '@better-auth/telemetry': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.11)(kysely@0.29.5)(nanostores@1.5.3))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
+ '@noble/ciphers': 2.4.0
+ '@noble/hashes': 2.4.0
+ better-call: 1.4.0(zod@4.5.4)
+ defu: 6.1.7
+ jose: 6.2.11
+ kysely: 0.29.5
+ nanostores: 1.5.3
+ zod: 4.5.4
+ optionalDependencies:
+ drizzle-kit: 0.31.10
+ drizzle-orm: 0.45.2(@electric-sql/pglite@0.5.8)(@opentelemetry/api@1.9.1)(@types/pg@8.23.1)(@upstash/redis@1.38.4)(kysely@0.29.5)(pg@8.23.0)
+ next: 16.3.4(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
+ pg: 8.23.0
+ react: 19.2.8
+ react-dom: 19.2.8(react@19.2.8)
+ vitest: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ transitivePeerDependencies:
+ - '@cloudflare/workers-types'
+ - '@opentelemetry/api'
+
better-call@1.3.7(zod@4.5.4):
dependencies:
'@better-auth/utils': 0.4.3
@@ -10805,8 +10920,6 @@ snapshots:
css-what@6.2.2: {}
- css.escape@1.5.1: {}
-
cssesc@3.0.0: {}
csstype@3.2.3: {}
@@ -10898,10 +11011,6 @@ snapshots:
devtools-protocol@0.0.1624250: {}
- dom-accessibility-api@0.5.16: {}
-
- dom-accessibility-api@0.6.3: {}
-
dom-serializer@2.0.0:
dependencies:
domelementtype: 2.3.0
@@ -11283,6 +11392,8 @@ snapshots:
fflate@0.4.9: {}
+ fflate@0.8.3: {}
+
figures@6.1.0:
dependencies:
is-unicode-supported: 2.1.0
@@ -11350,6 +11461,8 @@ snapshots:
semver-regex: 4.0.5
super-regex: 1.1.0
+ flatted@3.4.4: {}
+
form-data-encoder@4.1.0: {}
forwarded@0.2.0: {}
@@ -11556,7 +11669,8 @@ snapshots:
help-me@5.0.0: {}
- html-escaper@2.0.2: {}
+ html-escaper@2.0.2:
+ optional: true
html-to-text@9.0.5:
dependencies:
@@ -11706,18 +11820,21 @@ snapshots:
isexe@4.0.0: {}
- istanbul-lib-coverage@3.2.2: {}
+ istanbul-lib-coverage@3.2.2:
+ optional: true
istanbul-lib-report@3.0.1:
dependencies:
istanbul-lib-coverage: 3.2.2
make-dir: 4.0.0
supports-color: 7.2.0
+ optional: true
istanbul-reports@3.2.0:
dependencies:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.1
+ optional: true
iterare@1.2.1: {}
@@ -11917,12 +12034,14 @@ snapshots:
lru-cache@11.5.2: {}
- lz-string@1.5.0: {}
-
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.6.0
+ magic-string@1.2.3:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.6.0
+
magicast@0.5.4:
dependencies:
'@babel/parser': 7.29.8
@@ -11938,6 +12057,7 @@ snapshots:
make-dir@4.0.0:
dependencies:
semver: 7.8.5
+ optional: true
maplibre-gl@6.7.0:
dependencies:
@@ -12360,8 +12480,6 @@ snapshots:
mimic-response@4.0.0: {}
- min-indent@1.0.1: {}
-
minimatch@10.2.6:
dependencies:
brace-expansion: 5.0.9
@@ -12937,12 +13055,6 @@ snapshots:
prettier@3.9.6: {}
- pretty-format@27.5.1:
- dependencies:
- ansi-regex: 5.0.1
- ansi-styles: 5.2.0
- react-is: 17.0.2
-
pretty-ms@9.3.1:
dependencies:
parse-ms: 4.0.0
@@ -13087,8 +13199,6 @@ snapshots:
react-is@16.13.1: {}
- react-is@17.0.2: {}
-
react-remove-scroll-bar@2.3.8(@types/react@19.2.18)(react@19.2.8):
dependencies:
react: 19.2.8
@@ -13130,11 +13240,6 @@ snapshots:
dependencies:
resolve: 1.22.12
- redent@3.0.0:
- dependencies:
- indent-string: 4.0.0
- strip-indent: 3.0.0
-
reflect-metadata@0.2.2: {}
rehype-harden@1.1.8:
@@ -13604,10 +13709,6 @@ snapshots:
strip-final-newline@4.0.0: {}
- strip-indent@3.0.0:
- dependencies:
- min-indent: 1.0.1
-
strip-json-comments@5.0.3: {}
strtok3@10.3.5:
@@ -13648,6 +13749,7 @@ snapshots:
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
+ optional: true
supports-color@8.1.1:
dependencies:
@@ -13745,7 +13847,12 @@ snapshots:
dependencies:
convert-hrtime: 5.0.0
- tinybench@2.9.0: {}
+ tinybench@2.9.0:
+ optional: true
+
+ tinybench@6.1.4: {}
+
+ tinyexec@1.3.0: {}
tinyexec@1.3.1: {}
@@ -14036,6 +14143,15 @@ snapshots:
terser: 5.51.2
tsx: 4.23.13
+ vitest-browser-react@2.3.0(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@5.0.0):
+ dependencies:
+ react: 19.2.8
+ react-dom: 19.2.8(react@19.2.8)
+ vitest: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ optionalDependencies:
+ '@types/react': 19.2.18
+ '@types/react-dom': 19.2.7(@types/react@19.2.18)
+
vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@4.1.11)(@vitest/coverage-v8@4.1.11)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)):
dependencies:
'@vitest/expect': 4.1.11
@@ -14065,34 +14181,55 @@ snapshots:
'@vitest/coverage-v8': 4.1.11(@vitest/browser@4.1.11)(vitest@4.1.11)
transitivePeerDependencies:
- msw
+ optional: true
- vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.4.1)(@vitest/browser-playwright@4.1.11)(@vitest/coverage-v8@4.1.11)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)):
+ vitest@5.0.0(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)):
dependencies:
- '@vitest/expect': 4.1.11
- '@vitest/mocker': 4.1.11(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
- '@vitest/pretty-format': 4.1.11
- '@vitest/runner': 4.1.11
- '@vitest/snapshot': 4.1.11
- '@vitest/spy': 4.1.11
- '@vitest/utils': 4.1.11
+ '@types/chai': 5.2.3
+ '@vitest/mocker': 5.0.0(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ chai: 6.2.2
es-module-lexer: 2.3.2
expect-type: 1.4.0
- magic-string: 0.30.21
+ magic-string: 1.2.3
obug: 2.1.4
- pathe: 2.0.3
picomatch: 4.0.7
std-env: 4.2.0
- tinybench: 2.9.0
- tinyexec: 1.3.1
+ tinybench: 6.1.4
+ tinyexec: 1.3.0
+ tinyglobby: 0.2.17
+ vite: 8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@opentelemetry/api': 1.9.1
+ '@types/node': 24.13.3
+ '@vitest/browser-playwright': 5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.63.0)(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)
+ '@vitest/coverage-v8': 5.0.0(@vitest/browser@5.0.0)(vitest@5.0.0)
+ '@vitest/ui': 5.0.0(vitest@5.0.0)
+ transitivePeerDependencies:
+ - msw
+
+ vitest@5.0.0(@opentelemetry/api@1.9.1)(@types/node@26.4.1)(@vitest/browser-playwright@5.0.0)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)):
+ dependencies:
+ '@types/chai': 5.2.3
+ '@vitest/mocker': 5.0.0(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))
+ chai: 6.2.2
+ es-module-lexer: 2.3.2
+ expect-type: 1.4.0
+ magic-string: 1.2.3
+ obug: 2.1.4
+ picomatch: 4.0.7
+ std-env: 4.2.0
+ tinybench: 6.1.4
+ tinyexec: 1.3.0
tinyglobby: 0.2.17
- tinyrainbow: 3.1.1
vite: 8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13)
why-is-node-running: 2.3.0
optionalDependencies:
'@opentelemetry/api': 1.9.1
'@types/node': 26.4.1
- '@vitest/browser-playwright': 4.1.11(bufferutil@4.1.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(playwright@1.63.0)(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@4.1.11)
- '@vitest/coverage-v8': 4.1.11(@vitest/browser@4.1.11)(vitest@4.1.11)
+ '@vitest/browser-playwright': 5.0.0(bufferutil@4.1.0)(msw@2.15.0(@types/node@26.4.1)(typescript@7.0.2))(playwright@1.63.0)(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.23.13))(vitest@5.0.0)
+ '@vitest/coverage-v8': 5.0.0(@vitest/browser@5.0.0)(vitest@5.0.0)
+ '@vitest/ui': 5.0.0(vitest@5.0.0)
transitivePeerDependencies:
- msw
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index cefdf641..55703b06 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -6,7 +6,7 @@ catalog:
'@types/node': ^24.13.3
motion: ^13.2.0
sonner: ^2.0.8
- vitest: ^4.1.11
+ vitest: ^5.0.0
zod: ^4.5.4
overrides:
'@types/react': 19.2.18