express-response-middleware
Version:
Transform an express response
197 lines (188 loc) • 5.5 kB
JavaScript
;
var node_async_hooks = require('node:async_hooks');
const isInSend$1 = new node_async_hooks.AsyncLocalStorage();
const errorHandler = (err, _req, res, _next) => {
res.status(500).set("content-language", "en").json({ message: err.message }).end();
};
const jsonMiddleware = (fn) => (req, res, next) => {
const originalJsonFn = res.json;
const originalSendFn = res.send;
res.send = function() {
return isInSend$1.run(
true,
() => originalSendFn.apply(this, arguments)
);
};
res.json = function(json) {
const originalEndFn = res.end;
if (res.headersSent) return res;
let mayBePromise;
try {
mayBePromise = fn(json, req, res);
} catch (e) {
res.json = originalJsonFn;
errorHandler(e, req, res);
return res;
}
if (mayBePromise instanceof Promise) {
mayBePromise.then((result) => {
if (res.headersSent) return;
res.end = originalEndFn;
originalJsonFn.call(this, result === void 0 ? json : result);
}).catch((e) => {
res.json = originalJsonFn;
res.end = originalEndFn;
errorHandler(e, req, res);
});
res.end = function() {
if (isInSend$1.getStore()) {
originalEndFn.apply(this, arguments);
}
return res;
};
} else {
const result = mayBePromise;
if (res.headersSent) return res;
originalJsonFn.call(this, result === void 0 ? json : result);
}
return res;
};
next();
};
const endMiddleware = (fn) => (req, res, next) => {
const originalEndFn = res.end;
res.end = function() {
if (res.headersSent) return originalEndFn.apply(this, arguments);
let mayBePromise;
try {
mayBePromise = fn(req, res);
} catch (e) {
res.end = originalEndFn;
errorHandler(e, req, res);
return res;
}
if (mayBePromise instanceof Promise) {
mayBePromise.then(() => {
if (res.headersSent) {
console.error(
"sending response while in endMiddleware is undefined behaviour"
);
return;
}
originalEndFn.apply(this, arguments);
}).catch((e) => {
res.end = originalEndFn;
errorHandler(e, req, res);
});
res.end = function() {
return res;
};
} else {
if (res.headersSent) {
console.error(
"sending response while in endMiddleware is undefined behaviour"
);
return res;
}
return originalEndFn.apply(this, arguments);
}
return res;
};
next();
};
const writeMiddleware = (fn) => (req, res, next) => {
const originalWrite = res.write;
const originalEndFn = res.end;
res.write = function(chunk) {
if (res.writableEnded) return false;
let mayBePromise;
try {
mayBePromise = fn(
chunk,
// Since `encoding` is an optional argument to `res.write`,
// make sure it is a string and not actually the callback.
// biome-ignore lint/style/noArguments: pass argument type
typeof arguments[1] === "string" ? arguments[1] : null,
req,
res
);
} catch (e) {
errorHandler(e, req, res);
return false;
}
if (mayBePromise instanceof Promise) {
mayBePromise.then((result2) => {
res.end = originalEndFn;
if (res.writableEnded) return false;
arguments[0] = result2 === void 0 ? chunk : result2;
const writeResponse = originalWrite.apply(res, arguments);
if (res.__isEnd) res.end();
return writeResponse;
}).catch((e) => {
res.end = originalEndFn;
errorHandler(e, req, res);
});
res.end = function() {
this.__isEnd = true;
return res;
};
return false;
}
const result = mayBePromise;
if (res.writableEnded) return false;
arguments[0] = result === void 0 ? chunk : result;
return originalWrite.apply(res, arguments);
};
next();
};
const isInSend = new node_async_hooks.AsyncLocalStorage();
const jsonpMiddleware = (fn) => (req, res, next) => {
const originalJsonpFn = res.jsonp;
const originalSendFn = res.send;
res.send = function() {
return isInSend.run(
true,
() => originalSendFn.apply(this, arguments)
);
};
res.jsonp = function(json) {
const originalEndFn = res.end;
if (res.headersSent) return res;
let mayBePromise;
try {
mayBePromise = fn(json, req, res);
} catch (e) {
res.json = originalJsonpFn;
errorHandler(e, req, res);
return res;
}
if (mayBePromise instanceof Promise) {
mayBePromise.then((result) => {
if (res.headersSent) return;
res.end = originalEndFn;
originalJsonpFn.call(this, result === void 0 ? json : result);
}).catch((e) => {
res.jsonp = originalJsonpFn;
res.end = originalEndFn;
errorHandler(e, req, res);
});
res.end = function() {
if (isInSend.getStore()) {
originalEndFn.apply(this, arguments);
}
return res;
};
} else {
const result = mayBePromise;
if (res.headersSent) return res;
originalJsonpFn.call(this, result === void 0 ? json : result);
}
return res;
};
next();
};
exports.endMiddleware = endMiddleware;
exports.jsonMiddleware = jsonMiddleware;
exports.jsonpMiddleware = jsonpMiddleware;
exports.writeMiddleware = writeMiddleware;
//# sourceMappingURL=index.cjs.map