From e0868151ce96be18590b7f5231039005fa55bae3 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sat, 2 Jan 2021 19:09:16 -0500 Subject: [PATCH] Removing `send` event & replacing with `onsend(req, res, body, status, headers)` to customize the response by returning `[body, status, headers]` - event cannot mutate `body` if the variable type changes --- README.md | 6 +++--- lib/woodland.js | 27 +++++++++++++-------------- package.json | 2 +- test/test.js | 6 ++++-- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index f7ecc36..eef070d 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,9 @@ Returns an `Array` or `Object` of routes for the specified method. ##### log (msg = "", level = "debug") Logs to `stdout` or `stderr` depending on the `level`, & what the minimum log level is set to. +##### onsend (req, res, body, status, headers) +**Override** to customize response `body`, `status`, or `headers`. Must return `[body, status, headers]`! + ##### route (req, res) Function for `http.createServer()` or `https.createServer()`. @@ -131,9 +134,6 @@ Executes after the response has been sent. ##### finish (req, res) Executes after the response has been sent. -##### send (req, res, body, status, headers) -Executes before the response has been sent; arguments are by reference such that they can be mutated. - ## Helpers `req` & `res` are decorated with helper functions to simplify responding. diff --git a/lib/woodland.js b/lib/woodland.js index e0f6e6c..f01a920 100644 --- a/lib/woodland.js +++ b/lib/woodland.js @@ -124,29 +124,24 @@ class Woodland extends EventEmitter { res.header = res.setHeader; res.json = (arg, status = 200, headers = {"content-type": "application/json; charset=utf-8"}) => res.send(JSON.stringify(arg), status, headers); res.redirect = (uri, perm = true) => res.send("", perm ? 301 : 302, {"location": uri}); - res.send = (body, status = 200, headers = {}) => { + res.send = (body = "", status = 200, headers = {}) => { if (res.headersSent === false) { - const ev = "send"; - let output = body; - - if (this.listenerCount(ev) > 0) { - this.emit(ev, req, res, output, status, headers); - } + [body, status, headers] = this.onsend(req, res, body, status, headers); if (this.time) { headers["x-response-time"] = `${ms(req.precise.stop().diff(), this.digit)}`; } - if (pipeable(req.method, output)) { + if (pipeable(req.method, body)) { writeHead(res, status, headers); - output.on("error", () => void 0).pipe(res); + body.on("error", () => void 0).pipe(res); } else { - if (typeof output !== "string" && "toString" in output) { - output = output.toString(); + if (typeof body !== "string" && "toString" in body) { + body = body.toString(); } if (req.headers.range !== void 0) { - const buffered = Buffer.from(output); + const buffered = Buffer.from(body); partial(req, res, buffered, status, headers); @@ -161,11 +156,11 @@ class Woodland extends EventEmitter { const cl = "content-length"; if (res.getHeader(cl) === void 0) { - res.header(cl, Buffer.byteLength(output)); + res.header(cl, Buffer.byteLength(body)); } writeHead(res, status, headers); - res.end(output, this.charset); + res.end(body, this.charset); } } @@ -296,6 +291,10 @@ class Woodland extends EventEmitter { return this; } + onsend (req, res, body, status, headers) { + return [body, status, headers]; + } + options (...args) { return this.use(...args, "OPTIONS"); } diff --git a/package.json b/package.json index 300884b..686af65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "woodland", - "version": "15.1.12", + "version": "16.0.0", "description": "Lightweight HTTP router with automatic headers", "main": "index.js", "scripts": { diff --git a/test/test.js b/test/test.js index 7354353..7f50336 100644 --- a/test/test.js +++ b/test/test.js @@ -30,9 +30,11 @@ function always (req, res, next) { } router.on("connect", (req, res) => res.header("x-onconnect", "true")); -router.on("send", (req, res, body, status, headers) => { +router.onsend = (req, res, body, status, headers) => { headers["x-by-reference"] = "true"; -}); + + return [body, status, headers]; +}; router.on("finish", () => void 0); router.always("/.*", always).ignore(always); router.use("/", (req, res) => res.send(req.method !== "OPTIONS" ? "Hello World!" : ""));