@mswjs/interceptors 0.32.1 → 0.33.0

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 (121) hide show
  1. package/README.md +35 -7
  2. package/lib/browser/{chunk-732REFPX.mjs → chunk-5ETVT6GU.mjs} +28 -79
  3. package/lib/browser/chunk-5ETVT6GU.mjs.map +1 -0
  4. package/lib/browser/chunk-6MBJUL74.js +142 -0
  5. package/lib/browser/chunk-6MBJUL74.js.map +1 -0
  6. package/lib/browser/chunk-7A4UJNSW.mjs +196 -0
  7. package/lib/browser/chunk-7A4UJNSW.mjs.map +1 -0
  8. package/lib/browser/{chunk-PSX5J3RF.js → chunk-7GVJEW45.js} +30 -81
  9. package/lib/browser/chunk-7GVJEW45.js.map +1 -0
  10. package/lib/browser/{chunk-2CRB3JAQ.js → chunk-FXSPMSSQ.js} +1 -1
  11. package/lib/browser/chunk-FXSPMSSQ.js.map +1 -0
  12. package/lib/browser/{chunk-OMISYKWR.mjs → chunk-GGUENBDN.mjs} +1 -1
  13. package/lib/browser/chunk-GGUENBDN.mjs.map +1 -0
  14. package/lib/browser/chunk-NU2MPFD6.mjs +142 -0
  15. package/lib/browser/chunk-NU2MPFD6.mjs.map +1 -0
  16. package/lib/browser/chunk-VRKVKT62.js +196 -0
  17. package/lib/browser/chunk-VRKVKT62.js.map +1 -0
  18. package/lib/browser/glossary-7d7adb4b.d.ts +66 -0
  19. package/lib/browser/index.d.ts +1 -1
  20. package/lib/browser/index.js +2 -2
  21. package/lib/browser/index.mjs +1 -1
  22. package/lib/browser/interceptors/XMLHttpRequest/index.d.ts +2 -6
  23. package/lib/browser/interceptors/XMLHttpRequest/index.js +4 -4
  24. package/lib/browser/interceptors/XMLHttpRequest/index.mjs +3 -3
  25. package/lib/browser/interceptors/fetch/index.d.ts +1 -1
  26. package/lib/browser/interceptors/fetch/index.js +4 -4
  27. package/lib/browser/interceptors/fetch/index.mjs +3 -3
  28. package/lib/browser/presets/browser.d.ts +1 -1
  29. package/lib/browser/presets/browser.js +6 -6
  30. package/lib/browser/presets/browser.mjs +4 -4
  31. package/lib/node/{BatchInterceptor-2badedde.d.ts → BatchInterceptor-13d40c95.d.ts} +1 -1
  32. package/lib/node/{Interceptor-88ee47c0.d.ts → Interceptor-a31b1217.d.ts} +35 -13
  33. package/lib/node/RemoteHttpInterceptor.d.ts +2 -2
  34. package/lib/node/RemoteHttpInterceptor.js +55 -52
  35. package/lib/node/RemoteHttpInterceptor.js.map +1 -1
  36. package/lib/node/RemoteHttpInterceptor.mjs +53 -50
  37. package/lib/node/RemoteHttpInterceptor.mjs.map +1 -1
  38. package/lib/node/{chunk-5JMJ55U7.js → chunk-2MWIWEWV.js} +144 -113
  39. package/lib/node/chunk-2MWIWEWV.js.map +1 -0
  40. package/lib/node/{chunk-2COJKQQB.js → chunk-42632LKH.js} +3 -3
  41. package/lib/node/chunk-5WWNCLB3.js +196 -0
  42. package/lib/node/chunk-5WWNCLB3.js.map +1 -0
  43. package/lib/node/{chunk-TGTPXCLF.mjs → chunk-BUCULLYM.mjs} +1 -1
  44. package/lib/node/{chunk-TGTPXCLF.mjs.map → chunk-BUCULLYM.mjs.map} +1 -1
  45. package/lib/node/{chunk-OJ6O4LSC.mjs → chunk-BZ3Y7YV5.mjs} +1 -1
  46. package/lib/node/chunk-BZ3Y7YV5.mjs.map +1 -0
  47. package/lib/node/{chunk-3OJLYEWA.mjs → chunk-CU3YXMM4.mjs} +138 -107
  48. package/lib/node/chunk-CU3YXMM4.mjs.map +1 -0
  49. package/lib/node/{chunk-PNWPIDEL.mjs → chunk-HGQLG7KE.mjs} +2 -2
  50. package/lib/node/{chunk-EIBTX65O.js → chunk-IDEEMJ3F.js} +1 -1
  51. package/lib/node/chunk-IDEEMJ3F.js.map +1 -0
  52. package/lib/node/chunk-KY3RJ2M3.mjs +196 -0
  53. package/lib/node/chunk-KY3RJ2M3.mjs.map +1 -0
  54. package/lib/node/{chunk-PYD4E2EJ.js → chunk-P6QG76R3.js} +34 -85
  55. package/lib/node/chunk-P6QG76R3.js.map +1 -0
  56. package/lib/node/{chunk-DV4PBH4D.mjs → chunk-TOV4TYIX.mjs} +29 -80
  57. package/lib/node/chunk-TOV4TYIX.mjs.map +1 -0
  58. package/lib/node/{chunk-BFLYGQ6D.js → chunk-YGM3BCJU.js} +1 -1
  59. package/lib/node/chunk-YGM3BCJU.js.map +1 -0
  60. package/lib/node/index.d.ts +2 -2
  61. package/lib/node/index.js +4 -4
  62. package/lib/node/index.mjs +3 -3
  63. package/lib/node/interceptors/ClientRequest/index.d.ts +2 -2
  64. package/lib/node/interceptors/ClientRequest/index.js +4 -4
  65. package/lib/node/interceptors/ClientRequest/index.mjs +3 -3
  66. package/lib/node/interceptors/XMLHttpRequest/index.d.ts +2 -6
  67. package/lib/node/interceptors/XMLHttpRequest/index.js +5 -5
  68. package/lib/node/interceptors/XMLHttpRequest/index.mjs +4 -4
  69. package/lib/node/interceptors/fetch/index.d.ts +1 -1
  70. package/lib/node/interceptors/fetch/index.js +52 -123
  71. package/lib/node/interceptors/fetch/index.js.map +1 -1
  72. package/lib/node/interceptors/fetch/index.mjs +50 -121
  73. package/lib/node/interceptors/fetch/index.mjs.map +1 -1
  74. package/lib/node/presets/node.d.ts +1 -1
  75. package/lib/node/presets/node.js +7 -7
  76. package/lib/node/presets/node.mjs +5 -5
  77. package/package.json +2 -2
  78. package/src/InterceptorError.ts +7 -0
  79. package/src/RemoteHttpInterceptor.ts +62 -57
  80. package/src/RequestController.test.ts +49 -0
  81. package/src/RequestController.ts +81 -0
  82. package/src/glossary.ts +4 -6
  83. package/src/interceptors/ClientRequest/MockHttpSocket.ts +22 -16
  84. package/src/interceptors/ClientRequest/index.test.ts +2 -33
  85. package/src/interceptors/ClientRequest/index.ts +32 -82
  86. package/src/interceptors/ClientRequest/utils/recordRawHeaders.ts +170 -0
  87. package/src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts +1 -1
  88. package/src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts +27 -108
  89. package/src/interceptors/XMLHttpRequest/index.ts +0 -6
  90. package/src/interceptors/fetch/index.ts +52 -169
  91. package/src/utils/handleRequest.ts +213 -0
  92. package/src/utils/responseUtils.ts +4 -4
  93. package/lib/browser/chunk-2CRB3JAQ.js.map +0 -1
  94. package/lib/browser/chunk-732REFPX.mjs.map +0 -1
  95. package/lib/browser/chunk-MAEPOYB6.mjs +0 -213
  96. package/lib/browser/chunk-MAEPOYB6.mjs.map +0 -1
  97. package/lib/browser/chunk-MQJ3JOOK.js +0 -49
  98. package/lib/browser/chunk-MQJ3JOOK.js.map +0 -1
  99. package/lib/browser/chunk-OMISYKWR.mjs.map +0 -1
  100. package/lib/browser/chunk-OUWBQF3Z.mjs +0 -49
  101. package/lib/browser/chunk-OUWBQF3Z.mjs.map +0 -1
  102. package/lib/browser/chunk-PSX5J3RF.js.map +0 -1
  103. package/lib/browser/chunk-WBHIW62P.js +0 -213
  104. package/lib/browser/chunk-WBHIW62P.js.map +0 -1
  105. package/lib/browser/glossary-1c204f45.d.ts +0 -44
  106. package/lib/node/chunk-3OJLYEWA.mjs.map +0 -1
  107. package/lib/node/chunk-5JMJ55U7.js.map +0 -1
  108. package/lib/node/chunk-BFLYGQ6D.js.map +0 -1
  109. package/lib/node/chunk-DV4PBH4D.mjs.map +0 -1
  110. package/lib/node/chunk-EIBTX65O.js.map +0 -1
  111. package/lib/node/chunk-KWV3JXSI.mjs +0 -49
  112. package/lib/node/chunk-KWV3JXSI.mjs.map +0 -1
  113. package/lib/node/chunk-OJ6O4LSC.mjs.map +0 -1
  114. package/lib/node/chunk-PYD4E2EJ.js.map +0 -1
  115. package/lib/node/chunk-UXCYRE4F.js +0 -49
  116. package/lib/node/chunk-UXCYRE4F.js.map +0 -1
  117. package/src/utils/getRawFetchHeaders.test.ts +0 -50
  118. package/src/utils/getRawFetchHeaders.ts +0 -56
  119. package/src/utils/toInteractiveRequest.ts +0 -23
  120. /package/lib/node/{chunk-2COJKQQB.js.map → chunk-42632LKH.js.map} +0 -0
  121. /package/lib/node/{chunk-PNWPIDEL.mjs.map → chunk-HGQLG7KE.mjs.map} +0 -0
@@ -2,24 +2,49 @@ import { DeferredPromise } from '@open-draft/deferred-promise';
2
2
  import { Logger } from '@open-draft/logger';
3
3
  import { Emitter, Listener } from 'strict-event-emitter';
4
4
 
5
+ declare const kRequestHandled: unique symbol;
6
+ declare const kResponsePromise: unique symbol;
5
7
  declare class RequestController {
6
- protected request: Request;
7
- responsePromise: DeferredPromise<Response | undefined>;
8
+ private request;
9
+ /**
10
+ * Internal response promise.
11
+ * Available only for the library internals to grab the
12
+ * response instance provided by the developer.
13
+ * @note This promise cannot be rejected. It's either infinitely
14
+ * pending or resolved with whichever Response was passed to `respondWith()`.
15
+ */
16
+ [kResponsePromise]: DeferredPromise<Response | Error | undefined>;
17
+ /**
18
+ * Internal flag indicating if this request has been handled.
19
+ * @note The response promise becomes "fulfilled" on the next tick.
20
+ */
21
+ [kRequestHandled]: boolean;
8
22
  constructor(request: Request);
9
- respondWith(response?: Response): void;
23
+ /**
24
+ * Respond to this request with the given `Response` instance.
25
+ * @example
26
+ * controller.respondWith(new Response())
27
+ * controller.respondWith(Response.json({ id }))
28
+ * controller.respondWith(Response.error())
29
+ */
30
+ respondWith(response: Response): void;
31
+ /**
32
+ * Error this request with the given error.
33
+ * @example
34
+ * controller.errorWith()
35
+ * controller.errorWith(new Error('Oops!'))
36
+ */
37
+ errorWith(error?: Error): void;
10
38
  }
11
39
 
12
- type InteractiveRequest = globalThis.Request & {
13
- respondWith: RequestController['respondWith'];
14
- };
15
-
16
40
  declare const IS_PATCHED_MODULE: unique symbol;
17
41
  type RequestCredentials = 'omit' | 'include' | 'same-origin';
18
42
  type HttpRequestEventMap = {
19
43
  request: [
20
44
  args: {
21
- request: InteractiveRequest;
45
+ request: Request;
22
46
  requestId: string;
47
+ controller: RequestController;
23
48
  }
24
49
  ];
25
50
  response: [
@@ -35,10 +60,7 @@ type HttpRequestEventMap = {
35
60
  error: unknown;
36
61
  request: Request;
37
62
  requestId: string;
38
- controller: {
39
- respondWith(response: Response): void;
40
- errorWith(error?: Error): void;
41
- };
63
+ controller: RequestController;
42
64
  }
43
65
  ];
44
66
  };
@@ -102,4 +124,4 @@ declare class Interceptor<Events extends InterceptorEventMap> {
102
124
  private clearInstance;
103
125
  }
104
126
 
105
- export { ExtractEventNames as E, HttpRequestEventMap as H, IS_PATCHED_MODULE as I, RequestCredentials as R, InterceptorEventMap as a, InterceptorSubscription as b, INTERNAL_REQUEST_ID_HEADER_NAME as c, deleteGlobalSymbol as d, InterceptorReadyState as e, Interceptor as f, getGlobalSymbol as g, InteractiveRequest as h };
127
+ export { ExtractEventNames as E, HttpRequestEventMap as H, IS_PATCHED_MODULE as I, RequestCredentials as R, InterceptorEventMap as a, InterceptorSubscription as b, INTERNAL_REQUEST_ID_HEADER_NAME as c, deleteGlobalSymbol as d, InterceptorReadyState as e, Interceptor as f, getGlobalSymbol as g };
@@ -1,6 +1,6 @@
1
1
  import { ChildProcess } from 'child_process';
2
- import { f as Interceptor, H as HttpRequestEventMap } from './Interceptor-88ee47c0.js';
3
- import { a as BatchInterceptor } from './BatchInterceptor-2badedde.js';
2
+ import { f as Interceptor, H as HttpRequestEventMap } from './Interceptor-a31b1217.js';
3
+ import { a as BatchInterceptor } from './BatchInterceptor-13d40c95.js';
4
4
  import { ClientRequestInterceptor } from './interceptors/ClientRequest/index.js';
5
5
  import { XMLHttpRequestInterceptor } from './interceptors/XMLHttpRequest/index.js';
6
6
  import '@open-draft/deferred-promise';
@@ -1,37 +1,37 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunk2COJKQQBjs = require('./chunk-2COJKQQB.js');
3
+ var _chunk42632LKHjs = require('./chunk-42632LKH.js');
4
4
 
5
5
 
6
- var _chunk5JMJ55U7js = require('./chunk-5JMJ55U7.js');
6
+ var _chunk2MWIWEWVjs = require('./chunk-2MWIWEWV.js');
7
7
 
8
8
 
9
- var _chunkPYD4E2EJjs = require('./chunk-PYD4E2EJ.js');
9
+ var _chunkP6QG76R3js = require('./chunk-P6QG76R3.js');
10
10
  require('./chunk-LK6DILFK.js');
11
- require('./chunk-EIBTX65O.js');
11
+ require('./chunk-IDEEMJ3F.js');
12
12
 
13
13
 
14
14
 
15
- var _chunkUXCYRE4Fjs = require('./chunk-UXCYRE4F.js');
15
+ var _chunk5WWNCLB3js = require('./chunk-5WWNCLB3.js');
16
16
 
17
17
 
18
- var _chunkBFLYGQ6Djs = require('./chunk-BFLYGQ6D.js');
18
+ var _chunkYGM3BCJUjs = require('./chunk-YGM3BCJU.js');
19
19
 
20
20
  // src/RemoteHttpInterceptor.ts
21
- var RemoteHttpInterceptor = class extends _chunk2COJKQQBjs.BatchInterceptor {
21
+ var RemoteHttpInterceptor = class extends _chunk42632LKHjs.BatchInterceptor {
22
22
  constructor() {
23
23
  super({
24
24
  name: "remote-interceptor",
25
25
  interceptors: [
26
- new (0, _chunk5JMJ55U7js.ClientRequestInterceptor)(),
27
- new (0, _chunkPYD4E2EJjs.XMLHttpRequestInterceptor)()
26
+ new (0, _chunk2MWIWEWVjs.ClientRequestInterceptor)(),
27
+ new (0, _chunkP6QG76R3js.XMLHttpRequestInterceptor)()
28
28
  ]
29
29
  });
30
30
  }
31
31
  setup() {
32
32
  super.setup();
33
33
  let handleParentMessage;
34
- this.on("request", async ({ request, requestId }) => {
34
+ this.on("request", async ({ request, requestId, controller }) => {
35
35
  var _a;
36
36
  const serializedRequest = JSON.stringify({
37
37
  id: requestId,
@@ -64,7 +64,7 @@ var RemoteHttpInterceptor = class extends _chunk2COJKQQBjs.BatchInterceptor {
64
64
  statusText: responseInit.statusText,
65
65
  headers: responseInit.headers
66
66
  });
67
- request.respondWith(mockedResponse);
67
+ controller.respondWith(mockedResponse);
68
68
  return resolve();
69
69
  }
70
70
  };
@@ -91,7 +91,7 @@ function requestReviver(key, value) {
91
91
  return value;
92
92
  }
93
93
  }
94
- var _RemoteHttpResolver = class extends _chunkBFLYGQ6Djs.Interceptor {
94
+ var _RemoteHttpResolver = class extends _chunkYGM3BCJUjs.Interceptor {
95
95
  constructor(options) {
96
96
  super(_RemoteHttpResolver.symbol);
97
97
  this.process = options.process;
@@ -113,53 +113,56 @@ var _RemoteHttpResolver = class extends _chunkBFLYGQ6Djs.Interceptor {
113
113
  requestReviver
114
114
  );
115
115
  logger.info("parsed intercepted request", requestJson);
116
- const capturedRequest = new Request(requestJson.url, {
116
+ const request = new Request(requestJson.url, {
117
117
  method: requestJson.method,
118
118
  headers: new Headers(requestJson.headers),
119
119
  credentials: requestJson.credentials,
120
120
  body: requestJson.body
121
121
  });
122
- const { interactiveRequest, requestController } = _chunkUXCYRE4Fjs.toInteractiveRequest.call(void 0, capturedRequest);
123
- this.emitter.once("request", () => {
124
- if (requestController.responsePromise.state === "pending") {
125
- requestController.respondWith(void 0);
126
- }
127
- });
128
- await _chunkUXCYRE4Fjs.emitAsync.call(void 0, this.emitter, "request", {
129
- request: interactiveRequest,
130
- requestId: requestJson.id
131
- });
132
- const mockedResponse = await requestController.responsePromise;
133
- if (!mockedResponse) {
134
- return;
135
- }
136
- logger.info("event.respondWith called with:", mockedResponse);
137
- const responseClone = mockedResponse.clone();
138
- const responseText = await mockedResponse.text();
139
- const serializedResponse = JSON.stringify({
140
- status: mockedResponse.status,
141
- statusText: mockedResponse.statusText,
142
- headers: Array.from(mockedResponse.headers.entries()),
143
- body: responseText
144
- });
145
- this.process.send(
146
- `response:${requestJson.id}:${serializedResponse}`,
147
- (error) => {
148
- if (error) {
149
- return;
150
- }
151
- this.emitter.emit("response", {
152
- response: responseClone,
153
- isMockedResponse: true,
154
- request: capturedRequest,
155
- requestId: requestJson.id
122
+ const controller = new (0, _chunk5WWNCLB3js.RequestController)(request);
123
+ await _chunk5WWNCLB3js.handleRequest.call(void 0, {
124
+ request,
125
+ requestId: requestJson.id,
126
+ controller,
127
+ emitter: this.emitter,
128
+ onResponse: async (response) => {
129
+ this.logger.info("received mocked response!", { response });
130
+ const responseClone = response.clone();
131
+ const responseText = await responseClone.text();
132
+ const serializedResponse = JSON.stringify({
133
+ status: response.status,
134
+ statusText: response.statusText,
135
+ headers: Array.from(response.headers.entries()),
136
+ body: responseText
156
137
  });
138
+ this.process.send(
139
+ `response:${requestJson.id}:${serializedResponse}`,
140
+ (error) => {
141
+ if (error) {
142
+ return;
143
+ }
144
+ this.emitter.emit("response", {
145
+ request,
146
+ requestId: requestJson.id,
147
+ response: responseClone,
148
+ isMockedResponse: true
149
+ });
150
+ }
151
+ );
152
+ logger.info(
153
+ "sent serialized mocked response to the parent:",
154
+ serializedResponse
155
+ );
156
+ },
157
+ onRequestError: (response) => {
158
+ this.logger.info("received a network error!", { response });
159
+ throw new Error("Not implemented");
160
+ },
161
+ onError: (error) => {
162
+ this.logger.info("request has errored!", { error });
163
+ throw new Error("Not implemented");
157
164
  }
158
- );
159
- logger.info(
160
- "sent serialized mocked response to the parent:",
161
- serializedResponse
162
- );
165
+ });
163
166
  };
164
167
  this.subscriptions.push(() => {
165
168
  this.process.removeListener("message", handleChildMessage);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/RemoteHttpInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChildProcess } from 'child_process'\nimport { HttpRequestEventMap } from './glossary'\nimport { Interceptor } from './Interceptor'\nimport { BatchInterceptor } from './BatchInterceptor'\nimport { ClientRequestInterceptor } from './interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from './interceptors/XMLHttpRequest'\nimport { toInteractiveRequest } from './utils/toInteractiveRequest'\nimport { emitAsync } from './utils/emitAsync'\n\nexport interface SerializedRequest {\n id: string\n url: string\n method: string\n headers: Array<[string, string]>\n credentials: RequestCredentials\n body: string\n}\n\ninterface RevivedRequest extends Omit<SerializedRequest, 'url' | 'headers'> {\n url: URL\n headers: Headers\n}\n\nexport interface SerializedResponse {\n status: number\n statusText: string\n headers: Array<[string, string]>\n body: string\n}\n\nexport class RemoteHttpInterceptor extends BatchInterceptor<\n [ClientRequestInterceptor, XMLHttpRequestInterceptor]\n> {\n constructor() {\n super({\n name: 'remote-interceptor',\n interceptors: [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n ],\n })\n }\n\n protected setup() {\n super.setup()\n\n let handleParentMessage: NodeJS.MessageListener\n\n this.on('request', async ({ request, requestId }) => {\n // Send the stringified intercepted request to\n // the parent process where the remote resolver is established.\n const serializedRequest = JSON.stringify({\n id: requestId,\n method: request.method,\n url: request.url,\n headers: Array.from(request.headers.entries()),\n credentials: request.credentials,\n body: ['GET', 'HEAD'].includes(request.method)\n ? null\n : await request.text(),\n } as SerializedRequest)\n\n this.logger.info(\n 'sent serialized request to the child:',\n serializedRequest\n )\n process.send?.(`request:${serializedRequest}`)\n\n const responsePromise = new Promise<void>((resolve) => {\n handleParentMessage = (message) => {\n if (typeof message !== 'string') {\n return resolve()\n }\n\n if (message.startsWith(`response:${requestId}`)) {\n const [, serializedResponse] =\n message.match(/^response:.+?:(.+)$/) || []\n\n if (!serializedResponse) {\n return resolve()\n }\n\n const responseInit = JSON.parse(\n serializedResponse\n ) as SerializedResponse\n\n const mockedResponse = new Response(responseInit.body, {\n status: responseInit.status,\n statusText: responseInit.statusText,\n headers: responseInit.headers,\n })\n\n request.respondWith(mockedResponse)\n return resolve()\n }\n }\n })\n\n // Listen for the mocked response message from the parent.\n this.logger.info(\n 'add \"message\" listener to the parent process',\n handleParentMessage\n )\n process.addListener('message', handleParentMessage)\n\n return responsePromise\n })\n\n this.subscriptions.push(() => {\n process.removeListener('message', handleParentMessage)\n })\n }\n}\n\nexport function requestReviver(key: string, value: any) {\n switch (key) {\n case 'url':\n return new URL(value)\n\n case 'headers':\n return new Headers(value)\n\n default:\n return value\n }\n}\n\nexport interface RemoveResolverOptions {\n process: ChildProcess\n}\n\nexport class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('remote-resolver')\n private process: ChildProcess\n\n constructor(options: RemoveResolverOptions) {\n super(RemoteHttpResolver.symbol)\n this.process = options.process\n }\n\n protected setup() {\n const logger = this.logger.extend('setup')\n\n const handleChildMessage: NodeJS.MessageListener = async (message) => {\n logger.info('received message from child!', message)\n\n if (typeof message !== 'string' || !message.startsWith('request:')) {\n logger.info('unknown message, ignoring...')\n return\n }\n\n const [, serializedRequest] = message.match(/^request:(.+)$/) || []\n if (!serializedRequest) {\n return\n }\n\n const requestJson = JSON.parse(\n serializedRequest,\n requestReviver\n ) as RevivedRequest\n logger.info('parsed intercepted request', requestJson)\n\n const capturedRequest = new Request(requestJson.url, {\n method: requestJson.method,\n headers: new Headers(requestJson.headers),\n credentials: requestJson.credentials,\n body: requestJson.body,\n })\n\n const { interactiveRequest, requestController } =\n toInteractiveRequest(capturedRequest)\n\n this.emitter.once('request', () => {\n if (requestController.responsePromise.state === 'pending') {\n requestController.respondWith(undefined)\n }\n })\n\n await emitAsync(this.emitter, 'request', {\n request: interactiveRequest,\n requestId: requestJson.id,\n })\n\n const mockedResponse = await requestController.responsePromise\n\n if (!mockedResponse) {\n return\n }\n\n logger.info('event.respondWith called with:', mockedResponse)\n const responseClone = mockedResponse.clone()\n const responseText = await mockedResponse.text()\n\n // Send the mocked response to the child process.\n const serializedResponse = JSON.stringify({\n status: mockedResponse.status,\n statusText: mockedResponse.statusText,\n headers: Array.from(mockedResponse.headers.entries()),\n body: responseText,\n } as SerializedResponse)\n\n this.process.send(\n `response:${requestJson.id}:${serializedResponse}`,\n (error) => {\n if (error) {\n return\n }\n\n // Emit an optimistic \"response\" event at this point,\n // not to rely on the back-and-forth signaling for the sake of the event.\n this.emitter.emit('response', {\n response: responseClone,\n isMockedResponse: true,\n request: capturedRequest,\n requestId: requestJson.id,\n })\n }\n )\n\n logger.info(\n 'sent serialized mocked response to the parent:',\n serializedResponse\n )\n }\n\n this.subscriptions.push(() => {\n this.process.removeListener('message', handleChildMessage)\n logger.info('removed the \"message\" listener from the child process!')\n })\n\n logger.info('adding a \"message\" listener to the child process')\n this.process.addListener('message', handleChildMessage)\n\n this.process.once('error', () => this.dispose())\n this.process.once('exit', () => this.dispose())\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/RemoteHttpInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChildProcess } from 'child_process'\nimport { HttpRequestEventMap } from './glossary'\nimport { Interceptor } from './Interceptor'\nimport { BatchInterceptor } from './BatchInterceptor'\nimport { ClientRequestInterceptor } from './interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from './interceptors/XMLHttpRequest'\nimport { handleRequest } from './utils/handleRequest'\nimport { RequestController } from './RequestController'\n\nexport interface SerializedRequest {\n id: string\n url: string\n method: string\n headers: Array<[string, string]>\n credentials: RequestCredentials\n body: string\n}\n\ninterface RevivedRequest extends Omit<SerializedRequest, 'url' | 'headers'> {\n url: URL\n headers: Headers\n}\n\nexport interface SerializedResponse {\n status: number\n statusText: string\n headers: Array<[string, string]>\n body: string\n}\n\nexport class RemoteHttpInterceptor extends BatchInterceptor<\n [ClientRequestInterceptor, XMLHttpRequestInterceptor]\n> {\n constructor() {\n super({\n name: 'remote-interceptor',\n interceptors: [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n ],\n })\n }\n\n protected setup() {\n super.setup()\n\n let handleParentMessage: NodeJS.MessageListener\n\n this.on('request', async ({ request, requestId, controller }) => {\n // Send the stringified intercepted request to\n // the parent process where the remote resolver is established.\n const serializedRequest = JSON.stringify({\n id: requestId,\n method: request.method,\n url: request.url,\n headers: Array.from(request.headers.entries()),\n credentials: request.credentials,\n body: ['GET', 'HEAD'].includes(request.method)\n ? null\n : await request.text(),\n } as SerializedRequest)\n\n this.logger.info(\n 'sent serialized request to the child:',\n serializedRequest\n )\n\n process.send?.(`request:${serializedRequest}`)\n\n const responsePromise = new Promise<void>((resolve) => {\n handleParentMessage = (message) => {\n if (typeof message !== 'string') {\n return resolve()\n }\n\n if (message.startsWith(`response:${requestId}`)) {\n const [, serializedResponse] =\n message.match(/^response:.+?:(.+)$/) || []\n\n if (!serializedResponse) {\n return resolve()\n }\n\n const responseInit = JSON.parse(\n serializedResponse\n ) as SerializedResponse\n\n const mockedResponse = new Response(responseInit.body, {\n status: responseInit.status,\n statusText: responseInit.statusText,\n headers: responseInit.headers,\n })\n\n /**\n * @todo Support \"errorWith\" as well.\n * This response handling from the child is incomplete.\n */\n\n controller.respondWith(mockedResponse)\n return resolve()\n }\n }\n })\n\n // Listen for the mocked response message from the parent.\n this.logger.info(\n 'add \"message\" listener to the parent process',\n handleParentMessage\n )\n process.addListener('message', handleParentMessage)\n\n return responsePromise\n })\n\n this.subscriptions.push(() => {\n process.removeListener('message', handleParentMessage)\n })\n }\n}\n\nexport function requestReviver(key: string, value: any) {\n switch (key) {\n case 'url':\n return new URL(value)\n\n case 'headers':\n return new Headers(value)\n\n default:\n return value\n }\n}\n\nexport interface RemoveResolverOptions {\n process: ChildProcess\n}\n\nexport class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('remote-resolver')\n private process: ChildProcess\n\n constructor(options: RemoveResolverOptions) {\n super(RemoteHttpResolver.symbol)\n this.process = options.process\n }\n\n protected setup() {\n const logger = this.logger.extend('setup')\n\n const handleChildMessage: NodeJS.MessageListener = async (message) => {\n logger.info('received message from child!', message)\n\n if (typeof message !== 'string' || !message.startsWith('request:')) {\n logger.info('unknown message, ignoring...')\n return\n }\n\n const [, serializedRequest] = message.match(/^request:(.+)$/) || []\n if (!serializedRequest) {\n return\n }\n\n const requestJson = JSON.parse(\n serializedRequest,\n requestReviver\n ) as RevivedRequest\n\n logger.info('parsed intercepted request', requestJson)\n\n const request = new Request(requestJson.url, {\n method: requestJson.method,\n headers: new Headers(requestJson.headers),\n credentials: requestJson.credentials,\n body: requestJson.body,\n })\n\n const controller = new RequestController(request)\n await handleRequest({\n request,\n requestId: requestJson.id,\n controller,\n emitter: this.emitter,\n onResponse: async (response) => {\n this.logger.info('received mocked response!', { response })\n\n const responseClone = response.clone()\n const responseText = await responseClone.text()\n\n // // Send the mocked response to the child process.\n const serializedResponse = JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n body: responseText,\n } as SerializedResponse)\n\n this.process.send(\n `response:${requestJson.id}:${serializedResponse}`,\n (error) => {\n if (error) {\n return\n }\n\n // Emit an optimistic \"response\" event at this point,\n // not to rely on the back-and-forth signaling for the sake of the event.\n this.emitter.emit('response', {\n request,\n requestId: requestJson.id,\n response: responseClone,\n isMockedResponse: true,\n })\n }\n )\n\n logger.info(\n 'sent serialized mocked response to the parent:',\n serializedResponse\n )\n },\n onRequestError: (response) => {\n this.logger.info('received a network error!', { response })\n throw new Error('Not implemented')\n },\n onError: (error) => {\n this.logger.info('request has errored!', { error })\n throw new Error('Not implemented')\n },\n })\n }\n\n this.subscriptions.push(() => {\n this.process.removeListener('message', handleChildMessage)\n logger.info('removed the \"message\" listener from the child process!')\n })\n\n logger.info('adding a \"message\" listener to the child process')\n this.process.addListener('message', handleChildMessage)\n\n this.process.once('error', () => this.dispose())\n this.process.once('exit', () => this.dispose())\n }\n}\n"]}
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  BatchInterceptor
3
- } from "./chunk-PNWPIDEL.mjs";
3
+ } from "./chunk-HGQLG7KE.mjs";
4
4
  import {
5
5
  ClientRequestInterceptor
6
- } from "./chunk-3OJLYEWA.mjs";
6
+ } from "./chunk-CU3YXMM4.mjs";
7
7
  import {
8
8
  XMLHttpRequestInterceptor
9
- } from "./chunk-DV4PBH4D.mjs";
9
+ } from "./chunk-TOV4TYIX.mjs";
10
10
  import "./chunk-6HYIRFX2.mjs";
11
- import "./chunk-OJ6O4LSC.mjs";
11
+ import "./chunk-BZ3Y7YV5.mjs";
12
12
  import {
13
- emitAsync,
14
- toInteractiveRequest
15
- } from "./chunk-KWV3JXSI.mjs";
13
+ RequestController,
14
+ handleRequest
15
+ } from "./chunk-KY3RJ2M3.mjs";
16
16
  import {
17
17
  Interceptor
18
- } from "./chunk-TGTPXCLF.mjs";
18
+ } from "./chunk-BUCULLYM.mjs";
19
19
 
20
20
  // src/RemoteHttpInterceptor.ts
21
21
  var RemoteHttpInterceptor = class extends BatchInterceptor {
@@ -31,7 +31,7 @@ var RemoteHttpInterceptor = class extends BatchInterceptor {
31
31
  setup() {
32
32
  super.setup();
33
33
  let handleParentMessage;
34
- this.on("request", async ({ request, requestId }) => {
34
+ this.on("request", async ({ request, requestId, controller }) => {
35
35
  var _a;
36
36
  const serializedRequest = JSON.stringify({
37
37
  id: requestId,
@@ -64,7 +64,7 @@ var RemoteHttpInterceptor = class extends BatchInterceptor {
64
64
  statusText: responseInit.statusText,
65
65
  headers: responseInit.headers
66
66
  });
67
- request.respondWith(mockedResponse);
67
+ controller.respondWith(mockedResponse);
68
68
  return resolve();
69
69
  }
70
70
  };
@@ -113,53 +113,56 @@ var _RemoteHttpResolver = class extends Interceptor {
113
113
  requestReviver
114
114
  );
115
115
  logger.info("parsed intercepted request", requestJson);
116
- const capturedRequest = new Request(requestJson.url, {
116
+ const request = new Request(requestJson.url, {
117
117
  method: requestJson.method,
118
118
  headers: new Headers(requestJson.headers),
119
119
  credentials: requestJson.credentials,
120
120
  body: requestJson.body
121
121
  });
122
- const { interactiveRequest, requestController } = toInteractiveRequest(capturedRequest);
123
- this.emitter.once("request", () => {
124
- if (requestController.responsePromise.state === "pending") {
125
- requestController.respondWith(void 0);
126
- }
127
- });
128
- await emitAsync(this.emitter, "request", {
129
- request: interactiveRequest,
130
- requestId: requestJson.id
131
- });
132
- const mockedResponse = await requestController.responsePromise;
133
- if (!mockedResponse) {
134
- return;
135
- }
136
- logger.info("event.respondWith called with:", mockedResponse);
137
- const responseClone = mockedResponse.clone();
138
- const responseText = await mockedResponse.text();
139
- const serializedResponse = JSON.stringify({
140
- status: mockedResponse.status,
141
- statusText: mockedResponse.statusText,
142
- headers: Array.from(mockedResponse.headers.entries()),
143
- body: responseText
144
- });
145
- this.process.send(
146
- `response:${requestJson.id}:${serializedResponse}`,
147
- (error) => {
148
- if (error) {
149
- return;
150
- }
151
- this.emitter.emit("response", {
152
- response: responseClone,
153
- isMockedResponse: true,
154
- request: capturedRequest,
155
- requestId: requestJson.id
122
+ const controller = new RequestController(request);
123
+ await handleRequest({
124
+ request,
125
+ requestId: requestJson.id,
126
+ controller,
127
+ emitter: this.emitter,
128
+ onResponse: async (response) => {
129
+ this.logger.info("received mocked response!", { response });
130
+ const responseClone = response.clone();
131
+ const responseText = await responseClone.text();
132
+ const serializedResponse = JSON.stringify({
133
+ status: response.status,
134
+ statusText: response.statusText,
135
+ headers: Array.from(response.headers.entries()),
136
+ body: responseText
156
137
  });
138
+ this.process.send(
139
+ `response:${requestJson.id}:${serializedResponse}`,
140
+ (error) => {
141
+ if (error) {
142
+ return;
143
+ }
144
+ this.emitter.emit("response", {
145
+ request,
146
+ requestId: requestJson.id,
147
+ response: responseClone,
148
+ isMockedResponse: true
149
+ });
150
+ }
151
+ );
152
+ logger.info(
153
+ "sent serialized mocked response to the parent:",
154
+ serializedResponse
155
+ );
156
+ },
157
+ onRequestError: (response) => {
158
+ this.logger.info("received a network error!", { response });
159
+ throw new Error("Not implemented");
160
+ },
161
+ onError: (error) => {
162
+ this.logger.info("request has errored!", { error });
163
+ throw new Error("Not implemented");
157
164
  }
158
- );
159
- logger.info(
160
- "sent serialized mocked response to the parent:",
161
- serializedResponse
162
- );
165
+ });
163
166
  };
164
167
  this.subscriptions.push(() => {
165
168
  this.process.removeListener("message", handleChildMessage);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/RemoteHttpInterceptor.ts"],"sourcesContent":["import { ChildProcess } from 'child_process'\nimport { HttpRequestEventMap } from './glossary'\nimport { Interceptor } from './Interceptor'\nimport { BatchInterceptor } from './BatchInterceptor'\nimport { ClientRequestInterceptor } from './interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from './interceptors/XMLHttpRequest'\nimport { toInteractiveRequest } from './utils/toInteractiveRequest'\nimport { emitAsync } from './utils/emitAsync'\n\nexport interface SerializedRequest {\n id: string\n url: string\n method: string\n headers: Array<[string, string]>\n credentials: RequestCredentials\n body: string\n}\n\ninterface RevivedRequest extends Omit<SerializedRequest, 'url' | 'headers'> {\n url: URL\n headers: Headers\n}\n\nexport interface SerializedResponse {\n status: number\n statusText: string\n headers: Array<[string, string]>\n body: string\n}\n\nexport class RemoteHttpInterceptor extends BatchInterceptor<\n [ClientRequestInterceptor, XMLHttpRequestInterceptor]\n> {\n constructor() {\n super({\n name: 'remote-interceptor',\n interceptors: [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n ],\n })\n }\n\n protected setup() {\n super.setup()\n\n let handleParentMessage: NodeJS.MessageListener\n\n this.on('request', async ({ request, requestId }) => {\n // Send the stringified intercepted request to\n // the parent process where the remote resolver is established.\n const serializedRequest = JSON.stringify({\n id: requestId,\n method: request.method,\n url: request.url,\n headers: Array.from(request.headers.entries()),\n credentials: request.credentials,\n body: ['GET', 'HEAD'].includes(request.method)\n ? null\n : await request.text(),\n } as SerializedRequest)\n\n this.logger.info(\n 'sent serialized request to the child:',\n serializedRequest\n )\n process.send?.(`request:${serializedRequest}`)\n\n const responsePromise = new Promise<void>((resolve) => {\n handleParentMessage = (message) => {\n if (typeof message !== 'string') {\n return resolve()\n }\n\n if (message.startsWith(`response:${requestId}`)) {\n const [, serializedResponse] =\n message.match(/^response:.+?:(.+)$/) || []\n\n if (!serializedResponse) {\n return resolve()\n }\n\n const responseInit = JSON.parse(\n serializedResponse\n ) as SerializedResponse\n\n const mockedResponse = new Response(responseInit.body, {\n status: responseInit.status,\n statusText: responseInit.statusText,\n headers: responseInit.headers,\n })\n\n request.respondWith(mockedResponse)\n return resolve()\n }\n }\n })\n\n // Listen for the mocked response message from the parent.\n this.logger.info(\n 'add \"message\" listener to the parent process',\n handleParentMessage\n )\n process.addListener('message', handleParentMessage)\n\n return responsePromise\n })\n\n this.subscriptions.push(() => {\n process.removeListener('message', handleParentMessage)\n })\n }\n}\n\nexport function requestReviver(key: string, value: any) {\n switch (key) {\n case 'url':\n return new URL(value)\n\n case 'headers':\n return new Headers(value)\n\n default:\n return value\n }\n}\n\nexport interface RemoveResolverOptions {\n process: ChildProcess\n}\n\nexport class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('remote-resolver')\n private process: ChildProcess\n\n constructor(options: RemoveResolverOptions) {\n super(RemoteHttpResolver.symbol)\n this.process = options.process\n }\n\n protected setup() {\n const logger = this.logger.extend('setup')\n\n const handleChildMessage: NodeJS.MessageListener = async (message) => {\n logger.info('received message from child!', message)\n\n if (typeof message !== 'string' || !message.startsWith('request:')) {\n logger.info('unknown message, ignoring...')\n return\n }\n\n const [, serializedRequest] = message.match(/^request:(.+)$/) || []\n if (!serializedRequest) {\n return\n }\n\n const requestJson = JSON.parse(\n serializedRequest,\n requestReviver\n ) as RevivedRequest\n logger.info('parsed intercepted request', requestJson)\n\n const capturedRequest = new Request(requestJson.url, {\n method: requestJson.method,\n headers: new Headers(requestJson.headers),\n credentials: requestJson.credentials,\n body: requestJson.body,\n })\n\n const { interactiveRequest, requestController } =\n toInteractiveRequest(capturedRequest)\n\n this.emitter.once('request', () => {\n if (requestController.responsePromise.state === 'pending') {\n requestController.respondWith(undefined)\n }\n })\n\n await emitAsync(this.emitter, 'request', {\n request: interactiveRequest,\n requestId: requestJson.id,\n })\n\n const mockedResponse = await requestController.responsePromise\n\n if (!mockedResponse) {\n return\n }\n\n logger.info('event.respondWith called with:', mockedResponse)\n const responseClone = mockedResponse.clone()\n const responseText = await mockedResponse.text()\n\n // Send the mocked response to the child process.\n const serializedResponse = JSON.stringify({\n status: mockedResponse.status,\n statusText: mockedResponse.statusText,\n headers: Array.from(mockedResponse.headers.entries()),\n body: responseText,\n } as SerializedResponse)\n\n this.process.send(\n `response:${requestJson.id}:${serializedResponse}`,\n (error) => {\n if (error) {\n return\n }\n\n // Emit an optimistic \"response\" event at this point,\n // not to rely on the back-and-forth signaling for the sake of the event.\n this.emitter.emit('response', {\n response: responseClone,\n isMockedResponse: true,\n request: capturedRequest,\n requestId: requestJson.id,\n })\n }\n )\n\n logger.info(\n 'sent serialized mocked response to the parent:',\n serializedResponse\n )\n }\n\n this.subscriptions.push(() => {\n this.process.removeListener('message', handleChildMessage)\n logger.info('removed the \"message\" listener from the child process!')\n })\n\n logger.info('adding a \"message\" listener to the child process')\n this.process.addListener('message', handleChildMessage)\n\n this.process.once('error', () => this.dispose())\n this.process.once('exit', () => this.dispose())\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/RemoteHttpInterceptor.ts"],"sourcesContent":["import { ChildProcess } from 'child_process'\nimport { HttpRequestEventMap } from './glossary'\nimport { Interceptor } from './Interceptor'\nimport { BatchInterceptor } from './BatchInterceptor'\nimport { ClientRequestInterceptor } from './interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from './interceptors/XMLHttpRequest'\nimport { handleRequest } from './utils/handleRequest'\nimport { RequestController } from './RequestController'\n\nexport interface SerializedRequest {\n id: string\n url: string\n method: string\n headers: Array<[string, string]>\n credentials: RequestCredentials\n body: string\n}\n\ninterface RevivedRequest extends Omit<SerializedRequest, 'url' | 'headers'> {\n url: URL\n headers: Headers\n}\n\nexport interface SerializedResponse {\n status: number\n statusText: string\n headers: Array<[string, string]>\n body: string\n}\n\nexport class RemoteHttpInterceptor extends BatchInterceptor<\n [ClientRequestInterceptor, XMLHttpRequestInterceptor]\n> {\n constructor() {\n super({\n name: 'remote-interceptor',\n interceptors: [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n ],\n })\n }\n\n protected setup() {\n super.setup()\n\n let handleParentMessage: NodeJS.MessageListener\n\n this.on('request', async ({ request, requestId, controller }) => {\n // Send the stringified intercepted request to\n // the parent process where the remote resolver is established.\n const serializedRequest = JSON.stringify({\n id: requestId,\n method: request.method,\n url: request.url,\n headers: Array.from(request.headers.entries()),\n credentials: request.credentials,\n body: ['GET', 'HEAD'].includes(request.method)\n ? null\n : await request.text(),\n } as SerializedRequest)\n\n this.logger.info(\n 'sent serialized request to the child:',\n serializedRequest\n )\n\n process.send?.(`request:${serializedRequest}`)\n\n const responsePromise = new Promise<void>((resolve) => {\n handleParentMessage = (message) => {\n if (typeof message !== 'string') {\n return resolve()\n }\n\n if (message.startsWith(`response:${requestId}`)) {\n const [, serializedResponse] =\n message.match(/^response:.+?:(.+)$/) || []\n\n if (!serializedResponse) {\n return resolve()\n }\n\n const responseInit = JSON.parse(\n serializedResponse\n ) as SerializedResponse\n\n const mockedResponse = new Response(responseInit.body, {\n status: responseInit.status,\n statusText: responseInit.statusText,\n headers: responseInit.headers,\n })\n\n /**\n * @todo Support \"errorWith\" as well.\n * This response handling from the child is incomplete.\n */\n\n controller.respondWith(mockedResponse)\n return resolve()\n }\n }\n })\n\n // Listen for the mocked response message from the parent.\n this.logger.info(\n 'add \"message\" listener to the parent process',\n handleParentMessage\n )\n process.addListener('message', handleParentMessage)\n\n return responsePromise\n })\n\n this.subscriptions.push(() => {\n process.removeListener('message', handleParentMessage)\n })\n }\n}\n\nexport function requestReviver(key: string, value: any) {\n switch (key) {\n case 'url':\n return new URL(value)\n\n case 'headers':\n return new Headers(value)\n\n default:\n return value\n }\n}\n\nexport interface RemoveResolverOptions {\n process: ChildProcess\n}\n\nexport class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('remote-resolver')\n private process: ChildProcess\n\n constructor(options: RemoveResolverOptions) {\n super(RemoteHttpResolver.symbol)\n this.process = options.process\n }\n\n protected setup() {\n const logger = this.logger.extend('setup')\n\n const handleChildMessage: NodeJS.MessageListener = async (message) => {\n logger.info('received message from child!', message)\n\n if (typeof message !== 'string' || !message.startsWith('request:')) {\n logger.info('unknown message, ignoring...')\n return\n }\n\n const [, serializedRequest] = message.match(/^request:(.+)$/) || []\n if (!serializedRequest) {\n return\n }\n\n const requestJson = JSON.parse(\n serializedRequest,\n requestReviver\n ) as RevivedRequest\n\n logger.info('parsed intercepted request', requestJson)\n\n const request = new Request(requestJson.url, {\n method: requestJson.method,\n headers: new Headers(requestJson.headers),\n credentials: requestJson.credentials,\n body: requestJson.body,\n })\n\n const controller = new RequestController(request)\n await handleRequest({\n request,\n requestId: requestJson.id,\n controller,\n emitter: this.emitter,\n onResponse: async (response) => {\n this.logger.info('received mocked response!', { response })\n\n const responseClone = response.clone()\n const responseText = await responseClone.text()\n\n // // Send the mocked response to the child process.\n const serializedResponse = JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n body: responseText,\n } as SerializedResponse)\n\n this.process.send(\n `response:${requestJson.id}:${serializedResponse}`,\n (error) => {\n if (error) {\n return\n }\n\n // Emit an optimistic \"response\" event at this point,\n // not to rely on the back-and-forth signaling for the sake of the event.\n this.emitter.emit('response', {\n request,\n requestId: requestJson.id,\n response: responseClone,\n isMockedResponse: true,\n })\n }\n )\n\n logger.info(\n 'sent serialized mocked response to the parent:',\n serializedResponse\n )\n },\n onRequestError: (response) => {\n this.logger.info('received a network error!', { response })\n throw new Error('Not implemented')\n },\n onError: (error) => {\n this.logger.info('request has errored!', { error })\n throw new Error('Not implemented')\n },\n })\n }\n\n this.subscriptions.push(() => {\n this.process.removeListener('message', handleChildMessage)\n logger.info('removed the \"message\" listener from the child process!')\n })\n\n logger.info('adding a \"message\" listener to the child process')\n this.process.addListener('message', handleChildMessage)\n\n this.process.once('error', () => this.dispose())\n this.process.once('exit', () => this.dispose())\n }\n}\n"],"mappings":"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","names":[]}