git.fiddlerwoaroof.com
index.js
c09dd540
 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,
   );
 }