69 lines
1.9 KiB
TypeScript
Executable File
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,
|
|
});
|
|
}
|