@athenna/http
Version:
The Athenna Http server. Built on top of fastify.
259 lines (258 loc) • 6.33 kB
JavaScript
/**
* @athenna/http
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { View } from '@athenna/view';
import { Macroable } from '@athenna/common';
export class Response extends Macroable {
constructor(response, request) {
super();
this.response = response;
this.request = request;
}
/**
* Verify if the response has been already sent. Keep
* in mind that this method will only return `true`
* after `response.send()`, `response.view()`,
* `response.sendFile()` or `response.download()` methods
* call.
*
* @example
* ```ts
* if (response.sent) {
* // do something
* }
* ```
*/
get sent() {
return this.response.sent;
}
/**
* Get the response body sent in response. Keep
* in mind that this method will only return `true`
* after `response.send()`, `response.view()`,
* `response.sendFile()` or `response.download()` methods
* call.
*
* @example
* ```ts
* const { createdAt, updatedAt } = response.body
* ```
*/
get body() {
return this.response.body;
}
/**
* Get the status code sent in response. Keep
* in mind that this method will only return `true`
* after `response.send()`, `response.view()`,
* `response.sendFile()` or `response.download()` methods
* call.
*
* @example
* ```ts
* if (response.statusCode !== 200) {
* // do something
* }
* ```
*/
get statusCode() {
return this.response.statusCode;
}
/**
* Get the headers set in the response.
*
* @example
* ```ts
* const headers = response.headers
* ```
*/
get headers() {
return this.response.getHeaders();
}
/**
* Get the time in MS of how much the request has
* taken to response. Keep in mind that this method
* will only return `true` after `response.send()`,
* `response.view()`, `response.sendFile()` or
* `response.download()` methods call.
*
* @example
* ```ts
* console.log(response.responseTime) // 1000
* ```
*/
get responseTime() {
return this.response.elapsedTime;
}
/**
* Terminate the request sending an HTML content to be rendered.
*
* @example
* ```ts
* return response.html('<h1>Hello World!</h1>')
* ```
*/
async html(html) {
await this.safeHeader('Content-Type', 'text/html; charset=utf-8').send(html);
this.response.body = html;
return this;
}
/**
* Terminate the request sending a view to be rendered.
*
* @example
* ```ts
* return response.view('welcome', { name: 'lenon' })
* ```
*/
async view(view, data) {
const content = await View.edge
.createRenderer()
.share({ request: this.request })
.render(view, data);
return this.html(content);
}
/**
* Terminate the request sending the response body or not.
*
* @example
* ```ts
* return response.send({ name: 'lenon' })
* ```
*/
async send(data) {
await this.response.send(data);
this.response.body = data;
return this;
}
/**
* Terminate the request sending a file.
*
* @example
* ```ts
* return response.sendFile('img.png')
* ```
*/
async sendFile(filename, filepath, options) {
await this.response.sendFile(filename, filepath, options);
return this;
}
/**
* Terminate the request sending a file with custom name.
*
* @example
* ```ts
* return response.download('img.png', 'custom-img.png')
* ```
*/
async download(filepath, filename, options) {
await this.response.download(filename, filepath, options);
return this;
}
/**
* Set the response status code.
*
* @example
* ```ts
* return response.status(200).send()
* ```
*/
status(code) {
this.response.status(code);
return this;
}
/**
* Add some header to the response.
*
* @example
* ```ts
* response.header('content-type', 'application/json')
*
* return response.header('accept-encoding', 'gzip').send(user)
* ```
*/
header(header, value) {
this.response.header(header, value);
return this;
}
/**
* Verify if response has some header.
*
* @example
* ```ts
* if (response.hasHeader('content-type')) {
* // do something
* }
* ```
*/
hasHeader(header) {
return this.response.hasHeader(header);
}
/**
* Add some header safely to the response. This means that
* the header is not going to be added if is already set.
*
* @example
* ```ts
* response.safeHeader('content-type', 'application/json')
* ```
*/
safeHeader(header, value) {
this.response.header(header, value);
return this;
}
/**
* Remove some header from the response.
*
* @example
* ```ts
* response.removeHeader('content-type')
* ```
*/
removeHeader(header) {
this.response.removeHeader(header);
return this;
}
/**
* Redirect the response to other url. You can also set a
* different status code for the redirect.
*
* @example
* ```ts
* return response.redirect('users', 304)
* ```
*/
async redirectTo(url, status) {
if (status) {
await this.response.redirect(url, status);
return this;
}
await this.response.redirect(url);
return this;
}
/**
* Apply helmet in response.
*
* @example
* ```ts
* return response
* .helmet({ enableCSPNonces: false })
* .view('profile', user)
* ```
*/
helmet(options) {
this.response.helmet(options);
return this;
}
/**
* Get the original fastify response.
*/
getFastifyResponse() {
return this.response;
}
}