Skip to main content

latest
Works with
This package works with Deno
JSR Score
64%
Published
2 months ago (0.2.0)
rootapp.ts
import { expandGlob, walk } from 'jsr:@std/fs@^0.221.0'; import { basename, extname, join, relative, toFileUrl } from 'jsr:@std/path@^0.221.0'; const globOpts = { root: Deno.cwd(), includeDirs: false, extended: true, globstar: true, }; async function errorpage(ctx: any, request: Request, code: number) { for await (const entry of expandGlob(`./errors/${code}.[jt]s?(x)`, globOpts)) { const handler = (await import(toFileUrl(entry.path).href)).default; if (!handler) { throw new Error(`${entry.path} does not have a default export`); } return await handler(ctx, request, code); } return new Response(null, { status: code }); } const middlewares: Function[] = []; for await (const entry of expandGlob('./middlewares/*.[jt]s?(x)', globOpts)) { const handler = (await import(toFileUrl(entry.path).href)).default; if (!handler) { throw new Error(`${entry.path} does not have a default export`); } middlewares.push(handler); } const routes: { route: string; path: string; module: any }[] = []; for await (const entry of expandGlob('./routes/**/*.[jt]s?(x)', globOpts)) { routes.push({ route: ('/' + relative(join(globOpts.root, 'routes'), entry.path)) .replace(/\.[jt]sx?$/, '').replace(/(?<=\/)index$/, ''), path: entry.path, module: null, }); } async function router(ctx: any, request: Request) { for (const { route, path, module } of routes) { const urlmatch = new URLPattern(route, request.url).exec(request.url); if (urlmatch === null) continue; const handler = await import(toFileUrl(path).href); if (request.method in handler) { return await handler[request.method](ctx, request); } if (request.method === 'HEAD' && 'GET' in handler) { let retval = await handler.GET(ctx, request); return new Response(null, { status: retval.status, statusText: retval.statusText, headers: retval.headers, }); } if ('default' in handler) { return await handler.default(ctx, request); } if (request.method === 'OPTIONS') { let allowed = Object.keys(handler).filter((s) => /^[A-Z]+$/.test(s)); if (allowed.includes('GET') && !allowed.includes('HEAD')) { allowed.push('HEAD'); } return new Response(null, { headers: { Allow: allowed.join(', ') } }); } // Method not known to the handler. return errorpage(ctx, request, 405); } return errorpage(ctx, request, 404); } Deno.serve(async (request) => { let ctx = {}; // Out of spite: return await middlewares.reduceRight( (a, b) => (c: Function, d: Function) => b(c, d, a), router, )(ctx, request); });