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,
);
}
|