diff --git a/app.ts b/app.ts index e8b4dc7..55ae7ad 100644 --- a/app.ts +++ b/app.ts @@ -5,9 +5,11 @@ import { HTTPOptions, join, log, + sep, serve, Server, } from "./deps.ts"; +import { getNestedDirectories } from "./util.ts"; export type Handler = (c: Context) => Promise | void; export type Middleware = (next: Handler) => Handler; @@ -176,18 +178,31 @@ export class Application { directory: string, ...middlewares: Middleware[] ): Application { - // TODO: Fallback handler if file does not exist if (!path.endsWith("/")) path += "/"; - const hdl = async (c: Context) => { - const file = c.path.substring(path.length); - if (file.length === 0) return await c.file(join(directory, "index.html")); - return await c.file(join(directory, file)); - }; - this.addPath(`${path}*`, Method.GET, hdl, ...middlewares); + (async () => { + const directories = await getNestedDirectories(directory); + directories.push(""); + for (const dir of directories) { + const hdl = async (c: Context) => { + const file = c.path.substring(join(path, dir, sep).length); + if (file.length === 0) { + return await c.file(join(directory, dir, "index.html")); + } + return await c.file(join(directory, dir, file)); + }; + this.addPath( + `${path + dir}/*`.replace(/\/+/, "/"), + Method.GET, + hdl, + ...middlewares, + ); + } + })(); return this; } } +// Logging await log.setup({ handlers: { timeHandler: new log.handlers.ConsoleHandler("INFO", { diff --git a/deps.ts b/deps.ts index 362ad53..4c76925 100644 --- a/deps.ts +++ b/deps.ts @@ -6,18 +6,18 @@ export { ServerRequest, setCookie, Status, -} from "https://deno.land/std@0.88.0/http/mod.ts"; +} from "https://deno.land/std@0.89.0/http/mod.ts"; export type { Cookie, HTTPOptions, Response, -} from "https://deno.land/std@0.88.0/http/mod.ts"; +} from "https://deno.land/std@0.89.0/http/mod.ts"; -export { MultipartReader } from "https://deno.land/std@0.88.0/mime/mod.ts"; +export { MultipartReader } from "https://deno.land/std@0.89.0/mime/mod.ts"; -export * as log from "https://deno.land/std@0.88.0/log/mod.ts"; +export * as log from "https://deno.land/std@0.89.0/log/mod.ts"; -export { format } from "https://deno.land/std@0.88.0/datetime/mod.ts"; +export { format } from "https://deno.land/std@0.89.0/datetime/mod.ts"; -export { extname, join } from "https://deno.land/std@0.88.0/path/mod.ts"; +export { extname, join, sep } from "https://deno.land/std@0.89.0/path/mod.ts"; diff --git a/router.ts b/router.ts index fb8fc05..be9a910 100644 --- a/router.ts +++ b/router.ts @@ -98,7 +98,7 @@ export class Node { } export class PathHandler { - private name?: string; + private readonly name?: string; constructor( private readonly path: string, private readonly method: Method, diff --git a/util.ts b/util.ts new file mode 100644 index 0000000..0625536 --- /dev/null +++ b/util.ts @@ -0,0 +1,15 @@ +import { join } from "./deps.ts"; + +export async function getNestedDirectories(dirname: string): Promise { + let items: string[] = []; + for await (const item of Deno.readDir(dirname)) { + if (item.isDirectory) { + items.push(item.name); + const jp = join(dirname, item.name); + let dirs = await getNestedDirectories(jp); + dirs = dirs.map((subdir) => join(item.name, subdir)); + items = items.concat(dirs); + } + } + return items; +}