kequapp
Version:
DEPRECATED: renamed to @kequtech/arbor
52 lines (51 loc) • 1.76 kB
JavaScript
import { logger } from "../built-in/logger.js";
import { Ex } from "../ex.js";
import { validateBranch } from "../utils/validate.js";
import { cacheBranches, cacheRoutes } from "./tools/cacher.js";
import { createRegexp } from "./tools/create-regexp.js";
import { matchGroups } from "./tools/extract.js";
export 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];
}