Prepare time-bound Setup URI integration for Commonlib release

Add Time-bound and Compatible generation to the Obsidian dialogue, browser peer check, and setup tools, with boundary and compatibility coverage. Show the fixed window end before sharing a Time-bound URI.

This review branch depends on unpublished @vrtmrz/livesync-commonlib 0.1.32-next.0. The root npm pin and Deno lockfile remain unchanged until that candidate is available; a fresh install of this commit is not yet expected to build.
This commit is contained in:
vorotamoroz committed 2026-09-28 10:22:28 +00:00
1 parent 2c2b9c90e4
commit 3a478cce3f
23 files changed
+1361 -119

No files matched your search

@@ -1,5 +1,7 @@
import { describe, expect, it, vi, afterEach } from "vitest";
import { registerSetupProtocolHandler, useSetupProtocolFeature } from "./setupProtocol";
import { encodeTimeBoundSetupURI } from "@vrtmrz/livesync-commonlib/setup-uri";
import { DEFAULT_SETTINGS } from "@vrtmrz/livesync-commonlib/compat/common/types";
vi.mock("@/common/types", () => {
return {
@@ -52,6 +54,35 @@ describe("setupObsidian/setupProtocol", () => {
expect(setupManager.decodeQR).not.toHaveBeenCalled();
});
it.each(["ephemeral", "persistent"] as const)(
"reconstructs the exact encrypted %s URI after protocol query decoding",
async (mode) => {
let protocolHandler: ((params: Record<string, string>) => Promise<void>) | undefined;
const host = {
services: {
API: {
registerProtocolHandler: vi.fn(
(_action: string, handler: (params: Record<string, string>) => Promise<void>) => {
protocolHandler = handler;
}
),
},
},
} as any;
const setupManager = { onUseSetupURI: vi.fn(async () => true), decodeQR: vi.fn() } as any;
registerSetupProtocolHandler(host, vi.fn(), setupManager);
const generated = await encodeTimeBoundSetupURI(DEFAULT_SETTINGS, "protocol-passphrase", { mode });
const decodedQuery = new URL(generated.uri.trim()).searchParams.get("settings");
expect(decodedQuery?.startsWith("%$")).toBe(true);
await protocolHandler!({ settings: decodedQuery! });
const reconstructed = setupManager.onUseSetupURI.mock.calls[0][1] as string;
expect(reconstructed.replace("mock-config://", "obsidian://setuplivesync?settings=")).toBe(
generated.uri.trim()
);
}
);
it("registerSetupProtocolHandler should route settingsQR payload to decodeQR", async () => {
let protocolHandler: ((params: Record<string, string>) => Promise<void>) | undefined;
const host = {