UNPKG

unmock-core

Version:

[![npm](https://img.shields.io/npm/v/unmock-core.svg)][npmjs] [![CircleCI](https://circleci.com/gh/unmock/unmock-js.svg?style=svg)](https://circleci.com/gh/unmock/unmock-js) [![codecov](https://codecov.io/gh/unmock/unmock-js/branch/dev/graph/badge.svg)](h

136 lines (133 loc) 6.03 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = require("debug"); const Mitm = require("mitm"); const console_1 = require("../console"); const fs_service_def_loader_1 = require("../fs-service-def-loader"); const generator_1 = require("../generator"); const filesystem_logger_1 = require("../loggers/filesystem-logger"); const snapshotter_1 = require("../loggers/snapshotter"); const parser_1 = require("../parser"); const serialize_1 = require("../serialize"); const serviceStore_1 = require("../service/serviceStore"); const utils_1 = require("../utils"); const client_request_tracker_1 = require("./client-request-tracker"); const debugLog = debug_1.default("unmock:node"); const respondFromSerializedResponse = (serializedResponse, res) => { res.writeHead(serializedResponse.statusCode, serializedResponse.headers); res.end(serializedResponse.body); }; const errorForMissingTemplate = (sreq) => { const serverUrl = `${sreq.protocol}://${sreq.host}`; return `No matching template found for intercepted request. Please ensure that 1. You have defined a service for host ${serverUrl} 2. The service has a path matching "${sreq.method} ${sreq.pathname}" For example, add the following to your service: servers: - url: ${sreq.protocol}://${sreq.host} paths: ${sreq.pathname}: ${sreq.method.toLowerCase()}: // OpenAPI operation object responses: 200: ... `; }; function handleRequestAndResponse(createResponse, req, res, clientRequest) { return __awaiter(this, void 0, void 0, function* () { try { const serializedRequest = yield serialize_1.serializeRequest(req); debugLog("Serialized request", JSON.stringify(serializedRequest)); const serializedResponse = createResponse(serializedRequest); if (serializedResponse === undefined) { debugLog("No match found, emitting error"); const errMsg = errorForMissingTemplate(serializedRequest); const formatted = console_1.CustomConsole.format("instruct", errMsg); clientRequest.emit("error", Error(formatted)); return; } debugLog("Responding with response", JSON.stringify(serializedResponse)); respondFromSerializedResponse(serializedResponse, res); } catch (err) { clientRequest.emit("error", Error(`unmock error: ${err.message}`)); } }); } const nodeBackendDefaultOptions = {}; class NodeBackend { constructor(config) { this.serviceStore = new serviceStore_1.ServiceStore([]); this.config = Object.assign(Object.assign({}, nodeBackendDefaultOptions), config); this.loadServices(); } loadServices() { const unmockDirectories = this.config.servicesDirectory ? [this.config.servicesDirectory] : utils_1.resolveUnmockDirectories(); debugLog(`Found unmock directories: ${JSON.stringify(unmockDirectories)}`); const serviceDefLoader = new fs_service_def_loader_1.FsServiceDefLoader({ unmockDirectories, }); const serviceDefs = serviceDefLoader.loadSync(); const coreServices = serviceDefs.map(serviceDef => parser_1.ServiceParser.parse(serviceDef)); this.serviceStore = new serviceStore_1.ServiceStore(coreServices); } get services() { return (this.serviceStore && this.serviceStore.services) || {}; } initialize(options) { if (process.env.NODE_ENV === "production" && !options.useInProduction()) { throw new Error("Are you trying to run unmock in production?"); } if (this.mitm !== undefined) { this.reset(); } this.mitm = Mitm(); client_request_tracker_1.default.start(); this.mitm.on("connect", (socket, opts) => this.mitmOnConnect(options, socket, opts)); const createResponse = generator_1.responseCreatorFactory({ listeners: [ new filesystem_logger_1.default({ directory: this.config.servicesDirectory }), snapshotter_1.default.getOrUpdateSnapshotter({}), ], options, store: this.serviceStore, }); this.mitm.on("request", (req, res) => this.mitmOnRequest(createResponse, req, res)); } reset() { if (this.mitm) { this.mitm.disable(); this.mitm = undefined; } if (this.serviceStore) { Object.values(this.serviceStore.services).forEach(service => service.reset()); } client_request_tracker_1.default.stop(); } mitmOnRequest(createResponse, req, res) { debugLog("Handling incoming message..."); req.on("error", (e) => debugLog("Error on intercepted request:", e)); req.on("abort", () => debugLog("Intercepted request aborted")); const clientRequest = client_request_tracker_1.default.pop(req); setImmediate(() => handleRequestAndResponse(createResponse, req, res, clientRequest)); } mitmOnConnect({ isWhitelisted }, socket, opts) { if (isWhitelisted(opts.host || "")) { socket.bypass(); } } } exports.default = NodeBackend; //# sourceMappingURL=index.js.map