Files
diachron/express/app.ts

124 lines
3.1 KiB
TypeScript

import express, {
Request as ExpressRequest,
Response as ExpressResponse,
} from "express";
import { match } from "path-to-regexp";
import { cli } from "./cli";
import { contentTypes } from "./content-types";
import { httpCodes } from "./http-codes";
import { routes } from "./routes";
import { services } from "./services";
// import { URLPattern } from 'node:url';
import {
Call,
InternalHandler,
Method,
ProcessedRoute,
Result,
Route,
massageMethod,
methodParser,
} from "./types";
const app = express();
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 matcher = match<Record<string, string>>(route.path);
const methodList = route.methods;
const handler: InternalHandler = async (
request: ExpressRequest,
): Promise<Result> => {
const method = massageMethod(request.method);
console.log("method", method);
if (!methodList.includes(method)) {
// XXX: Worth asserting this?
}
console.log("request.originalUrl", request.originalUrl);
console.log("beavis");
// const p = new URL(request.originalUrl);
// const path = p.pathname;
// console.log("p, path", p, path)
console.log("ok");
const req: Call = {
pattern: route.path,
// path,
path: request.originalUrl,
method,
parameters: { one: 1, two: 2 },
request,
};
const retval = await route.handler(req);
return retval;
};
for (const [_idx, method] of methodList.entries()) {
const pr: ProcessedRoute = { matcher, method, handler };
processedRoutes[method].push(pr);
}
});
async function handler(
req: ExpressRequest,
_res: ExpressResponse,
): Promise<Result> {
const method = await methodParser.parseAsync(req.method);
const byMethod = processedRoutes[method];
for (const [_idx, pr] of byMethod.entries()) {
const match = pr.matcher(req.url);
if (match) {
console.log("match", match);
const resp = await pr.handler(req);
return resp;
}
}
const retval: Result = {
code: httpCodes.clientErrors.NotFound,
contentType: contentTypes.text.plain,
result: "not found",
};
return retval;
}
app.use(async (req: ExpressRequest, res: ExpressResponse) => {
const result0 = await handler(req, res);
const code = result0.code.code;
const result = result0.result;
console.log(result);
res.status(code).send(result);
});
app.listen(cli.listen.port, cli.listen.host, () => {
console.log(`Listening on ${cli.listen.host}:${cli.listen.port}`);
});