UNPKG

availity-ekko

Version:

Mock server simulating Availity API rest services

181 lines (122 loc) 3.93 kB
'use strict'; const path = require('path'); const fs = require('fs'); const Promise = require('bluebird'); const chalk = require('chalk'); const config = require('../config'); const logger = require('../logger').getInstance(); const result = { cache: {}, sendFile(req, res, status, response, filePath) { res.status(status).sendFile(filePath, (err) => { if (err) { logger.error(`NOT FOUND ${filePath} `); config.events.emit(config.constants.EVENTS.FILE_NOT_FOUND, { req }); res.sendStatus(404); } else { const file = chalk.blue(filePath); const relativeFile = path.relative(process.cwd(), file); // Attach file path to response object for logging at the end of request cycle res.avFile = relativeFile; config.events.emit(config.constants.EVENTS.RESPONSE, { req, res: response, file: filePath }); } }); }, parseJSON(contents) { let replacedContents; try { replacedContents = JSON.parse(contents); } catch (err) { replacedContents = contents; } return replacedContents; }, sendJson(req, res, status, response, filePath) { try { const contents = fs.readFileSync(filePath, 'utf8'); const regex = /\${context}/g; const replacedContents = contents.replace(regex, config.options.pluginContext); const json = this.parseJSON(replacedContents); const relativeFile = path.relative(process.cwd(), filePath); // Attach file path to response object for logging at the end of request cycle res.avFile = relativeFile; res.status(status).json(json); config.events.emit(config.constants.EVENTS.RESPONSE, { req, res: response, file: filePath }); } catch (err) { logger.error(`NOT FOUND ${filePath} `); config.events.emit(config.constants.EVENTS.FILE_NOT_FOUND, { req }); res.sendStatus(404); } }, file(req, res, response, dataPath) { Promise.delay(response.latency || 200).then(() => { const filePath = path.join(dataPath, response.file); const status = response.status || 200; if (response.headers) { res.set(response.headers); } if (path.extname(filePath) === '.json') { this.sendJson(req, res, status, response, filePath); } else { this.sendFile(req, res, status, response, filePath); } }); }, url(req, res, response) { config.events.emit(config.constants.EVENTS.REDIRECT, { req, res: response }); res.redirect(response.url); }, send(req, res) { const route = res.locals.route; const request = res.locals.request; const routeId = route.id; const requestId = request.id; // cache: { // 'route1_request2': [0,0] // position 0 === response index; position 1 === repeat index // } const cacheKey = routeId + '_' + requestId; let indexes = result.cache[cacheKey]; if (!indexes) { // empty cache so hydrate indexes = result.cache[cacheKey] = [0, 0]; } let responseIndex = indexes[0]; let repeatIndex = indexes[1]; let response = request.responses[responseIndex]; if (repeatIndex >= response.repeat) { responseIndex = (responseIndex + 1) % request.responses.length; repeatIndex = 0; } repeatIndex++; // cache the latest index for the next request indexes[0] = responseIndex; indexes[1] = repeatIndex; result.cache[cacheKey] = indexes; // return the appropriate response object response = request.responses[responseIndex]; if (response.file) { this.file(req, res, response, route.dataPath); return; } if (response.url) { this.url(req, res, response); return; } res.sendStatus(404); } }; module.exports = result;