UNPKG

http-request-mock

Version:

Intercept & mock http requests issued by XMLHttpRequest, fetch, nodejs https/http module, axios, jquery, superagent, ky, node-fetch, request, got or any other request libraries by intercepting XMLHttpRequest, fetch and nodejs native requests in low level.

1,196 lines (1,180 loc) 113 kB
/******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/global */ /******/ (() => { /******/ __webpack_require__.g = (function() { /******/ if (typeof globalThis === 'object') return globalThis; /******/ try { /******/ return this || new Function('return this')(); /******/ } catch (e) { /******/ if (typeof window === 'object') return window; /******/ } /******/ })(); /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // EXPORTS __webpack_require__.d(__webpack_exports__, { i: () => (/* reexport */ mocker_mocker), A: () => (/* binding */ browser_pure) }); ;// CONCATENATED MODULE: ./src/common/bypass.ts var Bypass = /** @class */ (function () { function Bypass() { this.flag = 'yes'; } return Bypass; }()); /* harmony default export */ const bypass = (Bypass); ;// CONCATENATED MODULE: ./src/common/utils.ts var utils_filename = "/index.js"; /** * Get query parameters from the specified request url. * https://www.sitepoint.com/get-url-parameters-with-javascript/ * * @param {string} reqUrl */ function getQuery(reqUrl) { var _a; // no protocol, domain, path and hash tag var query = (reqUrl || '').replace(/^.*?\?/g, '').replace(/#.*$/g, ''); var obj = {}; if (query === reqUrl) { return obj; } if (query) { var parts = query.split('&'); for (var i = 0; i < parts.length; i++) { var _b = parts[i].split('='), key = _b[0], _c = _b[1], val = _c === void 0 ? '' : _c; // for keys which ends with square brackets, such as list[] or list[1] if (key.match(/\[(\d+)?\]$/)) { var field = key.replace(/\[(\d+)?\]/, ''); obj[field] = obj[field] || []; if (key.match(/\[\d+\]$/)) { // set array index, if it's an indexed array e.g. list[2] obj[field][Number((_a = /\[(\d+)\]/.exec(key)) === null || _a === void 0 ? void 0 : _a[1])] = val; } else { obj[field].push(val); } } else { if (key in obj) { obj[key] = [].concat(obj[key], val); } else { obj[key] = val; } } } } return obj; } /** * Convert query object to search string. * @param {object} queryObj */ function queryObject2String(queryObj) { var str = []; for (var key in queryObj) { if (Array.isArray(queryObj[key])) { for (var _i = 0, _a = queryObj[key]; _i < _a.length; _i++) { var val = _a[_i]; str.push(key + '=' + val); } } else { str.push(key + '=' + queryObj[key]); } } return str.join('&'); } /** * Check whether or not the specified obj is an object. * @param {unknown} obj */ function isObject(obj) { return Object.prototype.toString.call(obj) === '[object Object]'; } /** * Try to convert an object like string to an object. * @param {unknown} body */ function tryToParseObject(body) { var isObjLiked = typeof body === 'string' && body[0] === '{' && body[body.length - 1] === '}'; var isArrLiked = typeof body === 'string' && body[0] === '[' && body[body.length - 1] === ']'; if (!isObjLiked && !isArrLiked) { return body; } try { return JSON.parse(body); } catch (e) { return body; } } function tryToParsePostBody(body) { if (!body) { return body; } if (typeof body === 'string') { var info = tryToParseObject(body); if (info && typeof info === 'object') { return info; } } if (typeof body === 'string' && body.includes('&') && body.includes('=')) { return getQuery(body); } return body; } /** * Try to parse a JSON string * @param {unknown} body */ function tryToParseJson(str, defaultVal) { if (defaultVal === void 0) { defaultVal = null; } try { return JSON.parse(String(str)); } catch (e) { return defaultVal; } } /** * Sleep the specified number of milliseconds. * @param {number} ms */ function sleep(ms) { return new Promise(function (resolve) { return setTimeout(resolve, ms); }); } /** * Convert string to arraybuffer. * @param {string} str */ function str2arrayBuffer(str) { if (typeof TextEncoder === 'function') { return new TextEncoder().encode(str); } if (typeof ArrayBuffer === 'function') { var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char var bufView = new Uint16Array(buf); for (var i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } return null; } /** * Whether or not the specified data is arraybuffer. * @param {unknown} data */ function isArrayBuffer(data) { if (typeof ArrayBuffer === 'function' && data instanceof ArrayBuffer) { return true; } if (typeof Int32Array === 'function' && (data instanceof Int32Array)) { return true; } if (typeof Int16Array === 'function' && (data instanceof Int16Array)) { return true; } if (typeof Int8Array === 'function' && (data instanceof Int8Array)) { return true; } return false; } /** * Get current date. */ function currentDate() { var now = new Date(); var year = now.getFullYear(); var month = now.getMonth() + 1; var date = now.getDate(); var two = function (num) { return num < 10 ? "0".concat(num) : "".concat(num); }; return "".concat(two(year), "-").concat(two(month), "-").concat(two(date)); } /** * Get current time. */ function currentTime() { var now = new Date(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds(); var two = function (num) { return num < 10 ? "0".concat(num) : "".concat(num); }; return "".concat(two(hour), ":").concat(two(minute), ":").concat(two(second)); } /** * Get current datetime. */ function currentDatetime() { var now = new Date(); var year = now.getFullYear(); var month = now.getMonth() + 1; var date = now.getDate(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds(); var two = function (num) { return num < 10 ? "0".concat(num) : "".concat(num); }; return "".concat(two(year), "-").concat(two(month), "-").concat(two(date), " ").concat(two(hour), ":").concat(two(minute), ":").concat(two(second)); } /** * Check current environment: nodejs or not. * Note: arrow function is required. */ function isNodejs() { return (typeof process !== 'undefined') && (Object.prototype.toString.call(process) === '[object process]') && (!!(process.versions && process.versions.node)); } /** * Check if an object is a Promise */ function isPromise(object) { if (Promise && Promise.resolve) { return Promise.resolve(object) === object; } else { throw new Error('Promise not supported in your environment'); } } /** * Check if an object is imported. */ function isImported(obj) { return obj && typeof obj === 'object' && Object.keys(obj).length === 1 && ('default' in obj); } /** * Get caller file from error stack */ function getCallerFile() { var oldPrepareStackTrace = Error.prepareStackTrace; Error.prepareStackTrace = function (_, stack) { return stack; }; var stack = new Error().stack; Error.prepareStackTrace = oldPrepareStackTrace; if (stack !== null && typeof stack === 'object') { for (var i = 0; i < 50; i++) { var file = stack[i] ? stack[i].getFileName() : undefined; var next = stack[i + 1] ? stack[i + 1].getFileName() : undefined; if (file !== next && file === utils_filename) { return next; } } } } function get(obj, path, defaultValue) { if (typeof path === 'string') { path = path.replace(/\[(\w+)\]/g, '.$1'); path = path.split('.').filter(Boolean); } var result = obj; for (var _i = 0, _a = path; _i < _a.length; _i++) { var key = _a[_i]; if (result && result[key] !== undefined) { result = result[key]; } else { result = undefined; break; } } return (result === undefined ? defaultValue : result); } ;// CONCATENATED MODULE: ./src/config.ts var HTTPStatusCodes = { 100: 'Continue', 101: 'Switching Protocols', 102: 'Processing', 103: 'Early Hints', 200: 'OK', 201: 'Created', 202: 'Accepted', 203: 'Non-Authoritative Information', 204: 'No Content', 205: 'Reset Content', 206: 'Partial Content', 207: 'Multi-Status', 208: 'Already Reported', 226: 'IM Used', 300: 'Multiple Choices', 301: 'Moved Permanently', 302: 'Found', 303: 'See Other', 304: 'Not Modified', 305: 'Use Proxy', 307: 'Temporary Redirect', 308: 'Permanent Redirect', 400: 'Bad Request', 401: 'Unauthorized', 402: 'Payment Required', 403: 'Forbidden', 404: 'Not Found', 405: 'Method Not Allowed', 406: 'Not Acceptable', 407: 'Proxy Authentication Required', 408: 'Request Timeout', 409: 'Conflict', 410: 'Gone', 411: 'Length Required', 412: 'Precondition Failed', 413: 'Payload Too Large', 414: 'URI Too Long', 415: 'Unsupported Media Type', 416: 'Range Not Satisfiable', 417: 'Expectation Failed', 418: 'I\'m a Teapot', 421: 'Misdirected Request', 422: 'Unprocessable Entity', 423: 'Locked', 424: 'Failed Dependency', 425: 'Too Early', 426: 'Upgrade Required', 428: 'Precondition Required', 429: 'Too Many Requests', 431: 'Request Header Fields Too Large', 451: 'Unavailable For Legal Reasons', 500: 'Internal Server Error', 501: 'Not Implemented', 502: 'Bad Gateway', 503: 'Service Unavailable', 504: 'Gateway Timeout', 505: 'HTTP Version Not Supported', 506: 'Variant Also Negotiates', 507: 'Insufficient Storage', 508: 'Loop Detected', 509: 'Bandwidth Limit Exceeded', 510: 'Not Extended', 511: 'Network Authentication Required' }; ;// CONCATENATED MODULE: ./src/interceptor/base.ts var BaseInterceptor = /** @class */ (function () { function BaseInterceptor(mocker, proxyServer) { var _a; if (proxyServer === void 0) { proxyServer = ''; } this.proxyServer = ''; this.proxyMode = ''; this.mocker = mocker; if (/^(matched@localhost:\d+)|(middleware@\/)$/.test(proxyServer)) { _a = proxyServer.split('@'), this.proxyMode = _a[0], this.proxyServer = _a[1]; } this.global = BaseInterceptor.getGlobal(); } /** * Setup request mocker. * @param {Mocker} mocker */ BaseInterceptor.setup = function (mocker, proxyServer) { if (proxyServer === void 0) { proxyServer = ''; } return new this(mocker, proxyServer); }; /** * return global variable */ BaseInterceptor.getGlobal = function () { if (typeof window !== 'undefined') { return window; } else if (typeof __webpack_require__.g !== 'undefined') { return __webpack_require__.g; } throw new Error('Detect global variable error'); }; /** * Check whether the specified request url matches a defined mock item. * If a match is found, return mock meta information, otherwise a null is returned. * @param {string} reqUrl * @param {string} reqMethod */ BaseInterceptor.prototype.matchMockRequest = function (reqUrl, reqMethod) { // ignore matching when it is a proxy mode if (this.proxyMode === 'matched' && reqUrl.indexOf("http://".concat(this.proxyServer)) === 0) { return null; } var mockItem = this.mocker.matchMockItem(reqUrl, reqMethod); if (mockItem && mockItem.times !== undefined) { mockItem.times -= 1; } // "mockItem" should be returned if current request is under proxy mode of middleware and is marked by @deProxy if (this.proxyMode === 'middleware' && reqUrl.indexOf(this.getMiddlewareHost()) === 0) { return mockItem && mockItem.deProxy ? mockItem : null; } return mockItem; }; BaseInterceptor.prototype.getRequestInfo = function (requestInfo) { var info = { url: requestInfo.url, method: requestInfo.method || 'GET', query: getQuery(requestInfo.url), }; if (get(requestInfo, 'headers') || get(requestInfo, 'header')) { info.headers = get(requestInfo, 'headers') || get(requestInfo, 'header'); } if (requestInfo.body !== undefined) { info.rawBody = requestInfo.body; info.body = tryToParsePostBody(requestInfo.body); } return info; }; /** * Get full request url. * @param {string} url */ BaseInterceptor.prototype.getFullRequestUrl = function (url, method) { if (/^https?:\/\//i.test(url)) { return this.checkProxyUrl(url, method); } if (typeof URL === 'function' && typeof window === 'object' && window) { // https://github.com/huturen/http-request-mock/issues/21 // "window.location.href" might point to an embedded file (e.g., data:text/html;charset=utf-8,...), // potentially leading to an "Invalid URL" error. if (/^https?:\/\//i.test(window.location.href)) { return this.checkProxyUrl(new URL(url, window.location.href).href, method); } } if (typeof document === 'object' && document && typeof document.createElement === 'function') { var elemA = document.createElement('a'); elemA.href = url; return this.checkProxyUrl(elemA.href, method); } return this.checkProxyUrl(url, method); }; /** * Return a proxy url if in a proxy mode otherwise return the original url. * @param {string} url */ BaseInterceptor.prototype.checkProxyUrl = function (url, method) { if (!['matched', 'middleware'].includes(this.proxyMode) || !this.proxyServer) { return url; } var mockItem = this.mocker.matchMockItem(url, method); if (!mockItem) { return url; } var proxyUrl = this.proxyMode === 'middleware' ? "".concat(this.getMiddlewareHost()).concat(url.replace(/^(https?):\/\//, '/$1/')) : "http://".concat(this.proxyServer).concat(url.replace(/^(https?):\/\//, '/$1/')); return mockItem.deProxy ? url : proxyUrl; }; BaseInterceptor.prototype.getMiddlewareHost = function () { var _a = window.location, protocol = _a.protocol, host = _a.host; return "".concat(protocol, "//").concat(host); }; return BaseInterceptor; }()); /* harmony default export */ const base = (BaseInterceptor); ;// CONCATENATED MODULE: ./src/interceptor/fetch.ts var __extends = (undefined && undefined.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (undefined && undefined.__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); }; var __awaiter = (undefined && undefined.__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()); }); }; var __generator = (undefined && undefined.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; /* eslint-disable @typescript-eslint/ban-types */ var FetchInterceptor = /** @class */ (function (_super) { __extends(FetchInterceptor, _super); function FetchInterceptor(mocker, proxyServer) { if (proxyServer === void 0) { proxyServer = ''; } var _this = _super.call(this, mocker, proxyServer) || this; if (FetchInterceptor.instance) { return FetchInterceptor.instance; } FetchInterceptor.instance = _this; _this.fetch = _this.global.fetch.bind(_this.global); _this.intercept(); return _this; } /** * https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch * Intercept fetch object. */ FetchInterceptor.prototype.intercept = function () { // eslint-disable-next-line @typescript-eslint/no-this-alias var me = this; this.global.fetch = function (input, init) { var _this = this; var url; var params; // https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch // Note: the first argument of fetch maybe a Request or URL object. if (input instanceof URL) { url = input.toString(); params = init || {}; } else if (typeof input === 'object') { url = input.url; params = input; } else { url = input; params = init || {}; } var method = (params && params.method ? params.method : 'GET'); var requestUrl = me.getFullRequestUrl(url, method); return new Promise(function (resolve, reject) { var mockItem = me.matchMockRequest(requestUrl, method); if (!mockItem) { me.fetch(input, init).then(resolve).catch(reject); return; } me.setTimeoutForSingal(params, reject); var requestInfo = me.getRequestInfo(__assign(__assign({}, params), { url: requestUrl, method: method })); requestInfo.doOriginalCall = function () { return __awaiter(_this, void 0, void 0, function () { var res; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, me.getOriginalResponse(requestUrl, params)]; case 1: res = _a.sent(); requestInfo.doOriginalCall = undefined; return [2 /*return*/, res]; } }); }); }; var remoteInfo = mockItem === null || mockItem === void 0 ? void 0 : mockItem.getRemoteInfo(requestUrl); if (remoteInfo) { params.method = remoteInfo.method || method; me.setRemoteRequestHeaders(mockItem, params); me.fetch(remoteInfo.url, params) .then(function (fetchResponse) { me.sendRemoteResult(fetchResponse, mockItem, requestInfo, resolve); }) .catch(reject); return; } me.doMockRequest(mockItem, requestInfo, resolve).then(function (isBypassed) { if (isBypassed) { me.fetch(requestUrl, params).then(resolve).catch(reject); } }); }); }; return this; }; // eslint-disable-next-line @typescript-eslint/no-explicit-any FetchInterceptor.prototype.setTimeoutForSingal = function (params, reject) { var _a; if (!params.signal) { return; } var defaultTimeoutMsg = 'request timed out'; // If the signal is already aborted, immediately throw in order to reject the promise. if (params.signal.aborted) { reject(params.signal.reason || new Error(defaultTimeoutMsg)); } // Perform the main purpose of the API // Call resolve(result) when done. // Watch for 'abort' signals (_a = params.signal) === null || _a === void 0 ? void 0 : _a.addEventListener('abort', function () { var _a; // Stop the main operation, reject the promise with the abort reason. reject(((_a = params.signal) === null || _a === void 0 ? void 0 : _a.reason) || new Error(defaultTimeoutMsg)); }); }; /** * Set request headers for requests marked by remote config. * @param {AnyObject} fetchParams */ FetchInterceptor.prototype.setRemoteRequestHeaders = function (mockItem, fetchParams) { if (Object.keys(mockItem.remoteRequestHeaders).length <= 0) return; // https://developer.mozilla.org/en-US/docs/Web/API/Headers if (typeof fetchParams.headers.set === 'function') { Object.entries(mockItem.remoteRequestHeaders).forEach(function (_a) { var _b; var key = _a[0], val = _a[1]; (_b = fetchParams.headers) === null || _b === void 0 ? void 0 : _b.set(key, val); }); } else { fetchParams.headers = __assign(__assign({}, (fetchParams.headers || {})), mockItem.remoteRequestHeaders); } }; /** * Set remote result. * @param {FetchResponse} fetchResponse * @param {MockItem} mockItem * @param {RequestInfo} requestInfo * @param {Function} resolve */ FetchInterceptor.prototype.sendRemoteResult = function (fetchResponse, mockItem, requestInfo, resolve) { var _this = this; var headers = {}; if (typeof Headers === 'function' && fetchResponse.headers instanceof Headers) { fetchResponse.headers.forEach(function (val, key) { headers[key.toLocaleLowerCase()] = val; }); } fetchResponse.text().then(function (text) { var json = tryToParseJson(text); var remoteResponse = { status: fetchResponse.status, headers: headers, response: json || text, responseText: text, responseJson: json, }; _this.doMockRequest(mockItem, requestInfo, resolve, remoteResponse); }); }; /** * Get original response * @param {string} requestUrl * @param {FetchRequest | AnyObject} params */ FetchInterceptor.prototype.getOriginalResponse = function (requestUrl, params) { return __awaiter(this, void 0, void 0, function () { var status, headers, responseText, responseJson, responseBuffer, responseBlob, res, isBlobAvailable, _a, _b, _c, err_1; return __generator(this, function (_d) { switch (_d.label) { case 0: status = null; headers = {}; responseText = null; responseJson = null; responseBuffer = null; responseBlob = null; _d.label = 1; case 1: _d.trys.push([1, 13, , 14]); return [4 /*yield*/, this.fetch(requestUrl, params)]; case 2: res = _d.sent(); status = res.status; if (typeof Headers === 'function' && res.headers instanceof Headers) { res.headers.forEach(function (val, key) { return (headers[key.toLocaleLowerCase()] = val); }); } isBlobAvailable = typeof Blob === 'function' && typeof Blob.prototype.text === 'function' && typeof Blob.prototype.arrayBuffer === 'function' && typeof Blob.prototype.slice === 'function' && typeof Blob.prototype.stream === 'function'; if (!isBlobAvailable) return [3 /*break*/, 4]; return [4 /*yield*/, res.blob()]; case 3: _a = _d.sent(); return [3 /*break*/, 5]; case 4: _a = null; _d.label = 5; case 5: responseBlob = _a; if (!isBlobAvailable) return [3 /*break*/, 7]; return [4 /*yield*/, responseBlob.text()]; case 6: _b = _d.sent(); return [3 /*break*/, 9]; case 7: return [4 /*yield*/, res.text()]; case 8: _b = _d.sent(); _d.label = 9; case 9: responseText = _b; if (!isBlobAvailable) return [3 /*break*/, 11]; return [4 /*yield*/, responseBlob.arrayBuffer()]; case 10: _c = _d.sent(); return [3 /*break*/, 12]; case 11: _c = null; _d.label = 12; case 12: responseBuffer = _c; responseJson = responseText === null ? null : tryToParseJson(responseText); return [2 /*return*/, { status: status, headers: headers, responseText: responseText, responseJson: responseJson, responseBuffer: responseBuffer, responseBlob: responseBlob, error: null }]; case 13: err_1 = _d.sent(); return [2 /*return*/, { status: status, headers: headers, responseText: responseText, responseJson: responseJson, responseBuffer: responseBuffer, responseBlob: responseBlob, error: err_1 }]; case 14: return [2 /*return*/]; } }); }); }; /** * Make mock request. * @param {MockItem} mockItem * @param {RequestInfo} requestInfo * @param {Function} resolve */ FetchInterceptor.prototype.doMockRequest = function (mockItem, requestInfo, resolve, remoteResponse) { if (remoteResponse === void 0) { remoteResponse = null; } return __awaiter(this, void 0, void 0, function () { var isBypassed; return __generator(this, function (_a) { switch (_a.label) { case 0: isBypassed = false; if (!(mockItem.delay && mockItem.delay > 0)) return [3 /*break*/, 3]; return [4 /*yield*/, sleep(+mockItem.delay)]; case 1: _a.sent(); return [4 /*yield*/, this.doMockResponse(mockItem, requestInfo, resolve, remoteResponse)]; case 2: isBypassed = _a.sent(); return [3 /*break*/, 5]; case 3: return [4 /*yield*/, this.doMockResponse(mockItem, requestInfo, resolve, remoteResponse)]; case 4: isBypassed = _a.sent(); _a.label = 5; case 5: return [2 /*return*/, isBypassed]; } }); }); }; /** * Make mock request. * @param {MockItem} mockItem * @param {RequestInfo} requestInfo * @param {Function} resolve */ FetchInterceptor.prototype.doMockResponse = function (mockItem, requestInfo, resolve, remoteResponse) { if (remoteResponse === void 0) { remoteResponse = null; } return __awaiter(this, void 0, void 0, function () { var now, body, err_2, spent; return __generator(this, function (_a) { switch (_a.label) { case 0: now = Date.now(); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, mockItem.sendBody(requestInfo, remoteResponse)]; case 2: body = _a.sent(); if (body instanceof bypass) { if (remoteResponse) { throw new Error('A request which is marked by @remote tag cannot be bypassed.'); } return [2 /*return*/, true]; } return [3 /*break*/, 4]; case 3: err_2 = _a.sent(); console.warn('[http-request-mock] mock response error, ' + err_2.message); body = ''; return [3 /*break*/, 4]; case 4: spent = (Date.now() - now) + (mockItem.delay || 0); this.mocker.sendResponseLog(spent, body, requestInfo, mockItem); resolve(this.getFetchResponse(body, mockItem, requestInfo)); return [2 /*return*/, false]; } }); }); }; /** * https://developer.mozilla.org/en-US/docs/Web/API/Response * Format mock data. * @param {unknown} responseBody * @param {MockItem} mockItem * @param {RequestInfo} requestInfo */ FetchInterceptor.prototype.getFetchResponse = function (responseBody, mockItem, requestInfo) { var data = responseBody; var status = mockItem.status; var statusText = HTTPStatusCodes[status] || ''; var headers = typeof Headers === 'function' ? new Headers(__assign(__assign({}, mockItem.headers), { 'x-powered-by': 'http-request-mock' })) : Object.entries(__assign(__assign({}, mockItem.headers), { 'x-powered-by': 'http-request-mock' })); var body = typeof Blob === 'function' ? new Blob([typeof data === 'string' ? data : JSON.stringify(data)]) : data; if (typeof Response === 'function') { var response_1 = new Response(body, { status: status, statusText: statusText, headers: headers }); Object.defineProperty(response_1, 'url', { value: requestInfo.url }); return response_1; } var response = { body: body, bodyUsed: false, headers: headers, ok: true, redirected: false, status: status, statusText: statusText, url: requestInfo.url, type: 'basic', // response data depends on prepared data json: function () { if (typeof data === 'object') { return Promise.resolve(data); } if (typeof data === 'string') { try { return Promise.resolve(JSON.parse(data)); } catch (err) { // eslint-disable-line return Promise.resolve(null); } } return Promise.resolve(null); }, arrayBuffer: function () { if (typeof ArrayBuffer === 'function' && (data instanceof ArrayBuffer)) { return Promise.resolve(data); } if (typeof data === 'string' && typeof TextEncoder === 'function') { var encoder = new TextEncoder(); return Promise.resolve(encoder.encode(data).buffer); } return Promise.resolve(null); }, blob: function () { if (typeof Blob === 'function' && (data instanceof Blob)) { return Promise.resolve(data); } if (typeof data === 'string' && typeof Blob === 'function') { return Promise.resolve(new Blob([data], { type: 'text/plain' })); } return Promise.resolve(null); }, bytes: function () { if (typeof Uint8Array === 'function' && (data instanceof Uint8Array)) { return Promise.resolve(data); } if (typeof data === 'string' && typeof TextEncoder === 'function') { var encoder = new TextEncoder(); return Promise.resolve(encoder.encode(data)); } return Promise.resolve(null); }, formData: function () { if (typeof FormData === 'function') { return Promise.resolve((data instanceof FormData) ? data : null); } return Promise.resolve(null); }, text: function () { return Promise.resolve(typeof data === 'string' ? data : JSON.stringify(data)); }, // other methods that may be used clone: function () { return response; }, error: function () { return response; }, redirect: function () { return response; }, }; return response; }; return FetchInterceptor; }(base)); /* harmony default export */ const fetch = (FetchInterceptor); ;// CONCATENATED MODULE: ./src/interceptor/wx-request.ts var wx_request_extends = (undefined && undefined.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var wx_request_assign = (undefined && undefined.__assign) || function () { wx_request_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 wx_request_assign.apply(this, arguments); }; var wx_request_awaiter = (undefined && undefined.__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()); }); }; var wx_request_generator = (undefined && undefined.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; /* eslint-disable @typescript-eslint/no-empty-function */ var WxRequestInterceptor = /** @class */ (function (_super) { wx_request_extends(WxRequestInterceptor, _super); function WxRequestInterceptor(mocker, proxyServer) { if (proxyServer === void 0) { proxyServer = ''; } var _this = _super.call(this, mocker, proxyServer) || this; if (WxRequestInterceptor.instance) { return WxRequestInterceptor.instance; } WxRequestInterceptor.instance = _this; // Note: this.global has no wx object _this.wxRequest = wx.request.bind(wx); _this.intercept(); return _this; } /** * https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html * Intercept wx.request object. */ WxRequestInterceptor.prototype.intercept = function () { var _this = this; Object.defineProperty(wx, 'request', { configurable: true, enumerable: true, writable: true, value: function (wxRequestOpts) { if (!wxRequestOpts || !wxRequestOpts.url) { return; } wxRequestOpts.url = _this.getFullRequestUrl(wxRequestOpts.url, wxRequestOpts.method); var mockItem = _this.matchMockRequest(wxRequestOpts.url, wxRequestOpts.method); var remoteInfo = mockItem === null || mockItem === void 0 ? void 0 : mockItem.getRemoteInfo(wxRequestOpts.url); var requestInfo = _this.getRequestInfo(wxRequestOpts); if (mockItem && remoteInfo) { wxRequestOpts.url = remoteInfo.url; wxRequestOpts.method = remoteInfo.method || wxRequestOpts.method; if (Object.keys(mockItem.remoteRequestHeaders).length > 0) { wxRequestOpts.header = wx_request_assign(wx_request_assign({}, (wxRequestOpts.header || {})), mockItem.remoteRequestHeaders); } return _this.sendRemoteResult(wxRequestOpts, mockItem, requestInfo); } if (/^get$/i.test(wxRequestOpts.method) && isObject(wxRequestOpts.data)) { requestInfo.query = wx_request_assign(wx_request_assign({}, requestInfo.query), wxRequestOpts.data); } else { requestInfo.body = wxRequestOpts.data; } requestInfo.doOriginalCall = function () { return wx_request_awaiter(_this, void 0, void 0, function () { var res; return wx_request_generator(this, function (_a) { res = this.getOriginalResponse(wxRequestOpts); requestInfo.doOriginalCall = undefined; return [2 /*return*/, res]; }); }); }; if (mockItem) { _this.doMockRequest(mockItem, requestInfo, wxRequestOpts).then(function (isBypassed) { if (isBypassed) { _this.wxRequest(wxRequestOpts); // fallback to original wx.request } }); return _this.getRequstTask(); } else { wxRequestOpts.url = wxRequestOpts.url; return _this.wxRequest(wxRequestOpts); // fallback to original wx.request } } }); return this; }; WxRequestInterceptor.prototype.getRequstTask = function () { return { abort: function () { }, onHeadersReceived: function () { }, offHeadersReceived: function () { } }; }; /** * Set remote result. * @param {WxRequestOpts} wxRequestOpts * @param {MockItem} mockItem * @param {RequestInfo} requestInfo */ WxRequestInterceptor.prototype.sendRemoteResult = function (wxRequestOpts, mockItem, requestInfo) { // eslint-disable-next-line @typescript-eslint/no-this-alias var me = this; // fallback to original wx.request this.wxRequest(wx_request_assign(wx_request_assign({}, wxRequestOpts), { success: function (wxResponse) { var remoteResponse = { status: wxResponse.statusCode, headers: wxResponse.header, response: wxResponse.data, responseText: typeof wxResponse.data === 'string' ? wxResponse.data : JSON.stringify(wxResponse.data), responseJson: typeof wxResponse.data === 'string' ? tryToParseJson(wxResponse.data) : wxResponse.data }; me.doMockRequest(mockItem, requestInfo, wxRequestOpts, remoteResponse); } })); return this.getRequstTask(); }; /** * Get original response * @param {WxRequestOpts} wxRequestOpts */ WxRequestInterceptor.prototype.getOriginalResponse = function (wxRequestOpts) { var _this = this; return new Promise(function (resolve) { _this.wxRequest(wx_request_assign(wx_request_assign({}, wxRequestOpts), { success: function (wxResponse) { var data = wxResponse.data; resolve({ status: wxResponse.statusCode, headers: wxResponse.header, responseText: typeof data === 'string' ? data : JSON.stringify(data), responseJson: typeof data === 'string' ? tryToParseJson(data) : data, responseBuffer: typeof ArrayBuffer === 'function' && (data instanceof ArrayBuffer) ? data : null, // https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html // wx.request does not support Blob response data responseBlob: null, error: null, }); }, fail: function (err) { resolve({ status: 0, headers: {}, responseText: null, responseJson: null, responseBuffer: null, responseBlob: null, error: new Error("request error: ".concat(err.errMsg)), }); } })); }); }; /** * Make mock request. * @param {MockItem} mockItem * @param {RequestInfo} requestInfo * @param {WxRequestOpts} wxRequestOpts */ WxRequestInterceptor.prototype.doMockRequest = function (mockItem, requestInfo, wxRequestOpts, remoteResponse) { if (remoteResponse === void 0) { remoteResponse = null; } return wx_request_awaiter(this, void 0, void 0, function () { var isBypassed; return wx_request_generator(this, function (_a) { switch (_a.label) { case 0: isBypassed = false; if (!(mockItem.delay && mockItem.delay > 0)) return [3 /*break*/, 3]; return [4 /*yield*/, sleep(+mockItem.delay)]; case 1: _a.sent(); return [4 /*yield*/, this.doMockResponse(mockItem, requestInfo, wxRequestOpts, remoteResponse)]; case 2: isBypassed = _a.sent(); return [3 /*break*/, 5]; case 3: return [4 /*yield*/, this.doMockResponse(mockItem, requestInfo, wxRequestOpts, remoteResponse)]; case 4: isBypassed = _a.sent(); _a.label = 5; case 5: return [2 /*return*/, isBypassed]; } }); }); }; /** * Make mock response. * @param {MockItem} mockItem * @param {RequestInfo} requestInfo * @param {WxRequestOpts} wxRequestOpts */ WxRequestInterceptor.prototype.doMockResponse = function (mockItem, requestInfo, wxRequestOpts, remoteResponse) { if (remoteResponse === void 0) { remoteResponse = null; } return wx_request_awaiter(this, void 0, void 0, function () { var now, body, err_1, spent, wxResponse; return wx_request_generator(this, function (_a) { switch (_a.label) { case 0: now = Date.now();