import { APIGatewayEvent } from 'aws-lambda'; import { log } from '../system'; import { BadRequest } from './errors'; /** * An HTTP request object. * * @export * @class Request */ export class Request { /** * The request identifier. * * @type {string} * @memberof Request */ id: string; /** * The decoded authorization JWT information. * * @type {*} * @memberof Request */ auth: any; /** * The Javascript representation of the request body. * * @type {*} * @memberof Request */ data: any; /** * The path requested. * * @type {string} * @memberof Request */ path: string; /** * The method or verb requested. * * @type {string} * @memberof Request */ method: string; /** * The body of the request. * * @type {(string | null)} * @memberof Request */ body: string | null; /** * The underlying serverless event object. * * @type {APIGatewayEvent} * @memberof Request */ event: APIGatewayEvent; /** * The request headers. * * @type {{ [name: string]: string }} * @memberof Request */ headers: { [name: string]: string }; /** * The query parameters. * * @type {({ [name: string]: string } | null)} * @memberof Request */ query: { [name: string]: string } | null; /** * The path parameters. * * @type {({ [name: string]: string } | null)} * @memberof Request */ params: { [name: string]: string } | null; /** * Creates an instance of Request. * @param {APIGatewayEvent} event * @memberof Request */ constructor(event: APIGatewayEvent) { this.auth = null; this.headers = {}; this.event = event; this.body = event.body; this.path = event.path; this.method = event.httpMethod; this.params = event.pathParameters; this.query = event.queryStringParameters; this.id = event.requestContext.requestId; // Normalize all header keys with capitalization. for (let key in event.headers) { let value = event.headers[key]; key = key.replace(/(^[a-zA-Z]|-[a-zA-Z])/g, (str, char) => { return str.replace(char, char.toUpperCase()); }); this.headers[key] = value; } this.parseBody(); } /** * Parses the body of a request if the Content-Type header is * application/json. If parsing fails, a Bad Request is thrown. * * @private * @throws {BadRequest} * @memberof Request */ private parseBody() { let content = this.headers['Content-Type']; if (content && content.includes('application/json')) { try { this.data = JSON.parse(this.body); } catch (err) { log.error(err); throw new BadRequest('Parsing the request body failed.'); } } } }