@tsed/common
Version:
A TypeScript Framework on top of Express
257 lines • 7.3 kB
JavaScript
"use strict";
var PlatformResponse_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlatformResponse = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@tsed/core");
const di_1 = require("@tsed/di");
const PlatformViews_1 = require("./PlatformViews");
const onFinished = require("on-finished");
/**
* Platform Response abstraction layer.
* @platform
*/
let PlatformResponse = PlatformResponse_1 = class PlatformResponse {
constructor(raw) {
this.raw = raw;
}
/**
* Get the current statusCode
*/
get statusCode() {
return this.raw.statusCode;
}
/**
* An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during that request / response cycle (if any). Otherwise, this property is identical to app.locals.
*
* This property is useful for exposing request-level information such as the request path name, authenticated user, user settings, and so on.
*/
get locals() {
return this.raw.locals;
}
/**
* Create a new instance of PlatformResponse
* @param injector
* @param res
*/
static create(injector, res) {
const locals = new Map();
locals.set(di_1.DI_PARAM_OPTIONS, res);
return injector.invoke(PlatformResponse_1, locals);
}
static onFinished(res, cb) {
onFinished(res, cb);
}
/**
* Returns the HTTP response header specified by field. The match is case-insensitive.
*
* ```typescript
* response.get('Content-Type') // => "text/plain"
* ```
*
* @param name
*/
get(name) {
return this.raw.get(name);
}
/**
* Return the Framework response object (express, koa, etc...)
*/
getResponse() {
return this.raw;
}
/**
* Return the Node.js response object
*/
getRes() {
return this.raw;
}
hasStatus() {
return this.statusCode !== 200;
}
/**
* Sets the HTTP status for the response.
*
* @param status
*/
status(status) {
this.raw.status(status);
return this;
}
/**
* Set header `field` to `val`, or pass
* an object of header fields.
*
* Examples:
* ```typescript
* response.setHeaders({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
* ```
*
* Aliased as `res.header()`.
*/
setHeaders(headers) {
// apply headers
Object.entries(headers).forEach(([key, item]) => {
this.setHeader(key, item);
});
return this;
}
setHeader(key, item) {
this.raw.set(key, String(item));
return this;
}
/**
* Set `Content-Type` response header with `type` through `mime.lookup()`
* when it does not contain "/", or set the Content-Type to `type` otherwise.
*
* Examples:
*
* res.type('.html');
* res.type('html');
* res.type('json');
* res.type('application/json');
* res.type('png');
*/
contentType(contentType) {
this.raw.contentType(contentType);
return this;
}
contentLength(length) {
this.setHeader("Content-Length", length);
return this;
}
getContentLength() {
if (this.get("Content-Length")) {
return parseInt(this.get("Content-Length"), 10) || 0;
}
}
getContentType() {
return (this.get("Content-Type") || "").split(";")[0];
}
/**
* Sets the HTTP response Content-Disposition header field to “attachment”.
* If a filename is given, then it sets the Content-Type based on the extension name via res.type(), and sets the Content-Disposition “filename=” parameter.
*
* ```typescript
* res.attachment()
* // Content-Disposition: attachment
*
* res.attachment('path/to/logo.png')
* // Content-Disposition: attachment; filename="logo.png"
* // Content-Type: image/png
* ```
*
* @param filename
*/
attachment(filename) {
this.raw.attachment(filename);
return this;
}
/**
* Redirects to the URL derived from the specified path, with specified status, a positive integer that corresponds to an [HTTP status code](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
* If not specified, status defaults to `302 Found`.
*
* @param status
* @param url
*/
redirect(status, url) {
this.raw.redirect(status, url);
return this;
}
/**
* Sets the response Location HTTP header to the specified path parameter.
*
* @param location
*/
location(location) {
this.raw.location(location);
return this;
}
/**
* Stream the given data.
*
* @param data
*/
stream(data) {
data.pipe(this.raw);
return this;
}
/**
* Renders a view and sends the rendered HTML string to the client.
*
* @param path
* @param options
*/
async render(path, options = {}) {
return this.platformViews.render(path, {
...this.locals,
...options
});
}
/**
* Send any data to your consumer.
*
* This method accept a ReadableStream, a plain object, boolean, string, number, null and undefined data.
* It choose the better way to send the data.
*
* @param data
*/
body(data) {
if (data === undefined) {
this.raw.send();
return this;
}
if (core_1.isStream(data)) {
this.stream(data);
return this;
}
if (Buffer.isBuffer(data)) {
if (!this.getContentType()) {
this.contentType("application/octet-stream");
}
this.contentLength(data.length);
this.raw.send(data.toString());
return this;
}
if (core_1.isBoolean(data) || core_1.isNumber(data) || core_1.isString(data) || data === null) {
this.raw.send(data);
return this;
}
this.raw.json(data);
return this;
}
/**
* Add a listener to handler the end of the request/response.
* @param cb
*/
onEnd(cb) {
PlatformResponse_1.onFinished(this.getRes(), cb);
return this;
}
isDone() {
if (!this.raw) {
return true;
}
const res = this.getRes();
return Boolean(this.isHeadersSent() || res.writableEnded || res.writableFinished);
}
destroy() {
// @ts-ignore
delete this.raw;
}
isHeadersSent() {
return this.getRes().headersSent;
}
};
tslib_1.__decorate([
di_1.Inject(),
tslib_1.__metadata("design:type", PlatformViews_1.PlatformViews)
], PlatformResponse.prototype, "platformViews", void 0);
PlatformResponse = PlatformResponse_1 = tslib_1.__decorate([
di_1.Injectable(),
di_1.Scope(di_1.ProviderScope.INSTANCE),
tslib_1.__param(0, di_1.Opts),
tslib_1.__metadata("design:paramtypes", [Object])
], PlatformResponse);
exports.PlatformResponse = PlatformResponse;
//# sourceMappingURL=PlatformResponse.js.map