Router/file_router.ts
2025-01-04 18:05:31 -07:00

69 lines
1.9 KiB
TypeScript
Executable File

import Router from "./router.ts";
import type { Handler, RouteConfigurator } from "./types.ts";
function crawl(dir: string, callback: (path: string) => void) {
for (const entry of Deno.readDirSync(dir)) {
const path = Deno.build.os === "windows"
? `${dir}\\${entry.name}`
: `${dir}/${entry.name}`;
if (entry.isDirectory) {
crawl(path, callback);
} else {
callback(path);
}
}
}
/**
* @example
* ```ts
* import {FileRouter} from "@bearmetal/router"
*
* const router = new FileRouter("dirName");
* Deno.listen(router.handle);
* ```
*/
export class FileRouter extends Router {
constructor(root: string) {
super();
crawl(root, async (path) => {
let relativePath = path.replace(root, "");
if (path.endsWith(".ts") || path.endsWith(".js")) {
relativePath = relativePath.replace(/\.[tj]s/, "");
const handlers = await import(path);
if (handlers.default) {
handlers.default instanceof Router
? this.use(relativePath, handlers.default)
: this.route(relativePath).get(handlers.default);
}
if (handlers.handlers) {
for (const [method, handler] of Object.entries(handlers.handlers)) {
this.route(relativePath)[method as keyof RouteConfigurator](
handler as Handler,
);
}
}
}
if (path.endsWith(".htm") || path.endsWith(".html")) {
const headers = new Headers();
headers.set("Content-Type", "text/html");
this.route(relativePath).get((_ctx) => {
return new Response(Deno.readTextFileSync(path), { headers });
});
}
});
}
}
if (import.meta.main) {
const router = new FileRouter("fileRouterTest");
router.serveDirectory("docs", "/", { showIndex: true });
Deno.serve({
port: 8000,
handler: router.handle,
});
}