fix(web): preserve remote resume edits during autosave

This commit is contained in:
Cursor Agent
2026-05-26 23:08:57 +00:00
parent 8da780c868
commit 004ac15cb3
4 changed files with 251 additions and 81 deletions
+1
View File
@@ -40,6 +40,7 @@
"@reactive-resume/fonts": "workspace:*",
"@reactive-resume/import": "workspace:*",
"@reactive-resume/pdf": "workspace:*",
"@reactive-resume/resume": "workspace:*",
"@reactive-resume/schema": "workspace:*",
"@reactive-resume/ui": "workspace:*",
"@reactive-resume/utils": "workspace:*",
@@ -5,6 +5,7 @@ import type { Resume } from "./draft";
import { act, renderHook } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { i18n } from "@lingui/core";
import { ORPCError } from "@orpc/client";
import { defaultResumeData } from "@reactive-resume/schema/resume/default";
import { useBuilderResumeUpdateSubscription, useResumeStore, useResumeUpdateSubscription } from "./draft";
@@ -30,9 +31,14 @@ const toastMocks = vi.hoisted(() => ({
error: vi.fn(() => "sync-error-toast"),
}));
vi.mock("@orpc/client", () => ({
consumeEventIterator: consumeEventIteratorMock,
}));
vi.mock("@orpc/client", async (importOriginal) => {
const actual = await importOriginal<typeof import("@orpc/client")>();
return {
...actual,
consumeEventIterator: consumeEventIteratorMock,
};
});
vi.mock("@tanstack/react-query", () => ({
useQueryClient: () => queryClientMock,
@@ -103,10 +109,25 @@ function withBasicsName(resume: Resume, name: string): Resume {
};
}
function withSummaryContent(resume: Resume, content: string): Resume {
return {
...resume,
data: {
...resume.data,
summary: {
...resume.data.summary,
content,
},
},
};
}
function withUpdatedAt(resume: Resume, updatedAt: string): Resume {
return { ...resume, updatedAt: new Date(updatedAt) };
}
async function flushMicrotasks() {
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
for (let index = 0; index < 10; index += 1) await Promise.resolve();
}
describe("builder resume autosave", () => {
@@ -131,10 +152,11 @@ describe("builder resume autosave", () => {
useResumeStore.getState().reset();
});
it("coalesces rapid local edits into one full-data update", async () => {
it("coalesces rapid local edits into one data patch", async () => {
const initial = makeResume("resume-rapid");
const updated = withBasicsName(initial, "Latest Name");
const updated = withUpdatedAt(withBasicsName(initial, "Latest Name"), "2026-05-26T12:01:00.000Z");
orpcMocks.updateResume.mockResolvedValue(updated);
orpcMocks.patchResume.mockResolvedValue(updated);
useResumeStore.getState().initialize(initial);
useResumeStore.getState().updateResumeData((draft) => {
@@ -147,21 +169,25 @@ describe("builder resume autosave", () => {
vi.advanceTimersByTime(500);
await flushMicrotasks();
expect(orpcMocks.updateResume).toHaveBeenCalledTimes(1);
expect(orpcMocks.updateResume).toHaveBeenCalledWith(
{ id: initial.id, data: updated.data },
expect(orpcMocks.patchResume).toHaveBeenCalledTimes(1);
expect(orpcMocks.patchResume).toHaveBeenCalledWith(
{
id: initial.id,
expectedUpdatedAt: initial.updatedAt,
operations: [{ op: "replace", path: "/basics/name", value: "Latest Name" }],
},
expect.objectContaining({ signal: expect.any(AbortSignal) }),
);
expect(orpcMocks.patchResume).not.toHaveBeenCalled();
expect(orpcMocks.updateResume).not.toHaveBeenCalled();
});
it("saves the latest pending snapshot after an in-flight save resolves", async () => {
const initial = makeResume("resume-in-flight");
const first = withBasicsName(initial, "First Name");
const latest = withBasicsName(initial, "Latest Name");
const first = withUpdatedAt(withBasicsName(initial, "First Name"), "2026-05-26T12:01:00.000Z");
const latest = withUpdatedAt(withBasicsName(initial, "Latest Name"), "2026-05-26T12:02:00.000Z");
let resolveFirst!: (resume: Resume) => void;
orpcMocks.updateResume
orpcMocks.patchResume
.mockReturnValueOnce(
new Promise<Resume>((resolve) => {
resolveFirst = resolve;
@@ -183,24 +209,32 @@ describe("builder resume autosave", () => {
vi.advanceTimersByTime(500);
await flushMicrotasks();
expect(orpcMocks.updateResume).toHaveBeenCalledTimes(1);
expect(orpcMocks.patchResume).toHaveBeenCalledTimes(1);
resolveFirst(first);
await flushMicrotasks();
expect(orpcMocks.updateResume).toHaveBeenCalledTimes(2);
expect(orpcMocks.updateResume.mock.calls[0]?.[0]).toEqual({ id: initial.id, data: first.data });
expect(orpcMocks.updateResume.mock.calls[1]?.[0]).toEqual({ id: initial.id, data: latest.data });
expect(orpcMocks.patchResume).not.toHaveBeenCalled();
expect(orpcMocks.patchResume).toHaveBeenCalledTimes(2);
expect(orpcMocks.patchResume.mock.calls[0]?.[0]).toEqual({
id: initial.id,
expectedUpdatedAt: initial.updatedAt,
operations: [{ op: "replace", path: "/basics/name", value: "First Name" }],
});
expect(orpcMocks.patchResume.mock.calls[1]?.[0]).toEqual({
id: initial.id,
expectedUpdatedAt: first.updatedAt,
operations: [{ op: "replace", path: "/basics/name", value: "Latest Name" }],
});
expect(orpcMocks.updateResume).not.toHaveBeenCalled();
});
it("does not run a stale debounced save after immediately saving an edit made during an in-flight save", async () => {
const initial = makeResume("resume-stale-timer");
const first = withBasicsName(initial, "First Name");
const latest = withBasicsName(initial, "Latest Name");
const first = withUpdatedAt(withBasicsName(initial, "First Name"), "2026-05-26T12:01:00.000Z");
const latest = withUpdatedAt(withBasicsName(initial, "Latest Name"), "2026-05-26T12:02:00.000Z");
let resolveFirst!: (resume: Resume) => void;
orpcMocks.updateResume
orpcMocks.patchResume
.mockReturnValueOnce(
new Promise<Resume>((resolve) => {
resolveFirst = resolve;
@@ -221,18 +255,22 @@ describe("builder resume autosave", () => {
resolveFirst(first);
await flushMicrotasks();
expect(orpcMocks.updateResume).toHaveBeenCalledTimes(2);
expect(orpcMocks.patchResume).toHaveBeenCalledTimes(2);
vi.advanceTimersByTime(500);
await flushMicrotasks();
expect(orpcMocks.updateResume).toHaveBeenCalledTimes(2);
expect(orpcMocks.updateResume.mock.calls[1]?.[0]).toEqual({ id: initial.id, data: latest.data });
expect(orpcMocks.patchResume).toHaveBeenCalledTimes(2);
expect(orpcMocks.patchResume.mock.calls[1]?.[0]).toEqual({
id: initial.id,
expectedUpdatedAt: first.updatedAt,
operations: [{ op: "replace", path: "/basics/name", value: "Latest Name" }],
});
});
it("keeps the latest draft data and shows a persistent toast when saving fails", async () => {
const initial = makeResume("resume-failure");
orpcMocks.updateResume.mockRejectedValue(new Error("network down"));
orpcMocks.patchResume.mockRejectedValue(new Error("network down"));
useResumeStore.getState().initialize(initial);
useResumeStore.getState().updateResumeData((draft) => {
@@ -247,7 +285,42 @@ describe("builder resume autosave", () => {
"Your latest changes could not be saved.",
expect.objectContaining({ duration: Number.POSITIVE_INFINITY }),
);
expect(orpcMocks.patchResume).not.toHaveBeenCalled();
expect(orpcMocks.updateResume).not.toHaveBeenCalled();
});
it("rebases pending local edits after a server version conflict", async () => {
const initial = makeResume("resume-conflict");
const remote = withUpdatedAt(withSummaryContent(initial, "Remote Summary"), "2026-05-26T12:01:00.000Z");
const merged = withUpdatedAt(withBasicsName(remote, "Local Name"), "2026-05-26T12:02:00.000Z");
orpcMocks.patchResume.mockRejectedValueOnce(new ORPCError("RESUME_VERSION_CONFLICT")).mockResolvedValueOnce(merged);
orpcMocks.getResumeById.mockResolvedValue(remote);
useResumeStore.getState().initialize(initial);
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.name = "Local Name";
});
vi.advanceTimersByTime(500);
await flushMicrotasks();
expect(orpcMocks.getResumeById).toHaveBeenCalledWith(
{ id: initial.id },
expect.objectContaining({ signal: expect.any(AbortSignal) }),
);
expect(orpcMocks.patchResume).toHaveBeenCalledTimes(2);
expect(orpcMocks.patchResume.mock.calls[0]?.[0]).toEqual({
id: initial.id,
expectedUpdatedAt: initial.updatedAt,
operations: [{ op: "replace", path: "/basics/name", value: "Local Name" }],
});
expect(orpcMocks.patchResume.mock.calls[1]?.[0]).toEqual({
id: initial.id,
expectedUpdatedAt: remote.updatedAt,
operations: [{ op: "replace", path: "/basics/name", value: "Local Name" }],
});
expect(useResumeStore.getState().resume?.data.basics.name).toBe("Local Name");
expect(useResumeStore.getState().resume?.data.summary.content).toBe("Remote Summary");
});
});
@@ -317,10 +390,12 @@ describe("resume update stream subscription", () => {
it("does not overwrite pending local builder edits when a remote update arrives", async () => {
const initial = makeResume("resume-pending");
const remote = withBasicsName(initial, "Remote Name");
const remote = withUpdatedAt(withSummaryContent(initial, "Remote Summary"), "2026-05-26T12:01:00.000Z");
const merged = withUpdatedAt(withBasicsName(remote, "Local Name"), "2026-05-26T12:02:00.000Z");
const cancel = vi.fn().mockResolvedValue(undefined);
consumeEventIteratorMock.mockReturnValue(cancel);
orpcMocks.getResumeById.mockResolvedValue(remote);
orpcMocks.patchResume.mockResolvedValue(merged);
routerParamsMock.value = { resumeId: initial.id };
useResumeStore.getState().initialize(initial);
useResumeStore.getState().updateResumeData((draft) => {
@@ -336,5 +411,15 @@ describe("resume update stream subscription", () => {
expect(queryClientMock.setQueryData).toHaveBeenCalledWith(["resume", "getById", initial.id], remote);
expect(useResumeStore.getState().resume?.data.basics.name).toBe("Local Name");
expect(useResumeStore.getState().resume?.data.summary.content).toBe("Remote Summary");
expect(orpcMocks.patchResume).toHaveBeenCalledWith(
{
id: initial.id,
expectedUpdatedAt: remote.updatedAt,
operations: [{ op: "replace", path: "/basics/name", value: "Local Name" }],
},
expect.objectContaining({ signal: expect.any(AbortSignal) }),
);
expect(orpcMocks.updateResume).not.toHaveBeenCalled();
});
});
+105 -24
View File
@@ -2,7 +2,7 @@ import type { ResumeData } from "@reactive-resume/schema/resume/data";
import type { QueryClient, QueryKey } from "@tanstack/react-query";
import type { WritableDraft } from "immer";
import { t } from "@lingui/core/macro";
import { consumeEventIterator } from "@orpc/client";
import { consumeEventIterator, ORPCError } from "@orpc/client";
import { useQueryClient } from "@tanstack/react-query";
import { useParams } from "@tanstack/react-router";
import { debounce, isEqual } from "es-toolkit";
@@ -10,6 +10,7 @@ import { useCallback, useEffect, useState } from "react";
import { toast } from "sonner";
import { immer } from "zustand/middleware/immer";
import { create } from "zustand/react";
import { applyResumePatches, createResumePatches } from "@reactive-resume/resume/patch";
import { orpc, streamClient } from "@/libs/orpc/client";
export type Resume = {
@@ -48,6 +49,7 @@ type Runtime = {
hasPendingLocalChanges: boolean;
isSaving: boolean;
pendingResume?: Resume;
serverResume?: Resume;
syncErrorToastId?: string | number;
syncResume: ReturnType<typeof debounce<(resume: Resume) => void>>;
beforeUnloadHandler?: () => void;
@@ -82,57 +84,131 @@ function createResumeUpdateEventIterator(resumeId: string) {
function setRuntimeBaseline(resume: Resume) {
const runtime = getRuntime(resume.id);
runtime.serverResume = cloneResume(resume);
runtime.hasPendingLocalChanges = false;
runtime.pendingResume = undefined;
}
function isAbortError(error: unknown): error is DOMException {
return error instanceof DOMException && error.name === "AbortError";
}
function isResumeVersionConflict(error: unknown): error is ORPCError {
return error instanceof ORPCError && error.code === "RESUME_VERSION_CONFLICT";
}
function rebasePendingResumeOnServer(serverResume: Resume, localResume: Resume) {
const runtime = getRuntime(serverResume.id);
const baseline = runtime.serverResume;
if (!baseline || baseline.id !== serverResume.id) {
throw new Error("Cannot rebase resume draft without a server baseline.");
}
const operations = createResumePatches(baseline.data, localResume.data);
runtime.serverResume = cloneResume(serverResume);
runtime.queryClient?.setQueryData(getResumeQueryKey(serverResume.id), serverResume);
if (operations.length === 0) {
runtime.hasPendingLocalChanges = false;
runtime.pendingResume = undefined;
useResumeStore.getState().replaceResumeFromServer(serverResume);
return;
}
const rebased: Resume = {
...serverResume,
data: applyResumePatches(serverResume.data, operations),
};
runtime.syncResume.cancel();
runtime.pendingResume = cloneResume(rebased);
runtime.hasPendingLocalChanges = true;
useResumeStore.getState().replaceResumeDraft(rebased);
}
function handleSuccessfulResumeSave(runtime: Runtime, submitted: Resume, saved: Resume, submittedData: ResumeData) {
runtime.serverResume = cloneResume(saved);
runtime.queryClient?.setQueryData(getResumeQueryKey(submitted.id), saved);
const currentResume = useResumeStore.getState().resume;
const currentDataStillMatchesSubmission =
currentResume?.id === submitted.id && isEqual(currentResume.data, submittedData);
if (currentDataStillMatchesSubmission && !runtime.pendingResume) {
runtime.hasPendingLocalChanges = false;
useResumeStore.getState().replaceResumeFromServer(saved);
} else {
runtime.hasPendingLocalChanges = true;
useResumeStore.getState().mergeResumeMetadata(saved);
if (!runtime.pendingResume && currentResume?.id === submitted.id && !isEqual(currentResume.data, submittedData)) {
runtime.syncResume.cancel();
runtime.pendingResume = cloneResume(currentResume);
}
}
if (runtime.syncErrorToastId !== undefined) {
toast.dismiss(runtime.syncErrorToastId);
runtime.syncErrorToastId = undefined;
}
}
async function flushResumeSave(id: string) {
const runtime = runtimes.get(id);
if (!runtime || runtime.isSaving || !runtime.pendingResume) return;
const submitted = runtime.pendingResume;
const submittedData = cloneResumeData(submitted.data);
const baseline = runtime.serverResume;
runtime.pendingResume = undefined;
runtime.isSaving = true;
try {
const updated = (await orpc.resume.update.call(
{ id: submitted.id, data: submittedData },
if (!baseline || baseline.id !== submitted.id) {
throw new Error("Cannot save resume draft without a server baseline.");
}
const operations = createResumePatches(baseline.data, submittedData);
if (operations.length === 0) {
handleSuccessfulResumeSave(runtime, submitted, baseline, submittedData);
return;
}
const updated = (await orpc.resume.patch.call(
{ id: submitted.id, expectedUpdatedAt: baseline.updatedAt, operations },
{ signal: runtime.abortController.signal },
)) as Resume;
runtime.queryClient?.setQueryData(getResumeQueryKey(submitted.id), updated);
handleSuccessfulResumeSave(runtime, submitted, updated, submittedData);
} catch (error: unknown) {
if (isAbortError(error)) return;
const currentResume = useResumeStore.getState().resume;
const currentDataStillMatchesSubmission =
currentResume?.id === submitted.id && isEqual(currentResume.data, submittedData);
let syncError = error;
if (currentDataStillMatchesSubmission && !runtime.pendingResume) {
runtime.hasPendingLocalChanges = false;
useResumeStore.getState().replaceResumeFromServer(updated);
} else {
runtime.hasPendingLocalChanges = true;
useResumeStore.getState().mergeResumeMetadata(updated);
if (isResumeVersionConflict(error)) {
try {
const latest = (await orpc.resume.getById.call(
{ id: submitted.id },
{ signal: runtime.abortController.signal },
)) as Resume;
const currentResume = useResumeStore.getState().resume;
const localResume = currentResume?.id === submitted.id ? currentResume : submitted;
if (!runtime.pendingResume && currentResume?.id === submitted.id && !isEqual(currentResume.data, submittedData)) {
runtime.syncResume.cancel();
runtime.pendingResume = cloneResume(currentResume);
rebasePendingResumeOnServer(latest, localResume);
return;
} catch (rebaseError: unknown) {
if (isAbortError(rebaseError)) return;
syncError = rebaseError;
}
}
if (runtime.syncErrorToastId !== undefined) {
toast.dismiss(runtime.syncErrorToastId);
runtime.syncErrorToastId = undefined;
}
} catch (error: unknown) {
if (error instanceof DOMException && error.name === "AbortError") return;
runtime.pendingResume ??= submitted;
runtime.hasPendingLocalChanges = true;
runtime.syncErrorToastId = toast.error(t`Your latest changes could not be saved.`, {
id: runtime.syncErrorToastId,
duration: Number.POSITIVE_INFINITY,
});
console.warn("Resume autosave failed:", syncError);
} finally {
runtime.isSaving = false;
if (runtime.pendingResume && runtime.syncErrorToastId === undefined) void flushResumeSave(id);
@@ -404,7 +480,12 @@ export function useBuilderResumeUpdateSubscription() {
queryClient.setQueryData(getResumeQueryKey(resumeId), resume);
if (hasPendingLocalChanges(resumeId)) {
useResumeStore.getState().mergeResumeMetadata(resume);
const currentResume = useResumeStore.getState().resume;
if (!currentResume || currentResume.id !== resumeId) return;
rebasePendingResumeOnServer(resume, currentResume);
const runtime = getRuntime(resumeId);
if (!runtime.isSaving && runtime.syncErrorToastId === undefined) void flushResumeSave(resumeId);
return;
}
+31 -28
View File
@@ -85,19 +85,19 @@ importers:
version: 3.1053.0
'@better-auth/api-key':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))
'@better-auth/drizzle-adapter':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))
'@better-auth/infra':
specifier: ^0.2.8
version: 0.2.8(97af957868093b766f74c847443b5514)
version: 0.2.8(52486eeb3cc3b91786b2cceb6f087465)
'@better-auth/oauth-provider':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))
'@better-auth/passkey':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))(nanostores@1.3.0)
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))(nanostores@1.3.0)
'@hono/node-server':
specifier: ^2.0.4
version: 2.0.4(hono@4.12.23)
@@ -163,7 +163,7 @@ importers:
version: 6.0.0
better-auth:
specifier: 1.6.11
version: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
version: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
cjk-regex:
specifier: ^3.4.0
version: 3.4.0
@@ -278,16 +278,16 @@ importers:
version: 1.5.0(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
'@better-auth/api-key':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))
'@better-auth/infra':
specifier: ^0.2.8
version: 0.2.8(97af957868093b766f74c847443b5514)
version: 0.2.8(52486eeb3cc3b91786b2cceb6f087465)
'@better-auth/oauth-provider':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))
'@better-auth/passkey':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))(nanostores@1.3.0)
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))(nanostores@1.3.0)
'@dnd-kit/core':
specifier: ^6.3.1
version: 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
@@ -339,6 +339,9 @@ importers:
'@reactive-resume/pdf':
specifier: workspace:*
version: link:../../packages/pdf
'@reactive-resume/resume':
specifier: workspace:*
version: link:../../packages/resume
'@reactive-resume/schema':
specifier: workspace:*
version: link:../../packages/schema
@@ -401,7 +404,7 @@ importers:
version: 6.0.191(zod@4.4.3)
better-auth:
specifier: 1.6.11
version: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
version: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
cmdk:
specifier: ^1.1.1
version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
@@ -613,7 +616,7 @@ importers:
version: 6.0.0
better-auth:
specifier: 1.6.11
version: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
version: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
drizzle-orm:
specifier: 1.0.0-rc.3
version: 1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3)
@@ -662,19 +665,19 @@ importers:
dependencies:
'@better-auth/api-key':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))
'@better-auth/drizzle-adapter':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))
'@better-auth/infra':
specifier: ^0.2.8
version: 0.2.8(97af957868093b766f74c847443b5514)
version: 0.2.8(52486eeb3cc3b91786b2cceb6f087465)
'@better-auth/oauth-provider':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))
'@better-auth/passkey':
specifier: ^1.6.11
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))(nanostores@1.3.0)
version: 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))(nanostores@1.3.0)
'@reactive-resume/db':
specifier: workspace:*
version: link:../db
@@ -692,7 +695,7 @@ importers:
version: 6.0.0
better-auth:
specifier: 1.6.11
version: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
version: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
drizzle-orm:
specifier: 1.0.0-rc.3
version: 1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3)
@@ -8621,11 +8624,11 @@ snapshots:
'@bcoe/v8-coverage@1.0.2': {}
'@better-auth/api-key@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))':
'@better-auth/api-key@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))':
dependencies:
'@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
'@better-auth/utils': 0.4.0
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
zod: 4.4.3
'@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)':
@@ -8649,12 +8652,12 @@ snapshots:
optionalDependencies:
drizzle-orm: 1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3)
'@better-auth/infra@0.2.8(97af957868093b766f74c847443b5514)':
'@better-auth/infra@0.2.8(52486eeb3cc3b91786b2cceb6f087465)':
dependencies:
'@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
'@better-auth/sso': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))
'@better-auth/sso': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))
'@better-fetch/fetch': 1.1.21
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-call: 1.3.5(zod@4.4.3)
jose: 6.2.3
libphonenumber-js: 1.13.3
@@ -8677,24 +8680,24 @@ snapshots:
'@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
'@better-auth/utils': 0.4.0
'@better-auth/oauth-provider@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))':
'@better-auth/oauth-provider@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))':
dependencies:
'@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
'@better-auth/utils': 0.4.0
'@better-fetch/fetch': 1.1.21
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-call: 1.3.5(zod@4.4.3)
jose: 6.2.3
zod: 4.4.3
'@better-auth/passkey@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))(nanostores@1.3.0)':
'@better-auth/passkey@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))(nanostores@1.3.0)':
dependencies:
'@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
'@better-auth/utils': 0.4.0
'@better-fetch/fetch': 1.1.21
'@simplewebauthn/browser': 13.3.0
'@simplewebauthn/server': 13.3.0
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-call: 1.3.5(zod@4.4.3)
nanostores: 1.3.0
zod: 4.4.3
@@ -8704,12 +8707,12 @@ snapshots:
'@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
'@better-auth/utils': 0.4.0
'@better-auth/sso@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))':
'@better-auth/sso@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7))(better-call@1.3.5(zod@4.4.3))':
dependencies:
'@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
'@better-auth/utils': 0.4.0
'@better-fetch/fetch': 1.1.21
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-auth: 1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7)
better-call: 1.3.5(zod@4.4.3)
fast-xml-parser: 5.8.0
jose: 6.2.3
@@ -11446,7 +11449,7 @@ snapshots:
node-addon-api: 8.8.0
node-gyp-build: 4.8.4
better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7):
better-auth@1.6.11(@opentelemetry/api@1.9.1)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7):
dependencies:
'@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
'@better-auth/drizzle-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(drizzle-orm@1.0.0-rc.3(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(effect@4.0.0-beta.70)(pg@8.21.0)(zod@4.4.3))