deno.land / x / duck_web_framework@0.1.1 / duck.ts

نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { serve, HTTPOptions, Server } from "https://deno.land/std@0.70.0/http/server.ts";import { DuckResponse } from "./response.ts";import { DuckRequest } from "./request.ts";import { Router } from "./router.ts";import { Middleware, ErrorMiddlewareFunction, MiddlewareFunction } from "./middleware.ts";import { CookieJar } from "./cookie_jar.ts";
export class Duck extends Router { port?: number; hostname?: string; certFile?: string; keyFile?: string; server?: Server;
private async run() { if (this.server) { for await (const request of this.server!) { let res = new DuckResponse(request); const req = new DuckRequest(request); await req.parseBody(); // get middlewares that match the request let matchingMiddlewares = Middleware.findMatching(this.middlewares, req); // create functions which take optional error parameter and call middleware const middlewaresToRun = matchingMiddlewares.map((middleware, i) => (error?: Error): any => { middleware.setParams(req); // if there are no more defined middlewares, fallback to the default one let next = middlewaresToRun[i + 1] ? middlewaresToRun[i + 1] : ((error?: any) => error ? this.defaultErrorHandler(error, req, res) : this.defaultHandler(req, res)); // there can either be an error or not if (!error) { if (middleware.handler.length === 4) return next(); return (middleware.handler as MiddlewareFunction)(req, res, next); }
// if this middleware is an error handler - ok if (middleware.handler.length === 4) return (middleware.handler as ErrorMiddlewareFunction)(error, req, res, next);
// if not, call the next middleware wrapper (hopefully it will recursively reach an error handler) return next(error); } ); try { if (middlewaresToRun.length === 0) return this.defaultHandler(req, res); middlewaresToRun[0](); } catch (err) { this.defaultErrorHandler(err, req, res); } } } }
private defaultHandler(req: DuckRequest, res: DuckResponse) { res.status(404).send({ code: 404, message: `Cannot ${req.method} ${req.url}` }); }
private defaultErrorHandler( err: any, req: DuckRequest, res: DuckResponse, ) { console.error(err); res.status(500).send({ ok: false }); }
/** * Starts an http server with given options * @param {HTTPOptions} options - options for server instance */ listen(options: HTTPOptions): Promise<void> { return new Promise((resolve, reject) => { try { this.server = serve(options); this.run(); resolve(); } catch (e) { reject(e); } }); }
/** * Currently not implemented - will be in the future */ listenTLS() { throw new Error("NotImplemented"); }
/** * Middleware that adds cookies to request and response * @see CookieJar * @param {DuckRequest} req * @param {DuckResponse} res * @param {Function} next */ static cookies(req: DuckRequest, res: DuckResponse, next: Function) { const cookieJar = new CookieJar(req, res); req.cookies = cookieJar; res.cookies = cookieJar; next(); }
static async logger(req: DuckRequest, res: DuckResponse, next: Function) { await next(); if (!res) return console.log(req.method, req.url); if (req.error) console.error(req.error); console.log(`Got a request from ${req.remoteAddr.hostname}: [${res.gStatus}] ${req.method} ${req.url}`); }}
duck_web_framework

Version Info

Tagged at
3 years ago