@respond-run/router
Version:
Filesystem-based router for Vite-powered Cloudflare Workers
47 lines (46 loc) • 1.65 kB
JavaScript
/**
* Creates a route handler from a Vite import.meta.glob() result
*/
export function createRouter(globs) {
const routeMap = Object.entries(globs).map(([filePath, loader]) => {
let routePath = filePath.replace(/^.*\/routes/, '').replace(/\.ts$/, '');
if (routePath.endsWith('/index')) {
routePath = routePath.replace(/\/index$/, '') || '/';
}
const paramNames = [];
const regex = new RegExp('^' + routePath.replace(/\[(\w+)\]/g, (_, name) => {
paramNames.push(name);
return '([^/]+)';
}) + '$');
return {
filePath,
loader: loader,
regex,
paramNames
};
});
return async function handleRoutes(request, env, ctx) {
const url = new URL(request.url);
const pathname = url.pathname.replace(/\/$/, '') || '/';
const method = request.method.toUpperCase();
for (const { regex, paramNames, loader } of routeMap) {
const match = pathname.match(regex);
if (!match)
continue;
const params = Object.fromEntries(paramNames.map((key, i) => [key, match[i + 1]]));
const mod = await loader();
const handler = mod[method];
if (!handler) {
return new Response('Method Not Allowed', { status: 405 });
}
return handler(request, env, ctx, params);
}
return new Response('Not Found', { status: 404 });
};
}
/**
* Optional helper for defining routes with strong type hints.
*/
export function defineRoute(fn) {
return fn;
}