use-server
Version:
A light-weight, promise-based and middleware-driven web framework
96 lines (74 loc) • 2.68 kB
JavaScript
const Emitter = require('events');
const http = require('http');
const onFinished = require('on-finished');
const compose = require('use-compose');
const bindExpress = require('./express');
const statuses = http.STATUS_CODES;
class Application extends Emitter {
// babel 6 bug on no constructor, see https://github.com/babel/babel/issues/4254
// after babel fix it, remove this constructor
constructor() {
var _this;
//eslint-disable-line
_this = super();
this._middlewares = [];
this.use = function () {
for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
middlewares[_key] = arguments[_key];
}
for (const middleware of middlewares) {
if (typeof middleware !== 'function') throw new TypeError('use() only accept function');
_this._middlewares.push(middleware);
}
return _this;
};
this.listener = () => {
const stack = compose(this._middlewares);
// forward the request to new url
// usage: return req.forward('/new/path')
const forward = (req, resp, newUrl) => {
req.originalUrl = req.url;
req.url = newUrl;
return stack.call(this, req, resp);
};
return (req, resp) => {
req.app = this;
req.basePath = ''; // compatible with use-router
req.forward = forward.bind(this, req, resp);
const onerror = this._onerror.bind(this, resp);
onFinished(resp, onerror);
return stack.call(this, req, resp).then(() => {
if (resp.headersSent) return resp.end();
resp.statusCode = 404;
return resp.end(statuses[404]);
}).catch(onerror);
};
};
this.listen = function () {
const server = http.createServer(_this.listener());
return server.listen.apply(server, arguments);
};
this._onerror = (resp, err) => {
if (!err) return;
if (this.listenerCount('error') <= 0) {
console.error('Caught an error in use-server: %s', err.stack || err.toString());
} else {
this.emit('error', err);
}
if (resp.headersSent) return resp.end();
let statusCode = parseInt(err.statusCode || err.status || err.code, 10);
if (!statusCode || typeof statusCode !== 'number' || statusCode >= 1000 || statusCode < 400) {
statusCode = 500;
}
resp.statusCode = statusCode;
resp.end(err.message || statuses[statusCode] || 'Unknown Error');
};
}
// used as `http.createServer(app.listerner())`
}
module.exports = () => {
const app = new Application();
bindExpress(app);
return app;
};
;