addEventListener("fetch", (event) => { event.respondWith(handleRequest(event.request)); }); function parse_url(url) { const theURL = url instanceof URL ? url : new URL(url); return [theURL.pathname.split("/"), theURL.searchParams]; } function uuidv4() { return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => ( c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4))) ).toString(16), ); } function ok(body, init) { return new Response(body, { ...init, status: 200 }); } function handlePath(path, searchParams) { const uuid = path.length >= 2 && path[1]; const response = path.length === 4 && path[3]; if (response) { return { route: "respond", uuid, response, email: path[2] }; } else if (uuid) { return { route: "summary", uuid }; } else { return { route: "notfound", path, searchParams }; } } async function get() {} const routeHandlers = { async notfound({ path }) { return new Response(`invalid path ${path}`, { status: 404 }); }, async summary({ uuid }) { const settings = await RSVPS.get(`${uuid}:settings`); if (settings) { const rsvps = {}; let args = { prefix: `${uuid}:response:` }; let rawRSVPs; do { rawRSVPs = await RSVPS.list(args); for (let { name } of rawRSVPs.keys) { const [_, __, email] = name.split(":"); const response = await RSVPS.get(name); rsvps[email] = response; } args = { cursor: rawRSVPs.cursor }; } while (!rawRSVPs.list_complete); const responseData = { settings: JSON.parse(settings), rsvps, }; return ok(JSON.stringify(responseData), { headers: { "Content-Type": "application/json" }, }); } else { return new Response(`invalid invite ${uuid}`, { status: 404 }); } }, async respond({ uuid, email, response }) { const settings = await RSVPS.get(`${uuid}:settings`); if (settings) { if (!email.includes("@")) { return new Response(`invalid email ${response}`, { status: 404 }); } if (response === "yes" || response === "no" || response === "maybe") { await RSVPS.put(`${uuid}:response:${email}`, response); return new Response(`${uuid} ${email} ${response}`, { status: 200 }); } else { return new Response(`invalid response ${response}`, { status: 404 }); } } else { return new Response(`invalid invite ${uuid}`, { status: 404 }); } }, }; const methodHandlers = { async GET(p, sp) { const route = handlePath(p, sp); return await routeHandlers[route.route](route); }, async POST() { const inviteUUID = uuidv4(); await RSVPS.put(`${inviteUUID}:settings`, "{}"); return ok(inviteUUID); }, default() { return new Response("405 unsupported", { status: 405 }); }, }; /** * Respond with hello worker text * @param {Request} request */ async function handleRequest(request) { /** @type {number} */ const nums = JSON.parse((await RSVPS.get("test:count")) || "0") + 1; await RSVPS.put("test:count", JSON.stringify(nums)); const [p, sp] = parse_url(request.url); return await (methodHandlers[request.method] || methodHandlers.default)( p, sp, ); }