Files
diachron/deno/app.ts
2025-03-07 21:22:31 -06:00

85 lines
2.2 KiB
TypeScript

import { services } from "./services.ts";
import {
DenoRequest,
DenoResponse,
InternalHandler,
massageMethod,
Method,
ProcessedRoute,
Request as Request,
Route,
} from "./types.ts";
import { routes } from "./routes.ts";
services.logging.log({ source: "logging", text: ["1"] });
const processedRoutes: { [K in Method]: ProcessedRoute[] } = {
"GET": [],
"POST": [],
"PUT": [],
"PATCH": [],
"DELETE": [],
};
function isPromise<T>(value: T | Promise<T>): value is Promise<T> {
return typeof (value as any)?.then === "function";
}
routes.forEach(
(route: Route, _idx: number, _allRoutes: Route[]) => {
const pattern: URLPattern = new URLPattern({ pathname: route.path });
const methodList = route.methods;
const handler: InternalHandler = async (denoRequest: DenoRequest) => {
const method = massageMethod(denoRequest.method);
if (!methodList.includes(method)) {
// XXX: Worth asserting this?
}
const p = new URL(denoRequest.url);
const path = p.pathname;
const req: Request = {
pattern: route.path,
path,
method,
parameters: { one: 1, two: 2 },
denoRequest,
};
const retval = route.handler(req);
if (isPromise(retval)) {
return await retval;
} else {
return retval;
}
};
for (const [_idx, method] of methodList.entries()) {
const pr: ProcessedRoute = { pattern, method, handler };
processedRoutes[method].push(pr);
}
},
);
async function handler(req: DenoRequest): Promise<DenoResponse> {
const m = req.method;
const m1 = massageMethod(m);
const byMethod = processedRoutes[m1];
for (const [_idx, pr] of byMethod.entries()) {
const match = pr.pattern.exec(req.url);
if (match) {
const resp = await pr.handler(req);
return new globalThis.Response(resp.result);
}
}
return new globalThis.Response("not found", { status: 404 });
}
Deno.serve(handler);