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
JavaScript
;
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;