@reflet/express
Version:
Well-defined and well-typed express decorators
108 lines (107 loc) • 3.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractSendHandler = exports.Send = void 0;
const type_guards_1 = require("./type-guards");
const reflet_error_1 = require("./reflet-error");
const metadata_map_1 = require("./metadata-map");
const METAKEY_SEND = Symbol('send');
function Send(optionsOrHandler = {}) {
return (target, key, descriptor) => {
const sendHandler = typeof optionsOrHandler === 'function'
? optionsOrHandler
: optionsOrHandler.json
? handleWithJsonMethod
: handleWithSendMethod;
if (key) {
(0, metadata_map_1.defineMetadata)(METAKEY_SEND, sendHandler, target, key);
}
else {
(0, metadata_map_1.defineMetadata)(METAKEY_SEND, sendHandler, target.prototype);
}
};
}
exports.Send = Send;
(function (Send) {
function Dont(targetMaybe, keyMaybe) {
if (targetMaybe) {
if (keyMaybe)
(0, metadata_map_1.defineMetadata)(METAKEY_SEND, null, targetMaybe, keyMaybe);
else
(0, metadata_map_1.defineMetadata)(METAKEY_SEND, null, targetMaybe.prototype);
}
else {
return (target, key, descriptor) => {
if (key)
(0, metadata_map_1.defineMetadata)(METAKEY_SEND, null, target, key);
else
(0, metadata_map_1.defineMetadata)(METAKEY_SEND, null, target.prototype);
};
}
}
Send.Dont = Dont;
})(Send = exports.Send || (exports.Send = {}));
/**
* @internal
*/
function extractSendHandler(target, key, appClass) {
// Send decorator on method
const methodSendHandler = (0, metadata_map_1.getOwnMetadata)(METAKEY_SEND, target.prototype, key);
if (methodSendHandler !== undefined) {
return methodSendHandler;
}
// Send decorator on router
const routerSendHandler = (0, metadata_map_1.getOwnMetadata)(METAKEY_SEND, target.prototype);
if (routerSendHandler !== undefined) {
return routerSendHandler;
}
// No Send decorator on method or router
const appSendHandler = appClass
? (0, metadata_map_1.getOwnMetadata)(METAKEY_SEND, appClass.prototype)
: undefined;
return appSendHandler;
}
exports.extractSendHandler = extractSendHandler;
/**
* @internal
*/
function handleWithSendMethod(value, { req, res, next }) {
// Readable stream
if ((0, type_guards_1.isReadableStream)(value)) {
value.pipe(res);
return;
}
// Response object itself
if (value === res) {
// A stream is piping to the response so we let it go
if (res.listenerCount('unpipe') > 0) {
return;
}
// The response will try to send itself, which will cause a cryptic error
// ('TypeError: Converting circular structure to JSON')
next(new reflet_error_1.RefletExpressError('RESPONSE_OBJECT_SENT', `Cannot send the response object.`));
return;
}
res.send(value);
}
/**
* @internal
*/
function handleWithJsonMethod(value, { req, res, next }) {
// Readable stream
if ((0, type_guards_1.isReadableStream)(value)) {
value.pipe(res);
return;
}
// Response object itself
if (value === res) {
// A stream is piping to the response so we let it go
if (res.listenerCount('unpipe') > 0) {
return;
}
// The response will try to send itself, which will cause a cryptic error
// ('TypeError: Converting circular structure to JSON')
next(new reflet_error_1.RefletExpressError('RESPONSE_OBJECT_SENT', `Cannot send the response object.`));
return;
}
res.json(value);
}