kequapp
Version:
A minimal, zero-magic Node web framework built on native APIs
53 lines (52 loc) • 1.77 kB
JavaScript
import Ex from "../built-in/tools/ex.js";
import logger from "../util/logger.js";
import { validateBranch } from "../util/validate.js";
import createRegexp from "./create-regexp.js";
import { cacheBranches, cacheRoutes } from "./util/cacher.js";
import { matchGroups } from "./util/extract.js";
export default function createRouter(structure) {
validateBranch(structure);
const routes = cacheRoutes(structure);
const branches = cacheBranches(structure);
return function router(method, url) {
const matchedRoutes = routes.filter((item) => item.regexp.test(url));
const route = getRoute(matchedRoutes, method) ??
generate404(branches, url, method);
const params = matchGroups(url, route.regexp);
const methods = getMethods(matchedRoutes, route.autoHead);
return [route, params, methods];
};
}
function getRoute(routes, method) {
const route = routes.find((item) => item.method === method);
if (route === undefined && method === 'HEAD') {
return routes.find((item) => item.autoHead && item.method === 'GET');
}
return route;
}
function generate404(branches, key, method) {
const branch = branches.find((item) => item.regexp.test(key)) ?? {
regexp: createRegexp('/**'),
actions: [],
errorHandlers: [],
renderers: [],
autoHead: true,
logger,
};
return {
...branch,
method,
actions: [
...branch.actions,
() => {
throw Ex.NotFound();
},
],
};
}
function getMethods(routes, autoHead) {
const set = new Set(routes.map((item) => item.method));
if (autoHead && set.has('GET'))
set.add('HEAD');
return [...set];
}