@mswjs/interceptors 0.15.1 → 0.15.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 (90) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +68 -49
  3. package/lib/BatchInterceptor.d.ts +18 -0
  4. package/lib/BatchInterceptor.js +79 -0
  5. package/lib/BatchInterceptor.js.map +1 -0
  6. package/lib/Interceptor.d.ts +49 -0
  7. package/lib/Interceptor.js +197 -0
  8. package/lib/Interceptor.js.map +1 -0
  9. package/lib/RemoteInterceptor.d.ts +24 -0
  10. package/lib/RemoteInterceptor.js +216 -0
  11. package/lib/RemoteInterceptor.js.map +1 -0
  12. package/lib/glossary.d.ts +32 -0
  13. package/lib/glossary.js +3 -0
  14. package/lib/glossary.js.map +1 -0
  15. package/lib/index.d.ts +2 -2
  16. package/lib/index.js +2 -2
  17. package/lib/index.js.map +1 -1
  18. package/lib/interceptors/ClientRequest/NodeClientRequest.d.ts +5 -5
  19. package/lib/interceptors/ClientRequest/NodeClientRequest.js +56 -15
  20. package/lib/interceptors/ClientRequest/NodeClientRequest.js.map +1 -1
  21. package/lib/interceptors/ClientRequest/http.get.d.ts +2 -3
  22. package/lib/interceptors/ClientRequest/http.get.js +2 -5
  23. package/lib/interceptors/ClientRequest/http.get.js.map +1 -1
  24. package/lib/interceptors/ClientRequest/http.request.d.ts +2 -3
  25. package/lib/interceptors/ClientRequest/http.request.js +3 -6
  26. package/lib/interceptors/ClientRequest/http.request.js.map +1 -1
  27. package/lib/interceptors/ClientRequest/index.d.ts +14 -4
  28. package/lib/interceptors/ClientRequest/index.js +59 -46
  29. package/lib/interceptors/ClientRequest/index.js.map +1 -1
  30. package/lib/interceptors/ClientRequest/utils/getIncomingMessageBody.js +7 -2
  31. package/lib/interceptors/ClientRequest/utils/getIncomingMessageBody.js.map +1 -1
  32. package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.d.ts +11 -4
  33. package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.js +110 -58
  34. package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.js.map +1 -1
  35. package/lib/interceptors/XMLHttpRequest/index.d.ts +11 -5
  36. package/lib/interceptors/XMLHttpRequest/index.js +43 -25
  37. package/lib/interceptors/XMLHttpRequest/index.js.map +1 -1
  38. package/lib/interceptors/fetch/index.d.ts +8 -2
  39. package/lib/interceptors/fetch/index.js +120 -68
  40. package/lib/interceptors/fetch/index.js.map +1 -1
  41. package/lib/presets/browser.d.ts +3 -1
  42. package/lib/presets/browser.js +2 -2
  43. package/lib/presets/browser.js.map +1 -1
  44. package/lib/presets/node.d.ts +3 -1
  45. package/lib/presets/node.js +1 -1
  46. package/lib/presets/node.js.map +1 -1
  47. package/lib/utils/AsyncEventEmitter.d.ts +29 -0
  48. package/lib/utils/AsyncEventEmitter.js +241 -0
  49. package/lib/utils/AsyncEventEmitter.js.map +1 -0
  50. package/lib/utils/createLazyCallback.d.ts +11 -0
  51. package/lib/utils/createLazyCallback.js +75 -0
  52. package/lib/utils/createLazyCallback.js.map +1 -0
  53. package/lib/utils/nextTick.d.ts +2 -0
  54. package/lib/utils/nextTick.js +16 -0
  55. package/lib/utils/nextTick.js.map +1 -0
  56. package/lib/utils/toIsoResponse.d.ts +1 -1
  57. package/package.json +6 -6
  58. package/src/BatchInterceptor.test.ts +113 -0
  59. package/src/BatchInterceptor.ts +60 -0
  60. package/src/Interceptor.test.ts +166 -0
  61. package/src/Interceptor.ts +226 -0
  62. package/src/RemoteInterceptor.ts +176 -0
  63. package/src/glossary.ts +42 -0
  64. package/src/index.ts +2 -2
  65. package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +87 -70
  66. package/src/interceptors/ClientRequest/NodeClientRequest.ts +139 -100
  67. package/src/interceptors/ClientRequest/http.get.ts +7 -11
  68. package/src/interceptors/ClientRequest/http.request.ts +8 -12
  69. package/src/interceptors/ClientRequest/index.test.ts +43 -0
  70. package/src/interceptors/ClientRequest/index.ts +46 -46
  71. package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.test.ts +9 -0
  72. package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts +9 -2
  73. package/src/interceptors/XMLHttpRequest/XMLHttpRequestOverride.ts +215 -159
  74. package/src/interceptors/XMLHttpRequest/index.ts +41 -23
  75. package/src/interceptors/fetch/index.ts +81 -55
  76. package/src/presets/browser.ts +3 -3
  77. package/src/presets/node.ts +3 -3
  78. package/src/utils/AsyncEventEmitter.test.ts +68 -0
  79. package/src/utils/AsyncEventEmitter.ts +171 -0
  80. package/src/utils/createLazyCallback.ts +49 -0
  81. package/src/utils/nextTick.ts +11 -0
  82. package/src/utils/toIsoResponse.ts +1 -1
  83. package/lib/createInterceptor.d.ts +0 -54
  84. package/lib/createInterceptor.js +0 -27
  85. package/lib/createInterceptor.js.map +0 -1
  86. package/lib/remote.d.ts +0 -21
  87. package/lib/remote.js +0 -178
  88. package/lib/remote.js.map +0 -1
  89. package/src/createInterceptor.ts +0 -100
  90. package/src/remote.ts +0 -174
@@ -1,4 +1,19 @@
1
1
  "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
2
17
  var __values = (this && this.__values) || function(o) {
3
18
  var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
4
19
  if (m) return m.call(o);
@@ -30,68 +45,66 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
30
45
  return (mod && mod.__esModule) ? mod : { "default": mod };
31
46
  };
32
47
  Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.interceptClientRequest = void 0;
34
- var debug_1 = require("debug");
48
+ exports.ClientRequestInterceptor = void 0;
35
49
  var http_1 = __importDefault(require("http"));
36
50
  var https_1 = __importDefault(require("https"));
51
+ var Interceptor_1 = require("../../Interceptor");
37
52
  var http_get_1 = require("./http.get");
38
53
  var http_request_1 = require("./http.request");
39
- var log = debug_1.debug('http override');
40
54
  /**
41
- * Intercepts requests issued by native "http" and "https" modules.
55
+ * Intercept requests made via the `ClientRequest` class.
56
+ * Such requests include `http.get`, `https.request`, etc.
42
57
  */
43
- var interceptClientRequest = function (observer, resolver) {
44
- var e_1, _a;
45
- var pureModules = new Map();
46
- var modules = [
47
- ['http', http_1.default],
48
- ['https', https_1.default],
49
- ];
50
- try {
51
- for (var modules_1 = __values(modules), modules_1_1 = modules_1.next(); !modules_1_1.done; modules_1_1 = modules_1.next()) {
52
- var _b = __read(modules_1_1.value, 2), protocol = _b[0], requestModule = _b[1];
53
- log('patching the "%s" module...', protocol);
54
- pureModules.set(protocol, {
55
- module: requestModule,
56
- request: requestModule.request,
57
- get: requestModule.get,
58
+ var ClientRequestInterceptor = /** @class */ (function (_super) {
59
+ __extends(ClientRequestInterceptor, _super);
60
+ function ClientRequestInterceptor() {
61
+ var _this = _super.call(this, ClientRequestInterceptor.symbol) || this;
62
+ _this.modules = new Map();
63
+ _this.modules.set('http', http_1.default);
64
+ _this.modules.set('https', https_1.default);
65
+ return _this;
66
+ }
67
+ ClientRequestInterceptor.prototype.setup = function () {
68
+ var e_1, _a;
69
+ var log = this.log.extend('setup');
70
+ var _loop_1 = function (protocol, requestModule) {
71
+ var pureRequest = requestModule.request, pureGet = requestModule.get;
72
+ this_1.subscriptions.push(function () {
73
+ requestModule.request = pureRequest;
74
+ requestModule.get = pureGet;
75
+ log('native "%s" module restored!', protocol);
58
76
  });
59
- // @ts-ignore Call signature overloads are incompatible.
77
+ var options = {
78
+ emitter: this_1.emitter,
79
+ log: this_1.log,
80
+ };
81
+ // @ts-ignore
60
82
  requestModule.request =
61
- // Force a line-break to prevent ignoring the "request" call.
62
- http_request_1.request(protocol, resolver, observer);
63
- // @ts-ignore Call signature overloads are incompatible.
83
+ // Force a line break.
84
+ http_request_1.request(protocol, options);
85
+ // @ts-ignore
64
86
  requestModule.get =
65
- // Force a line-break to prevent ignoring the "get" call.
66
- http_get_1.get(protocol, resolver, observer);
67
- }
68
- }
69
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
70
- finally {
87
+ // Force a line break.
88
+ http_get_1.get(protocol, options);
89
+ log('native "%s" module patched!', protocol);
90
+ };
91
+ var this_1 = this;
71
92
  try {
72
- if (modules_1_1 && !modules_1_1.done && (_a = modules_1.return)) _a.call(modules_1);
73
- }
74
- finally { if (e_1) throw e_1.error; }
75
- }
76
- return function () {
77
- var e_2, _a;
78
- log('done, restoring modules...');
79
- try {
80
- for (var _b = __values(pureModules.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
81
- var requestModule = _c.value;
82
- requestModule.module.get = requestModule.get;
83
- requestModule.module.request = requestModule.request;
93
+ for (var _b = __values(this.modules), _c = _b.next(); !_c.done; _c = _b.next()) {
94
+ var _d = __read(_c.value, 2), protocol = _d[0], requestModule = _d[1];
95
+ _loop_1(protocol, requestModule);
84
96
  }
85
97
  }
86
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
98
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
87
99
  finally {
88
100
  try {
89
101
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
90
102
  }
91
- finally { if (e_2) throw e_2.error; }
103
+ finally { if (e_1) throw e_1.error; }
92
104
  }
93
- pureModules.clear();
94
105
  };
95
- };
96
- exports.interceptClientRequest = interceptClientRequest;
106
+ ClientRequestInterceptor.symbol = Symbol('http');
107
+ return ClientRequestInterceptor;
108
+ }(Interceptor_1.Interceptor));
109
+ exports.ClientRequestInterceptor = ClientRequestInterceptor;
97
110
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interceptors/ClientRequest/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAA6B;AAC7B,8CAAuB;AACvB,gDAAyB;AAEzB,uCAAgC;AAEhC,+CAAwC;AAExC,IAAM,GAAG,GAAG,aAAK,CAAC,eAAe,CAAC,CAAA;AAYlC;;GAEG;AACI,IAAM,sBAAsB,GAAgB,UAAC,QAAQ,EAAE,QAAQ;;IACpE,IAAM,WAAW,GAAgB,IAAI,GAAG,EAAE,CAAA;IAC1C,IAAM,OAAO,GAAgC;QAC3C,CAAC,MAAM,EAAE,cAAI,CAAC;QACd,CAAC,OAAO,EAAE,eAAK,CAAC;KACjB,CAAA;;QAED,KAAwC,IAAA,YAAA,SAAA,OAAO,CAAA,gCAAA,qDAAE;YAAtC,IAAA,KAAA,4BAAyB,EAAxB,QAAQ,QAAA,EAAE,aAAa,QAAA;YACjC,GAAG,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAA;YAE5C,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE;gBACxB,MAAM,EAAE,aAAa;gBACrB,OAAO,EAAE,aAAa,CAAC,OAAO;gBAC9B,GAAG,EAAE,aAAa,CAAC,GAAG;aACvB,CAAC,CAAA;YAEF,wDAAwD;YACxD,aAAa,CAAC,OAAO;gBACnB,6DAA6D;gBAC7D,sBAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;YAEvC,wDAAwD;YACxD,aAAa,CAAC,GAAG;gBACf,yDAAyD;gBACzD,cAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;SACpC;;;;;;;;;IAED,OAAO;;QACL,GAAG,CAAC,4BAA4B,CAAC,CAAA;;YAEjC,KAA4B,IAAA,KAAA,SAAA,WAAW,CAAC,MAAM,EAAE,CAAA,gBAAA,4BAAE;gBAA7C,IAAM,aAAa,WAAA;gBACtB,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAA;gBAC5C,aAAa,CAAC,MAAM,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,CAAA;aACrD;;;;;;;;;QAED,WAAW,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC,CAAA;AACH,CAAC,CAAA;AArCY,QAAA,sBAAsB,0BAqClC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interceptors/ClientRequest/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAAuB;AACvB,gDAAyB;AAEzB,iDAA+C;AAE/C,uCAAgC;AAChC,+CAAwC;AAOxC;;;GAGG;AACH;IAA8C,4CAAgC;IAI5E;QAAA,YACE,kBAAM,wBAAwB,CAAC,MAAM,CAAC,SAKvC;QAHC,KAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAA;QACxB,KAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAI,CAAC,CAAA;QAC9B,KAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAK,CAAC,CAAA;;IAClC,CAAC;IAES,wCAAK,GAAf;;QACE,IAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gCAExB,QAAQ,EAAE,aAAa;YACzB,IAAS,WAAW,GAAmB,aAAa,QAAhC,EAAO,OAAO,GAAK,aAAa,IAAlB,CAAkB;YAE5D,OAAK,aAAa,CAAC,IAAI,CAAC;gBACtB,aAAa,CAAC,OAAO,GAAG,WAAW,CAAA;gBACnC,aAAa,CAAC,GAAG,GAAG,OAAO,CAAA;gBAE3B,GAAG,CAAC,8BAA8B,EAAE,QAAQ,CAAC,CAAA;YAC/C,CAAC,CAAC,CAAA;YAEF,IAAM,OAAO,GAAsB;gBACjC,OAAO,EAAE,OAAK,OAAO;gBACrB,GAAG,EAAE,OAAK,GAAG;aACd,CAAA;YAED,aAAa;YACb,aAAa,CAAC,OAAO;gBACnB,sBAAsB;gBACtB,sBAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAE5B,aAAa;YACb,aAAa,CAAC,GAAG;gBACf,sBAAsB;gBACtB,cAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAExB,GAAG,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAA;;;;YAzB9C,KAAwC,IAAA,KAAA,SAAA,IAAI,CAAC,OAAO,CAAA,gBAAA;gBAAzC,IAAA,KAAA,mBAAyB,EAAxB,QAAQ,QAAA,EAAE,aAAa,QAAA;wBAAvB,QAAQ,EAAE,aAAa;aA0BlC;;;;;;;;;IACH,CAAC;IAzCM,+BAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IA0ChC,+BAAC;CAAA,AA3CD,CAA8C,yBAAW,GA2CxD;AA3CY,4DAAwB"}
@@ -38,9 +38,14 @@ function getIncomingMessageBody(response) {
38
38
  var encoding = response.readableEncoding || 'utf8';
39
39
  stream.setEncoding(encoding);
40
40
  log('using encoding:', encoding);
41
- stream.once('data', function (responseBody) {
41
+ var body = '';
42
+ stream.on('data', function (responseBody) {
42
43
  log('response body read:', responseBody);
43
- resolve(responseBody);
44
+ body += responseBody;
45
+ });
46
+ stream.once('end', function () {
47
+ log('response body end');
48
+ resolve(body);
44
49
  });
45
50
  stream.once('error', function (error) {
46
51
  log('error while reading response body:', error);
@@ -1 +1 @@
1
- {"version":3,"file":"getIncomingMessageBody.js","sourceRoot":"","sources":["../../../../src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,+BAA6B;AAE7B,iCAAoC;AACpC,yCAA4B;AAE5B,IAAM,GAAG,GAAG,aAAK,CAAC,6BAA6B,CAAC,CAAA;AAEhD,SAAgB,sBAAsB,CACpC,QAAyB;IAEzB,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO,EAAE,MAAM;QACjC,GAAG,CAAC,kCAAkC,CAAC,CAAA;QAEvC,kDAAkD;QAClD,mDAAmD;QACnD,yDAAyD;QACzD,gDAAgD;QAChD,IAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,oBAAW,EAAE,CAAC,CAAA;QACtD,IAAM,MAAM,GACV,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,MAAM;YAC7C,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACzC,CAAC,CAAC,aAAa,CAAA;QAEnB,IAAM,QAAQ,GAAG,QAAQ,CAAC,gBAAgB,IAAI,MAAM,CAAA;QACpD,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;QAC5B,GAAG,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAA;QAEhC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,UAAC,YAAY;YAC/B,GAAG,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAA;YACxC,OAAO,CAAC,YAAY,CAAC,CAAA;QACvB,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,UAAC,KAAK;YACzB,GAAG,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAA;YAChD,MAAM,CAAC,KAAK,CAAC,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AA9BD,wDA8BC"}
1
+ {"version":3,"file":"getIncomingMessageBody.js","sourceRoot":"","sources":["../../../../src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,+BAA6B;AAE7B,iCAAoC;AACpC,yCAA4B;AAE5B,IAAM,GAAG,GAAG,aAAK,CAAC,6BAA6B,CAAC,CAAA;AAEhD,SAAgB,sBAAsB,CACpC,QAAyB;IAEzB,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO,EAAE,MAAM;QACjC,GAAG,CAAC,kCAAkC,CAAC,CAAA;QAEvC,kDAAkD;QAClD,mDAAmD;QACnD,yDAAyD;QACzD,gDAAgD;QAChD,IAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,oBAAW,EAAE,CAAC,CAAA;QACtD,IAAM,MAAM,GACV,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,MAAM;YAC7C,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACzC,CAAC,CAAC,aAAa,CAAA;QAEnB,IAAM,QAAQ,GAAG,QAAQ,CAAC,gBAAgB,IAAI,MAAM,CAAA;QACpD,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;QAC5B,GAAG,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAA;QAEhC,IAAI,IAAI,GAAG,EAAE,CAAC;QAEd,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAC,YAAY;YAC7B,GAAG,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAA;YACxC,IAAI,IAAI,YAAY,CAAC;QACvB,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE;YACjB,GAAG,CAAC,mBAAmB,CAAC,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,UAAC,KAAK;YACzB,GAAG,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAA;YAChD,MAAM,CAAC,KAAK,CAAC,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AArCD,wDAqCC"}
@@ -1,23 +1,30 @@
1
+ /**
2
+ * XMLHttpRequest override class.
3
+ * Inspired by https://github.com/marvinhagemeister/xhr-mocklet.
4
+ */
5
+ import type { Debugger } from 'debug';
1
6
  import { Headers } from 'headers-polyfill';
2
- import { Observer, Resolver } from '../../createInterceptor';
7
+ import type { XMLHttpRequestEmitter } from '.';
3
8
  declare type XMLHttpRequestEventHandler = (this: XMLHttpRequest, event: Event | ProgressEvent<any>) => void;
4
9
  interface XMLHttpRequestEvent<EventMap extends any> {
5
10
  name: keyof EventMap;
6
11
  listener: XMLHttpRequestEventHandler;
7
12
  }
8
13
  interface CreateXMLHttpRequestOverrideOptions {
9
- pureXMLHttpRequest: typeof window.XMLHttpRequest;
10
- observer: Observer;
11
- resolver: Resolver;
14
+ XMLHttpRequest: typeof window.XMLHttpRequest;
15
+ emitter: XMLHttpRequestEmitter;
16
+ log: Debugger;
12
17
  }
13
18
  interface InternalXMLHttpRequestEventTargetEventMap extends XMLHttpRequestEventTargetEventMap {
14
19
  readystatechange: Event;
15
20
  }
21
+ export declare type ExtractCallbacks<Key extends string> = Key extends 'abort' | `on${infer _CallbackName}` ? Key : never;
16
22
  export declare const createXMLHttpRequestOverride: (options: CreateXMLHttpRequestOverrideOptions) => {
17
23
  new (): {
18
24
  _requestHeaders: Headers;
19
25
  _responseHeaders: Headers;
20
26
  _events: XMLHttpRequestEvent<InternalXMLHttpRequestEventTargetEventMap>[];
27
+ log: Debugger;
21
28
  readonly UNSENT: 0;
22
29
  readonly OPENED: 1;
23
30
  readonly HEADERS_RECEIVED: 2;
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -64,10 +75,6 @@ var __read = (this && this.__read) || function (o, n) {
64
75
  };
65
76
  Object.defineProperty(exports, "__esModule", { value: true });
66
77
  exports.createXMLHttpRequestOverride = void 0;
67
- /**
68
- * XMLHttpRequest override class.
69
- * Inspired by https://github.com/marvinhagemeister/xhr-mocklet.
70
- */
71
78
  var until_1 = require("@open-draft/until");
72
79
  var headers_polyfill_1 = require("headers-polyfill");
73
80
  var xmldom_1 = require("@xmldom/xmldom");
@@ -76,15 +83,15 @@ var toIsoResponse_1 = require("../../utils/toIsoResponse");
76
83
  var uuid_1 = require("../../utils/uuid");
77
84
  var bufferFrom_1 = require("./utils/bufferFrom");
78
85
  var createEvent_1 = require("./utils/createEvent");
79
- var createDebug = require('debug');
86
+ var createLazyCallback_1 = require("../../utils/createLazyCallback");
80
87
  var createXMLHttpRequestOverride = function (options) {
81
88
  var _a;
82
- var pureXMLHttpRequest = options.pureXMLHttpRequest, observer = options.observer, resolver = options.resolver;
83
- var debug = createDebug('XHR');
89
+ var XMLHttpRequest = options.XMLHttpRequest, emitter = options.emitter, log = options.log;
84
90
  return _a = /** @class */ (function () {
85
91
  function XMLHttpRequestOverride() {
86
92
  // Collection of events modified by `addEventListener`/`removeEventListener` calls.
87
93
  this._events = [];
94
+ this.log = log;
88
95
  this.UNSENT = 0;
89
96
  this.OPENED = 1;
90
97
  this.HEADERS_RECEIVED = 2;
@@ -120,10 +127,10 @@ var createXMLHttpRequestOverride = function (options) {
120
127
  if (nextState === this.readyState) {
121
128
  return;
122
129
  }
123
- debug('readyState change %d -> %d', this.readyState, nextState);
130
+ this.log('readyState change %d -> %d', this.readyState, nextState);
124
131
  this.readyState = nextState;
125
132
  if (nextState !== this.UNSENT) {
126
- debug('triggerring readystate change...');
133
+ this.log('triggerring readystate change...');
127
134
  this.trigger('readystatechange');
128
135
  }
129
136
  };
@@ -133,8 +140,8 @@ var createXMLHttpRequestOverride = function (options) {
133
140
  */
134
141
  XMLHttpRequestOverride.prototype.trigger = function (eventName, options) {
135
142
  var e_1, _a;
136
- debug('trigger "%s" (%d)', eventName, this.readyState);
137
- debug('resolve listener for event "%s"', eventName);
143
+ this.log('trigger "%s" (%d)', eventName, this.readyState);
144
+ this.log('resolve listener for event "%s"', eventName);
138
145
  // @ts-expect-error XMLHttpRequest class has no index signature.
139
146
  var callback = this["on" + eventName];
140
147
  callback === null || callback === void 0 ? void 0 : callback.call(this, createEvent_1.createEvent(this, eventName, options));
@@ -142,7 +149,7 @@ var createXMLHttpRequestOverride = function (options) {
142
149
  for (var _b = __values(this._events), _c = _b.next(); !_c.done; _c = _b.next()) {
143
150
  var event_1 = _c.value;
144
151
  if (event_1.name === eventName) {
145
- debug('calling mock event listener "%s" (%d)', eventName, this.readyState);
152
+ log('calling mock event listener "%s" (%d)', eventName, this.readyState);
146
153
  event_1.listener.call(this, createEvent_1.createEvent(this, eventName, options));
147
154
  }
148
155
  }
@@ -157,7 +164,7 @@ var createXMLHttpRequestOverride = function (options) {
157
164
  return this;
158
165
  };
159
166
  XMLHttpRequestOverride.prototype.reset = function () {
160
- debug('reset');
167
+ this.log('reset');
161
168
  this.setReadyState(this.UNSENT);
162
169
  this.status = 200;
163
170
  this.statusText = 'OK';
@@ -172,8 +179,8 @@ var createXMLHttpRequestOverride = function (options) {
172
179
  if (async === void 0) { async = true; }
173
180
  return __awaiter(this, void 0, void 0, function () {
174
181
  return __generator(this, function (_a) {
175
- debug = createDebug("XHR " + method + " " + url);
176
- debug('open', { method: method, url: url, async: async, user: user, password: password });
182
+ this.log = this.log.extend("request " + method + " " + url);
183
+ this.log('open', { method: method, url: url, async: async, user: user, password: password });
177
184
  this.reset();
178
185
  this.setReadyState(this.OPENED);
179
186
  if (typeof url === 'undefined') {
@@ -193,7 +200,7 @@ var createXMLHttpRequestOverride = function (options) {
193
200
  };
194
201
  XMLHttpRequestOverride.prototype.send = function (data) {
195
202
  var _this = this;
196
- debug('send %s %s', this.method, this.url);
203
+ this.log('send %s %s', this.method, this.url);
197
204
  this.data = data || '';
198
205
  var url;
199
206
  try {
@@ -205,9 +212,9 @@ var createXMLHttpRequestOverride = function (options) {
205
212
  // resolve the relative request URL against the current window location.
206
213
  url = new URL(this.url, window.location.href);
207
214
  }
208
- debug('request headers', this._requestHeaders);
215
+ this.log('request headers', this._requestHeaders);
209
216
  // Create an intercepted request instance exposed to the request intercepting middleware.
210
- var isoRequest = {
217
+ var isomorphicRequest = {
211
218
  id: uuid_1.uuidv4(),
212
219
  url: url,
213
220
  method: this.method,
@@ -215,17 +222,32 @@ var createXMLHttpRequestOverride = function (options) {
215
222
  credentials: this.withCredentials ? 'include' : 'omit',
216
223
  body: this.data,
217
224
  };
218
- observer.emit('request', isoRequest);
219
- debug('awaiting mocked response...');
220
- Promise.resolve(until_1.until(function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
221
- return [2 /*return*/, resolver(isoRequest, this)];
222
- }); }); })).then(function (_a) {
225
+ var interactiveIsomorphicRequest = __assign(__assign({}, isomorphicRequest), { respondWith: createLazyCallback_1.createLazyCallback() });
226
+ this.log('emitting the "request" event for %d listener(s)...', emitter.listenerCount('request'));
227
+ emitter.emit('request', interactiveIsomorphicRequest);
228
+ this.log('awaiting mocked response...');
229
+ Promise.resolve(until_1.until(function () { return __awaiter(_this, void 0, void 0, function () {
230
+ var _a, mockedResponse;
231
+ return __generator(this, function (_b) {
232
+ switch (_b.label) {
233
+ case 0: return [4 /*yield*/, emitter.untilIdle('request')];
234
+ case 1:
235
+ _b.sent();
236
+ this.log('all request listeners have been resolved!');
237
+ return [4 /*yield*/, interactiveIsomorphicRequest.respondWith.invoked()];
238
+ case 2:
239
+ _a = __read.apply(void 0, [_b.sent(), 1]), mockedResponse = _a[0];
240
+ this.log('event.respondWith called with:', mockedResponse);
241
+ return [2 /*return*/, mockedResponse];
242
+ }
243
+ });
244
+ }); })).then(function (_a) {
223
245
  var _b;
224
246
  var _c = __read(_a, 2), middlewareException = _c[0], mockedResponse = _c[1];
225
247
  // When the request middleware throws an exception, error the request.
226
248
  // This cancels the request and is similar to a network error.
227
249
  if (middlewareException) {
228
- debug('middleware function threw an exception!', middlewareException);
250
+ _this.log('middleware function threw an exception!', middlewareException);
229
251
  // No way to propagate the actual error message.
230
252
  _this.trigger('error');
231
253
  _this.abort();
@@ -233,7 +255,7 @@ var createXMLHttpRequestOverride = function (options) {
233
255
  }
234
256
  // Return a mocked response, if provided in the middleware.
235
257
  if (mockedResponse) {
236
- debug('received mocked response', mockedResponse);
258
+ _this.log('received mocked response', mockedResponse);
237
259
  // Trigger a loadstart event to indicate the initialization of the fetch.
238
260
  _this.trigger('loadstart');
239
261
  _this.status = mockedResponse.status || 200;
@@ -241,17 +263,17 @@ var createXMLHttpRequestOverride = function (options) {
241
263
  _this._responseHeaders = mockedResponse.headers
242
264
  ? headers_polyfill_1.objectToHeaders(mockedResponse.headers)
243
265
  : new headers_polyfill_1.Headers();
244
- debug('set response status', _this.status, _this.statusText);
245
- debug('set response headers', _this._responseHeaders);
266
+ _this.log('set response status', _this.status, _this.statusText);
267
+ _this.log('set response headers', _this._responseHeaders);
246
268
  // Mark that response headers has been received
247
269
  // and trigger a ready state event to reflect received headers
248
270
  // in a custom `onreadystatechange` callback.
249
271
  _this.setReadyState(_this.HEADERS_RECEIVED);
250
- debug('response type', _this.responseType);
272
+ _this.log('response type', _this.responseType);
251
273
  _this.response = _this.getResponseBody(mockedResponse.body);
252
274
  _this.responseText = mockedResponse.body || '';
253
275
  _this.responseXML = _this.getResponseXML();
254
- debug('set response body', _this.response);
276
+ _this.log('set response body', _this.response);
255
277
  if (mockedResponse.body && _this.response) {
256
278
  _this.setReadyState(_this.LOADING);
257
279
  // Presense of the mocked response implies a response body (not null).
@@ -272,18 +294,18 @@ var createXMLHttpRequestOverride = function (options) {
272
294
  _this.trigger('load');
273
295
  // Trigger a loadend event to indicate the fetch has completed.
274
296
  _this.trigger('loadend');
275
- observer.emit('response', isoRequest, toIsoResponse_1.toIsoResponse(mockedResponse));
297
+ emitter.emit('response', isomorphicRequest, toIsoResponse_1.toIsoResponse(mockedResponse));
276
298
  }
277
299
  else {
278
- debug('no mocked response received!');
300
+ _this.log('no mocked response received!');
279
301
  // Perform an original request, when the request middleware returned no mocked response.
280
- var originalRequest_1 = new pureXMLHttpRequest();
281
- debug('opening an original request %s %s', _this.method, _this.url);
302
+ var originalRequest_1 = new XMLHttpRequest();
303
+ _this.log('opening an original request %s %s', _this.method, _this.url);
282
304
  originalRequest_1.open(_this.method, _this.url, (_b = _this.async) !== null && _b !== void 0 ? _b : true, _this.user, _this.password);
283
305
  // Reflect a successful state of the original request
284
306
  // on the patched instance.
285
307
  originalRequest_1.addEventListener('load', function () {
286
- debug('original "onload"');
308
+ _this.log('original "onload"');
287
309
  _this.status = originalRequest_1.status;
288
310
  _this.statusText = originalRequest_1.statusText;
289
311
  _this.responseURL = originalRequest_1.responseURL;
@@ -291,7 +313,7 @@ var createXMLHttpRequestOverride = function (options) {
291
313
  _this.response = originalRequest_1.response;
292
314
  _this.responseText = originalRequest_1.responseText;
293
315
  _this.responseXML = originalRequest_1.responseXML;
294
- debug('set mock request readyState to DONE');
316
+ _this.log('set mock request readyState to DONE');
295
317
  // Explicitly mark the mocked request instance as done
296
318
  // so the response never hangs.
297
319
  /**
@@ -299,14 +321,14 @@ var createXMLHttpRequestOverride = function (options) {
299
321
  * in the case of unhandled request.
300
322
  */
301
323
  _this.setReadyState(_this.DONE);
302
- debug('received original response', _this.status, _this.statusText);
303
- debug('original response body:', _this.response);
324
+ _this.log('received original response', _this.status, _this.statusText);
325
+ _this.log('original response body:', _this.response);
304
326
  var responseHeaders = originalRequest_1.getAllResponseHeaders();
305
- debug('original response headers:\n', responseHeaders);
327
+ _this.log('original response headers:\n', responseHeaders);
306
328
  _this._responseHeaders = headers_polyfill_1.stringToHeaders(responseHeaders);
307
- debug('original response headers (normalized)', _this._responseHeaders);
308
- debug('original response finished');
309
- observer.emit('response', isoRequest, {
329
+ _this.log('original response headers (normalized)', _this._responseHeaders);
330
+ _this.log('original response finished');
331
+ emitter.emit('response', isomorphicRequest, {
310
332
  status: originalRequest_1.status,
311
333
  statusText: originalRequest_1.statusText,
312
334
  headers: _this._responseHeaders,
@@ -321,13 +343,13 @@ var createXMLHttpRequestOverride = function (options) {
321
343
  if (_this.async) {
322
344
  originalRequest_1.timeout = _this.timeout;
323
345
  }
324
- debug('send', _this.data);
346
+ _this.log('send', _this.data);
325
347
  originalRequest_1.send(_this.data);
326
348
  }
327
349
  });
328
350
  };
329
351
  XMLHttpRequestOverride.prototype.abort = function () {
330
- debug('abort');
352
+ this.log('abort');
331
353
  if (this.readyState > this.UNSENT && this.readyState < this.DONE) {
332
354
  this.setReadyState(this.UNSENT);
333
355
  this.trigger('abort');
@@ -337,36 +359,36 @@ var createXMLHttpRequestOverride = function (options) {
337
359
  return false;
338
360
  };
339
361
  XMLHttpRequestOverride.prototype.setRequestHeader = function (name, value) {
340
- debug('set request header "%s" to "%s"', name, value);
362
+ this.log('set request header "%s" to "%s"', name, value);
341
363
  this._requestHeaders.append(name, value);
342
364
  };
343
365
  XMLHttpRequestOverride.prototype.getResponseHeader = function (name) {
344
- debug('get response header "%s"', name);
366
+ this.log('get response header "%s"', name);
345
367
  if (this.readyState < this.HEADERS_RECEIVED) {
346
- debug('cannot return a header: headers not received (state: %s)', this.readyState);
368
+ this.log('cannot return a header: headers not received (state: %s)', this.readyState);
347
369
  return null;
348
370
  }
349
371
  var headerValue = this._responseHeaders.get(name);
350
- debug('resolved response header "%s" to "%s"', name, headerValue, this._responseHeaders);
372
+ this.log('resolved response header "%s" to "%s"', name, headerValue, this._responseHeaders);
351
373
  return headerValue;
352
374
  };
353
375
  XMLHttpRequestOverride.prototype.getAllResponseHeaders = function () {
354
- debug('get all response headers');
376
+ this.log('get all response headers');
355
377
  if (this.readyState < this.HEADERS_RECEIVED) {
356
- debug('cannot return headers: headers not received (state: %s)', this.readyState);
378
+ this.log('cannot return headers: headers not received (state: %s)', this.readyState);
357
379
  return '';
358
380
  }
359
381
  return headers_polyfill_1.headersToString(this._responseHeaders);
360
382
  };
361
383
  XMLHttpRequestOverride.prototype.addEventListener = function (name, listener) {
362
- debug('addEventListener', name, listener);
384
+ this.log('addEventListener', name, listener);
363
385
  this._events.push({
364
386
  name: name,
365
387
  listener: listener,
366
388
  });
367
389
  };
368
390
  XMLHttpRequestOverride.prototype.removeEventListener = function (name, listener) {
369
- debug('removeEventListener', name, listener);
391
+ this.log('removeEventListener', name, listener);
370
392
  this._events = this._events.filter(function (storedEvent) {
371
393
  return storedEvent.name !== name && storedEvent.listener !== listener;
372
394
  });
@@ -378,21 +400,21 @@ var createXMLHttpRequestOverride = function (options) {
378
400
  XMLHttpRequestOverride.prototype.getResponseBody = function (body) {
379
401
  // Handle an improperly set "null" value of the mocked response body.
380
402
  var textBody = body !== null && body !== void 0 ? body : '';
381
- debug('coerced response body to', textBody);
403
+ this.log('coerced response body to', textBody);
382
404
  switch (this.responseType) {
383
405
  case 'json': {
384
- debug('resolving response body as JSON');
406
+ this.log('resolving response body as JSON');
385
407
  return parseJson_1.parseJson(textBody);
386
408
  }
387
409
  case 'blob': {
388
410
  var blobType = this.getResponseHeader('content-type') || 'text/plain';
389
- debug('resolving response body as Blob', { type: blobType });
411
+ this.log('resolving response body as Blob', { type: blobType });
390
412
  return new Blob([textBody], {
391
413
  type: blobType,
392
414
  });
393
415
  }
394
416
  case 'arraybuffer': {
395
- debug('resolving response body as ArrayBuffer');
417
+ this.log('resolving response body as ArrayBuffer');
396
418
  var arrayBuffer = bufferFrom_1.bufferFrom(textBody);
397
419
  return arrayBuffer;
398
420
  }
@@ -412,6 +434,35 @@ var createXMLHttpRequestOverride = function (options) {
412
434
  * to the given XMLHttpRequest instance.
413
435
  */
414
436
  XMLHttpRequestOverride.prototype.propagateCallbacks = function (request) {
437
+ var e_2, _a;
438
+ this.log('propagating request callbacks to the original request');
439
+ var callbackNames = [
440
+ 'abort',
441
+ 'onerror',
442
+ 'ontimeout',
443
+ 'onload',
444
+ 'onloadstart',
445
+ 'onloadend',
446
+ 'onprogress',
447
+ 'onreadystatechange',
448
+ ];
449
+ try {
450
+ for (var callbackNames_1 = __values(callbackNames), callbackNames_1_1 = callbackNames_1.next(); !callbackNames_1_1.done; callbackNames_1_1 = callbackNames_1.next()) {
451
+ var callbackName = callbackNames_1_1.value;
452
+ var callback = this[callbackName];
453
+ if (callback) {
454
+ request[callbackName] = this[callbackName];
455
+ this.log('propagated the "%s" callback', callbackName, callback);
456
+ }
457
+ }
458
+ }
459
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
460
+ finally {
461
+ try {
462
+ if (callbackNames_1_1 && !callbackNames_1_1.done && (_a = callbackNames_1.return)) _a.call(callbackNames_1);
463
+ }
464
+ finally { if (e_2) throw e_2.error; }
465
+ }
415
466
  request.onabort = this.abort;
416
467
  request.onerror = this.onerror;
417
468
  request.ontimeout = this.ontimeout;
@@ -426,18 +477,19 @@ var createXMLHttpRequestOverride = function (options) {
426
477
  * to the given XMLHttpRequest instance.
427
478
  */
428
479
  XMLHttpRequestOverride.prototype.propagateListeners = function (request) {
429
- debug('propagating request listeners (%d) to the original request', this._events.length, this._events);
480
+ this.log('propagating request listeners (%d) to the original request', this._events.length, this._events);
430
481
  this._events.forEach(function (_a) {
431
482
  var name = _a.name, listener = _a.listener;
432
483
  request.addEventListener(name, listener);
433
484
  });
434
485
  };
435
486
  XMLHttpRequestOverride.prototype.propagateHeaders = function (request, headers) {
436
- debug('propagating request headers to the original request', headers);
487
+ var _this = this;
488
+ this.log('propagating request headers to the original request', headers);
437
489
  // Preserve the request headers casing.
438
490
  Object.entries(headers.raw()).forEach(function (_a) {
439
491
  var _b = __read(_a, 2), name = _b[0], value = _b[1];
440
- debug('setting "%s" (%s) header on the original request', name, value);
492
+ _this.log('setting "%s" (%s) header on the original request', name, value);
441
493
  request.setRequestHeader(name, value);
442
494
  });
443
495
  };