UNPKG

@n1k1t/mock-server

Version:

Powerful util to setup mocks over HTTP APIs

110 lines 5.04 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HttpExecutor = void 0; const axios_1 = __importDefault(require("axios")); const https_proxy_agent_1 = require("https-proxy-agent"); const lodash_1 = __importDefault(require("lodash")); const logger_1 = require("../../../logger"); const models_1 = require("../../models"); const logger = logger_1.Logger.build('Server.Transports.Http.Executor'); class HttpExecutor extends models_1.Executor { async exec(context, options) { await super.exec(context, options).catch((error) => { if (error instanceof models_1.ExecutorManualError) { return null; } logger.error('Got unexpected error while execution', error?.stack ?? error); }); return context.complete(); } async match(context) { const expectation = context.provider.storages.expectations.match(context.snapshot); if (!expectation && context.hasStatuses(['handling'])) { context.assign({ outgoing: await this.reply(context, { type: 'plain', status: 404, dataRaw: Buffer.from('Expectation was not found'), headers: {}, }), }); return null; } return expectation; } async forward(context, incoming, configuration) { const options = await this .compileForwardingConfiguration(context, incoming, configuration) .catch((error) => { context.snapshot.assign({ error: { code: 'UNKNOWN', message: error?.message ?? 'Unknown' }, outgoing: { type: 'plain', status: 502, headers: {} }, }); logger.error('Got error while execution [compileForwardingConfiguration] method', error?.stack ?? error); throw error; }); const response = await axios_1.default .request(options) .catch((error) => { if (!error.response) { context.snapshot.assign({ error: lodash_1.default.pick(error, ['message', 'code']), outgoing: { type: 'plain', status: 502, headers: {} }, }); logger.error('Got error while forwaring', error?.stack ?? error); throw error; } return error.response; }); const type = (0, models_1.extractPayloadType)(response.headers) ?? 'plain'; const data = (0, models_1.parsePayload)(type, response.data); return { incoming, outgoing: { type: type, status: response.status, headers: response.headers, data, dataRaw: response.data, }, }; } async reply(context, outgoing) { outgoing.headers = lodash_1.default.omitBy(Object.assign(lodash_1.default.omit(outgoing.headers, ['transfer-encoding']), { 'content-type': outgoing.headers['content-type'] ?? (outgoing.type === 'json' ? 'application/json' : outgoing.type === 'xml' ? 'application/xml' : undefined), ...(outgoing.dataRaw && { 'content-length': String(outgoing.dataRaw.length) }), }), lodash_1.default.isNil); context.response.writeHead(outgoing.status, outgoing.headers); context.response.write(outgoing.dataRaw ?? ''); context.response.end(); return outgoing; } /** Compiles Axios request configuration to forward */ async compileForwardingConfiguration(context, incoming, configuration) { const url = new URL(configuration.url ?? incoming.path, configuration.baseUrl); const isSecured = url.protocol.includes('https'); return { timeout: configuration.timeout ?? 30000, method: incoming.method, headers: Object.assign(incoming.headers, { connection: 'close', ...(configuration.options?.overrideHost !== false && { host: url.host }), ...(incoming.dataRaw && { 'content-length': String(incoming.dataRaw.length) }), }), ...(configuration.url && { url: configuration.url }), ...(configuration.baseUrl && { baseURL: configuration.baseUrl, url: incoming.path }), data: incoming.dataRaw, params: context.incoming.query, responseType: 'arraybuffer', ...((configuration.proxy && !isSecured) && { proxy: configuration.proxy }), ...((configuration.proxy && isSecured) && { httpsAgent: new https_proxy_agent_1.HttpsProxyAgent(`http://${configuration.proxy.host}:${configuration.proxy.port}`), }), }; } } exports.HttpExecutor = HttpExecutor; //# sourceMappingURL=executor.js.map