Skip to main content
Module

x/dinar/lib/core/Application.ts

deno web framewrok maybe :<
Latest
File
import { serve, ServerRequest, qs } from "../deps.ts";import { MetaDataStorage } from "./metadata.ts";import { InjectorDescriptor, Constructor, InjectorType, MiddlewareTypes, MiddlewareConstructor, PipeConstructor, FilterConstructor, StaticConstructor, LoggerConstructor, InterceptorConstructor, GuardConstructor } from "../@types/types.ts";import { RouterStorage } from "./router.ts";import { Context } from "./Context.ts";import { NotFountException } from "../constant/Exception.ts";import { Uuid } from "../utils/Uuid.ts";import { MiddlewareStorage } from "./middleware-storage.ts";import { RouteMethod } from "../constant/RouteMethods.ts";
export class Application { async run() { await MetaDataStorage.resolve(); const { port: port, hostname } = MetaDataStorage.envConfig; const s = serve({ port: +port, hostname }); const { pipes, guards, middlewares, interceptors, filters, staticServers, loggers } = MiddlewareStorage; console.log(`server is running on http://${hostname}:${port}/`); for await (const req of s) { const { url, body, query, method } = await this.prepareGenerateContext(req); const router = RouterStorage.find(url, method); let c = new Context(req, url, query, undefined, body); try { for (const middleware of middlewares) { await middleware.apply(req); } for (const guard of guards) { await guard.can(c); } if (router !== null) { const params = router.parseParams(url); c = Context.fromContext(c, params); const { args, argumentsMetadataArr } = await router.injectArugments(c); for (const pipe of pipes) { await pipe.validate(argumentsMetadataArr, c); } const result = await router.apply(args); c.res.body = result; } else { let found = false; for (const staticServer of staticServers) { found = await staticServer.apply(c); if (found) break; } if (!found) throw new NotFountException(); } } catch (e) { // httpExceptionFilter for (const filter of filters) { await filter.catch(e, c); } } finally { for (const interceptor of interceptors) { await interceptor.apply(c); } for (const logger of loggers) { logger.log(c); } } } }
private async bodyParser(rawRequest: ServerRequest) { const buf = await Deno.readAll(rawRequest.body); const decoder = new TextDecoder(); const bodyStr = decoder.decode(buf); const result: any = {}; if (bodyStr !== "") { for (const kv of bodyStr.split("&")) { const [k, v] = kv.split("="); result[k] = v; } } return result; }
private async prepareGenerateContext(rawRequest: ServerRequest) { const body = await this.bodyParser(rawRequest); const url = rawRequest.url.split("?")[0].replace(/\/{2.}/, "/"); const query = qs.parse(rawRequest.url.split("?")[1] ?? ""); const method = rawRequest.method.toUpperCase() as RouteMethod; return { body, url, query, method }; }
private use(m: Constructor, type: MiddlewareTypes) { m.prototype.id = m.prototype.id ?? Uuid.v4(); const params = (Reflect.getMetadata("design:paramtypes", m) as Constructor[]) ?? []; const args = params.map((param) => { param.prototype.id = param.prototype.id ?? Uuid.v4(); return param.prototype.id; }); const des: InjectorDescriptor = { target: m.prototype.id, args: args, proto: m, priority: args.length, type: InjectorType.Middleware, middlewareTypes: type, }; MetaDataStorage.addMiddleware(des); }
useGlobalMiddleware(middleware: MiddlewareConstructor) { this.use(middleware, MiddlewareTypes.Middleware); }
useGlobalGuard(guard: GuardConstructor) { this.use(guard, MiddlewareTypes.Guard); }
useGlobalInterceptor(ic: InterceptorConstructor) { this.use(ic, MiddlewareTypes.Interceptor); }
useGlobalExceptionFilter(filter: FilterConstructor) { this.use(filter, MiddlewareTypes.Filter); }
useGlobalPipe(pipe: PipeConstructor) { this.use(pipe, MiddlewareTypes.Pipe); }
useStatic(staticServer: StaticConstructor) { this.use(staticServer, MiddlewareTypes.StaticServer); }
useLogger(logger: LoggerConstructor) { this.use(logger, MiddlewareTypes.Logger); }}