import { STORAGE_KEY } from "@/app/constant"; import { SyncStore } from "@/app/store/sync"; export type WebDAVConfig = SyncStore["webdav"]; export type WebDavClient = ReturnType; export function createWebDavClient(store: SyncStore) { const folder = STORAGE_KEY; const fileName = `${folder}/backup.json`; const config = store.webdav; const proxyUrl = store.useProxy && store.proxyUrl.length > 0 ? store.proxyUrl : undefined; return { async check() { try { const res = await fetch(this.path(folder, proxyUrl), { method: "MKCOL", headers: this.headers(), }); console.log("[WebDav] check", res.status, res.statusText); return [201, 200, 404, 301, 302, 307, 308].includes(res.status); } catch (e) { console.error("[WebDav] failed to check", e); } return false; }, async get(key: string) { const res = await fetch(this.path(fileName, proxyUrl), { method: "GET", headers: this.headers(), }); console.log("[WebDav] get key = ", key, res.status, res.statusText); return await res.text(); }, async set(key: string, value: string) { const res = await fetch(this.path(fileName, proxyUrl), { method: "PUT", headers: this.headers(), body: value, }); console.log("[WebDav] set key = ", key, res.status, res.statusText); }, headers() { const auth = btoa(config.username + ":" + config.password); return { authorization: `Basic ${auth}`, }; }, path(path: string, proxyUrl: string = "") { if (!path.endsWith("/")) { path += "/"; } if (path.startsWith("/")) { path = path.slice(1); } if (proxyUrl.length > 0 && !proxyUrl.endsWith("/")) { proxyUrl += "/"; } let url; if (proxyUrl.length > 0 || proxyUrl === "/") { let u = new URL(proxyUrl + "/api/webdav/" + path); // add query params u.searchParams.append("endpoint", config.endpoint); url = u.toString(); } else { url = "/api/upstash/" + path + "?endpoint=" + config.endpoint; } return url; }, }; }