express-intercept
Version:
Build Express middleware to intercept / replace / inspect / transform response
122 lines (121 loc) • 3.51 kB
JavaScript
;
// _payload.ts
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResponsePayload = void 0;
const _compression_js_1 = require("./_compression.js");
function send(queue, dest, cb) {
let error;
if (queue.length === 1) {
const item = queue[0];
try {
dest.end(item[0], item[1], sendResult);
}
catch (e) {
catchError(e);
}
}
else {
try {
queue.forEach(item => {
if (!error)
dest.write(item[0], item[1], catchError);
});
}
catch (e) {
catchError(e);
}
// close stream even after error
try {
dest.end(sendResult);
}
catch (e) {
catchError(e);
}
}
if (cb)
cb(); // success callback
function catchError(e) {
error = error || e;
}
function sendResult(e) {
if (cb)
cb(e || error);
cb = null; // callback only once
}
}
class ResponsePayload {
res;
queue = [];
constructor(res) {
this.res = res;
//
}
push(chunk, encoding) {
if (chunk == null)
return; // EOF
this.queue.push([chunk, encoding]);
}
pipe(destination) {
send(this.queue, destination);
return destination;
}
getBuffer() {
const { queue, res } = this;
// force Buffer
const buffers = queue.map(item => Buffer.isBuffer(item[0]) ? item[0] : Buffer.from(item[0], item[1]));
// concat Buffer
let buffer = (buffers.length === 1) ? buffers[0] : Buffer.concat(buffers);
// decompress Buffer
const encoding = (0, _compression_js_1.findEncoding)(res.getHeader("Content-Encoding"));
if (encoding && buffer.length) {
buffer = (0, _compression_js_1.decompressBuffer)(buffer, encoding);
}
return buffer;
}
setBuffer(buffer) {
const { queue, res } = this;
if (!buffer)
buffer = Buffer.of();
// ETag:
var etagFn = res.app && res.app.get('etag fn');
if ("function" === typeof etagFn) {
res.setHeader("ETag", etagFn(buffer));
}
else {
res.removeHeader("ETag");
}
// recompress Buffer as compressed before
const encoding = (0, _compression_js_1.findEncoding)(res.getHeader("Content-Encoding"));
if (encoding && buffer.length) {
buffer = (0, _compression_js_1.compressBuffer)(buffer, encoding);
}
const length = +buffer.length;
if (length) {
res.setHeader("Content-Length", "" + length);
}
else {
res.removeHeader("Content-Length");
}
// empty
queue.splice(0);
// update
queue.push([buffer]);
}
getString() {
const { queue } = this;
// shortcut when only string chunks given and no Buffer chunks mixed
const stringOnly = !queue.filter(chunk => "string" !== typeof chunk[0]).length;
if (stringOnly)
return queue.map(item => item[0]).join("");
const buffer = this.getBuffer();
// Buffer to string
return buffer.toString();
}
setString(text) {
if (!text)
text = "";
const buffer = Buffer.from(text);
this.setBuffer(buffer);
}
}
exports.ResponsePayload = ResponsePayload;