Socket
Socket
Sign inDemoInstall

http-api-proxy-server

Package Overview
Dependencies
327
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.1 to 0.0.2

21

dist/proxy-server.d.ts

@@ -1,2 +0,1 @@

import { IncomingMessage as Req } from "http";
export type HttpApiProxyServerSettings = {

@@ -16,4 +15,11 @@ find?: string;

};
type ResponseBody = (Record<string, unknown> & GraphQLCompatibleResponse) | any;
type ResponseBody = Record<string, unknown> & GraphQLCompatibleResponse;
type RequestId = `responseFor${string}`;
export type Request = {
requestId: RequestId;
url?: string;
method?: string;
headers: Record<string, string | string[] | undefined>;
body: string | undefined;
};
type ProxyResponse = {

@@ -29,12 +35,15 @@ body: ResponseBody;

type ProxyBehavior = "SAVE_RESPONSES_FOR_NEW_QUERIES" | "RELOAD_RESPONSES_WITH_ERRORS" | "NO_REQUEST_FORWARDING" | "FORCE_UPDATE_ALL";
export declare const generateResponseOverwriteCode: (req: Req, potentialPathsForChanges: MatchPaths[], searchValue: string, filePath: string) => string;
export declare const generateResponseOverwriteCode: (request: Request, potentialPathsForChanges: MatchPaths[], searchValue: string, filePath: string) => string;
export declare const hasError: (resp: ProxyResponse) => boolean;
export declare const printErrors: (response: ProxyResponse, settings: HttpApiProxyServerSettings | undefined, filePath: string) => void;
export declare const requestToId: (req: Req) => RequestId;
export declare const createRequestId: ({ url, body, }: {
url: string | undefined;
body: string | undefined;
}) => RequestId;
export declare const isNumberString: (str: string) => boolean;
export declare const findObjectPaths: (obj: ResponseBody, search: string) => MatchPaths[];
export declare const printFindDeveloperHelp: (req: Req, response: ProxyResponse, filePath: string, find: string | undefined) => void;
export declare const printFindDeveloperHelp: (request: Request, response: ProxyResponse, filePath: string, find: string | undefined) => void;
export declare const printResponseLogs: (settings: {
responsesToLog?: RequestId[];
}, req: Req, response: ProxyResponse) => void;
}, request: Request, response: ProxyResponse) => void;
/** @description Snapshots responses for request and provide them as stubs. */

@@ -41,0 +50,0 @@ export declare class HttpApiProxyServer {

@@ -53,3 +53,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpApiProxyServer = exports.printResponseLogs = exports.printFindDeveloperHelp = exports.findObjectPaths = exports.isNumberString = exports.requestToId = exports.printErrors = exports.hasError = exports.generateResponseOverwriteCode = void 0;
exports.HttpApiProxyServer = exports.printResponseLogs = exports.printFindDeveloperHelp = exports.findObjectPaths = exports.isNumberString = exports.createRequestId = exports.printErrors = exports.hasError = exports.generateResponseOverwriteCode = void 0;
var axios_1 = __importDefault(require("axios"));

@@ -62,14 +62,12 @@ var http_1 = require("http");

var defaultProxyBehavior = "SAVE_RESPONSES_FOR_NEW_QUERIES";
// TODO THINK ABOUT: putting the Options above (along with find from Settings) into separate yarn commands (and maybe own files)
// TODO move into class
var generateResponseOverwriteCode = function (req, potentialPathsForChanges, searchValue, filePath) {
var cacheDirPath = ["put", "your", "path", "here"];
var requestId = (0, exports.requestToId)(req);
var generateResponseOverwriteCode = function (request, potentialPathsForChanges, searchValue, filePath) {
var cacheDirPathExample = ["put", "your", "path", "here"];
// TODO update code
return "You can change values containing \"".concat(searchValue, "\" as follows:\n\n import ").concat(requestId, " from '").concat(filePath, "'\n\n ").concat(potentialPathsForChanges
return "You can change values containing \"".concat(searchValue, "\" as follows:\n\n import ").concat(request.requestId, " from '").concat(filePath, "'\n\n ").concat(potentialPathsForChanges
.map(function (_a) {
var path = _a.path, value = _a.value;
return "".concat(requestId).concat(path, " = ").concat(value, "\n");
return "".concat(request.requestId).concat(path, " = ").concat(value, "\n");
})
.join(" "), "\n\n // Use the custom values like this:\n const proxyServer = new HttpApiProxyServer({\n cacheDirPath: ").concat(JSON.stringify(cacheDirPath), ",\n overwrites: {").concat(requestId, "},\n })\n\n // Do not forget to run proxyServer.start() and proxyServer.stop() to use the proxy\n ");
.join(" "), "\n\n // Use the custom values like this:\n const proxyServer = new HttpApiProxyServer({\n cacheDirPath: ").concat(JSON.stringify(cacheDirPathExample), ",\n overwrites: {").concat(request.requestId, "},\n })\n\n // Do not forget to run proxyServer.start() and proxyServer.stop() to use the proxy\n ");
};

@@ -99,8 +97,9 @@ exports.generateResponseOverwriteCode = generateResponseOverwriteCode;

// TODO move into class
var requestToId = function (req) {
if (!req.url) {
var createRequestId = function (_a) {
var url = _a.url, body = _a.body;
if (!url) {
throw new Error("[requestToId] Cannot handle a request with missing URL");
}
return (requestIdPrefix +
Array.from(req.url)
Array.from(JSON.stringify({ url: url, body: body }))
.reduce(function (hash, char) { return 0 | (31 * hash + char.charCodeAt(0)); }, 0)

@@ -110,3 +109,3 @@ .toString()

};
exports.requestToId = requestToId;
exports.createRequestId = createRequestId;
var isNumberString = function (str) {

@@ -136,3 +135,3 @@ return !isNaN(str) && !isNaN(parseFloat(str));

// TODO move into class
var printFindDeveloperHelp = function (req, response, filePath, find) {
var printFindDeveloperHelp = function (request, response, filePath, find) {
// TODO exclude if (!find)

@@ -148,10 +147,10 @@ if (!find)

return (0, print_1.printLimit)(responseValuePaths.length, find, matchMax, filePath);
return (0, print_1.print)((0, exports.generateResponseOverwriteCode)(req, responseValuePaths, find, filePath));
return (0, print_1.print)((0, exports.generateResponseOverwriteCode)(request, responseValuePaths, find, filePath));
};
exports.printFindDeveloperHelp = printFindDeveloperHelp;
// TODO move into class
var printResponseLogs = function (settings, req, response) {
var printResponseLogs = function (settings, request, response) {
var _a;
if ((_a = settings.responsesToLog) === null || _a === void 0 ? void 0 : _a.includes((0, exports.requestToId)(req)))
(0, print_1.print)("".concat((0, exports.requestToId)(req), ": ").concat(JSON.stringify(response)));
if ((_a = settings.responsesToLog) === null || _a === void 0 ? void 0 : _a.includes(request.requestId))
(0, print_1.print)("".concat(request.requestId, ": ").concat(JSON.stringify(response)));
};

@@ -161,7 +160,9 @@ exports.printResponseLogs = printResponseLogs;

/** This insures there will be no type errors when using headers in axios. It also replaces accept-encoding to make sure axios can handle.*/
var convertHeaders = function (headers) { return (__assign(__assign({}, Object.keys(headers).reduce(function (obj, key) {
var convertHeaders = function (headers, host, port) { return (__assign(__assign({}, Object.keys(headers).reduce(function (obj, key) {
var _a;
var _b, _c;
return (__assign(__assign({}, obj), (_a = {}, _a[key] = (_c = (_b = headers[key]) === null || _b === void 0 ? void 0 : _b.toString()) !== null && _c !== void 0 ? _c : "", _a)));
}, {})), { "accept-encoding": "gzip" })); };
}, {})), {
// host and port need to be in the headers in order for the TLS handshake to work
host: host, port: port, "accept-encoding": "gzip" })); };
var getRequestBody = function (req) {

@@ -171,3 +172,5 @@ return new Promise(function (resolve, reject) {

req.on("data", function (chunk) {
body += chunk.toString().split("\\n").join("\r\n");
body += chunk.toString();
// We used to include this "fix" which broke things later.
// body += chunk.toString().split("\\n").join("\r\n");
});

@@ -178,20 +181,10 @@ req.on("end", function () { return resolve(body); });

};
var convertToAxiosRequestConfig = function (req) { return __awaiter(void 0, void 0, void 0, function () {
var _a, _b;
var _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
_a = [{ headers: convertHeaders(req.headers), url: "".concat(req.headers.port === "443" ? "https" : "http", "://").concat(req.headers.host).concat(req.url), method: req.method }];
if (!(req.method === "POST")) return [3 /*break*/, 2];
_c = {};
return [4 /*yield*/, getRequestBody(req)];
case 1:
_b = (_c.data = _d.sent(), _c);
return [3 /*break*/, 3];
case 2:
_b = {};
_d.label = 3;
case 3: return [2 /*return*/, (__assign.apply(void 0, _a.concat([(_b)])))];
}
var convertToAxiosRequestConfig = function (request, host, port) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, ({
headers: convertHeaders(request.headers, host, port),
url: "".concat(port === "443" ? "https" : "http", "://").concat(host).concat(request.url),
method: request.method,
data: request.body,
})];
});

@@ -220,4 +213,4 @@ }); };

var _this = this;
this.printReplacementCharAlert = function (stringValue, req) {
if (_this.cache.getMetaInfo((0, exports.requestToId)(req))["ignoreBrockenChars"])
this.printReplacementCharAlert = function (stringValue, request) {
if (_this.cache.getMetaInfo(request.requestId)["ignoreBrockenChars"])
return;

@@ -231,3 +224,3 @@ var replacementChar = /\uFFFD/g;

? "".concat(brockenChars.join(", ").slice(0, 99), "...")
: brockenChars.join(", "), " in ").concat(_this.cache.filePathForRequest(req)));
: brockenChars.join(", "), " in ").concat(_this.cache.filePathForRequest(request)));
}

@@ -238,16 +231,15 @@ };

};
this.resolveRequest = function (req) { return __awaiter(_this, void 0, void 0, function () {
var requestId, localResponse;
this.resolveRequest = function (request) { return __awaiter(_this, void 0, void 0, function () {
var localResponse;
return __generator(this, function (_a) {
requestId = (0, exports.requestToId)(req);
localResponse = this.getLocalResponseIfExists(requestId);
localResponse = this.getLocalResponseIfExists(request.requestId);
switch (this.settings.proxyBehavior) {
case "FORCE_UPDATE_ALL":
return [2 /*return*/, this.getApiResponseAndSaveToLocal(req)];
return [2 /*return*/, this.getApiResponseAndSaveToLocal(request)];
case "SAVE_RESPONSES_FOR_NEW_QUERIES":
return [2 /*return*/, localResponse || this.getApiResponseAndSaveToLocal(req)];
return [2 /*return*/, localResponse || this.getApiResponseAndSaveToLocal(request)];
case "RELOAD_RESPONSES_WITH_ERRORS":
return [2 /*return*/, localResponse && !(0, exports.hasError)(localResponse)
? localResponse
: this.getApiResponseAndSaveToLocal(req)];
: this.getApiResponseAndSaveToLocal(request)];
case "NO_REQUEST_FORWARDING":

@@ -257,3 +249,3 @@ if (localResponse)

else
throw Error("[HttpApiProxyServer proxyBehavior is set to ".concat(this.settings.proxyBehavior, "] No ").concat(requestId, " stored in the proxy cache"));
throw Error("[HttpApiProxyServer proxyBehavior is set to ".concat(this.settings.proxyBehavior, "] No ").concat(request.requestId, " stored in the proxy cache"));
}

@@ -263,10 +255,10 @@ return [2 /*return*/, localResponse];

}); };
this.getApiResponseAndSaveToLocal = function (req) { return __awaiter(_this, void 0, void 0, function () {
this.getApiResponseAndSaveToLocal = function (request) { return __awaiter(_this, void 0, void 0, function () {
var apiResponse;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.realApiResponse(req)];
case 0: return [4 /*yield*/, this.realApiResponse(request)];
case 1:
apiResponse = _a.sent();
this.cache.saveResponse(req, apiResponse);
this.cache.saveResponse(request, apiResponse);
return [2 /*return*/, apiResponse];

@@ -276,4 +268,4 @@ }

}); };
this.realApiResponse = function (req) { return __awaiter(_this, void 0, void 0, function () {
var requestConfig, _a, data, status, error_1, axiosError;
this.realApiResponse = function (request) { return __awaiter(_this, void 0, void 0, function () {
var host, port, requestConfig, _a, data, status, error_1, axiosError;
var _b, _c;

@@ -283,8 +275,8 @@ return __generator(this, function (_d) {

case 0:
req.headers.host = this.settings.sourceHost;
req.headers.port = this.settings.sourcePort.toString();
host = this.settings.sourceHost;
port = this.settings.sourcePort.toString();
_d.label = 1;
case 1:
_d.trys.push([1, 4, , 5]);
return [4 /*yield*/, convertToAxiosRequestConfig(req)];
return [4 /*yield*/, convertToAxiosRequestConfig(request, host, port)];
case 2:

@@ -304,3 +296,3 @@ requestConfig = _d.sent();

{
message: "[HttpApiProxyServer] No successful response from ".concat(req.headers.host),
message: "[HttpApiProxyServer] No successful response from ".concat(host),
},

@@ -317,9 +309,8 @@ axiosError.toJSON(),

/** Prints console outputs depending on its inputs. No output is also possible */
this.printConsoleFeedback = function (req, response) {
this.printConsoleFeedback = function (request, response) {
var _a;
var filePath = _this.cache.filePathForRequest(req);
// TODO cleanup parameter order (once in class)
(0, exports.printFindDeveloperHelp)(req, response, filePath, (_a = _this.settings) === null || _a === void 0 ? void 0 : _a.find);
var filePath = _this.cache.filePathForRequest(request);
(0, exports.printFindDeveloperHelp)(request, response, filePath, (_a = _this.settings) === null || _a === void 0 ? void 0 : _a.find);
(0, exports.printErrors)(response, _this.settings, filePath);
(0, exports.printResponseLogs)(_this.settings, req, response);
(0, exports.printResponseLogs)(_this.settings, request, response);
};

@@ -382,11 +373,37 @@ // TODO Test using to have been called with (put handles in other function)

this.initialOverwrites = this.overwrites;
// TODO do not pass requestToId but import inside ResponseCacheConnector
this.cache = new response_cache_1.ResponseCacheConnector(cacheDirPath, exports.requestToId);
this.httpServer = (0, http_1.createServer)(function (req, res) {
_this.resolveRequest(req).then(function (response) {
_this.printReplacementCharAlert(JSON.stringify(response.body), req);
_this.printConsoleFeedback(req, response);
_this.replyToClient(res, response);
this.cache = new response_cache_1.ResponseCacheConnector(cacheDirPath);
this.httpServer = (0, http_1.createServer)(function (req, res) { return __awaiter(_this, void 0, void 0, function () {
var url, body, _a, requestId, request;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
url = req.url;
if (!(req.method === "POST")) return [3 /*break*/, 2];
return [4 /*yield*/, getRequestBody(req)];
case 1:
_a = _b.sent();
return [3 /*break*/, 3];
case 2:
_a = undefined;
_b.label = 3;
case 3:
body = _a;
requestId = (0, exports.createRequestId)({ url: url, body: body });
request = {
requestId: requestId,
url: url,
body: body,
method: req.method,
headers: req.headers,
};
this.resolveRequest(request).then(function (response) {
_this.printReplacementCharAlert(JSON.stringify(response.body), request);
_this.printConsoleFeedback(request, response);
_this.replyToClient(res, response);
});
return [2 /*return*/];
}
});
});
}); });
}

@@ -393,0 +410,0 @@ return HttpApiProxyServer;

@@ -6,6 +6,17 @@ "use strict";

};
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var proxy_server_1 = require("./proxy-server");
var print_1 = require("./print");
jest.mock('./print', function () { return ({
jest.mock("./print", function () { return ({
print: jest.fn(function () { return null; }),

@@ -16,13 +27,21 @@ printError: jest.fn(function () { return null; }),

}); });
var req0415987281 = { url: '/graphql?mock' };
//const reqOther = { url: '/graphql?test' } as Req
var createRequest = function (overwrites) {
var _a, _b;
return (__assign({ requestId: (0, proxy_server_1.createRequestId)({
url: (_a = overwrites.url) !== null && _a !== void 0 ? _a : "/",
body: (_b = overwrites.body) !== null && _b !== void 0 ? _b : undefined,
}), method: "GET", url: "/", headers: {}, body: undefined }, overwrites));
};
var req1927740808 = createRequest({
url: "/graphql?mock",
});
var mockResponses = {
responseFor123456: { status: 200, body: { msg: 'unknown response' } },
responseFor0415987281: { status: 200, body: { msg: 'req0415987281' } },
responseFor123456: { status: 200, body: { msg: "unknown response" } },
responseFor0415987281: { status: 200, body: { msg: "req0415987281" } },
};
var basePath = 'test/responses';
var path = basePath + '/test';
var existingPathMock = path + '/responseFor0415987281.json';
var basePath = "test/responses";
var path = basePath + "/test";
var existingPathMock = path + "/responseFor0415987281.json";
// TODO replace with mocks for wrapper functions
jest.mock('fs', function () { return ({
jest.mock("fs", function () { return ({
existsSync: jest.fn(function (filepath) {

@@ -37,19 +56,19 @@ return filepath === existingPathMock ||

}); });
describe('Proxy-Server', function () {
describe("Proxy-Server", function () {
beforeEach(function () {
jest.clearAllMocks(); // resets call counts for the mocks
});
it('generateMockCode will generate the correct mock code', function () {
it("generateMockCode will generate the correct mock code", function () {
var potentialMockPaths = [
{ path: '.this.is.a.path', value: 'example-value1' },
{ path: '.this.is.a.path.too', value: 'example-value2' },
{ path: ".this.is.a.path", value: "example-value1" },
{ path: ".this.is.a.path.too", value: "example-value2" },
];
var searchValue = 'example';
var filePath = './responses/name/responseFor0415987281.json';
var expectedCode = "You can change values containing \"example\" as follows:\n\n import responseFor0415987281 from './responses/name/responseFor0415987281.json'\n\n responseFor0415987281.this.is.a.path = example-value1\n responseFor0415987281.this.is.a.path.too = example-value2\n\n\n // Use the custom values like this:\n const proxyServer = new HttpApiProxyServer({\n cacheDirPath: [\"put\",\"your\",\"path\",\"here\"],\n overwrites: {responseFor0415987281},\n })\n\n // Do not forget to run proxyServer.start() and proxyServer.stop() to use the proxy\n ";
var generatedCode = (0, proxy_server_1.generateResponseOverwriteCode)(req0415987281, potentialMockPaths, searchValue, filePath);
var searchValue = "example";
var filePath = "./responses/name/responseFor1927740808.json";
var expectedCode = "You can change values containing \"example\" as follows:\n\n import responseFor1927740808 from './responses/name/responseFor1927740808.json'\n\n responseFor1927740808.this.is.a.path = example-value1\n responseFor1927740808.this.is.a.path.too = example-value2\n\n\n // Use the custom values like this:\n const proxyServer = new HttpApiProxyServer({\n cacheDirPath: [\"put\",\"your\",\"path\",\"here\"],\n overwrites: {responseFor1927740808},\n })\n\n // Do not forget to run proxyServer.start() and proxyServer.stop() to use the proxy\n ";
var generatedCode = (0, proxy_server_1.generateResponseOverwriteCode)(req1927740808, potentialMockPaths, searchValue, filePath);
expect(generatedCode).toEqual(expectedCode);
});
describe('hasError', function () {
it.each(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n resp | expected\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "], ["\n resp | expected\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "])), { body: { errors: [] }, status: 400 }, true, { body: { errors: [] }, status: 200 }, true, { body: {}, status: 400 }, true, { body: {}, status: 200 }, false)('returns $expected when response is $resp', function (_a) {
describe("hasError", function () {
it.each(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n resp | expected\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "], ["\n resp | expected\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "])), { body: { errors: [] }, status: 400 }, true, { body: { errors: [] }, status: 200 }, true, { body: {}, status: 400 }, true, { body: {}, status: 200 }, false)("returns $expected when response is $resp", function (_a) {
var resp = _a.resp, expected = _a.expected;

@@ -59,22 +78,39 @@ expect((0, proxy_server_1.hasError)(resp)).toBe(expected);

});
describe('requestToId', function () {
var prefix = 'responseFor';
describe("createRequestId", function () {
var prefix = "responseFor";
it("returns a string that starts with ".concat(prefix), function () {
var result1 = (0, proxy_server_1.requestToId)({ url: '/graphql?mock' });
var result2 = (0, proxy_server_1.requestToId)({ url: '/graphql?test' });
var result1 = (0, proxy_server_1.createRequestId)({
url: "/graphql?mock",
body: undefined,
});
var result2 = (0, proxy_server_1.createRequestId)({
url: "/graphql?test",
body: undefined,
});
expect(result1.startsWith(prefix)).toBe(true);
expect(result2.startsWith(prefix)).toBe(true);
});
it('returns a different value for different input reqests', function () {
var result1 = (0, proxy_server_1.requestToId)({ url: '/graphql?mock' });
var result2 = (0, proxy_server_1.requestToId)({ url: '/graphql?test' });
it("returns a different value for different urls", function () {
var result1 = (0, proxy_server_1.createRequestId)({
url: "/graphql?mock",
body: undefined,
});
var result2 = (0, proxy_server_1.createRequestId)({
url: "/graphql?test",
body: undefined,
});
expect(result1).not.toEqual(result2);
});
it('returns a valide filename or variable name for Typescript', function () {
var result = (0, proxy_server_1.requestToId)({ url: '/graphql?mock' });
it("returns a different value for different body data", function () {
var result1 = (0, proxy_server_1.createRequestId)({ url: "/graphql", body: "data1" });
var result2 = (0, proxy_server_1.createRequestId)({ url: "/graphql", body: "data2" });
expect(result1).not.toEqual(result2);
});
it("returns a valide filename or variable name for Typescript", function () {
var result = (0, proxy_server_1.createRequestId)({ url: "/graphql?mock", body: undefined });
expect(/[^a-zA-Z0-9_]/.test(result)).toBe(false);
});
});
describe('isNumberString', function () {
it.each(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n value | expected\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "], ["\n value | expected\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "])), '123', true, '0', true, '-42', true, '', false, 'one', false, '1string', false, 'test2', false)('returns $expected when value is $value', function (_a) {
describe("isNumberString", function () {
it.each(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n value | expected\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "], ["\n value | expected\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "])), "123", true, "0", true, "-42", true, "", false, "one", false, "1string", false, "test2", false)("returns $expected when value is $value", function (_a) {
var value = _a.value, expected = _a.expected;

@@ -84,13 +120,13 @@ expect((0, proxy_server_1.isNumberString)(value)).toBe(expected);

});
describe('findObjectPaths', function () {
it('will return the paths to a JSON field containg the search value', function () {
describe("findObjectPaths", function () {
it("will return the paths to a JSON field containg the search value", function () {
expect((0, proxy_server_1.findObjectPaths)({
status: 200,
body: { key1: { a: 'no', b: 'a test' }, key2: 'the test' },
}, 'test')).toEqual([
{ path: '.body.key1.b', value: '"a test"' },
{ path: '.body.key2', value: '"the test"' },
body: { key1: { a: "no", b: "a test" }, key2: "the test" },
}, "test")).toEqual([
{ path: ".body.key1.b", value: '"a test"' },
{ path: ".body.key2", value: '"the test"' },
]);
});
it('will handle arrays', function () {
it("will handle arrays", function () {
expect((0, proxy_server_1.findObjectPaths)({

@@ -100,17 +136,17 @@ status: 200,

key1: {
a: 'no',
a: "no",
b: [
'the test',
'or',
'a test',
['test', { something: ['x', 'testing'], value: 'test' }],
"the test",
"or",
"a test",
["test", { something: ["x", "testing"], value: "test" }],
],
},
},
}, 'test')).toEqual([
{ path: '.body.key1.b[0]', value: '"the test"' },
{ path: '.body.key1.b[2]', value: '"a test"' },
{ path: '.body.key1.b[3][0]', value: '"test"' },
{ path: '.body.key1.b[3][1].something[1]', value: '"testing"' },
{ path: '.body.key1.b[3][1].value', value: '"test"' },
}, "test")).toEqual([
{ path: ".body.key1.b[0]", value: '"the test"' },
{ path: ".body.key1.b[2]", value: '"a test"' },
{ path: ".body.key1.b[3][0]", value: '"test"' },
{ path: ".body.key1.b[3][1].something[1]", value: '"testing"' },
{ path: ".body.key1.b[3][1].value", value: '"test"' },
]);

@@ -120,28 +156,28 @@ });

// TODO split into fn cases
test.each(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n matchCount | fn\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "], ["\n matchCount | fn\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "])), 0, 'printNoMatch', 1, 'print', 42, 'print', 80, 'print', 81, 'printLimit', 123, 'printLimit')('printFindDeveloperHelp will call only $fn if there are $matchCount matches', function (_a) {
test.each(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n matchCount | fn\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "], ["\n matchCount | fn\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n ", " | ", "\n "])), 0, "printNoMatch", 1, "print", 42, "print", 80, "print", 81, "printLimit", 123, "printLimit")("printFindDeveloperHelp will call only $fn if there are $matchCount matches", function (_a) {
var matchCount = _a.matchCount, fn = _a.fn;
var body = { a: Array.from({ length: matchCount }).fill('t') };
(0, proxy_server_1.printFindDeveloperHelp)(req0415987281, { status: 200, body: body }, '', 't');
expect(print_1.print).toHaveBeenCalledTimes(fn === 'print' ? 1 : 0);
expect(print_1.printLimit).toHaveBeenCalledTimes(fn === 'printLimit' ? 1 : 0);
expect(print_1.printNoMatch).toHaveBeenCalledTimes(fn === 'printNoMatch' ? 1 : 0);
var body = { a: Array.from({ length: matchCount }).fill("t") };
(0, proxy_server_1.printFindDeveloperHelp)(req1927740808, { status: 200, body: body }, "", "t");
expect(print_1.print).toHaveBeenCalledTimes(fn === "print" ? 1 : 0);
expect(print_1.printLimit).toHaveBeenCalledTimes(fn === "printLimit" ? 1 : 0);
expect(print_1.printNoMatch).toHaveBeenCalledTimes(fn === "printNoMatch" ? 1 : 0);
});
describe('handleResponseLogs', function () {
test('will not log anyting if settings do not request any response logs', function () {
(0, proxy_server_1.printResponseLogs)({}, req0415987281, {
describe("handleResponseLogs", function () {
test("will not log anyting if settings do not request any response logs", function () {
(0, proxy_server_1.printResponseLogs)({}, req1927740808, {
status: 200,
body: { t: 'test' },
body: { t: "test" },
});
expect(print_1.print).not.toHaveBeenCalled();
});
test('will not log anyting if the response is not matching', function () {
test("will not log anyting if the response is not matching", function () {
(0, proxy_server_1.printResponseLogs)({
responsesToLog: ['responseFor123456', 'responseFor987654'],
}, req0415987281, { status: 200, body: { t: 'test' } });
responsesToLog: ["responseFor123456", "responseFor987654"],
}, req1927740808, { status: 200, body: { t: "test" } });
expect(print_1.print).not.toHaveBeenCalled();
});
test('will log matching responses', function () {
test("will log matching responses", function () {
(0, proxy_server_1.printResponseLogs)({
responsesToLog: ['responseFor0415987281', 'responseFor123456'],
}, req0415987281, { status: 200, body: { t: 'test' } });
responsesToLog: [req1927740808.requestId, "responseFor123456"],
}, req1927740808, { status: 200, body: { t: "test" } });
expect(print_1.print).toHaveBeenCalled();

@@ -148,0 +184,0 @@ });

@@ -1,3 +0,1 @@

/// <reference types="node" />
import { IncomingMessage as Req } from "http";
type ResponseData = Record<string, unknown> & {

@@ -9,2 +7,9 @@ errors?: {

type RequestId = `responseFor${string}`;
type Request = {
requestId: RequestId;
url?: string;
method?: string;
headers: Record<string, string | string[] | undefined>;
body: string | undefined;
};
type ProxyResponse = {

@@ -16,7 +21,6 @@ body: ResponseData;

private cacheDirPath;
private requestToId;
constructor(cacheDirPath: string[] | undefined, requestIdFunction: (req: Req) => RequestId);
constructor(cacheDirPath?: string[]);
private requireDir;
getResponse: (requestId: string) => any;
saveResponse: (req: Req, response: ProxyResponse) => void;
saveResponse: (request: Request, response: ProxyResponse) => void;
getMetaInfo: (requestId: string) => any;

@@ -26,4 +30,4 @@ saveMetaInfo: (requestId: string, metaInfo: Record<string, boolean>) => void;

private metaInfoFilePathForRequestId;
filePathForRequest: (req: Req) => string;
filePathForRequest: (request: Request) => string;
}
export {};

@@ -25,2 +25,5 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -30,5 +33,5 @@ exports.ResponseCacheConnector = void 0;

var print_1 = require("./print");
var path = __importStar(require("path"));
var path_1 = __importDefault(require("path"));
var ResponseCacheConnector = /** @class */ (function () {
function ResponseCacheConnector(cacheDirPath, requestIdFunction) {
function ResponseCacheConnector(cacheDirPath) {
if (cacheDirPath === void 0) { cacheDirPath = ["responses"]; }

@@ -42,13 +45,13 @@ var _this = this;

};
this.saveResponse = function (req, response) {
if (!req.url) {
this.saveResponse = function (request, response) {
if (!request.url) {
throw new Error("[saveResponse] Cannot handle a request with missing URL");
}
var responseDir = _this.requireDir();
var fileName = _this.filePathForRequest(req);
var logLine = "".concat(fileName, ", ").concat(decodeURIComponent(req.url));
var fileName = _this.filePathForRequest(request);
var logLine = "".concat(fileName, ", ").concat(decodeURIComponent(request.url));
try {
fs.appendFileSync(
// TODO create log name config
path.join(responseDir, "apiQuery.log"), logLine + "\n\n");
path_1.default.join(responseDir, "apiQuery.log"), logLine + "\n\n");
}

@@ -84,12 +87,11 @@ catch (_a) {

this.filePathForRequestId = function (RequestId) {
return path.join(path.join.apply(path, _this.cacheDirPath), "".concat(RequestId, ".json"));
return path_1.default.join(path_1.default.join.apply(path_1.default, _this.cacheDirPath), "".concat(RequestId, ".json"));
};
this.metaInfoFilePathForRequestId = function (RequestId) {
return path.join(path.join.apply(path, _this.cacheDirPath), "".concat(RequestId, ".meta.json"));
return path_1.default.join(path_1.default.join.apply(path_1.default, _this.cacheDirPath), "".concat(RequestId, ".meta.json"));
};
this.filePathForRequest = function (req) {
return _this.filePathForRequestId(_this.requestToId(req));
this.filePathForRequest = function (request) {
return _this.filePathForRequestId(request.requestId);
};
this.cacheDirPath = cacheDirPath;
this.requestToId = requestIdFunction;
}

@@ -99,3 +101,3 @@ ResponseCacheConnector.prototype.requireDir = function () {

this.cacheDirPath.forEach(function (part) {
currentDir = path.join(currentDir, part);
currentDir = path_1.default.join(currentDir, part);
if (!fs.existsSync(currentDir))

@@ -102,0 +104,0 @@ fs.mkdirSync(currentDir);

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var proxy_server_1 = require("./proxy-server");
var response_cache_1 = require("./response-cache");
describe('ResponseCacheConnector', function () {
var req0415987281 = { url: '/graphql?mock' };
//const reqOther = { url: '/graphql?test' } as Req
var cache = new response_cache_1.ResponseCacheConnector(['test', 'responses', 'testName'], proxy_server_1.requestToId);
test('filePathForHash will build valid path', function () {
expect(cache.filePathForRequestId('hash')).toEqual('test/responses/testName/hash.json');
var createRequest = function (overwrites) {
var _a, _b;
return (__assign({ requestId: (0, proxy_server_1.createRequestId)({
url: (_a = overwrites.url) !== null && _a !== void 0 ? _a : "/",
body: (_b = overwrites.body) !== null && _b !== void 0 ? _b : undefined,
}), method: "GET", url: "/", headers: {}, body: undefined }, overwrites));
};
describe("ResponseCacheConnector", function () {
var req1927740808 = createRequest({ url: "/graphql?mock" });
var cache = new response_cache_1.ResponseCacheConnector(["test", "responses", "testName"]);
test("filePathForHash will build valid path", function () {
expect(cache.filePathForRequestId("hash")).toEqual("test/responses/testName/hash.json");
});
test('filePathForRequest will build valid path', function () {
expect(cache.filePathForRequest(req0415987281)).toEqual('test/responses/testName/responseFor0415987281.json');
test("filePathForRequest will build valid path", function () {
expect(cache.filePathForRequest(req1927740808)).toEqual("test/responses/testName/responseFor1927740808.json");
});
});
{
"name": "http-api-proxy-server",
"version": "0.0.1",
"version": "0.0.2",
"license": "MIT",

@@ -11,2 +11,3 @@ "main": "dist/index.js",

"test": "yarn test:unit && yarn use-case:tests",
"lint": "echo TODO",
"test:unit": "jest --config=\"jest.config.ts\"",

@@ -13,0 +14,0 @@ "test:unit:watch": "yarn run test:unit -- --watchAll",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc