importmap_mocha-rails 0.3.2 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 956db9517ae928bdba1055e2fa794e0a5268e5cd51fbd5ee77b3d2f581974863
4
- data.tar.gz: 82ea0c468ab45e738ee23a35b2c3342e20fc2db5e83ffb2cad1695ff32f6d9e4
3
+ metadata.gz: 55c9689c64ecb2902d9fcb77c63837596a8a7f6a3409d33b08384e1adb92db5d
4
+ data.tar.gz: e7f7fbe95e2e778add22a79931a7b0b8ced8fe2ea5a1263a52b476826918cc85
5
5
  SHA512:
6
- metadata.gz: fd744f1ccb15cadea9a96a17950763a518ad8ed752ec01a3ad8c49320e08cd3232dd44b21c4f17ae3cb49e4ab0d828e9c9f38f3387dbe51596af125877cf6646
7
- data.tar.gz: 6b78eb3f5d241937458ae8ce568fe86eb743db54decd9841fe87f5517371d532e59292fd5b8e694042f36a5e928c75326fe4dd386491e5710316ed635fe97ebb
6
+ metadata.gz: b57ba9684a4778aa2304d4daaca9b8dcdc9685b7992ba3bfece3bf120736d05a9e3dd96d0153eed4e3d23e2e729ffde4c7530b7acd0f9a855a997640e6294855
7
+ data.tar.gz: 73568ec4bf12eba6c7fe126babd98cf443c4cd4a0c8c24629080d434888d5a8dc4d3c128eecec2d671c6c3556f629ca71fa1584c2c58d5c8f1376307d1d8af41
data/README.md CHANGED
@@ -77,6 +77,8 @@ describe('clear controller', () => {
77
77
  });
78
78
  ```
79
79
 
80
+ ![screenshot](./images/screenshot01.png)
81
+
80
82
  # Configuration
81
83
 
82
84
  * config.importmap_mocha_style: The style of the test code, `"bdd"` or `"tdd"`. Default is `"bdd"`.
@@ -30,6 +30,15 @@ module ImportmapMocha
30
30
  app.config.importmap.paths << Engine.root.join('config/importmap.rb') if Rails.application.respond_to?(:importmap)
31
31
  end
32
32
 
33
+ initializer "importmap_mocha.cache_sweeper", before: "importmap.cache_sweeper" do |app|
34
+ if app.config.importmap.sweep_cache && !app.config.cache_classes
35
+ app.config.importmap.cache_sweepers << Engine.root.join('app/assets/javascripts')
36
+ app.config.importmap.cache_sweepers << Engine.root.join('vendor/javascripts')
37
+ app.config.importmap.cache_sweepers += Rails.application.config.importmap_mocha_path
38
+ end
39
+ end
40
+
41
+
33
42
  initializer 'importmap_mocha.routes' do
34
43
  Rails.application.routes.prepend do
35
44
  scope module: 'importmap_mocha' do
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ImportmapMocha
4
- VERSION = '0.3.2'
4
+ VERSION = '0.3.4'
5
5
  end
@@ -1,7 +1,6 @@
1
1
  // src/interceptors/fetch/index.ts
2
2
  import { invariant as invariant2 } from "outvariant";
3
- import { DeferredPromise as DeferredPromise2 } from "@open-draft/deferred-promise";
4
- import { until } from "@open-draft/until";
3
+ import { DeferredPromise as DeferredPromise3 } from "@open-draft/deferred-promise";
5
4
 
6
5
  // src/glossary.ts
7
6
  var IS_PATCHED_MODULE = Symbol("isPatchedModule");
@@ -9,6 +8,7 @@ var IS_PATCHED_MODULE = Symbol("isPatchedModule");
9
8
  // src/Interceptor.ts
10
9
  import { Logger } from "@open-draft/logger";
11
10
  import { Emitter } from "strict-event-emitter";
11
+ var INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
12
12
  function getGlobalSymbol(symbol) {
13
13
  return (
14
14
  // @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587
@@ -152,47 +152,65 @@ var Interceptor = class {
152
152
  }
153
153
  };
154
154
 
155
- // src/utils/uuid.ts
156
- function uuidv4() {
157
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
158
- const r = Math.random() * 16 | 0;
159
- const v = c == "x" ? r : r & 3 | 8;
160
- return v.toString(16);
161
- });
162
- }
163
-
164
- // src/utils/RequestController.ts
155
+ // src/RequestController.ts
165
156
  import { invariant } from "outvariant";
166
157
  import { DeferredPromise } from "@open-draft/deferred-promise";
158
+
159
+ // src/InterceptorError.ts
160
+ var InterceptorError = class extends Error {
161
+ constructor(message) {
162
+ super(message);
163
+ this.name = "InterceptorError";
164
+ Object.setPrototypeOf(this, InterceptorError.prototype);
165
+ }
166
+ };
167
+
168
+ // src/RequestController.ts
169
+ var kRequestHandled = Symbol("kRequestHandled");
170
+ var kResponsePromise = Symbol("kResponsePromise");
167
171
  var RequestController = class {
168
172
  constructor(request) {
169
173
  this.request = request;
170
- this.responsePromise = new DeferredPromise();
174
+ this[kRequestHandled] = false;
175
+ this[kResponsePromise] = new DeferredPromise();
171
176
  }
177
+ /**
178
+ * Respond to this request with the given `Response` instance.
179
+ * @example
180
+ * controller.respondWith(new Response())
181
+ * controller.respondWith(Response.json({ id }))
182
+ * controller.respondWith(Response.error())
183
+ */
172
184
  respondWith(response) {
173
- invariant(
174
- this.responsePromise.state === "pending",
175
- 'Failed to respond to "%s %s" request: the "request" event has already been responded to.',
185
+ invariant.as(
186
+ InterceptorError,
187
+ !this[kRequestHandled],
188
+ 'Failed to respond to the "%s %s" request: the "request" event has already been handled.',
189
+ this.request.method,
190
+ this.request.url
191
+ );
192
+ this[kRequestHandled] = true;
193
+ this[kResponsePromise].resolve(response);
194
+ }
195
+ /**
196
+ * Error this request with the given error.
197
+ * @example
198
+ * controller.errorWith()
199
+ * controller.errorWith(new Error('Oops!'))
200
+ */
201
+ errorWith(error) {
202
+ invariant.as(
203
+ InterceptorError,
204
+ !this[kRequestHandled],
205
+ 'Failed to error the "%s %s" request: the "request" event has already been handled.',
176
206
  this.request.method,
177
207
  this.request.url
178
208
  );
179
- this.responsePromise.resolve(response);
209
+ this[kRequestHandled] = true;
210
+ this[kResponsePromise].resolve(error);
180
211
  }
181
212
  };
182
-
183
- // src/utils/toInteractiveRequest.ts
184
- function toInteractiveRequest(request) {
185
- const requestController = new RequestController(request);
186
- Reflect.set(
187
- request,
188
- "respondWith",
189
- requestController.respondWith.bind(requestController)
190
- );
191
- return {
192
- interactiveRequest: request,
193
- requestController
194
- };
195
- }
213
+ kResponsePromise, kRequestHandled;
196
214
 
197
215
  // src/utils/emitAsync.ts
198
216
  async function emitAsync(emitter, eventName, ...data) {
@@ -205,6 +223,10 @@ async function emitAsync(emitter, eventName, ...data) {
205
223
  }
206
224
  }
207
225
 
226
+ // src/utils/handleRequest.ts
227
+ import { DeferredPromise as DeferredPromise2 } from "@open-draft/deferred-promise";
228
+ import { until } from "@open-draft/until";
229
+
208
230
  // src/utils/isPropertyAccessible.ts
209
231
  function isPropertyAccessible(obj, key) {
210
232
  try {
@@ -215,6 +237,164 @@ function isPropertyAccessible(obj, key) {
215
237
  }
216
238
  }
217
239
 
240
+ // src/utils/responseUtils.ts
241
+ var RESPONSE_STATUS_CODES_WITHOUT_BODY = /* @__PURE__ */ new Set([
242
+ 101,
243
+ 103,
244
+ 204,
245
+ 205,
246
+ 304
247
+ ]);
248
+ function isResponseWithoutBody(status) {
249
+ return RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status);
250
+ }
251
+ function createServerErrorResponse(body) {
252
+ return new Response(
253
+ JSON.stringify(
254
+ body instanceof Error ? {
255
+ name: body.name,
256
+ message: body.message,
257
+ stack: body.stack
258
+ } : body
259
+ ),
260
+ {
261
+ status: 500,
262
+ statusText: "Unhandled Exception",
263
+ headers: {
264
+ "Content-Type": "application/json"
265
+ }
266
+ }
267
+ );
268
+ }
269
+ function isResponseError(response) {
270
+ return isPropertyAccessible(response, "type") && response.type === "error";
271
+ }
272
+
273
+ // src/utils/isNodeLikeError.ts
274
+ function isNodeLikeError(error) {
275
+ if (error == null) {
276
+ return false;
277
+ }
278
+ if (!(error instanceof Error)) {
279
+ return false;
280
+ }
281
+ return "code" in error && "errno" in error;
282
+ }
283
+
284
+ // src/utils/handleRequest.ts
285
+ async function handleRequest(options) {
286
+ const handleResponse = (response) => {
287
+ if (response instanceof Error) {
288
+ options.onError(response);
289
+ } else if (isResponseError(response)) {
290
+ options.onRequestError(response);
291
+ } else {
292
+ options.onResponse(response);
293
+ }
294
+ return true;
295
+ };
296
+ const handleResponseError = (error) => {
297
+ if (error instanceof InterceptorError) {
298
+ throw result.error;
299
+ }
300
+ if (isNodeLikeError(error)) {
301
+ options.onError(error);
302
+ return true;
303
+ }
304
+ if (error instanceof Response) {
305
+ return handleResponse(error);
306
+ }
307
+ return false;
308
+ };
309
+ options.emitter.once("request", ({ requestId: pendingRequestId }) => {
310
+ if (pendingRequestId !== options.requestId) {
311
+ return;
312
+ }
313
+ if (options.controller[kResponsePromise].state === "pending") {
314
+ options.controller[kResponsePromise].resolve(void 0);
315
+ }
316
+ });
317
+ const requestAbortPromise = new DeferredPromise2();
318
+ if (options.request.signal) {
319
+ options.request.signal.addEventListener(
320
+ "abort",
321
+ () => {
322
+ requestAbortPromise.reject(options.request.signal.reason);
323
+ },
324
+ { once: true }
325
+ );
326
+ }
327
+ const result = await until(async () => {
328
+ const requestListtenersPromise = emitAsync(options.emitter, "request", {
329
+ requestId: options.requestId,
330
+ request: options.request,
331
+ controller: options.controller
332
+ });
333
+ await Promise.race([
334
+ // Short-circuit the request handling promise if the request gets aborted.
335
+ requestAbortPromise,
336
+ requestListtenersPromise,
337
+ options.controller[kResponsePromise]
338
+ ]);
339
+ const mockedResponse = await options.controller[kResponsePromise];
340
+ return mockedResponse;
341
+ });
342
+ if (requestAbortPromise.state === "rejected") {
343
+ options.onError(requestAbortPromise.rejectionReason);
344
+ return true;
345
+ }
346
+ if (result.error) {
347
+ if (handleResponseError(result.error)) {
348
+ return true;
349
+ }
350
+ if (options.emitter.listenerCount("unhandledException") > 0) {
351
+ const unhandledExceptionController = new RequestController(
352
+ options.request
353
+ );
354
+ await emitAsync(options.emitter, "unhandledException", {
355
+ error: result.error,
356
+ request: options.request,
357
+ requestId: options.requestId,
358
+ controller: unhandledExceptionController
359
+ }).then(() => {
360
+ if (unhandledExceptionController[kResponsePromise].state === "pending") {
361
+ unhandledExceptionController[kResponsePromise].resolve(void 0);
362
+ }
363
+ });
364
+ const nextResult = await until(
365
+ () => unhandledExceptionController[kResponsePromise]
366
+ );
367
+ if (nextResult.error) {
368
+ return handleResponseError(nextResult.error);
369
+ }
370
+ if (nextResult.data) {
371
+ return handleResponse(nextResult.data);
372
+ }
373
+ }
374
+ options.onResponse(createServerErrorResponse(result.error));
375
+ return true;
376
+ }
377
+ if (result.data) {
378
+ return handleResponse(result.data);
379
+ }
380
+ return false;
381
+ }
382
+
383
+ // src/utils/canParseUrl.ts
384
+ function canParseUrl(url) {
385
+ try {
386
+ new URL(url);
387
+ return true;
388
+ } catch (_error) {
389
+ return false;
390
+ }
391
+ }
392
+
393
+ // src/createRequestId.ts
394
+ function createRequestId() {
395
+ return Math.random().toString(16).slice(2);
396
+ }
397
+
218
398
  // src/interceptors/fetch/index.ts
219
399
  var _FetchInterceptor = class extends Interceptor {
220
400
  constructor() {
@@ -223,99 +403,81 @@ var _FetchInterceptor = class extends Interceptor {
223
403
  checkEnvironment() {
224
404
  return typeof globalThis !== "undefined" && typeof globalThis.fetch !== "undefined";
225
405
  }
226
- setup() {
406
+ async setup() {
227
407
  const pureFetch = globalThis.fetch;
228
408
  invariant2(
229
409
  !pureFetch[IS_PATCHED_MODULE],
230
410
  'Failed to patch the "fetch" module: already patched.'
231
411
  );
232
412
  globalThis.fetch = async (input, init) => {
233
- var _a;
234
- const requestId = uuidv4();
235
- const request = new Request(input, init);
413
+ const requestId = createRequestId();
414
+ const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !canParseUrl(input) ? new URL(input, location.origin) : input;
415
+ const request = new Request(resolvedInput, init);
416
+ const responsePromise = new DeferredPromise3();
417
+ const controller = new RequestController(request);
236
418
  this.logger.info("[%s] %s", request.method, request.url);
237
- const { interactiveRequest, requestController } = toInteractiveRequest(request);
419
+ this.logger.info("awaiting for the mocked response...");
238
420
  this.logger.info(
239
- 'emitting the "request" event for %d listener(s)...',
421
+ 'emitting the "request" event for %s listener(s)...',
240
422
  this.emitter.listenerCount("request")
241
423
  );
242
- this.emitter.once("request", ({ requestId: pendingRequestId }) => {
243
- if (pendingRequestId !== requestId) {
244
- return;
245
- }
246
- if (requestController.responsePromise.state === "pending") {
247
- requestController.responsePromise.resolve(void 0);
248
- }
249
- });
250
- this.logger.info("awaiting for the mocked response...");
251
- const signal = interactiveRequest.signal;
252
- const requestAborted = new DeferredPromise2();
253
- signal.addEventListener(
254
- "abort",
255
- () => {
256
- requestAborted.reject(signal.reason);
424
+ const isRequestHandled = await handleRequest({
425
+ request,
426
+ requestId,
427
+ emitter: this.emitter,
428
+ controller,
429
+ onResponse: async (response) => {
430
+ this.logger.info("received mocked response!", {
431
+ response
432
+ });
433
+ if (this.emitter.listenerCount("response") > 0) {
434
+ this.logger.info('emitting the "response" event...');
435
+ await emitAsync(this.emitter, "response", {
436
+ // Clone the mocked response for the "response" event listener.
437
+ // This way, the listener can read the response and not lock its body
438
+ // for the actual fetch consumer.
439
+ response: response.clone(),
440
+ isMockedResponse: true,
441
+ request,
442
+ requestId
443
+ });
444
+ }
445
+ Object.defineProperty(response, "url", {
446
+ writable: false,
447
+ enumerable: true,
448
+ configurable: false,
449
+ value: request.url
450
+ });
451
+ responsePromise.resolve(response);
257
452
  },
258
- { once: true }
259
- );
260
- const resolverResult = await until(async () => {
261
- const listenersFinished = emitAsync(this.emitter, "request", {
262
- request: interactiveRequest,
263
- requestId
264
- });
265
- await Promise.race([
266
- requestAborted,
267
- // Put the listeners invocation Promise in the same race condition
268
- // with the request abort Promise because otherwise awaiting the listeners
269
- // would always yield some response (or undefined).
270
- listenersFinished,
271
- requestController.responsePromise
272
- ]);
273
- this.logger.info("all request listeners have been resolved!");
274
- const mockedResponse2 = await requestController.responsePromise;
275
- this.logger.info("event.respondWith called with:", mockedResponse2);
276
- return mockedResponse2;
277
- });
278
- if (requestAborted.state === "rejected") {
279
- return Promise.reject(requestAborted.rejectionReason);
280
- }
281
- if (resolverResult.error) {
282
- return Promise.reject(createNetworkError(resolverResult.error));
283
- }
284
- const mockedResponse = resolverResult.data;
285
- if (mockedResponse && !((_a = request.signal) == null ? void 0 : _a.aborted)) {
286
- this.logger.info("received mocked response:", mockedResponse);
287
- if (isPropertyAccessible(mockedResponse, "type") && mockedResponse.type === "error") {
288
- this.logger.info(
289
- "received a network error response, rejecting the request promise..."
290
- );
291
- return Promise.reject(createNetworkError(mockedResponse));
453
+ onRequestError: (response) => {
454
+ this.logger.info("request has errored!", { response });
455
+ responsePromise.reject(createNetworkError(response));
456
+ },
457
+ onError: (error) => {
458
+ this.logger.info("request has been aborted!", { error });
459
+ responsePromise.reject(error);
292
460
  }
293
- const responseClone = mockedResponse.clone();
294
- this.emitter.emit("response", {
295
- response: responseClone,
296
- isMockedResponse: true,
297
- request: interactiveRequest,
298
- requestId
299
- });
300
- const response = new Response(mockedResponse.body, mockedResponse);
301
- Object.defineProperty(response, "url", {
302
- writable: false,
303
- enumerable: true,
304
- configurable: false,
305
- value: request.url
306
- });
307
- return response;
461
+ });
462
+ if (isRequestHandled) {
463
+ this.logger.info("request has been handled, returning mock promise...");
464
+ return responsePromise;
308
465
  }
309
- this.logger.info("no mocked response received!");
466
+ this.logger.info(
467
+ "no mocked response received, performing request as-is..."
468
+ );
310
469
  return pureFetch(request).then((response) => {
311
- const responseClone = response.clone();
312
- this.logger.info("original fetch performed", responseClone);
313
- this.emitter.emit("response", {
314
- response: responseClone,
315
- isMockedResponse: false,
316
- request: interactiveRequest,
317
- requestId
318
- });
470
+ this.logger.info("original fetch performed", response);
471
+ if (this.emitter.listenerCount("response") > 0) {
472
+ this.logger.info('emitting the "response" event...');
473
+ const responseClone = response.clone();
474
+ this.emitter.emit("response", {
475
+ response: responseClone,
476
+ isMockedResponse: false,
477
+ request,
478
+ requestId
479
+ });
480
+ }
319
481
  return response;
320
482
  });
321
483
  };
@@ -347,9 +509,6 @@ function createNetworkError(cause) {
347
509
  // src/interceptors/XMLHttpRequest/index.ts
348
510
  import { invariant as invariant4 } from "outvariant";
349
511
 
350
- // src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
351
- import { until as until2 } from "@open-draft/until";
352
-
353
512
  // src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
354
513
  import { invariant as invariant3 } from "outvariant";
355
514
  import { isNodeProcess } from "is-node-process";
@@ -547,18 +706,6 @@ function parseJson(data) {
547
706
  }
548
707
  }
549
708
 
550
- // src/utils/responseUtils.ts
551
- var RESPONSE_STATUS_CODES_WITHOUT_BODY = /* @__PURE__ */ new Set([
552
- 101,
553
- 103,
554
- 204,
555
- 205,
556
- 304
557
- ]);
558
- function isResponseWithoutBody(status) {
559
- return RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status);
560
- }
561
-
562
709
  // src/interceptors/XMLHttpRequest/utils/createResponse.ts
563
710
  function createResponse(request, body) {
564
711
  const responseBodyOrNull = isResponseWithoutBody(request.status) ? null : body;
@@ -594,7 +741,7 @@ var XMLHttpRequestController = class {
594
741
  this.method = "GET";
595
742
  this.url = null;
596
743
  this.events = /* @__PURE__ */ new Map();
597
- this.requestId = uuidv4();
744
+ this.requestId = createRequestId();
598
745
  this.requestHeaders = new Headers();
599
746
  this.responseBuffer = new Uint8Array();
600
747
  this.request = createProxy(initialRequest, {
@@ -676,7 +823,10 @@ var XMLHttpRequestController = class {
676
823
  this.request.readyState
677
824
  );
678
825
  if (IS_NODE) {
679
- this.request.setRequestHeader("X-Request-Id", this.requestId);
826
+ this.request.setRequestHeader(
827
+ INTERNAL_REQUEST_ID_HEADER_NAME,
828
+ this.requestId
829
+ );
680
830
  }
681
831
  return invoke();
682
832
  }
@@ -1001,7 +1151,11 @@ function createXMLHttpRequestProxy({
1001
1151
  const XMLHttpRequestProxy = new Proxy(globalThis.XMLHttpRequest, {
1002
1152
  construct(target, args, newTarget) {
1003
1153
  logger.info("constructed new XMLHttpRequest");
1004
- const originalRequest = Reflect.construct(target, args, newTarget);
1154
+ const originalRequest = Reflect.construct(
1155
+ target,
1156
+ args,
1157
+ newTarget
1158
+ );
1005
1159
  const prototypeDescriptors = Object.getOwnPropertyDescriptors(
1006
1160
  target.prototype
1007
1161
  );
@@ -1017,57 +1171,35 @@ function createXMLHttpRequestProxy({
1017
1171
  logger
1018
1172
  );
1019
1173
  xhrRequestController.onRequest = async function({ request, requestId }) {
1020
- const { interactiveRequest, requestController } = toInteractiveRequest(request);
1174
+ const controller = new RequestController(request);
1021
1175
  this.logger.info("awaiting mocked response...");
1022
- emitter.once("request", ({ requestId: pendingRequestId }) => {
1023
- if (pendingRequestId !== requestId) {
1024
- return;
1025
- }
1026
- if (requestController.responsePromise.state === "pending") {
1027
- requestController.respondWith(void 0);
1176
+ this.logger.info(
1177
+ 'emitting the "request" event for %s listener(s)...',
1178
+ emitter.listenerCount("request")
1179
+ );
1180
+ const isRequestHandled = await handleRequest({
1181
+ request,
1182
+ requestId,
1183
+ controller,
1184
+ emitter,
1185
+ onResponse: (response) => {
1186
+ this.respondWith(response);
1187
+ },
1188
+ onRequestError: () => {
1189
+ this.errorWith(new TypeError("Network error"));
1190
+ },
1191
+ onError: (error) => {
1192
+ this.logger.info("request errored!", { error });
1193
+ if (error instanceof Error) {
1194
+ this.errorWith(error);
1195
+ }
1028
1196
  }
1029
1197
  });
1030
- const resolverResult = await until2(async () => {
1198
+ if (!isRequestHandled) {
1031
1199
  this.logger.info(
1032
- 'emitting the "request" event for %s listener(s)...',
1033
- emitter.listenerCount("request")
1200
+ "no mocked response received, performing request as-is..."
1034
1201
  );
1035
- await emitAsync(emitter, "request", {
1036
- request: interactiveRequest,
1037
- requestId
1038
- });
1039
- this.logger.info('all "request" listeners settled!');
1040
- const mockedResponse2 = await requestController.responsePromise;
1041
- this.logger.info("event.respondWith called with:", mockedResponse2);
1042
- return mockedResponse2;
1043
- });
1044
- if (resolverResult.error) {
1045
- this.logger.info(
1046
- "request listener threw an exception, aborting request...",
1047
- resolverResult.error
1048
- );
1049
- xhrRequestController.errorWith(resolverResult.error);
1050
- return;
1051
1202
  }
1052
- const mockedResponse = resolverResult.data;
1053
- if (typeof mockedResponse !== "undefined") {
1054
- this.logger.info(
1055
- "received mocked response: %d %s",
1056
- mockedResponse.status,
1057
- mockedResponse.statusText
1058
- );
1059
- if (mockedResponse.type === "error") {
1060
- this.logger.info(
1061
- "received a network error response, rejecting the request promise..."
1062
- );
1063
- xhrRequestController.errorWith(new TypeError("Network error"));
1064
- return;
1065
- }
1066
- return xhrRequestController.respondWith(mockedResponse);
1067
- }
1068
- this.logger.info(
1069
- "no mocked response received, performing request as-is..."
1070
- );
1071
1203
  };
1072
1204
  xhrRequestController.onResponse = async function({
1073
1205
  response,
@@ -4,6 +4,7 @@ var IS_PATCHED_MODULE = Symbol("isPatchedModule");
4
4
  // src/Interceptor.ts
5
5
  import { Logger } from "@open-draft/logger";
6
6
  import { Emitter } from "strict-event-emitter";
7
+ var INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
7
8
  function getGlobalSymbol(symbol) {
8
9
  return (
9
10
  // @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587
@@ -198,6 +199,11 @@ var BatchInterceptor = class extends Interceptor {
198
199
  }
199
200
  };
200
201
 
202
+ // src/createRequestId.ts
203
+ function createRequestId() {
204
+ return Math.random().toString(16).slice(2);
205
+ }
206
+
201
207
  // src/utils/getCleanUrl.ts
202
208
  function getCleanUrl(url, isAbsolute = true) {
203
209
  return [isAbsolute && url.origin, url.pathname].filter(Boolean).join("");
@@ -226,9 +232,11 @@ function isResponseWithoutBody(status) {
226
232
  }
227
233
  export {
228
234
  BatchInterceptor,
235
+ INTERNAL_REQUEST_ID_HEADER_NAME,
229
236
  IS_PATCHED_MODULE,
230
237
  Interceptor,
231
238
  InterceptorReadyState,
239
+ createRequestId,
232
240
  decodeBuffer,
233
241
  deleteGlobalSymbol,
234
242
  encodeBuffer,