UNPKG

spirit

Version:

extensible web library for building applications & frameworks

108 lines (100 loc) 2.89 kB
"use strict"; /** * node adapter for spirit */ var core = require("../core/core"); var request = require("./request"); var response = require("./response"); var Response = require("./response-class.js").Response; var size_of = require("./utils.js").size_of; /** * Detects if 'Content-Length' headers are set * If not set, it sets the header * Only possible for string, buffer * stream type will usually not have a length and need * to be closed manually with `.end()` * * For file-stream, it's possible to fs.stat for a length * But this function is more of a simple fail-safe * * @param {response} resp - response * @return {object} response headers */ var content_length = function content_length(resp) { if (resp.body === undefined) { resp.headers["Content-Length"] = 0; return resp.headers; } var h = Response.get(resp, "Content-Length"); if (h === undefined) resp.headers["Content-Length"] = size_of(resp.body); return resp.headers; }; /** * strips all undefined values from `headers` * * this is needed because node `res.writeHead` will still write * headers with undefined values * * @param {object} headers - response headers * @return {object} response headers */ var strip = function strip(headers) { var keys = Object.keys(headers); for (var i = 0; i < keys.length; i++) { if (typeof headers[keys[i]] === "undefined") { delete headers[keys[i]]; } } return headers; }; /** * writes a http response map to a node HTTP response object * * It only knows how to write string/buffer and of course stream * * NOTE: There is no guards or type checking * * @param {http.Response} res - node http response object * @param {response-map} resp - response map */ var send = function send(res, resp) { res.writeHead(resp.status, strip(content_length(resp))); if (resp.body === undefined) { return res.end(); } // resp body is a stream if (typeof resp.body.pipe === "function") { resp.body.pipe(res); // resp body is a string or buffer } else { res.write(resp.body); res.end(); } }; var adapter = function adapter(handler, middleware) { if (middleware === undefined) { middleware = []; } else if (typeof middleware === "function") { middleware = [middleware]; } var adp = core.compose(handler, middleware); return function (req, res) { var request_map = request.create(req); adp(request_map).then(function (resp) { if (!response.is_response(resp)) { throw new Error("node.js adapter did not receive a proper response (response map). Got: " + JSON.stringify(resp)); } send(res, resp); }).catch(function (err) { var resp = response.err_response(err); if (process.env.NODE_ENV === "production") { resp.body_(); } send(res, resp); }); }; }; module.exports = { adapter: adapter, send: send };