express-intercept
Version:
Build Express middleware to intercept / replace / inspect / transform response
89 lines (88 loc) • 3.08 kB
JavaScript
;
// _handler.ts
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildResponseHandler = buildResponseHandler;
const _payload_js_1 = require("./_payload.js");
function buildResponseHandler(options, interceptor, container) {
const { _error, _if } = options || {};
return (req, res, next) => {
let started;
let stopped;
let payload;
let error;
let condition;
const original_write = res.write;
const intercept_write = res.write = function (chunk, encoding, cb) {
if (!started)
start();
if (stopped)
return original_write.apply(this, arguments);
const item = [].slice.call(arguments);
if ("function" === typeof item[item.length - 1])
cb = item.pop();
if (payload && item[0])
payload.push(item[0], item[1]);
if (cb)
cb(); // always success
return true;
};
const original_end = res.end;
const intercept_end = res.end = function (chunk, encoding, cb) {
if (!stopped && !started)
start();
const _stopped = stopped;
if (!stopped)
stop();
if (_stopped)
return original_end.apply(this, arguments);
const item = [].slice.call(arguments);
if ("function" === typeof item[item.length - 1])
cb = item.pop();
if (payload && item[0])
payload.push(item[0], item[1]);
if (payload)
payload.push(null); // EOF
if (cb)
cb(); // always success
if (error)
sendError(error);
if (!error)
finish().catch(sendError);
return this;
};
return next();
function start() {
started = true;
try {
// _if === null -> RUN
// _if(res) === false -> SKIP
// _if(res) === true -> RUN
// _if(res) instanceof Promise -> RUN
condition = !_if || _if(res);
if (!condition)
return stop();
}
catch (e) {
error = e;
return;
}
payload = container ? container() : new _payload_js_1.ResponsePayload(res);
}
function stop() {
stopped = true;
// restore to the original methods
if (res.write === intercept_write)
res.write = original_write;
if (res.end === intercept_end)
res.end = original_end;
}
async function finish() {
const readable = (await condition) && interceptor && (await interceptor(payload, req, res)) || payload;
readable.pipe(res);
}
function sendError(err) {
if (_error)
_error(err, req, res, (e) => null);
}
};
}