UNPKG

@m92/express-utils

Version:

Utility Module for Express Framework

132 lines (102 loc) 3.55 kB
'use strict' import context from 'express-http-context' import { nanoid } from 'nanoid' import { v4 as uuidv4 } from 'uuid' import autoBind from 'auto-bind' import { validationResult } from 'express-validator' export default class Middleware { constructor (CONFIG, CONSTANTS, thisExpressUtils) { const { logger, CustomError, reqHandler, httpContext } = thisExpressUtils const { asyncWrapper } = reqHandler this.CONFIG = CONFIG this.CONSTANTS = CONSTANTS this.logger = logger this.CustomError = CustomError this.asyncWrapper = asyncWrapper this.httpContext = httpContext autoBind(this) } init (app) { const { CONFIG } = this app.use(context.middleware) app.use(this.apiTagging) if (CONFIG.LOGGER_REQ_RES_LOG_ENABLED) { app.use(this.apiLogger) } } apiTagging (request, response, next) { const { CONFIG, CONSTANTS, httpContext } = this _tagSessionId(CONFIG, CONSTANTS, request, response, httpContext) _tagRequestId(CONFIG, CONSTANTS, request, response, httpContext) process.nextTick(next) } apiLogger (request, response, next) { const { logger, httpContext } = this const { ReqResLog } = logger httpContext.setReqResBodyLog(true) request.timestamp = Date.now() response.on('finish', () => { const reqResLog = new ReqResLog(request, response) logger._dispatch(reqResLog) }) process.nextTick(next) } requestValidator (validationFunction, errorMap) { const { CustomError, asyncWrapper } = this const validate = async (request, response, next) => { const validations = validationFunction() await Promise.all(validations.map(validation => validation.run(request))) const errors = validationResult(request) if (errors.isEmpty()) { return next() } const extractedErrors = errors.array().reduce((output, error) => { const { param, msg } = error const currentValue = output[param] if (!currentValue) { output[param] = [] } output[param].push(msg) return output }, {}) throw new CustomError(extractedErrors, errorMap) } return asyncWrapper(validate) } disableReqResBodyLogging (request, response, next) { const { httpContext } = this httpContext.setReqResBodyLog(false) process.nextTick(next) } } // --------- API Tagging ------------------------------------------------------- function _extractFromHeader (headers = {}, key = '') { let value = headers[key] || '' value = value || headers[key.toLowerCase()] || '' return value } function _tagSessionId (CONFIG, CONSTANTS, request, response, httpContext) { const { SESSION_ID_HEADER_KEY, SESSION_ID_PROP } = CONSTANTS const { headers = {} } = request const sessionId = _extractFromHeader(headers, SESSION_ID_HEADER_KEY) || httpContext.getSessionId() || nanoid() httpContext.setSessionId(sessionId) request[SESSION_ID_PROP] = sessionId response[SESSION_ID_PROP] = sessionId } function _tagRequestId (CONFIG, CONSTANTS, request, response, httpContext) { const { REQUEST_ID_HEADER_KEY, REQUEST_ID_PROP } = CONSTANTS const { headers = {} } = request const sessionId = _extractFromHeader(headers, REQUEST_ID_HEADER_KEY) || httpContext.getRequestId() || uuidv4() httpContext.setRequestId(sessionId) request[REQUEST_ID_PROP] = sessionId response[REQUEST_ID_PROP] = sessionId } // -----------------------------------------------------------------------------