msw 0.34.0 → 0.36.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/lib/esm/RequestHandler-deps.js +391 -66
  2. package/lib/esm/errors-deps.js +15 -1
  3. package/lib/esm/fetch-deps.js +9 -5
  4. package/lib/esm/graphql-deps.js +10 -6
  5. package/lib/esm/graphql.js +1 -0
  6. package/lib/esm/index-deps.js +2 -1
  7. package/lib/esm/index.js +102 -3893
  8. package/lib/esm/index2.js +1 -1
  9. package/lib/esm/mockServiceWorker.js +5 -5
  10. package/lib/esm/rest-deps.js +7 -15
  11. package/lib/esm/rest.js +1 -0
  12. package/lib/iife/index.js +3 -3
  13. package/lib/iife/mockServiceWorker.js +5 -5
  14. package/lib/types/context/data.d.ts +2 -3
  15. package/lib/types/context/extensions.d.ts +8 -0
  16. package/lib/types/context/index.d.ts +1 -0
  17. package/lib/types/graphql.d.ts +2 -1
  18. package/lib/types/handlers/GraphQLHandler.d.ts +7 -6
  19. package/lib/types/handlers/RequestHandler.d.ts +8 -8
  20. package/lib/types/handlers/RestHandler.d.ts +10 -12
  21. package/lib/types/index.d.ts +17 -7
  22. package/lib/types/native/index.d.ts +1 -1
  23. package/lib/types/node/glossary.d.ts +4 -14
  24. package/lib/types/node/index.d.ts +1 -1
  25. package/lib/types/node/setupServer.d.ts +1 -1
  26. package/lib/types/rest.d.ts +10 -9
  27. package/lib/types/setupWorker/glossary.d.ts +16 -26
  28. package/lib/types/setupWorker/start/utils/prepareStartHandler.d.ts +3 -3
  29. package/lib/types/sharedOptions.d.ts +12 -1
  30. package/lib/types/typeUtils.d.ts +5 -3
  31. package/lib/types/utils/getResponse.d.ts +1 -1
  32. package/lib/types/utils/handleRequest.d.ts +4 -4
  33. package/lib/types/utils/internal/getCallFrame.d.ts +1 -1
  34. package/lib/types/utils/internal/jsonParse.d.ts +2 -2
  35. package/lib/types/utils/internal/pipeEvents.d.ts +6 -0
  36. package/lib/types/utils/internal/requestHandlerUtils.d.ts +1 -1
  37. package/lib/types/utils/logging/prepareResponse.d.ts +1 -1
  38. package/lib/types/utils/matching/matchRequestUrl.d.ts +12 -2
  39. package/lib/types/utils/matching/normalizePath.d.ts +1 -1
  40. package/lib/types/utils/request/onUnhandledRequest.d.ts +1 -2
  41. package/lib/types/utils/request/parseBody.d.ts +2 -2
  42. package/lib/types/utils/request/parseWorkerRequest.d.ts +2 -2
  43. package/lib/types/utils/worker/createFallbackRequestListener.d.ts +2 -1
  44. package/lib/types/utils/worker/createRequestListener.d.ts +2 -1
  45. package/lib/umd/index.js +1070 -243
  46. package/lib/umd/mockServiceWorker.js +5 -5
  47. package/native/lib/index.js +501 -501
  48. package/node/lib/index.js +503 -503
  49. package/package.json +19 -19
@@ -6,6 +6,8 @@ var XMLHttpRequest = require('@mswjs/interceptors/lib/interceptors/XMLHttpReques
6
6
  var chalk = require('chalk');
7
7
  var require$$0 = require('events');
8
8
  var interceptors = require('@mswjs/interceptors');
9
+ var cookies = require('@mswjs/cookies');
10
+ var getCleanUrl = require('@mswjs/interceptors/lib/utils/getCleanUrl');
9
11
 
10
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
13
 
@@ -50,7 +52,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
50
52
 
51
53
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
52
54
 
53
- var lib$4 = {exports: {}};
55
+ var lib$3 = {exports: {}};
54
56
 
55
57
  (function (module, exports) {
56
58
  (function (global, factory) {
@@ -73,9 +75,9 @@ var lib$4 = {exports: {}};
73
75
  Object.defineProperty(exports, '__esModule', { value: true });
74
76
 
75
77
  })));
76
- }(lib$4, lib$4.exports));
78
+ }(lib$3, lib$3.exports));
77
79
 
78
- var lib$3 = {};
80
+ var lib$2 = {};
79
81
 
80
82
  var StrictEventEmitter$1 = {};
81
83
 
@@ -101,7 +103,7 @@ var __spreadArrays = (commonjsGlobal && commonjsGlobal.__spreadArrays) || functi
101
103
  };
102
104
  StrictEventEmitter$1.__esModule = true;
103
105
  StrictEventEmitter$1.StrictEventEmitter = void 0;
104
- var events_1 = require$$0__default['default'];
106
+ var events_1 = require$$0__default["default"];
105
107
  var StrictEventEmitter = /** @class */ (function (_super) {
106
108
  __extends$1(StrictEventEmitter, _super);
107
109
  function StrictEventEmitter() {
@@ -145,7 +147,7 @@ exports.__esModule = true;
145
147
  exports.StrictEventEmitter = void 0;
146
148
  var StrictEventEmitter_1 = StrictEventEmitter$1;
147
149
  __createBinding(exports, StrictEventEmitter_1, "StrictEventEmitter");
148
- }(lib$3));
150
+ }(lib$2));
149
151
 
150
152
  function use(currentHandlers, ...handlers) {
151
153
  currentHandlers.unshift(...handlers);
@@ -369,19 +371,19 @@ function uuidv4() {
369
371
  }
370
372
 
371
373
  /**
372
- * Parses a given string into a JSON.
374
+ * Parses a given value into a JSON.
373
375
  * Does not throw an exception on an invalid JSON string.
374
376
  */
375
- function jsonParse(str) {
377
+ function jsonParse(value) {
376
378
  try {
377
- return JSON.parse(str);
379
+ return JSON.parse(value);
378
380
  }
379
381
  catch (error) {
380
382
  return undefined;
381
383
  }
382
384
  }
383
385
 
384
- var lib$2 = {};
386
+ var lib$1 = {};
385
387
 
386
388
  var Headers = {};
387
389
 
@@ -905,11 +907,11 @@ var flattenHeadersList_1 = flattenHeadersList$1;
905
907
  Object.defineProperty(exports, "flattenHeadersList", { enumerable: true, get: function () { return flattenHeadersList_1.flattenHeadersList; } });
906
908
  var flattenHeadersObject_1 = flattenHeadersObject$1;
907
909
  Object.defineProperty(exports, "flattenHeadersObject", { enumerable: true, get: function () { return flattenHeadersObject_1.flattenHeadersObject; } });
908
- }(lib$2));
910
+ }(lib$1));
909
911
 
910
912
  function parseContentHeaders(headersString) {
911
913
  var _a, _b;
912
- const headers = lib$2.stringToHeaders(headersString);
914
+ const headers = lib$1.stringToHeaders(headersString);
913
915
  const contentType = headers.get('content-type') || 'text/plain';
914
916
  const disposition = headers.get('content-disposition');
915
917
  if (!disposition) {
@@ -980,403 +982,30 @@ function parseMultipartData(data, headers) {
980
982
  }
981
983
 
982
984
  /**
983
- * Parses a given request/response body based on the `Content-Type` header.
985
+ * Parses a given request/response body based on the "Content-Type" header.
984
986
  */
985
987
  function parseBody(body, headers) {
986
988
  // Return whatever falsey body value is given.
987
989
  if (!body) {
988
990
  return body;
989
991
  }
990
- const contentType = headers === null || headers === void 0 ? void 0 : headers.get('content-type');
992
+ const contentType = (headers === null || headers === void 0 ? void 0 : headers.get('content-type')) || '';
991
993
  // If the body has a Multipart Content-Type
992
994
  // parse it into an object.
993
- const hasMultipartContent = contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('multipart/form-data');
995
+ const hasMultipartContent = contentType.startsWith('multipart/form-data');
994
996
  if (hasMultipartContent && typeof body !== 'object') {
995
- return parseMultipartData(body, headers) || body;
997
+ return parseMultipartData(body.toString(), headers) || body;
996
998
  }
997
999
  // If the intercepted request's body has a JSON Content-Type
998
1000
  // parse it into an object.
999
- const hasJsonContent = contentType === null || contentType === void 0 ? void 0 : contentType.includes('json');
1001
+ const hasJsonContent = contentType.includes('json');
1000
1002
  if (hasJsonContent && typeof body !== 'object') {
1001
- return jsonParse(body) || body;
1003
+ return jsonParse(body.toString()) || body;
1002
1004
  }
1003
1005
  // Otherwise leave as-is.
1004
1006
  return body;
1005
1007
  }
1006
1008
 
1007
- var lib$1 = {};
1008
-
1009
- var CookieStore = {};
1010
-
1011
- var setCookie = {exports: {}};
1012
-
1013
- var defaultParseOptions = {
1014
- decodeValues: true,
1015
- map: false,
1016
- silent: false,
1017
- };
1018
-
1019
- function isNonEmptyString(str) {
1020
- return typeof str === "string" && !!str.trim();
1021
- }
1022
-
1023
- function parseString(setCookieValue, options) {
1024
- var parts = setCookieValue.split(";").filter(isNonEmptyString);
1025
- var nameValue = parts.shift().split("=");
1026
- var name = nameValue.shift();
1027
- var value = nameValue.join("="); // everything after the first =, joined by a "=" if there was more than one part
1028
-
1029
- options = options
1030
- ? Object.assign({}, defaultParseOptions, options)
1031
- : defaultParseOptions;
1032
-
1033
- try {
1034
- value = options.decodeValues ? decodeURIComponent(value) : value; // decode cookie value
1035
- } catch (e) {
1036
- console.error(
1037
- "set-cookie-parser encountered an error while decoding a cookie with value '" +
1038
- value +
1039
- "'. Set options.decodeValues to false to disable this feature.",
1040
- e
1041
- );
1042
- }
1043
-
1044
- var cookie = {
1045
- name: name, // grab everything before the first =
1046
- value: value,
1047
- };
1048
-
1049
- parts.forEach(function (part) {
1050
- var sides = part.split("=");
1051
- var key = sides.shift().trimLeft().toLowerCase();
1052
- var value = sides.join("=");
1053
- if (key === "expires") {
1054
- cookie.expires = new Date(value);
1055
- } else if (key === "max-age") {
1056
- cookie.maxAge = parseInt(value, 10);
1057
- } else if (key === "secure") {
1058
- cookie.secure = true;
1059
- } else if (key === "httponly") {
1060
- cookie.httpOnly = true;
1061
- } else if (key === "samesite") {
1062
- cookie.sameSite = value;
1063
- } else {
1064
- cookie[key] = value;
1065
- }
1066
- });
1067
-
1068
- return cookie;
1069
- }
1070
-
1071
- function parse$1(input, options) {
1072
- options = options
1073
- ? Object.assign({}, defaultParseOptions, options)
1074
- : defaultParseOptions;
1075
-
1076
- if (!input) {
1077
- if (!options.map) {
1078
- return [];
1079
- } else {
1080
- return {};
1081
- }
1082
- }
1083
-
1084
- if (input.headers && input.headers["set-cookie"]) {
1085
- // fast-path for node.js (which automatically normalizes header names to lower-case
1086
- input = input.headers["set-cookie"];
1087
- } else if (input.headers) {
1088
- // slow-path for other environments - see #25
1089
- var sch =
1090
- input.headers[
1091
- Object.keys(input.headers).find(function (key) {
1092
- return key.toLowerCase() === "set-cookie";
1093
- })
1094
- ];
1095
- // warn if called on a request-like object with a cookie header rather than a set-cookie header - see #34, 36
1096
- if (!sch && input.headers.cookie && !options.silent) {
1097
- console.warn(
1098
- "Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning."
1099
- );
1100
- }
1101
- input = sch;
1102
- }
1103
- if (!Array.isArray(input)) {
1104
- input = [input];
1105
- }
1106
-
1107
- options = options
1108
- ? Object.assign({}, defaultParseOptions, options)
1109
- : defaultParseOptions;
1110
-
1111
- if (!options.map) {
1112
- return input.filter(isNonEmptyString).map(function (str) {
1113
- return parseString(str, options);
1114
- });
1115
- } else {
1116
- var cookies = {};
1117
- return input.filter(isNonEmptyString).reduce(function (cookies, str) {
1118
- var cookie = parseString(str, options);
1119
- cookies[cookie.name] = cookie;
1120
- return cookies;
1121
- }, cookies);
1122
- }
1123
- }
1124
-
1125
- /*
1126
- Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas
1127
- that are within a single set-cookie field-value, such as in the Expires portion.
1128
-
1129
- This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
1130
- Node.js does this for every header *except* set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
1131
- React Native's fetch does this for *every* header, including set-cookie.
1132
-
1133
- Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
1134
- Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
1135
- */
1136
- function splitCookiesString(cookiesString) {
1137
- if (Array.isArray(cookiesString)) {
1138
- return cookiesString;
1139
- }
1140
- if (typeof cookiesString !== "string") {
1141
- return [];
1142
- }
1143
-
1144
- var cookiesStrings = [];
1145
- var pos = 0;
1146
- var start;
1147
- var ch;
1148
- var lastComma;
1149
- var nextStart;
1150
- var cookiesSeparatorFound;
1151
-
1152
- function skipWhitespace() {
1153
- while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
1154
- pos += 1;
1155
- }
1156
- return pos < cookiesString.length;
1157
- }
1158
-
1159
- function notSpecialChar() {
1160
- ch = cookiesString.charAt(pos);
1161
-
1162
- return ch !== "=" && ch !== ";" && ch !== ",";
1163
- }
1164
-
1165
- while (pos < cookiesString.length) {
1166
- start = pos;
1167
- cookiesSeparatorFound = false;
1168
-
1169
- while (skipWhitespace()) {
1170
- ch = cookiesString.charAt(pos);
1171
- if (ch === ",") {
1172
- // ',' is a cookie separator if we have later first '=', not ';' or ','
1173
- lastComma = pos;
1174
- pos += 1;
1175
-
1176
- skipWhitespace();
1177
- nextStart = pos;
1178
-
1179
- while (pos < cookiesString.length && notSpecialChar()) {
1180
- pos += 1;
1181
- }
1182
-
1183
- // currently special character
1184
- if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
1185
- // we found cookies separator
1186
- cookiesSeparatorFound = true;
1187
- // pos is inside the next cookie, so back up and return it.
1188
- pos = nextStart;
1189
- cookiesStrings.push(cookiesString.substring(start, lastComma));
1190
- start = pos;
1191
- } else {
1192
- // in param ',' or param separator ';',
1193
- // we continue from that comma
1194
- pos = lastComma + 1;
1195
- }
1196
- } else {
1197
- pos += 1;
1198
- }
1199
- }
1200
-
1201
- if (!cookiesSeparatorFound || pos >= cookiesString.length) {
1202
- cookiesStrings.push(cookiesString.substring(start, cookiesString.length));
1203
- }
1204
- }
1205
-
1206
- return cookiesStrings;
1207
- }
1208
-
1209
- setCookie.exports = parse$1;
1210
- setCookie.exports.parse = parse$1;
1211
- setCookie.exports.parseString = parseString;
1212
- setCookie.exports.splitCookiesString = splitCookiesString;
1213
-
1214
- (function (exports) {
1215
- var __rest = (commonjsGlobal && commonjsGlobal.__rest) || function (s, e) {
1216
- var t = {};
1217
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
1218
- t[p] = s[p];
1219
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
1220
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
1221
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
1222
- t[p[i]] = s[p[i]];
1223
- }
1224
- return t;
1225
- };
1226
- Object.defineProperty(exports, "__esModule", { value: true });
1227
- exports.PERSISTENCY_KEY = void 0;
1228
- const set_cookie_parser_1 = setCookie.exports;
1229
- exports.PERSISTENCY_KEY = 'MSW_COOKIE_STORE';
1230
- const SUPPORTS_LOCAL_STORAGE = typeof localStorage !== 'undefined';
1231
- class CookieStore {
1232
- constructor() {
1233
- this.store = new Map();
1234
- }
1235
- /**
1236
- * Sets the given request cookies into the store.
1237
- * Respects the `request.credentials` policy.
1238
- */
1239
- add(request, response) {
1240
- if (request.credentials === 'omit') {
1241
- return;
1242
- }
1243
- const requestUrl = new URL(request.url);
1244
- const responseCookies = response.headers.get('set-cookie');
1245
- if (!responseCookies) {
1246
- return;
1247
- }
1248
- const now = Date.now();
1249
- const parsedResponseCookies = set_cookie_parser_1.parse(responseCookies).map((_a) => {
1250
- var { maxAge } = _a, cookie = __rest(_a, ["maxAge"]);
1251
- return (Object.assign(Object.assign({}, cookie), { expires: maxAge === undefined ? cookie.expires : new Date(now + maxAge * 1000), maxAge }));
1252
- });
1253
- const prevCookies = this.store.get(requestUrl.origin) || new Map();
1254
- parsedResponseCookies.forEach((cookie) => {
1255
- this.store.set(requestUrl.origin, prevCookies.set(cookie.name, cookie));
1256
- });
1257
- }
1258
- /**
1259
- * Returns cookies relevant to the given request
1260
- * and its `request.credentials` policy.
1261
- */
1262
- get(request) {
1263
- this.deleteExpiredCookies();
1264
- const requestUrl = new URL(request.url);
1265
- const originCookies = this.store.get(requestUrl.origin) || new Map();
1266
- switch (request.credentials) {
1267
- case 'include': {
1268
- const documentCookies = set_cookie_parser_1.parse(document.cookie);
1269
- documentCookies.forEach((cookie) => {
1270
- originCookies.set(cookie.name, cookie);
1271
- });
1272
- return originCookies;
1273
- }
1274
- case 'same-origin': {
1275
- return originCookies;
1276
- }
1277
- default:
1278
- return new Map();
1279
- }
1280
- }
1281
- /**
1282
- * Returns a collection of all stored cookies.
1283
- */
1284
- getAll() {
1285
- this.deleteExpiredCookies();
1286
- return this.store;
1287
- }
1288
- /**
1289
- * Deletes all cookies associated with the given request.
1290
- */
1291
- deleteAll(request) {
1292
- const requestUrl = new URL(request.url);
1293
- this.store.delete(requestUrl.origin);
1294
- }
1295
- /**
1296
- * Clears the entire cookie store.
1297
- */
1298
- clear() {
1299
- this.store.clear();
1300
- }
1301
- /**
1302
- * Hydrates the virtual cookie store from the `localStorage` if defined.
1303
- */
1304
- hydrate() {
1305
- if (!SUPPORTS_LOCAL_STORAGE) {
1306
- return;
1307
- }
1308
- const persistedCookies = localStorage.getItem(exports.PERSISTENCY_KEY);
1309
- if (persistedCookies) {
1310
- try {
1311
- const parsedCookies = JSON.parse(persistedCookies);
1312
- parsedCookies.forEach(([origin, cookies]) => {
1313
- this.store.set(origin, new Map(cookies.map((_a) => {
1314
- var [token, _b] = _a, { expires } = _b, cookie = __rest(_b, ["expires"]);
1315
- return [
1316
- token,
1317
- expires === undefined
1318
- ? cookie
1319
- : Object.assign(Object.assign({}, cookie), { expires: new Date(expires) }),
1320
- ];
1321
- })));
1322
- });
1323
- }
1324
- catch (error) {
1325
- console.warn(`
1326
- [virtual-cookie] Failed to parse a stored cookie from the localStorage (key "${exports.PERSISTENCY_KEY}").
1327
-
1328
- Stored value:
1329
- ${localStorage.getItem(exports.PERSISTENCY_KEY)}
1330
-
1331
- Thrown exception:
1332
- ${error}
1333
-
1334
- Invalid value has been removed from localStorage to prevent subsequent failed parsing attempts.`);
1335
- localStorage.removeItem(exports.PERSISTENCY_KEY);
1336
- }
1337
- }
1338
- }
1339
- /**
1340
- * Persists the current virtual cookies into the `localStorage` if defined,
1341
- * so they are available on the next page load.
1342
- */
1343
- persist() {
1344
- if (!SUPPORTS_LOCAL_STORAGE) {
1345
- return;
1346
- }
1347
- const serializedCookies = Array.from(this.store.entries()).map(([origin, cookies]) => {
1348
- return [origin, Array.from(cookies.entries())];
1349
- });
1350
- localStorage.setItem(exports.PERSISTENCY_KEY, JSON.stringify(serializedCookies));
1351
- }
1352
- deleteExpiredCookies() {
1353
- const now = Date.now();
1354
- this.store.forEach((originCookies, origin) => {
1355
- originCookies.forEach(({ expires, name }) => {
1356
- if (expires !== undefined && expires.getTime() <= now) {
1357
- originCookies.delete(name);
1358
- }
1359
- });
1360
- if (originCookies.size === 0) {
1361
- this.store.delete(origin);
1362
- }
1363
- });
1364
- }
1365
- }
1366
- exports.default = new CookieStore();
1367
- }(CookieStore));
1368
-
1369
- (function (exports) {
1370
- var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
1371
- return (mod && mod.__esModule) ? mod : { "default": mod };
1372
- };
1373
- Object.defineProperty(exports, "__esModule", { value: true });
1374
- exports.PERSISTENCY_KEY = exports.store = void 0;
1375
- var CookieStore_1 = CookieStore;
1376
- Object.defineProperty(exports, "store", { enumerable: true, get: function () { return __importDefault(CookieStore_1).default; } });
1377
- Object.defineProperty(exports, "PERSISTENCY_KEY", { enumerable: true, get: function () { return CookieStore_1.PERSISTENCY_KEY; } });
1378
- }(lib$1));
1379
-
1380
1009
  function getAllCookies() {
1381
1010
  return parse_1(document.cookie);
1382
1011
  }
@@ -1387,7 +1016,7 @@ function getRequestCookies(request) {
1387
1016
  /**
1388
1017
  * @note No cookies persist on the document in Node.js: no document.
1389
1018
  */
1390
- if (typeof location === 'undefined') {
1019
+ if (typeof document === 'undefined' || typeof location === 'undefined') {
1391
1020
  return {};
1392
1021
  }
1393
1022
  switch (request.credentials) {
@@ -1408,8 +1037,8 @@ function getRequestCookies(request) {
1408
1037
 
1409
1038
  function setRequestCookies(request) {
1410
1039
  var _a;
1411
- lib$1.store.hydrate();
1412
- request.cookies = Object.assign(Object.assign({}, getRequestCookies(request)), Array.from((_a = lib$1.store.get(Object.assign(Object.assign({}, request), { url: request.url.toString() }))) === null || _a === void 0 ? void 0 : _a.entries()).reduce((cookies, [name, { value }]) => Object.assign(cookies, { [name]: value }), {}));
1040
+ cookies.store.hydrate();
1041
+ request.cookies = Object.assign(Object.assign({}, getRequestCookies(request)), Array.from((_a = cookies.store.get(Object.assign(Object.assign({}, request), { url: request.url.toString() }))) === null || _a === void 0 ? void 0 : _a.entries()).reduce((cookies, [name, { value }]) => Object.assign(cookies, { [name]: value }), {}));
1413
1042
  request.headers.set('cookie', Object.entries(request.cookies)
1414
1043
  .map(([name, value]) => `${name}=${value}`)
1415
1044
  .join('; '));
@@ -3403,7 +3032,7 @@ function isNameStart(code) {
3403
3032
  * Given a GraphQL source, parses it into a Document.
3404
3033
  * Throws GraphQLError if a syntax error is encountered.
3405
3034
  */
3406
- function parse(source, options) {
3035
+ function parse$1(source, options) {
3407
3036
  var parser = new Parser(source, options);
3408
3037
  return parser.parseDocument();
3409
3038
  }
@@ -4922,7 +4551,7 @@ function parseDocumentNode(node) {
4922
4551
  }
4923
4552
  function parseQuery(query) {
4924
4553
  try {
4925
- const ast = parse(query);
4554
+ const ast = parse$1(query);
4926
4555
  return parseDocumentNode(ast);
4927
4556
  }
4928
4557
  catch (error) {
@@ -5118,7 +4747,7 @@ function set(...args) {
5118
4747
  res.headers.append(name, value);
5119
4748
  }
5120
4749
  else {
5121
- const headers = lib$2.objectToHeaders(name);
4750
+ const headers = lib$1.objectToHeaders(name);
5122
4751
  headers.forEach((value, name) => {
5123
4752
  res.headers.append(name, value);
5124
4753
  });
@@ -5215,12 +4844,26 @@ const data = (payload) => {
5215
4844
  };
5216
4845
  };
5217
4846
 
4847
+ /**
4848
+ * Sets the GraphQL extensions on a given response.
4849
+ * @example
4850
+ * res(ctx.extensions({ tracing: { version: 1 }}))
4851
+ * @see {@link https://mswjs.io/docs/api/context/extensions `ctx.extensions()`}
4852
+ */
4853
+ const extensions = (payload) => {
4854
+ return (res) => {
4855
+ const prevBody = jsonParse(res.body) || {};
4856
+ const nextBody = mergeRight(prevBody, { extensions: payload });
4857
+ return json(nextBody)(res);
4858
+ };
4859
+ };
4860
+
5218
4861
  const SET_TIMEOUT_MAX_ALLOWED_INT = 2147483647;
5219
4862
  const MIN_SERVER_RESPONSE_TIME = 100;
5220
4863
  const MAX_SERVER_RESPONSE_TIME = 400;
5221
4864
  const NODE_SERVER_RESPONSE_TIME = 5;
5222
4865
  const getRandomServerResponseTime = () => {
5223
- if (lib$4.exports.isNodeProcess()) {
4866
+ if (lib$3.exports.isNodeProcess()) {
5224
4867
  return NODE_SERVER_RESPONSE_TIME;
5225
4868
  }
5226
4869
  return Math.floor(Math.random() * (MAX_SERVER_RESPONSE_TIME - MIN_SERVER_RESPONSE_TIME) +
@@ -5287,9 +4930,9 @@ const errors = (errorsList) => {
5287
4930
  };
5288
4931
  };
5289
4932
 
5290
- const useFetch = lib$4.exports.isNodeProcess() ? require('node-fetch') : window.fetch;
4933
+ const useFetch = lib$3.exports.isNodeProcess() ? require('node-fetch') : window.fetch;
5291
4934
  const augmentRequestInit = (requestInit) => {
5292
- const headers = new lib$2.Headers(requestInit.headers);
4935
+ const headers = new lib$1.Headers(requestInit.headers);
5293
4936
  headers.set('x-msw-bypass', 'true');
5294
4937
  return Object.assign(Object.assign({}, requestInit), { headers: headers.all() });
5295
4938
  };
@@ -5299,8 +4942,12 @@ const createFetchRequestParameters = (input) => {
5299
4942
  if (['GET', 'HEAD'].includes(method)) {
5300
4943
  return requestParameters;
5301
4944
  }
5302
- requestParameters.body =
5303
- typeof body === 'object' ? JSON.stringify(body) : body;
4945
+ if (typeof body === 'object' || typeof body === 'number') {
4946
+ requestParameters.body = JSON.stringify(body);
4947
+ }
4948
+ else {
4949
+ requestParameters.body = body;
4950
+ }
5304
4951
  return requestParameters;
5305
4952
  };
5306
4953
  /**
@@ -5389,63 +5036,345 @@ function prepareRequest(request) {
5389
5036
  * Formats a mocked response for introspection in the browser's console.
5390
5037
  */
5391
5038
  function prepareResponse(res) {
5392
- const responseHeaders = lib$2.objectToHeaders(res.headers);
5039
+ const responseHeaders = lib$1.objectToHeaders(res.headers);
5393
5040
  return Object.assign(Object.assign({}, res), {
5394
5041
  // Parse a response JSON body for preview in the logs
5395
5042
  body: parseBody(res.body, responseHeaders) });
5396
5043
  }
5397
5044
 
5398
- /**
5399
- * Converts a string path to a Regular Expression.
5400
- * Transforms path parameters into named RegExp groups.
5401
- */
5402
- const pathToRegExp = (path) => {
5403
- const pattern = path
5404
- // Escape literal dots
5405
- .replace(/\./g, '\\.')
5406
- // Escape literal slashes
5407
- .replace(/\//g, '/')
5408
- // Escape literal question marks
5409
- .replace(/\?/g, '\\?')
5410
- // Ignore trailing slashes
5411
- .replace(/\/+$/, '')
5412
- // Replace wildcard with any zero-to-any character sequence
5413
- .replace(/\*+/g, '.*')
5414
- // Replace parameters with named capturing groups
5415
- .replace(/:([^\d|^\/][a-zA-Z0-9_]*(?=(?:\/|\\.)|$))/g, (_, paramName) => `(?<${paramName}>[^\/]+?)`)
5416
- // Allow optional trailing slash
5417
- .concat('(\\/|$)');
5418
- return new RegExp(pattern, 'gi');
5419
- };
5420
-
5421
- /**
5422
- * Matches a given url against a path.
5423
- */
5424
- const match = (path, url) => {
5425
- const expression = path instanceof RegExp ? path : pathToRegExp(path);
5426
- const match = expression.exec(url) || false;
5427
- // Matches in strict mode: match string should equal to input (url)
5428
- // Otherwise loose matches will be considered truthy:
5429
- // match('/messages/:id', '/messages/123/users') // true
5430
- const matches = path instanceof RegExp ? !!match : !!match && match[0] === match.input;
5431
- return {
5432
- matches,
5433
- params: match && matches ? match.groups || null : null,
5434
- };
5435
- };
5436
-
5437
- var getCleanUrl$1 = {};
5438
-
5439
- Object.defineProperty(getCleanUrl$1, "__esModule", { value: true });
5440
- var getCleanUrl_2 = getCleanUrl$1.getCleanUrl = void 0;
5441
5045
  /**
5442
- * Removes query parameters and hashes from a given URL.
5046
+ * Tokenize input string.
5443
5047
  */
5444
- function getCleanUrl(url, isAbsolute) {
5445
- if (isAbsolute === void 0) { isAbsolute = true; }
5446
- return [isAbsolute && url.origin, url.pathname].filter(Boolean).join('');
5048
+ function lexer(str) {
5049
+ var tokens = [];
5050
+ var i = 0;
5051
+ while (i < str.length) {
5052
+ var char = str[i];
5053
+ if (char === "*" || char === "+" || char === "?") {
5054
+ tokens.push({ type: "MODIFIER", index: i, value: str[i++] });
5055
+ continue;
5056
+ }
5057
+ if (char === "\\") {
5058
+ tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] });
5059
+ continue;
5060
+ }
5061
+ if (char === "{") {
5062
+ tokens.push({ type: "OPEN", index: i, value: str[i++] });
5063
+ continue;
5064
+ }
5065
+ if (char === "}") {
5066
+ tokens.push({ type: "CLOSE", index: i, value: str[i++] });
5067
+ continue;
5068
+ }
5069
+ if (char === ":") {
5070
+ var name = "";
5071
+ var j = i + 1;
5072
+ while (j < str.length) {
5073
+ var code = str.charCodeAt(j);
5074
+ if (
5075
+ // `0-9`
5076
+ (code >= 48 && code <= 57) ||
5077
+ // `A-Z`
5078
+ (code >= 65 && code <= 90) ||
5079
+ // `a-z`
5080
+ (code >= 97 && code <= 122) ||
5081
+ // `_`
5082
+ code === 95) {
5083
+ name += str[j++];
5084
+ continue;
5085
+ }
5086
+ break;
5087
+ }
5088
+ if (!name)
5089
+ throw new TypeError("Missing parameter name at " + i);
5090
+ tokens.push({ type: "NAME", index: i, value: name });
5091
+ i = j;
5092
+ continue;
5093
+ }
5094
+ if (char === "(") {
5095
+ var count = 1;
5096
+ var pattern = "";
5097
+ var j = i + 1;
5098
+ if (str[j] === "?") {
5099
+ throw new TypeError("Pattern cannot start with \"?\" at " + j);
5100
+ }
5101
+ while (j < str.length) {
5102
+ if (str[j] === "\\") {
5103
+ pattern += str[j++] + str[j++];
5104
+ continue;
5105
+ }
5106
+ if (str[j] === ")") {
5107
+ count--;
5108
+ if (count === 0) {
5109
+ j++;
5110
+ break;
5111
+ }
5112
+ }
5113
+ else if (str[j] === "(") {
5114
+ count++;
5115
+ if (str[j + 1] !== "?") {
5116
+ throw new TypeError("Capturing groups are not allowed at " + j);
5117
+ }
5118
+ }
5119
+ pattern += str[j++];
5120
+ }
5121
+ if (count)
5122
+ throw new TypeError("Unbalanced pattern at " + i);
5123
+ if (!pattern)
5124
+ throw new TypeError("Missing pattern at " + i);
5125
+ tokens.push({ type: "PATTERN", index: i, value: pattern });
5126
+ i = j;
5127
+ continue;
5128
+ }
5129
+ tokens.push({ type: "CHAR", index: i, value: str[i++] });
5130
+ }
5131
+ tokens.push({ type: "END", index: i, value: "" });
5132
+ return tokens;
5133
+ }
5134
+ /**
5135
+ * Parse a string for the raw tokens.
5136
+ */
5137
+ function parse(str, options) {
5138
+ if (options === void 0) { options = {}; }
5139
+ var tokens = lexer(str);
5140
+ var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a;
5141
+ var defaultPattern = "[^" + escapeString(options.delimiter || "/#?") + "]+?";
5142
+ var result = [];
5143
+ var key = 0;
5144
+ var i = 0;
5145
+ var path = "";
5146
+ var tryConsume = function (type) {
5147
+ if (i < tokens.length && tokens[i].type === type)
5148
+ return tokens[i++].value;
5149
+ };
5150
+ var mustConsume = function (type) {
5151
+ var value = tryConsume(type);
5152
+ if (value !== undefined)
5153
+ return value;
5154
+ var _a = tokens[i], nextType = _a.type, index = _a.index;
5155
+ throw new TypeError("Unexpected " + nextType + " at " + index + ", expected " + type);
5156
+ };
5157
+ var consumeText = function () {
5158
+ var result = "";
5159
+ var value;
5160
+ // tslint:disable-next-line
5161
+ while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) {
5162
+ result += value;
5163
+ }
5164
+ return result;
5165
+ };
5166
+ while (i < tokens.length) {
5167
+ var char = tryConsume("CHAR");
5168
+ var name = tryConsume("NAME");
5169
+ var pattern = tryConsume("PATTERN");
5170
+ if (name || pattern) {
5171
+ var prefix = char || "";
5172
+ if (prefixes.indexOf(prefix) === -1) {
5173
+ path += prefix;
5174
+ prefix = "";
5175
+ }
5176
+ if (path) {
5177
+ result.push(path);
5178
+ path = "";
5179
+ }
5180
+ result.push({
5181
+ name: name || key++,
5182
+ prefix: prefix,
5183
+ suffix: "",
5184
+ pattern: pattern || defaultPattern,
5185
+ modifier: tryConsume("MODIFIER") || ""
5186
+ });
5187
+ continue;
5188
+ }
5189
+ var value = char || tryConsume("ESCAPED_CHAR");
5190
+ if (value) {
5191
+ path += value;
5192
+ continue;
5193
+ }
5194
+ if (path) {
5195
+ result.push(path);
5196
+ path = "";
5197
+ }
5198
+ var open = tryConsume("OPEN");
5199
+ if (open) {
5200
+ var prefix = consumeText();
5201
+ var name_1 = tryConsume("NAME") || "";
5202
+ var pattern_1 = tryConsume("PATTERN") || "";
5203
+ var suffix = consumeText();
5204
+ mustConsume("CLOSE");
5205
+ result.push({
5206
+ name: name_1 || (pattern_1 ? key++ : ""),
5207
+ pattern: name_1 && !pattern_1 ? defaultPattern : pattern_1,
5208
+ prefix: prefix,
5209
+ suffix: suffix,
5210
+ modifier: tryConsume("MODIFIER") || ""
5211
+ });
5212
+ continue;
5213
+ }
5214
+ mustConsume("END");
5215
+ }
5216
+ return result;
5217
+ }
5218
+ /**
5219
+ * Create path match function from `path-to-regexp` spec.
5220
+ */
5221
+ function match(str, options) {
5222
+ var keys = [];
5223
+ var re = pathToRegexp(str, keys, options);
5224
+ return regexpToFunction(re, keys, options);
5225
+ }
5226
+ /**
5227
+ * Create a path match function from `path-to-regexp` output.
5228
+ */
5229
+ function regexpToFunction(re, keys, options) {
5230
+ if (options === void 0) { options = {}; }
5231
+ var _a = options.decode, decode = _a === void 0 ? function (x) { return x; } : _a;
5232
+ return function (pathname) {
5233
+ var m = re.exec(pathname);
5234
+ if (!m)
5235
+ return false;
5236
+ var path = m[0], index = m.index;
5237
+ var params = Object.create(null);
5238
+ var _loop_1 = function (i) {
5239
+ // tslint:disable-next-line
5240
+ if (m[i] === undefined)
5241
+ return "continue";
5242
+ var key = keys[i - 1];
5243
+ if (key.modifier === "*" || key.modifier === "+") {
5244
+ params[key.name] = m[i].split(key.prefix + key.suffix).map(function (value) {
5245
+ return decode(value, key);
5246
+ });
5247
+ }
5248
+ else {
5249
+ params[key.name] = decode(m[i], key);
5250
+ }
5251
+ };
5252
+ for (var i = 1; i < m.length; i++) {
5253
+ _loop_1(i);
5254
+ }
5255
+ return { path: path, index: index, params: params };
5256
+ };
5257
+ }
5258
+ /**
5259
+ * Escape a regular expression string.
5260
+ */
5261
+ function escapeString(str) {
5262
+ return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
5263
+ }
5264
+ /**
5265
+ * Get the flags for a regexp from the options.
5266
+ */
5267
+ function flags(options) {
5268
+ return options && options.sensitive ? "" : "i";
5269
+ }
5270
+ /**
5271
+ * Pull out keys from a regexp.
5272
+ */
5273
+ function regexpToRegexp(path, keys) {
5274
+ if (!keys)
5275
+ return path;
5276
+ var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g;
5277
+ var index = 0;
5278
+ var execResult = groupsRegex.exec(path.source);
5279
+ while (execResult) {
5280
+ keys.push({
5281
+ // Use parenthesized substring match if available, index otherwise
5282
+ name: execResult[1] || index++,
5283
+ prefix: "",
5284
+ suffix: "",
5285
+ modifier: "",
5286
+ pattern: ""
5287
+ });
5288
+ execResult = groupsRegex.exec(path.source);
5289
+ }
5290
+ return path;
5291
+ }
5292
+ /**
5293
+ * Transform an array into a regexp.
5294
+ */
5295
+ function arrayToRegexp(paths, keys, options) {
5296
+ var parts = paths.map(function (path) { return pathToRegexp(path, keys, options).source; });
5297
+ return new RegExp("(?:" + parts.join("|") + ")", flags(options));
5298
+ }
5299
+ /**
5300
+ * Create a path regexp from string input.
5301
+ */
5302
+ function stringToRegexp(path, keys, options) {
5303
+ return tokensToRegexp(parse(path, options), keys, options);
5304
+ }
5305
+ /**
5306
+ * Expose a function for taking tokens and returning a RegExp.
5307
+ */
5308
+ function tokensToRegexp(tokens, keys, options) {
5309
+ if (options === void 0) { options = {}; }
5310
+ var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function (x) { return x; } : _d;
5311
+ var endsWith = "[" + escapeString(options.endsWith || "") + "]|$";
5312
+ var delimiter = "[" + escapeString(options.delimiter || "/#?") + "]";
5313
+ var route = start ? "^" : "";
5314
+ // Iterate over the tokens and create our regexp string.
5315
+ for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
5316
+ var token = tokens_1[_i];
5317
+ if (typeof token === "string") {
5318
+ route += escapeString(encode(token));
5319
+ }
5320
+ else {
5321
+ var prefix = escapeString(encode(token.prefix));
5322
+ var suffix = escapeString(encode(token.suffix));
5323
+ if (token.pattern) {
5324
+ if (keys)
5325
+ keys.push(token);
5326
+ if (prefix || suffix) {
5327
+ if (token.modifier === "+" || token.modifier === "*") {
5328
+ var mod = token.modifier === "*" ? "?" : "";
5329
+ route += "(?:" + prefix + "((?:" + token.pattern + ")(?:" + suffix + prefix + "(?:" + token.pattern + "))*)" + suffix + ")" + mod;
5330
+ }
5331
+ else {
5332
+ route += "(?:" + prefix + "(" + token.pattern + ")" + suffix + ")" + token.modifier;
5333
+ }
5334
+ }
5335
+ else {
5336
+ route += "(" + token.pattern + ")" + token.modifier;
5337
+ }
5338
+ }
5339
+ else {
5340
+ route += "(?:" + prefix + suffix + ")" + token.modifier;
5341
+ }
5342
+ }
5343
+ }
5344
+ if (end) {
5345
+ if (!strict)
5346
+ route += delimiter + "?";
5347
+ route += !options.endsWith ? "$" : "(?=" + endsWith + ")";
5348
+ }
5349
+ else {
5350
+ var endToken = tokens[tokens.length - 1];
5351
+ var isEndDelimited = typeof endToken === "string"
5352
+ ? delimiter.indexOf(endToken[endToken.length - 1]) > -1
5353
+ : // tslint:disable-next-line
5354
+ endToken === undefined;
5355
+ if (!strict) {
5356
+ route += "(?:" + delimiter + "(?=" + endsWith + "))?";
5357
+ }
5358
+ if (!isEndDelimited) {
5359
+ route += "(?=" + delimiter + "|" + endsWith + ")";
5360
+ }
5361
+ }
5362
+ return new RegExp(route, flags(options));
5363
+ }
5364
+ /**
5365
+ * Normalize the given path string, returning a regular expression.
5366
+ *
5367
+ * An empty array can be passed in for the keys, which will hold the
5368
+ * placeholder key descriptions. For example, using `/user/:id`, `keys` will
5369
+ * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
5370
+ */
5371
+ function pathToRegexp(path, keys, options) {
5372
+ if (path instanceof RegExp)
5373
+ return regexpToRegexp(path, keys);
5374
+ if (Array.isArray(path))
5375
+ return arrayToRegexp(path, keys, options);
5376
+ return stringToRegexp(path, keys, options);
5447
5377
  }
5448
- getCleanUrl_2 = getCleanUrl$1.getCleanUrl = getCleanUrl;
5449
5378
 
5450
5379
  const REDUNDANT_CHARACTERS_EXP = /[\?|#].*$/g;
5451
5380
  function getSearchParams(path) {
@@ -5467,9 +5396,12 @@ function getAbsoluteUrl(path, baseUrl) {
5467
5396
  return path;
5468
5397
  }
5469
5398
  // Resolve a relative request URL against a given custom "baseUrl"
5470
- // or the current location (in the case of browser/browser-like environments).
5471
- const origin = baseUrl || (typeof location !== 'undefined' && location.origin);
5472
- return origin ? new URL(path, origin).href : path;
5399
+ // or the document baseURI (in the case of browser/browser-like environments).
5400
+ const origin = baseUrl || (typeof document !== 'undefined' && document.baseURI);
5401
+ return origin
5402
+ ? // Encode and decode the path to preserve escaped characters.
5403
+ decodeURI(new URL(encodeURI(path), origin).href)
5404
+ : path;
5473
5405
  }
5474
5406
 
5475
5407
  /**
@@ -5488,12 +5420,48 @@ function normalizePath(path, baseUrl) {
5488
5420
  return cleanUrl(maybeAbsoluteUrl);
5489
5421
  }
5490
5422
 
5423
+ /**
5424
+ * Coerce a path supported by MSW into a path
5425
+ * supported by "path-to-regexp".
5426
+ */
5427
+ function coercePath(path) {
5428
+ return (path
5429
+ /**
5430
+ * Replace wildcards ("*") with unnamed capturing groups
5431
+ * because "path-to-regexp" doesn't support wildcards.
5432
+ * Ignore path parameter' modifiers (i.e. ":name*").
5433
+ */
5434
+ .replace(/([:a-zA-Z_-]*)(\*{1,2})+/g, (_, parameterName, wildcard) => {
5435
+ const expression = '(.*)';
5436
+ if (!parameterName) {
5437
+ return expression;
5438
+ }
5439
+ return parameterName.startsWith(':')
5440
+ ? `${parameterName}${wildcard}`
5441
+ : `${parameterName}${expression}`;
5442
+ })
5443
+ /**
5444
+ * Escape the protocol so that "path-to-regexp" could match
5445
+ * absolute URL.
5446
+ * @see https://github.com/pillarjs/path-to-regexp/issues/259
5447
+ */
5448
+ .replace(/^([^\/]+)(:)(?=\/\/)/g, '$1\\$2'));
5449
+ }
5491
5450
  /**
5492
5451
  * Returns the result of matching given request URL against a mask.
5493
5452
  */
5494
5453
  function matchRequestUrl(url, path, baseUrl) {
5495
5454
  const normalizedPath = normalizePath(path, baseUrl);
5496
- return match(normalizedPath, getCleanUrl_2(url));
5455
+ const cleanPath = typeof normalizedPath === 'string'
5456
+ ? coercePath(normalizedPath)
5457
+ : normalizedPath;
5458
+ const cleanUrl = getCleanUrl.getCleanUrl(url);
5459
+ const result = match(cleanPath, { decode: decodeURIComponent })(cleanUrl);
5460
+ const params = (result && result.params) || {};
5461
+ return {
5462
+ matches: result !== false,
5463
+ params,
5464
+ };
5497
5465
  }
5498
5466
 
5499
5467
  /**
@@ -5528,7 +5496,7 @@ const defaultResponseTransformers = [];
5528
5496
  function createResponseComposition(responseOverrides, defaultTransformers = defaultResponseTransformers) {
5529
5497
  return (...transformers) => __awaiter(this, void 0, void 0, function* () {
5530
5498
  const initialResponse = Object.assign({}, defaultResponse, {
5531
- headers: new lib$2.Headers({
5499
+ headers: new lib$1.Headers({
5532
5500
  'x-powered-by': 'msw',
5533
5501
  }),
5534
5502
  }, responseOverrides);
@@ -5549,18 +5517,21 @@ const response = Object.assign(createResponseComposition(), {
5549
5517
  },
5550
5518
  });
5551
5519
 
5520
+ const BUILD_FRAME = /(node_modules)?[\/\\]lib[\/\\](umd|esm|iief|cjs)[\/\\]|^[^\/\\]*$/;
5552
5521
  /**
5553
5522
  * Return the stack trace frame of a function's invocation.
5554
5523
  */
5555
- function getCallFrame() {
5524
+ function getCallFrame(error) {
5556
5525
  // In <IE11, new Error may return an undefined stack
5557
- const stack = (new Error().stack || '');
5558
- const frames = stack.split('\n');
5526
+ const stack = error.stack;
5527
+ if (!stack) {
5528
+ return;
5529
+ }
5530
+ const frames = stack.split('\n').slice(1);
5559
5531
  // Get the first frame that doesn't reference the library's internal trace.
5560
5532
  // Assume that frame is the invocation frame.
5561
- const ignoreFrameRegExp = /(node_modules)?[\/\\]lib[\/\\](umd|esm|iief|cjs)[\/\\]|^[^\/\\]*$/;
5562
- const declarationFrame = frames.slice(1).find((frame) => {
5563
- return !ignoreFrameRegExp.test(frame);
5533
+ const declarationFrame = frames.find((frame) => {
5534
+ return !BUILD_FRAME.test(frame);
5564
5535
  });
5565
5536
  if (!declarationFrame) {
5566
5537
  return;
@@ -5593,7 +5564,7 @@ class RequestHandler {
5593
5564
  this.shouldSkip = false;
5594
5565
  this.ctx = options.ctx || defaultContext;
5595
5566
  this.resolver = options.resolver;
5596
- const callFrame = getCallFrame();
5567
+ const callFrame = getCallFrame(new Error());
5597
5568
  this.info = Object.assign(Object.assign({}, options.info), { callFrame });
5598
5569
  }
5599
5570
  /**
@@ -5720,21 +5691,9 @@ class RestHandler extends RequestHandler {
5720
5691
  return;
5721
5692
  }
5722
5693
  const searchParams = getSearchParams(path);
5723
- const queryParams = [];
5724
5694
  searchParams.forEach((_, paramName) => {
5725
- queryParams.push(paramName);
5726
5695
  });
5727
- devUtils.warn(`\
5728
- Found a redundant usage of query parameters in the request handler URL for "${method} ${path}". Please match against a path instead, and access query parameters in the response resolver function:
5729
-
5730
- rest.${method.toLowerCase()}("${url}", (req, res, ctx) => {
5731
- const query = req.url.searchParams
5732
- ${queryParams
5733
- .map((paramName) => `\
5734
- const ${paramName} = query.get("${paramName}")`)
5735
- .join('\n')}
5736
- })\
5737
- `);
5696
+ devUtils.warn(`Found a redundant usage of query parameters in the request handler URL for "${method} ${path}". Please match against a path instead and access query parameters in the response resolver function using "req.url.searchParams".`);
5738
5697
  }
5739
5698
  parse(request, resolutionContext) {
5740
5699
  return matchRequestUrl(request.url, this.info.path, resolutionContext === null || resolutionContext === void 0 ? void 0 : resolutionContext.baseUrl);
@@ -5743,7 +5702,10 @@ ${queryParams
5743
5702
  return Object.assign(Object.assign({}, request), { params: parsedResult.params || {} });
5744
5703
  }
5745
5704
  predicate(request, parsedResult) {
5746
- return (isStringEqual(this.info.method, request.method) && parsedResult.matches);
5705
+ const matchesMethod = this.info.method instanceof RegExp
5706
+ ? this.info.method.test(request.method)
5707
+ : isStringEqual(this.info.method, request.method);
5708
+ return matchesMethod && parsedResult.matches;
5747
5709
  }
5748
5710
  log(request, response) {
5749
5711
  const publicUrl = getPublicUrlFromRequest(request);
@@ -5777,6 +5739,7 @@ const graphqlContext = {
5777
5739
  delay,
5778
5740
  fetch,
5779
5741
  data,
5742
+ extensions,
5780
5743
  errors,
5781
5744
  cookie,
5782
5745
  };
@@ -5823,10 +5786,10 @@ class GraphQLHandler extends RequestHandler {
5823
5786
  if (!parsedResult) {
5824
5787
  return false;
5825
5788
  }
5826
- if (!parsedResult.operationName) {
5789
+ if (!parsedResult.operationName && this.info.operationType !== 'all') {
5827
5790
  const publicUrl = getPublicUrlFromRequest(request);
5828
5791
  devUtils.warn(`\
5829
- Failed to intercept a GraphQL request at "${request.method} ${publicUrl}": unnamed GraphQL operations are not supported.
5792
+ Failed to intercept a GraphQL request at "${request.method} ${publicUrl}": anonymous GraphQL operations are not supported.
5830
5793
 
5831
5794
  Consider naming this operation or using "graphql.operation" request handler to intercept GraphQL requests regardless of their operation name/type. Read more: https://mswjs.io/docs/api/graphql/operation\
5832
5795
  `);
@@ -5836,7 +5799,7 @@ Consider naming this operation or using "graphql.operation" request handler to i
5836
5799
  const hasMatchingOperationType = this.info.operationType === 'all' ||
5837
5800
  parsedResult.operationType === this.info.operationType;
5838
5801
  const hasMatchingOperationName = this.info.operationName instanceof RegExp
5839
- ? this.info.operationName.test(parsedResult.operationName)
5802
+ ? this.info.operationName.test(parsedResult.operationName || '')
5840
5803
  : parsedResult.operationName === this.info.operationName;
5841
5804
  return (hasMatchingUrl.matches &&
5842
5805
  hasMatchingOperationType &&
@@ -5846,7 +5809,10 @@ Consider naming this operation or using "graphql.operation" request handler to i
5846
5809
  const loggedRequest = prepareRequest(request);
5847
5810
  const loggedResponse = prepareResponse(response);
5848
5811
  const statusColor = getStatusCodeColor(response.status);
5849
- console.groupCollapsed(devUtils.formatMessage('%s %s (%c%s%c)'), getTimestamp(), `${parsedRequest === null || parsedRequest === void 0 ? void 0 : parsedRequest.operationType} ${parsedRequest === null || parsedRequest === void 0 ? void 0 : parsedRequest.operationName}`, `color:${statusColor}`, `${response.status} ${response.statusText}`, 'color:inherit');
5812
+ const requestInfo = (parsedRequest === null || parsedRequest === void 0 ? void 0 : parsedRequest.operationName)
5813
+ ? `${parsedRequest === null || parsedRequest === void 0 ? void 0 : parsedRequest.operationType} ${parsedRequest === null || parsedRequest === void 0 ? void 0 : parsedRequest.operationName}`
5814
+ : `anonymous ${parsedRequest === null || parsedRequest === void 0 ? void 0 : parsedRequest.operationType}`;
5815
+ console.groupCollapsed(devUtils.formatMessage('%s %s (%c%s%c)'), getTimestamp(), `${requestInfo}`, `color:${statusColor}`, `${response.status} ${response.statusText}`, 'color:inherit');
5850
5816
  console.log('Request:', loggedRequest);
5851
5817
  console.log('Handler:', this);
5852
5818
  console.log('Response:', loggedResponse);
@@ -5871,10 +5837,10 @@ function groupHandlersByType(handlers) {
5871
5837
  graphql: [],
5872
5838
  });
5873
5839
  }
5874
- function getScoreForRestHandler() {
5840
+ function getRestHandlerScore() {
5875
5841
  return (request, handler) => {
5876
5842
  const { path, method } = handler.info;
5877
- if (path instanceof RegExp) {
5843
+ if (path instanceof RegExp || method instanceof RegExp) {
5878
5844
  return Infinity;
5879
5845
  }
5880
5846
  const hasSameMethod = isStringEqual(request.method, method);
@@ -5885,12 +5851,15 @@ function getScoreForRestHandler() {
5885
5851
  return score - methodScoreDelta;
5886
5852
  };
5887
5853
  }
5888
- function getScoreForGraphQLHandler(parsedQuery) {
5854
+ function getGraphQLHandlerScore(parsedQuery) {
5889
5855
  return (_, handler) => {
5890
5856
  if (typeof parsedQuery.operationName === 'undefined') {
5891
5857
  return Infinity;
5892
5858
  }
5893
5859
  const { operationType, operationName } = handler.info;
5860
+ if (typeof operationName !== 'string') {
5861
+ return Infinity;
5862
+ }
5894
5863
  const hasSameOperationType = parsedQuery.operationType === operationType;
5895
5864
  // Always treat a handler with the same operation type as a more similar one.
5896
5865
  const operationTypeScoreDelta = hasSameOperationType ? TYPE_MATCH_DELTA : 0;
@@ -5900,16 +5869,12 @@ function getScoreForGraphQLHandler(parsedQuery) {
5900
5869
  }
5901
5870
  function getSuggestedHandler(request, handlers, getScore) {
5902
5871
  const suggestedHandlers = handlers
5903
- .reduce((acc, handler) => {
5872
+ .reduce((suggestions, handler) => {
5904
5873
  const score = getScore(request, handler);
5905
- return acc.concat([[score, handler]]);
5874
+ return suggestions.concat([[score, handler]]);
5906
5875
  }, [])
5907
- .sort(([leftScore], [rightScore]) => {
5908
- return leftScore - rightScore;
5909
- })
5910
- .filter(([score]) => {
5911
- return score <= MAX_MATCH_SCORE;
5912
- })
5876
+ .sort(([leftScore], [rightScore]) => leftScore - rightScore)
5877
+ .filter(([score]) => score <= MAX_MATCH_SCORE)
5913
5878
  .slice(0, MAX_SUGGESTION_COUNT)
5914
5879
  .map(([, handler]) => handler);
5915
5880
  return suggestedHandlers;
@@ -5939,8 +5904,8 @@ function onUnhandledRequest(request, handlers, strategy = 'warn') {
5939
5904
  ? handlerGroups.graphql
5940
5905
  : handlerGroups.rest;
5941
5906
  const suggestedHandlers = getSuggestedHandler(request, relevantHandlers, parsedGraphQLQuery
5942
- ? getScoreForGraphQLHandler(parsedGraphQLQuery)
5943
- : getScoreForRestHandler());
5907
+ ? getGraphQLHandlerScore(parsedGraphQLQuery)
5908
+ : getRestHandlerScore());
5944
5909
  const handlerSuggestion = suggestedHandlers.length > 0
5945
5910
  ? getSuggestedHandlersMessage(suggestedHandlers)
5946
5911
  : '';
@@ -5960,8 +5925,10 @@ Read more: https://mswjs.io/docs/getting-started/mocks\
5960
5925
  const message = messageTemplate.join('\n\n');
5961
5926
  switch (strategy) {
5962
5927
  case 'error': {
5928
+ // Print a developer-friendly error.
5963
5929
  devUtils.error('Error: %s', message);
5964
- break;
5930
+ // Throw an exception to halt request processing and not perform the original request.
5931
+ throw new Error(devUtils.formatMessage('Cannot bypass a request when using the "error" strategy for the "onUnhandledRequest" option.'));
5965
5932
  }
5966
5933
  case 'warn': {
5967
5934
  devUtils.warn('Warning: %s', message);
@@ -5975,8 +5942,8 @@ Read more: https://mswjs.io/docs/getting-started/mocks\
5975
5942
  }
5976
5943
 
5977
5944
  function readResponseCookies(request, response) {
5978
- lib$1.store.add(Object.assign(Object.assign({}, request), { url: request.url.toString() }), response);
5979
- lib$1.store.persist();
5945
+ cookies.store.add(Object.assign(Object.assign({}, request), { url: request.url.toString() }), response);
5946
+ cookies.store.persist();
5980
5947
  }
5981
5948
 
5982
5949
  function handleRequest(request, handlers, options, emitter, handleRequestOptions) {
@@ -6004,7 +5971,12 @@ function handleRequest(request, handlers, options, emitter, handleRequestOptions
6004
5971
  // When the handled request returned no mocked response, warn the developer,
6005
5972
  // as it may be an oversight on their part. Perform the request as-is.
6006
5973
  if (!response) {
6007
- devUtils.warn('Expected a mocking resolver function to return a mocked response Object, but got: %s. Original response is going to be used instead.', response);
5974
+ devUtils.warn(`\
5975
+ Expected response resolver to return a mocked response Object, but got %s. The original response is going to be used instead.\
5976
+ \n
5977
+ \u2022 %s
5978
+ %s\
5979
+ `, response, handler.info.header, handler.info.callFrame);
6008
5980
  emitter.emit('request:end', request);
6009
5981
  (_c = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onBypassResponse) === null || _c === void 0 ? void 0 : _c.call(handleRequestOptions, request);
6010
5982
  return;
@@ -6028,6 +6000,23 @@ function handleRequest(request, handlers, options, emitter, handleRequestOptions
6028
6000
  });
6029
6001
  }
6030
6002
 
6003
+ /**
6004
+ * Pipes all emitted events from one emitter to another.
6005
+ */
6006
+ function pipeEvents(source, destination) {
6007
+ const rawEmit = source.emit;
6008
+ // @ts-ignore
6009
+ if (rawEmit._isPiped) {
6010
+ return;
6011
+ }
6012
+ source.emit = function (event, ...data) {
6013
+ destination.emit(event, ...data);
6014
+ return rawEmit.call(this, event, ...data);
6015
+ };
6016
+ // @ts-ignore
6017
+ source.emit._isPiped = true;
6018
+ }
6019
+
6031
6020
  const DEFAULT_LISTEN_OPTIONS = {
6032
6021
  onUnhandledRequest: 'warn',
6033
6022
  };
@@ -6036,7 +6025,9 @@ const DEFAULT_LISTEN_OPTIONS = {
6036
6025
  * Useful to generate identical API using different patches to request issuing modules.
6037
6026
  */
6038
6027
  function createSetupServer(...interceptors$1) {
6039
- const emitter = new lib$3.StrictEventEmitter();
6028
+ const emitter = new lib$2.StrictEventEmitter();
6029
+ const publicEmitter = new lib$2.StrictEventEmitter();
6030
+ pipeEvents(emitter, publicEmitter);
6040
6031
  return function setupServer(...requestHandlers) {
6041
6032
  requestHandlers.forEach((handler) => {
6042
6033
  if (Array.isArray(handler))
@@ -6046,7 +6037,7 @@ function createSetupServer(...interceptors$1) {
6046
6037
  // so it could be modified at a runtime.
6047
6038
  let currentHandlers = [...requestHandlers];
6048
6039
  // Error when attempting to run this function in a browser environment.
6049
- if (!lib$4.exports.isNodeProcess()) {
6040
+ if (!lib$3.exports.isNodeProcess()) {
6050
6041
  throw new Error(devUtils.formatMessage('Failed to execute `setupServer` in the environment that is not Node.js (i.e. a browser). Consider using `setupWorker` instead.'));
6051
6042
  }
6052
6043
  let resolvedOptions = {};
@@ -6106,11 +6097,20 @@ ${chalk.bold(`${pragma} ${header}`)}
6106
6097
  `);
6107
6098
  });
6108
6099
  },
6109
- on(eventType, listener) {
6110
- emitter.addListener(eventType, listener);
6100
+ events: {
6101
+ on(...args) {
6102
+ return publicEmitter.on(...args);
6103
+ },
6104
+ removeListener(...args) {
6105
+ return publicEmitter.removeListener(...args);
6106
+ },
6107
+ removeAllListeners(...args) {
6108
+ return publicEmitter.removeAllListeners(...args);
6109
+ },
6111
6110
  },
6112
6111
  close() {
6113
6112
  emitter.removeAllListeners();
6113
+ publicEmitter.removeAllListeners();
6114
6114
  interceptor.restore();
6115
6115
  },
6116
6116
  };