import type { Env } from "./bindings.js"; import { withApprovedDeviceApiControls } from "./api_controls.js"; import { jsonResponse } from "./responses.js"; import { SyncRequestError, SyncSchemaError, syncPullDocument } from "./sync_pull.js"; import { SyncPushConflictError, SyncPushPersistenceError, SyncPushRequestError, syncPushDocument, } from "./sync_push.js"; import { SyncResetPersistenceError, SyncResetRequestError, syncResetDocument, } from "./sync_reset.js"; import { SyncSnapshotConflictError, SyncSnapshotNotFoundError, SyncSnapshotPersistenceError, SyncSnapshotRequestError, syncSnapshotDownloadDocument, syncSnapshotUploadDocument, } from "./sync_snapshot.js"; import { SyncStatusSchemaError, syncStatusDocument } from "./sync_status.js"; export async function handleSyncRoute( request: Request, env: Env, url: URL, ): Promise { if (url.pathname === "/api/sync/pull") { return handleSyncPull(request, env, url); } if (url.pathname === "/api/sync/push") { return handleSyncPush(request, env); } if (url.pathname === "/api/sync/snapshot") { return handleSyncSnapshot(request, env, url); } if (url.pathname === "/api/sync/status") { return handleSyncStatus(request, env); } if (url.pathname === "/api/sync/reset") { return handleSyncReset(request, env); } return null; } function handleSyncPull(request: Request, env: Env, url: URL): Promise { return withApprovedDeviceApiControls( request, env, "sync.pull", ["GET"], async (context) => { try { return jsonResponse(await syncPullDocument(url, env, context), 200, { "Cache-Control": "no-store", }); } catch (error) { if (error instanceof SyncRequestError) { return jsonResponse( { error: "invalid_sync_pull" }, 400, { "Cache-Control": "no-store" }, ); } if (error instanceof SyncSchemaError) { return jsonResponse( { error: "sync_pull_invalid" }, 500, { "Cache-Control": "no-store" }, ); } throw error; } }, ); } function handleSyncPush(request: Request, env: Env): Promise { return withApprovedDeviceApiControls( request, env, "sync.push", ["POST"], async (context) => { try { return jsonResponse(await syncPushDocument(request, env, context), 201, { "Cache-Control": "no-store", }); } catch (error) { if (error instanceof SyncPushRequestError) { return jsonResponse( { error: "invalid_sync_push" }, 400, { "Cache-Control": "no-store" }, ); } if (error instanceof SyncPushConflictError) { return jsonResponse({ error: "sync_conflict" }, 409, { "Cache-Control": "no-store" }); } if (error instanceof SyncPushPersistenceError) { return jsonResponse( { error: "sync_push_failed" }, 500, { "Cache-Control": "no-store" }, ); } throw error; } }, ); } function handleSyncSnapshot(request: Request, env: Env, url: URL): Promise { return withApprovedDeviceApiControls( request, env, "sync.snapshot", ["GET", "POST"], async (context) => { try { if (request.method === "POST") { return jsonResponse(await syncSnapshotUploadDocument(request, env, context), 201, { "Cache-Control": "no-store", }); } return jsonResponse(await syncSnapshotDownloadDocument(url, env, context), 200, { "Cache-Control": "no-store", }); } catch (error) { if (error instanceof SyncSnapshotRequestError) { return jsonResponse( { error: "invalid_sync_snapshot" }, 400, { "Cache-Control": "no-store" }, ); } if (error instanceof SyncSnapshotNotFoundError) { return jsonResponse( { error: "sync_snapshot_not_found" }, 404, { "Cache-Control": "no-store" }, ); } if (error instanceof SyncSnapshotConflictError) { return jsonResponse( { error: "sync_snapshot_conflict" }, 409, { "Cache-Control": "no-store" }, ); } if (error instanceof SyncSnapshotPersistenceError) { return jsonResponse( { error: "sync_snapshot_failed" }, 500, { "Cache-Control": "no-store" }, ); } throw error; } }, ); } function handleSyncStatus(request: Request, env: Env): Promise { return withApprovedDeviceApiControls( request, env, "sync.status", ["GET"], async (context) => { try { return jsonResponse(await syncStatusDocument(env, context), 200, { "Cache-Control": "no-store", }); } catch (error) { if (error instanceof SyncStatusSchemaError) { return jsonResponse( { error: "sync_status_invalid" }, 500, { "Cache-Control": "no-store" }, ); } throw error; } }, ); } function handleSyncReset(request: Request, env: Env): Promise { return withApprovedDeviceApiControls( request, env, "sync.reset", ["POST"], async (context) => { try { return jsonResponse(await syncResetDocument(request, env, context), 200, { "Cache-Control": "no-store", }); } catch (error) { if (error instanceof SyncResetRequestError) { return jsonResponse( { error: "invalid_sync_reset" }, 400, { "Cache-Control": "no-store" }, ); } if (error instanceof SyncResetPersistenceError) { return jsonResponse( { error: "sync_reset_failed" }, 500, { "Cache-Control": "no-store" }, ); } throw error; } }, ); }