UNPKG

in-process-request

Version:

A node.js library that executes a http handler function in the current process without having to start a local http server.

137 lines (136 loc) 4.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createMockRequest = exports.createMockResponse = void 0; const http_1 = require("http"); const keysToLowerCase = (headers) => { const lowerCaseHeaders = {}; Object.keys(headers).forEach(k => { lowerCaseHeaders[k.toLowerCase()] = headers[k]; }); return lowerCaseHeaders; }; const getRawHeaders = (headers) => { const rawHeaders = []; Object.entries(headers).forEach(([key, value]) => { if (Array.isArray(value)) { value.forEach(v => { rawHeaders.push(key); rawHeaders.push(v); }); } else if (typeof value === 'string') { rawHeaders.push(key); rawHeaders.push(value); } }); return rawHeaders; }; const toBuffer = (param, encoding) => { if (Buffer.isBuffer(param)) { return param; } else if (typeof param === 'string') { return Buffer.from(param, encoding); } else { return Buffer.alloc(0); } }; const isUTF8 = (headers) => { if (headers['content-encoding']) { return false; } const contentType = headers['content-type'] || ''; return contentType.match(/charset=(utf-8|"utf-8")$/i) ? true : false; }; const createMockResponse = (req) => { const res = new http_1.ServerResponse(req); res.shouldKeepAlive = false; const chunks = []; const addChunk = (chunk, encoding) => chunks.push(toBuffer(chunk, encoding)); const headers = {}; res.write = (chunk, encodingOrCallback, maybeCallback) => { const encoding = typeof encodingOrCallback === 'string' ? encodingOrCallback : undefined; const callback = typeof maybeCallback === 'function' ? maybeCallback : (typeof encodingOrCallback === 'function' ? encodingOrCallback : undefined); addChunk(chunk, encoding); if (callback) { callback(null); } return true; }; res.setHeader('___internal___', '___internal___'); const originalSetHeader = res.setHeader.bind(res); res.setHeader = (name, value) => { originalSetHeader(name, value); const strVal = (typeof value === 'number') ? String(value) : value; headers[name.toLowerCase()] = strVal; return res; }; res.end = (chunkOrCallback, encodingOrCallback, maybeCallback) => { let encoding = undefined; let chunk = undefined; let callback = typeof chunkOrCallback === 'function' ? chunkOrCallback : undefined; if (!callback) { chunk = chunkOrCallback; callback = typeof encodingOrCallback === 'function' ? encodingOrCallback : undefined; } if (!callback) { encoding = encodingOrCallback; callback = maybeCallback; } addChunk(chunk, encoding); const body = Buffer.concat(chunks); const response = { body, isUTF8: isUTF8(headers), statusCode: res.statusCode, statusMessage: res.statusMessage, headers, }; res.emit('prefinish'); res.emit('finish'); res.emit('__mock_response', response); if (callback) { callback(null); } return res; }; return res; }; exports.createMockResponse = createMockResponse; const createMockRequest = (opts) => { const socket = { remoteAddress: opts.remoteAddress || '123.123.123.123', remotePort: opts.remotePort || 5757, encrypted: opts.ssl ? true : false, end: () => { }, destroy: () => { }, readable: true, on: () => undefined, removeListener: () => undefined, }; const body = toBuffer(opts.body); const contentLength = Buffer.byteLength(body); const req = new http_1.IncomingMessage(socket); req.method = (opts.method || 'GET').toUpperCase(); req.url = opts.path; req.headers = keysToLowerCase(opts.headers || {}); req.rawHeaders = getRawHeaders(opts.headers || {}); req.httpVersionMajor = 1; req.httpVersionMinor = 1; req.httpVersion = '1.1'; if (contentLength > 0 && !req.headers['content-length']) { req.headers['content-length'] = contentLength.toString(); req.rawHeaders.push('content-length'); req.rawHeaders.push(contentLength.toString()); } req._read = () => { if (contentLength > 0) { req.push(body); } req.push(null); }; return req; }; exports.createMockRequest = createMockRequest;