Port to itty-router

This commit is contained in:
Gabriel Simmer 2024-08-07 11:10:04 +01:00
parent 6aacd7c4d0
commit d121d60b76
Signed by: arch
SSH key fingerprint: SHA256:m3OEcdtrnBpMX+2BDGh/byv3hrCekCLzDYMdvGEKPPQ
3 changed files with 165 additions and 140 deletions

View file

@ -7,6 +7,9 @@
"": {
"name": "worker",
"version": "0.0.0",
"dependencies": {
"itty-router": "^5.0.17"
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "^0.4.5",
"vitest": "1.5.0",
@ -1574,6 +1577,12 @@
"dev": true,
"license": "ISC"
},
"node_modules/itty-router": {
"version": "5.0.17",
"resolved": "https://registry.npmjs.org/itty-router/-/itty-router-5.0.17.tgz",
"integrity": "sha512-ZHnPI0OOyTTLuNp2FdciejYaK4Wl3ZV3O0yEm8njOGggh/k/ek3BL7X2I5YsCOfc5vLhIJgj3Z4pUtLs6k9Ucg==",
"license": "MIT"
},
"node_modules/js-tokens": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz",

View file

@ -10,7 +10,10 @@
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "^0.4.5",
"wrangler": "^3.60.3",
"vitest": "1.5.0"
"vitest": "1.5.0",
"wrangler": "^3.60.3"
},
"dependencies": {
"itty-router": "^5.0.17"
}
}

View file

@ -1,24 +1,29 @@
import index from "./index.html";
import { IttyRouter, json, error, withParams } from 'itty-router'
export default {
async fetch(request, env, ctx) {
const router = IttyRouter();
const cache = caches.default;
async function withCache(request, env) {
const url = new URL(request.url);
const { pathname } = url;
const cacheUrl = new URL(request.url);
// Construct the cache key from the cache URL
const cacheKey = new Request(cacheUrl.toString(), request);
const cache = caches.default;
let response = await cache.match(cacheKey);
if (response) {
return response;
}
request.cacheKey = cacheKey;
}
async function snapshot(request, env, ctx, date = "LATEST") {
const kv = env.KV_STORE;
const bucket = env.R2_BUCKET;
const snapshot = async(date = "LATEST") => {
const { value, metadata } = await kv.getWithMetadata(date);
if (value == null) {
return {error: `${date} key not found`};
@ -37,11 +42,10 @@ export default {
file: `https://daily-servo-r2.gmem.ca/${value}.png`,
date: date,
}
}
}
switch (pathname) {
case "/": {
let l = await snapshot();
async function renderIndex(request, env, ctx) {
let l = await snapshot(request, env, ctx);
const response = new HTMLRewriter()
.on("#date", {
element(element) {
@ -62,29 +66,23 @@ export default {
new Response(index, { headers: { "Content-Type": "text/html",
"Cache-Control": "s-maxage=3600" } }),
);
ctx.waitUntil(cache.put(cacheKey, response.clone()));
ctx.waitUntil(cache.put(request.cacheKey, response.clone()));
return response
}
case "/latest": {
let l = await latest();
if (l.error != undefined) {
return new Response(JSON.stringify(l), {
status: 500,
headers: { "Content-Type": "application/json" }
});
}
return Response.redirect(`${l.file}`, 302);
}
case "/latest.json": {
}
async function latest(request, env) {
let l = await snapshot();
const response = new Response(JSON.stringify(l), {
headers: { "Content-Type": "application/json",
"Cache-Control": "s-maxage=3600"}
});
ctx.waitUntil(cache.put(cacheKey, response.clone()));
ctx.waitUntil(cache.put(request.cacheKey, response.clone()));
return response;
}
case "/list.json": {
}
async function snapshotList(request, env, ctx) {
const kv = env.KV_STORE;
let list = await kv.list();
let filtered = await Promise.all(
list.keys.filter((value) => value.name != "LATEST")
@ -96,11 +94,17 @@ export default {
headers: { "Content-Type": "application/json",
"Cache-Control": "s-maxage=3600"}
});
ctx.waitUntil(cache.put(cacheKey, response.clone()));
ctx.waitUntil(cache.put(request.cacheKey, response.clone()));
return response;
}
async function withAuth(request, env, ctx) {
if (request.headers.get("Authorization") != env.API_TOKEN) {
return new Response("Unauthorized", { status: 403 });
}
case "/new": {
if (request.method == "POST" && request.headers.get("Authorization") == env.API_TOKEN) {
}
async function newSnapshot(request, env, ctx) {
const body = await request.formData();
const {
date,
@ -120,21 +124,30 @@ export default {
// Keep for 1 year.
await kv.put(`${date}`, hash, { expirationTtl: 31_536_000 });
return new Response("Uploaded", { status: 201 });
} else {
return new Response("Unauthorized", { status: 403 });
return new Response("Uploaded", { status: 201});
}
async function specificSnapshot(request, env, ctx) {
const { pathname } = new URL(request.url);
const response = await snapshot(request, env, ctx, pathname.replace("/", ""))
if (response.error != undefined) {
return new Response(JSON.stringify(response), { status: 404, headers: {"Content-Type": "application/json"} });
}
}
default:
let snap = await snapshot(pathname.replace("/", ""));
if (snap.error != undefined) {
return new Response("Not found", { status: 404 });
}
const response = new Response(JSON.stringify(snap), {
headers: { "Content-Type": "application/json", "Cache-Control": "s-maxage=3600" }
});
ctx.waitUntil(cache.put(cacheKey, response.clone()));
return response;
}
},
};
return response
}
router
.get("/", withCache, renderIndex)
.get("/latest", withCache, latest)
.get("/latest.json", withCache, snapshot)
.get("/list.json", withCache, snapshotList)
.post("/new", withAuth, newSnapshot)
.get("*", withCache, specificSnapshot)
export default {
fetch: (request, ...args) =>
router
.fetch(request, ...args)
.then(json)
.catch(error)
}