@zimic/interceptor 0.17.0-canary.2 → 0.17.0-canary.4

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 (60) hide show
  1. package/dist/{chunk-TYHJPU5G.js → chunk-MXHLBRPB.js} +521 -61
  2. package/dist/chunk-MXHLBRPB.js.map +1 -0
  3. package/dist/{chunk-3SKHNQLL.mjs → chunk-OGL76CKO.mjs} +510 -60
  4. package/dist/chunk-OGL76CKO.mjs.map +1 -0
  5. package/dist/cli.js +141 -17
  6. package/dist/cli.js.map +1 -1
  7. package/dist/cli.mjs +137 -13
  8. package/dist/cli.mjs.map +1 -1
  9. package/dist/http.d.ts +23 -2
  10. package/dist/http.js +473 -270
  11. package/dist/http.js.map +1 -1
  12. package/dist/http.mjs +473 -270
  13. package/dist/http.mjs.map +1 -1
  14. package/dist/scripts/postinstall.js +6 -6
  15. package/dist/scripts/postinstall.js.map +1 -1
  16. package/dist/scripts/postinstall.mjs +5 -5
  17. package/dist/scripts/postinstall.mjs.map +1 -1
  18. package/dist/server.d.ts +16 -0
  19. package/dist/server.js +6 -6
  20. package/dist/server.mjs +1 -1
  21. package/package.json +12 -11
  22. package/src/cli/browser/init.ts +5 -6
  23. package/src/cli/cli.ts +140 -55
  24. package/src/cli/server/start.ts +22 -7
  25. package/src/cli/server/token/create.ts +33 -0
  26. package/src/cli/server/token/list.ts +23 -0
  27. package/src/cli/server/token/remove.ts +22 -0
  28. package/src/http/interceptor/HttpInterceptorClient.ts +49 -27
  29. package/src/http/interceptor/HttpInterceptorStore.ts +25 -9
  30. package/src/http/interceptor/LocalHttpInterceptor.ts +6 -3
  31. package/src/http/interceptor/RemoteHttpInterceptor.ts +41 -5
  32. package/src/http/interceptor/errors/RunningHttpInterceptorError.ts +1 -1
  33. package/src/http/interceptor/types/options.ts +15 -0
  34. package/src/http/interceptor/types/public.ts +11 -3
  35. package/src/http/interceptorWorker/HttpInterceptorWorker.ts +14 -16
  36. package/src/http/interceptorWorker/RemoteHttpInterceptorWorker.ts +17 -12
  37. package/src/http/interceptorWorker/types/options.ts +1 -0
  38. package/src/http/requestHandler/errors/TimesCheckError.ts +1 -1
  39. package/src/server/InterceptorServer.ts +52 -8
  40. package/src/server/constants.ts +1 -1
  41. package/src/server/errors/InvalidInterceptorTokenError.ts +13 -0
  42. package/src/server/errors/InvalidInterceptorTokenFileError.ts +13 -0
  43. package/src/server/errors/InvalidInterceptorTokenValueError.ts +13 -0
  44. package/src/server/types/options.ts +9 -0
  45. package/src/server/types/public.ts +9 -0
  46. package/src/server/types/schema.ts +4 -4
  47. package/src/server/utils/auth.ts +304 -0
  48. package/src/server/utils/fetch.ts +3 -1
  49. package/src/utils/data.ts +13 -0
  50. package/src/utils/files.ts +14 -0
  51. package/src/utils/{console.ts → logging.ts} +5 -7
  52. package/src/utils/webSocket.ts +57 -11
  53. package/src/webSocket/WebSocketClient.ts +11 -5
  54. package/src/webSocket/WebSocketHandler.ts +72 -51
  55. package/src/webSocket/WebSocketServer.ts +25 -4
  56. package/src/webSocket/constants.ts +2 -0
  57. package/src/webSocket/errors/UnauthorizedWebSocketConnectionError.ts +11 -0
  58. package/src/webSocket/types.ts +49 -52
  59. package/dist/chunk-3SKHNQLL.mjs.map +0 -1
  60. package/dist/chunk-TYHJPU5G.js.map +0 -1
package/dist/http.js CHANGED
@@ -41,7 +41,7 @@ var RunningHttpInterceptorError = class extends Error {
41
41
  __name(this, "RunningHttpInterceptorError");
42
42
  }
43
43
  constructor(additionalMessage) {
44
- super(`The interceptor is running.${additionalMessage}`);
44
+ super(`The interceptor is running. ${additionalMessage}`);
45
45
  this.name = "RunningHttpInterceptorError";
46
46
  }
47
47
  };
@@ -201,6 +201,88 @@ __name(createCachedDynamicImport, "createCachedDynamicImport");
201
201
  __name2(createCachedDynamicImport, "createCachedDynamicImport");
202
202
  var createCachedDynamicImport_default = createCachedDynamicImport;
203
203
 
204
+ // ../zimic-utils/dist/logging/Logger.mjs
205
+ var Logger = class _Logger {
206
+ static {
207
+ __name(this, "_Logger");
208
+ }
209
+ static {
210
+ __name2(this, "Logger");
211
+ }
212
+ prefix;
213
+ raw;
214
+ constructor(options = {}) {
215
+ const { prefix } = options;
216
+ this.prefix = prefix;
217
+ this.raw = prefix ? new _Logger({ ...options, prefix: void 0 }) : this;
218
+ }
219
+ logWithLevel(level, ...messages) {
220
+ if (this.prefix) {
221
+ console[level](this.prefix, ...messages);
222
+ } else {
223
+ console[level](...messages);
224
+ }
225
+ }
226
+ info(...messages) {
227
+ this.logWithLevel("log", ...messages);
228
+ }
229
+ warn(...messages) {
230
+ this.logWithLevel("warn", ...messages);
231
+ }
232
+ error(...messages) {
233
+ this.logWithLevel("error", ...messages);
234
+ }
235
+ table(headers, rows) {
236
+ const columnLengths = headers.map((header) => {
237
+ let maxValueLength = header.title.length;
238
+ for (const row of rows) {
239
+ const value = row[header.property];
240
+ if (value.length > maxValueLength) {
241
+ maxValueLength = value.length;
242
+ }
243
+ }
244
+ return maxValueLength;
245
+ });
246
+ const formattedRows = [];
247
+ const horizontalLine = columnLengths.map((length) => "\u2500".repeat(length));
248
+ formattedRows.push(horizontalLine, []);
249
+ for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
250
+ const header = headers[headerIndex];
251
+ const columnLength = columnLengths[headerIndex];
252
+ const value = header.title;
253
+ formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
254
+ }
255
+ formattedRows.push(horizontalLine);
256
+ for (const row of rows) {
257
+ formattedRows.push([]);
258
+ for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
259
+ const header = headers[headerIndex];
260
+ const columnLength = columnLengths[headerIndex];
261
+ const value = row[header.property];
262
+ formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
263
+ }
264
+ }
265
+ formattedRows.push(horizontalLine);
266
+ const formattedTable = formattedRows.map((row, index) => {
267
+ const isFirstLine = index === 0;
268
+ if (isFirstLine) {
269
+ return `\u250C\u2500${row.join("\u2500\u252C\u2500")}\u2500\u2510`;
270
+ }
271
+ const isLineAfterHeaders = index === 2;
272
+ if (isLineAfterHeaders) {
273
+ return `\u251C\u2500${row.join("\u2500\u253C\u2500")}\u2500\u2524`;
274
+ }
275
+ const isLastLine = index === formattedRows.length - 1;
276
+ if (isLastLine) {
277
+ return `\u2514\u2500${row.join("\u2500\u2534\u2500")}\u2500\u2518`;
278
+ }
279
+ return `\u2502 ${row.join(" \u2502 ")} \u2502`;
280
+ }).join("\n");
281
+ this.logWithLevel("log", formattedTable);
282
+ }
283
+ };
284
+ var Logger_default = Logger;
285
+
204
286
  // src/utils/environment.ts
205
287
  function isServerSide() {
206
288
  return typeof process !== "undefined" && typeof process.versions !== "undefined";
@@ -215,7 +297,10 @@ function isGlobalFileAvailable() {
215
297
  }
216
298
  __name(isGlobalFileAvailable, "isGlobalFileAvailable");
217
299
 
218
- // src/utils/console.ts
300
+ // src/utils/logging.ts
301
+ var logger = new Logger_default({
302
+ prefix: color2__default.default.cyan("[@zimic/interceptor]")
303
+ });
219
304
  function stringifyJSONToLog(value) {
220
305
  return JSON.stringify(
221
306
  value,
@@ -270,12 +355,6 @@ async function formatValueToLog(value, options = {}) {
270
355
  });
271
356
  }
272
357
  __name(formatValueToLog, "formatValueToLog");
273
- function logWithPrefix(messageOrMessages, options = {}) {
274
- const { method = "log" } = options;
275
- const messages = Array.isArray(messageOrMessages) ? messageOrMessages : [messageOrMessages];
276
- console[method](color2__default.default.cyan("[@zimic/interceptor]"), ...messages);
277
- }
278
- __name(logWithPrefix, "logWithPrefix");
279
358
 
280
359
  // src/http/requestHandler/errors/TimesCheckError.ts
281
360
  function createMessageHeader({
@@ -1200,209 +1279,23 @@ var HttpInterceptorWorker = class _HttpInterceptorWorker {
1200
1279
  formatValueToLog(request.searchParams.toObject()),
1201
1280
  formatValueToLog(request.body)
1202
1281
  ]);
1203
- logWithPrefix(
1204
- [
1205
- `${action === "bypass" ? "Warning:" : "Error:"} Request was not handled and was ${action === "bypass" ? color2__default.default.yellow("bypassed") : color2__default.default.red("rejected")}.
1282
+ logger[action === "bypass" ? "warn" : "error"](
1283
+ `${action === "bypass" ? "Warning:" : "Error:"} Request was not handled and was ${action === "bypass" ? color2__default.default.yellow("bypassed") : color2__default.default.red("rejected")}.
1206
1284
 
1207
1285
  `,
1208
- `${request.method} ${request.url}`,
1209
- "\n Headers:",
1210
- formattedHeaders,
1211
- "\n Search params:",
1212
- formattedSearchParams,
1213
- "\n Body:",
1214
- formattedBody,
1215
- "\n\nLearn more: https://github.com/zimicjs/zimic/wiki/api\u2010zimic\u2010interceptor\u2010http#unhandled-requests"
1216
- ],
1217
- { method: action === "bypass" ? "warn" : "error" }
1286
+ `${request.method} ${request.url}`,
1287
+ "\n Headers:",
1288
+ formattedHeaders,
1289
+ "\n Search params:",
1290
+ formattedSearchParams,
1291
+ "\n Body:",
1292
+ formattedBody,
1293
+ "\n\nLearn more: https://github.com/zimicjs/zimic/wiki/api\u2010zimic\u2010interceptor\u2010http#unhandled-requests"
1218
1294
  );
1219
1295
  }
1220
1296
  };
1221
1297
  var HttpInterceptorWorker_default = HttpInterceptorWorker;
1222
1298
 
1223
- // ../zimic-utils/dist/url/validateURLPathParams.mjs
1224
- var DuplicatedPathParamError = class extends Error {
1225
- static {
1226
- __name(this, "DuplicatedPathParamError");
1227
- }
1228
- static {
1229
- __name2(this, "DuplicatedPathParamError");
1230
- }
1231
- constructor(url, paramName) {
1232
- super(
1233
- `The path parameter '${paramName}' appears more than once in the URL '${url.toString()}'. This is not supported. Please make sure that each parameter is unique.`
1234
- );
1235
- this.name = "DuplicatedPathParamError";
1236
- }
1237
- };
1238
- function validateURLPathParams(url) {
1239
- URL_PATH_PARAM_REGEX.lastIndex = 0;
1240
- const matches = url.toString().matchAll(URL_PATH_PARAM_REGEX);
1241
- const uniqueParamNames = /* @__PURE__ */ new Set();
1242
- for (const match of matches) {
1243
- const paramName = match[1];
1244
- if (uniqueParamNames.has(paramName)) {
1245
- throw new DuplicatedPathParamError(url, paramName);
1246
- }
1247
- uniqueParamNames.add(paramName);
1248
- }
1249
- }
1250
- __name(validateURLPathParams, "validateURLPathParams");
1251
- __name2(validateURLPathParams, "validateURLPathParams");
1252
- var validateURLPathParams_default = validateURLPathParams;
1253
- var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
1254
- static {
1255
- __name(this, "LocalHttpInterceptorWorker");
1256
- }
1257
- internalWorker;
1258
- defaultHttpHandler;
1259
- httpHandlerGroups = [];
1260
- constructor(_options) {
1261
- super();
1262
- this.defaultHttpHandler = msw.http.all("*", async (context) => {
1263
- const request = context.request;
1264
- return this.bypassOrRejectUnhandledRequest(request);
1265
- });
1266
- }
1267
- get type() {
1268
- return "local";
1269
- }
1270
- get internalWorkerOrThrow() {
1271
- if (!this.internalWorker) {
1272
- throw new NotRunningHttpInterceptorError_default();
1273
- }
1274
- return this.internalWorker;
1275
- }
1276
- get internalWorkerOrCreate() {
1277
- this.internalWorker ??= this.createInternalWorker();
1278
- return this.internalWorker;
1279
- }
1280
- createInternalWorker() {
1281
- if (isServerSide() && "setupServer" in mswNode__namespace) {
1282
- return mswNode__namespace.setupServer(this.defaultHttpHandler);
1283
- }
1284
- if (isClientSide() && "setupWorker" in mswBrowser__namespace) {
1285
- return mswBrowser__namespace.setupWorker(this.defaultHttpHandler);
1286
- }
1287
- throw new UnknownHttpInterceptorPlatformError_default();
1288
- }
1289
- async start() {
1290
- await super.sharedStart(async () => {
1291
- const internalWorker = this.internalWorkerOrCreate;
1292
- const sharedOptions = {
1293
- onUnhandledRequest: "bypass"
1294
- };
1295
- if (this.isInternalBrowserWorker(internalWorker)) {
1296
- this.platform = "browser";
1297
- await this.startInBrowser(internalWorker, sharedOptions);
1298
- } else {
1299
- this.platform = "node";
1300
- this.startInNode(internalWorker, sharedOptions);
1301
- }
1302
- this.isRunning = true;
1303
- });
1304
- }
1305
- async startInBrowser(internalWorker, sharedOptions) {
1306
- try {
1307
- await internalWorker.start({ ...sharedOptions, quiet: true });
1308
- } catch (error) {
1309
- this.handleBrowserWorkerStartError(error);
1310
- }
1311
- }
1312
- handleBrowserWorkerStartError(error) {
1313
- if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
1314
- throw new UnregisteredBrowserServiceWorkerError_default();
1315
- }
1316
- throw error;
1317
- }
1318
- startInNode(internalWorker, sharedOptions) {
1319
- internalWorker.listen(sharedOptions);
1320
- }
1321
- async stop() {
1322
- await super.sharedStop(() => {
1323
- const internalWorker = this.internalWorkerOrCreate;
1324
- if (this.isInternalBrowserWorker(internalWorker)) {
1325
- this.stopInBrowser(internalWorker);
1326
- } else {
1327
- this.stopInNode(internalWorker);
1328
- }
1329
- this.clearHandlers();
1330
- this.internalWorker = void 0;
1331
- this.isRunning = false;
1332
- });
1333
- }
1334
- stopInBrowser(internalWorker) {
1335
- internalWorker.stop();
1336
- }
1337
- stopInNode(internalWorker) {
1338
- internalWorker.close();
1339
- }
1340
- isInternalBrowserWorker(worker) {
1341
- return "start" in worker && "stop" in worker;
1342
- }
1343
- hasInternalBrowserWorker() {
1344
- return this.isInternalBrowserWorker(this.internalWorkerOrThrow);
1345
- }
1346
- hasInternalNodeWorker() {
1347
- return !this.hasInternalBrowserWorker();
1348
- }
1349
- use(interceptor, method, rawURL, createResponse) {
1350
- const lowercaseMethod = method.toLowerCase();
1351
- const url = new URL(rawURL);
1352
- excludeURLParams_default(url);
1353
- validateURLPathParams_default(url);
1354
- const httpHandler = msw.http[lowercaseMethod](url.toString(), async (context) => {
1355
- const request = context.request;
1356
- const requestClone = request.clone();
1357
- let response = null;
1358
- try {
1359
- response = await createResponse({ ...context, request });
1360
- } catch (error) {
1361
- console.error(error);
1362
- }
1363
- if (!response) {
1364
- return this.bypassOrRejectUnhandledRequest(requestClone);
1365
- }
1366
- if (context.request.method === "HEAD") {
1367
- return new Response(null, {
1368
- status: response.status,
1369
- statusText: response.statusText,
1370
- headers: response.headers
1371
- });
1372
- }
1373
- return response;
1374
- });
1375
- this.internalWorkerOrThrow.use(httpHandler);
1376
- this.httpHandlerGroups.push({ interceptor, httpHandler });
1377
- }
1378
- async bypassOrRejectUnhandledRequest(request) {
1379
- const requestClone = request.clone();
1380
- const strategy = await super.getUnhandledRequestStrategy(request, "local");
1381
- await super.logUnhandledRequestIfNecessary(requestClone, strategy);
1382
- if (strategy?.action === "reject") {
1383
- return Response.error();
1384
- } else {
1385
- return msw.passthrough();
1386
- }
1387
- }
1388
- clearHandlers() {
1389
- this.internalWorkerOrThrow.resetHandlers();
1390
- this.httpHandlerGroups = [];
1391
- }
1392
- clearInterceptorHandlers(interceptor) {
1393
- const groupToRemoveIndex = this.httpHandlerGroups.findIndex((group) => group.interceptor === interceptor);
1394
- removeArrayIndex(this.httpHandlerGroups, groupToRemoveIndex);
1395
- this.internalWorkerOrThrow.resetHandlers();
1396
- for (const { httpHandler } of this.httpHandlerGroups) {
1397
- this.internalWorkerOrThrow.use(httpHandler);
1398
- }
1399
- }
1400
- get interceptorsWithHandlers() {
1401
- return this.httpHandlerGroups.map((group) => group.interceptor);
1402
- }
1403
- };
1404
- var LocalHttpInterceptorWorker_default = LocalHttpInterceptorWorker;
1405
-
1406
1299
  // src/http/requestHandler/RemoteHttpRequestHandler.ts
1407
1300
  var PENDING_PROPERTIES = /* @__PURE__ */ new Set(["then"]);
1408
1301
  var RemoteHttpRequestHandler = class {
@@ -1512,9 +1405,11 @@ var HttpInterceptorClient = class {
1512
1405
  static {
1513
1406
  __name(this, "HttpInterceptorClient");
1514
1407
  }
1515
- worker;
1516
1408
  store;
1517
1409
  _baseURL;
1410
+ createWorker;
1411
+ deleteWorker;
1412
+ worker;
1518
1413
  requestSaving;
1519
1414
  numberOfSavedRequests = 0;
1520
1415
  onUnhandledRequest;
@@ -1530,9 +1425,10 @@ var HttpInterceptorClient = class {
1530
1425
  OPTIONS: /* @__PURE__ */ new Map()
1531
1426
  };
1532
1427
  constructor(options) {
1533
- this.worker = options.worker;
1534
1428
  this.store = options.store;
1535
1429
  this.baseURL = options.baseURL;
1430
+ this.createWorker = options.createWorker;
1431
+ this.deleteWorker = options.deleteWorker;
1536
1432
  this.requestSaving = {
1537
1433
  enabled: options.requestSaving?.enabled ?? this.getDefaultRequestSavingEnabled(),
1538
1434
  safeLimit: options.requestSaving?.safeLimit ?? DEFAULT_REQUEST_SAVING_SAFE_LIMIT
@@ -1562,32 +1458,49 @@ var HttpInterceptorClient = class {
1562
1458
  }
1563
1459
  return this.baseURL.href;
1564
1460
  }
1461
+ get workerOrThrow() {
1462
+ if (!this.worker) {
1463
+ throw new NotRunningHttpInterceptorError_default();
1464
+ }
1465
+ return this.worker;
1466
+ }
1565
1467
  get platform() {
1566
- return this.worker.platform;
1468
+ return this.worker?.platform ?? null;
1567
1469
  }
1568
1470
  async start() {
1569
- await this.worker.start();
1570
- this.worker.registerRunningInterceptor(this);
1571
- this.markAsRunning(true);
1471
+ try {
1472
+ this.worker = this.createWorker();
1473
+ await this.worker.start();
1474
+ this.worker.registerRunningInterceptor(this);
1475
+ this.markAsRunning(true);
1476
+ } catch (error) {
1477
+ await this.stop();
1478
+ throw error;
1479
+ }
1572
1480
  }
1573
1481
  async stop() {
1574
- this.markAsRunning(false);
1575
- this.worker.unregisterRunningInterceptor(this);
1576
- const wasLastRunningInterceptor = this.numberOfRunningInterceptors() === 0;
1577
- if (wasLastRunningInterceptor) {
1578
- await this.worker.stop();
1482
+ this.worker?.unregisterRunningInterceptor(this);
1483
+ const isLastRunningInterceptor = this.numberOfRunningInterceptors === 0 || this.numberOfRunningInterceptors === 1;
1484
+ if (isLastRunningInterceptor) {
1485
+ await this.worker?.stop();
1486
+ this.deleteWorker();
1579
1487
  }
1488
+ this.markAsRunning(false);
1489
+ this.worker = void 0;
1580
1490
  }
1581
1491
  markAsRunning(isRunning) {
1582
- if (this.worker instanceof LocalHttpInterceptorWorker_default) {
1492
+ if (this.workerOrThrow.type === "local") {
1583
1493
  this.store.markLocalInterceptorAsRunning(this, isRunning);
1584
1494
  } else {
1585
1495
  this.store.markRemoteInterceptorAsRunning(this, isRunning, this.baseURL);
1586
1496
  }
1587
1497
  this.isRunning = isRunning;
1588
1498
  }
1589
- numberOfRunningInterceptors() {
1590
- if (this.worker instanceof LocalHttpInterceptorWorker_default) {
1499
+ get numberOfRunningInterceptors() {
1500
+ if (!this.isRunning) {
1501
+ return 0;
1502
+ }
1503
+ if (this.workerOrThrow.type === "local") {
1591
1504
  return this.store.numberOfRunningLocalInterceptors;
1592
1505
  } else {
1593
1506
  return this.store.numberOfRunningRemoteInterceptors(this.baseURL);
@@ -1636,7 +1549,7 @@ var HttpInterceptorClient = class {
1636
1549
  this.handlerClientsByMethod[handler.method].set(handler.path, handlerClients);
1637
1550
  const url = joinURL_default(this.baseURLAsString, handler.path);
1638
1551
  const urlRegex = createRegExpFromURL_default(url);
1639
- const registrationResult = this.worker.use(this, handler.method, url, async (context) => {
1552
+ const registrationResult = this.workerOrThrow.use(this, handler.method, url, async (context) => {
1640
1553
  const response = await this.handleInterceptedRequest(
1641
1554
  urlRegex,
1642
1555
  handler.method,
@@ -1695,10 +1608,9 @@ var HttpInterceptorClient = class {
1695
1608
  }
1696
1609
  }
1697
1610
  clear(options = {}) {
1698
- if (!this.isRunning) {
1699
- throw new NotRunningHttpInterceptorError_default();
1700
- }
1701
- const clearResults = [];
1611
+ const clearResults = [
1612
+ this.workerOrThrow.clearInterceptorHandlers(this)
1613
+ ];
1702
1614
  for (const method of http.HTTP_METHODS) {
1703
1615
  const newClearResults = this.clearMethodHandlers(method);
1704
1616
  for (const result of newClearResults) {
@@ -1707,8 +1619,6 @@ var HttpInterceptorClient = class {
1707
1619
  const handlersByPath = this.handlerClientsByMethod[method];
1708
1620
  handlersByPath.clear();
1709
1621
  }
1710
- const clearResult = this.worker.clearInterceptorHandlers(this);
1711
- clearResults.push(clearResult);
1712
1622
  if (options.onCommitSuccess) {
1713
1623
  void Promise.all(clearResults).then(options.onCommitSuccess, options.onCommitError);
1714
1624
  }
@@ -1726,6 +1636,189 @@ var HttpInterceptorClient = class {
1726
1636
  };
1727
1637
  var HttpInterceptorClient_default = HttpInterceptorClient;
1728
1638
 
1639
+ // ../zimic-utils/dist/url/validateURLPathParams.mjs
1640
+ var DuplicatedPathParamError = class extends Error {
1641
+ static {
1642
+ __name(this, "DuplicatedPathParamError");
1643
+ }
1644
+ static {
1645
+ __name2(this, "DuplicatedPathParamError");
1646
+ }
1647
+ constructor(url, paramName) {
1648
+ super(
1649
+ `The path parameter '${paramName}' appears more than once in the URL '${url.toString()}'. This is not supported. Please make sure that each parameter is unique.`
1650
+ );
1651
+ this.name = "DuplicatedPathParamError";
1652
+ }
1653
+ };
1654
+ function validateURLPathParams(url) {
1655
+ URL_PATH_PARAM_REGEX.lastIndex = 0;
1656
+ const matches = url.toString().matchAll(URL_PATH_PARAM_REGEX);
1657
+ const uniqueParamNames = /* @__PURE__ */ new Set();
1658
+ for (const match of matches) {
1659
+ const paramName = match[1];
1660
+ if (uniqueParamNames.has(paramName)) {
1661
+ throw new DuplicatedPathParamError(url, paramName);
1662
+ }
1663
+ uniqueParamNames.add(paramName);
1664
+ }
1665
+ }
1666
+ __name(validateURLPathParams, "validateURLPathParams");
1667
+ __name2(validateURLPathParams, "validateURLPathParams");
1668
+ var validateURLPathParams_default = validateURLPathParams;
1669
+ var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
1670
+ static {
1671
+ __name(this, "LocalHttpInterceptorWorker");
1672
+ }
1673
+ internalWorker;
1674
+ defaultHttpHandler;
1675
+ httpHandlerGroups = [];
1676
+ constructor(_options) {
1677
+ super();
1678
+ this.defaultHttpHandler = msw.http.all("*", async (context) => {
1679
+ const request = context.request;
1680
+ return this.bypassOrRejectUnhandledRequest(request);
1681
+ });
1682
+ }
1683
+ get type() {
1684
+ return "local";
1685
+ }
1686
+ get internalWorkerOrThrow() {
1687
+ if (!this.internalWorker) {
1688
+ throw new NotRunningHttpInterceptorError_default();
1689
+ }
1690
+ return this.internalWorker;
1691
+ }
1692
+ get internalWorkerOrCreate() {
1693
+ this.internalWorker ??= this.createInternalWorker();
1694
+ return this.internalWorker;
1695
+ }
1696
+ createInternalWorker() {
1697
+ if (isServerSide() && "setupServer" in mswNode__namespace) {
1698
+ return mswNode__namespace.setupServer(this.defaultHttpHandler);
1699
+ }
1700
+ if (isClientSide() && "setupWorker" in mswBrowser__namespace) {
1701
+ return mswBrowser__namespace.setupWorker(this.defaultHttpHandler);
1702
+ }
1703
+ throw new UnknownHttpInterceptorPlatformError_default();
1704
+ }
1705
+ async start() {
1706
+ await super.sharedStart(async () => {
1707
+ const internalWorker = this.internalWorkerOrCreate;
1708
+ const sharedOptions = {
1709
+ onUnhandledRequest: "bypass"
1710
+ };
1711
+ if (this.isInternalBrowserWorker(internalWorker)) {
1712
+ this.platform = "browser";
1713
+ await this.startInBrowser(internalWorker, sharedOptions);
1714
+ } else {
1715
+ this.platform = "node";
1716
+ this.startInNode(internalWorker, sharedOptions);
1717
+ }
1718
+ this.isRunning = true;
1719
+ });
1720
+ }
1721
+ async startInBrowser(internalWorker, sharedOptions) {
1722
+ try {
1723
+ await internalWorker.start({ ...sharedOptions, quiet: true });
1724
+ } catch (error) {
1725
+ this.handleBrowserWorkerStartError(error);
1726
+ }
1727
+ }
1728
+ handleBrowserWorkerStartError(error) {
1729
+ if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
1730
+ throw new UnregisteredBrowserServiceWorkerError_default();
1731
+ }
1732
+ throw error;
1733
+ }
1734
+ startInNode(internalWorker, sharedOptions) {
1735
+ internalWorker.listen(sharedOptions);
1736
+ }
1737
+ async stop() {
1738
+ await super.sharedStop(() => {
1739
+ const internalWorker = this.internalWorkerOrCreate;
1740
+ if (this.isInternalBrowserWorker(internalWorker)) {
1741
+ this.stopInBrowser(internalWorker);
1742
+ } else {
1743
+ this.stopInNode(internalWorker);
1744
+ }
1745
+ this.clearHandlers();
1746
+ this.internalWorker = void 0;
1747
+ this.isRunning = false;
1748
+ });
1749
+ }
1750
+ stopInBrowser(internalWorker) {
1751
+ internalWorker.stop();
1752
+ }
1753
+ stopInNode(internalWorker) {
1754
+ internalWorker.close();
1755
+ }
1756
+ isInternalBrowserWorker(worker) {
1757
+ return "start" in worker && "stop" in worker;
1758
+ }
1759
+ hasInternalBrowserWorker() {
1760
+ return this.isInternalBrowserWorker(this.internalWorkerOrThrow);
1761
+ }
1762
+ hasInternalNodeWorker() {
1763
+ return !this.hasInternalBrowserWorker();
1764
+ }
1765
+ use(interceptor, method, rawURL, createResponse) {
1766
+ const lowercaseMethod = method.toLowerCase();
1767
+ const url = new URL(rawURL);
1768
+ excludeURLParams_default(url);
1769
+ validateURLPathParams_default(url);
1770
+ const httpHandler = msw.http[lowercaseMethod](url.toString(), async (context) => {
1771
+ const request = context.request;
1772
+ const requestClone = request.clone();
1773
+ let response = null;
1774
+ try {
1775
+ response = await createResponse({ ...context, request });
1776
+ } catch (error) {
1777
+ console.error(error);
1778
+ }
1779
+ if (!response) {
1780
+ return this.bypassOrRejectUnhandledRequest(requestClone);
1781
+ }
1782
+ if (context.request.method === "HEAD") {
1783
+ return new Response(null, {
1784
+ status: response.status,
1785
+ statusText: response.statusText,
1786
+ headers: response.headers
1787
+ });
1788
+ }
1789
+ return response;
1790
+ });
1791
+ this.internalWorkerOrThrow.use(httpHandler);
1792
+ this.httpHandlerGroups.push({ interceptor, httpHandler });
1793
+ }
1794
+ async bypassOrRejectUnhandledRequest(request) {
1795
+ const requestClone = request.clone();
1796
+ const strategy = await super.getUnhandledRequestStrategy(request, "local");
1797
+ await super.logUnhandledRequestIfNecessary(requestClone, strategy);
1798
+ if (strategy?.action === "reject") {
1799
+ return Response.error();
1800
+ } else {
1801
+ return msw.passthrough();
1802
+ }
1803
+ }
1804
+ clearHandlers() {
1805
+ this.internalWorkerOrThrow.resetHandlers();
1806
+ this.httpHandlerGroups = [];
1807
+ }
1808
+ clearInterceptorHandlers(interceptor) {
1809
+ const groupToRemoveIndex = this.httpHandlerGroups.findIndex((group) => group.interceptor === interceptor);
1810
+ removeArrayIndex(this.httpHandlerGroups, groupToRemoveIndex);
1811
+ this.internalWorkerOrThrow.resetHandlers();
1812
+ for (const { httpHandler } of this.httpHandlerGroups) {
1813
+ this.internalWorkerOrThrow.use(httpHandler);
1814
+ }
1815
+ }
1816
+ get interceptorsWithHandlers() {
1817
+ return this.httpHandlerGroups.map((group) => group.interceptor);
1818
+ }
1819
+ };
1820
+ var LocalHttpInterceptorWorker_default = LocalHttpInterceptorWorker;
1821
+
1729
1822
  // src/utils/crypto.ts
1730
1823
  var importCrypto = createCachedDynamicImport_default(async () => {
1731
1824
  const globalCrypto = globalThis.crypto;
@@ -1789,6 +1882,19 @@ async function serializeResponse(response) {
1789
1882
  }
1790
1883
  __name(serializeResponse, "serializeResponse");
1791
1884
 
1885
+ // src/webSocket/errors/UnauthorizedWebSocketConnectionError.ts
1886
+ var UnauthorizedWebSocketConnectionError = class extends Error {
1887
+ constructor(event) {
1888
+ super(`${event.reason} (code ${event.code})`);
1889
+ this.event = event;
1890
+ this.name = "UnauthorizedWebSocketConnectionError";
1891
+ }
1892
+ static {
1893
+ __name(this, "UnauthorizedWebSocketConnectionError");
1894
+ }
1895
+ };
1896
+ var UnauthorizedWebSocketConnectionError_default = UnauthorizedWebSocketConnectionError;
1897
+
1792
1898
  // src/utils/webSocket.ts
1793
1899
  var WebSocketTimeoutError = class extends Error {
1794
1900
  static {
@@ -1834,29 +1940,58 @@ var WebSocketCloseTimeoutError = class extends WebSocketTimeoutError {
1834
1940
  var DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT = 60 * 1e3;
1835
1941
  var DEFAULT_WEB_SOCKET_MESSAGE_TIMEOUT = 3 * 60 * 1e3;
1836
1942
  async function waitForOpenClientSocket(socket, options = {}) {
1837
- const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT } = options;
1943
+ const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT, waitForAuthentication = false } = options;
1838
1944
  const isAlreadyOpen = socket.readyState === socket.OPEN;
1839
1945
  if (isAlreadyOpen) {
1840
1946
  return;
1841
1947
  }
1842
1948
  await new Promise((resolve, reject) => {
1843
- function handleOpenError(error) {
1949
+ function removeAllSocketListeners() {
1950
+ socket.removeEventListener("message", handleSocketMessage);
1844
1951
  socket.removeEventListener("open", handleOpenSuccess);
1952
+ socket.removeEventListener("error", handleOpenError);
1953
+ socket.removeEventListener("close", handleClose);
1954
+ }
1955
+ __name(removeAllSocketListeners, "removeAllSocketListeners");
1956
+ function handleOpenError(error) {
1957
+ removeAllSocketListeners();
1845
1958
  reject(error);
1846
1959
  }
1847
1960
  __name(handleOpenError, "handleOpenError");
1961
+ function handleClose(event) {
1962
+ const isUnauthorized = event.code === 1008;
1963
+ if (isUnauthorized) {
1964
+ const unauthorizedError = new UnauthorizedWebSocketConnectionError_default(event);
1965
+ handleOpenError(unauthorizedError);
1966
+ } else {
1967
+ handleOpenError(event);
1968
+ }
1969
+ }
1970
+ __name(handleClose, "handleClose");
1848
1971
  const openTimeout = setTimeout(() => {
1849
1972
  const timeoutError = new WebSocketOpenTimeoutError(timeoutDuration);
1850
1973
  handleOpenError(timeoutError);
1851
1974
  }, timeoutDuration);
1852
1975
  function handleOpenSuccess() {
1853
- socket.removeEventListener("error", handleOpenError);
1976
+ removeAllSocketListeners();
1854
1977
  clearTimeout(openTimeout);
1855
1978
  resolve();
1856
1979
  }
1857
1980
  __name(handleOpenSuccess, "handleOpenSuccess");
1858
- socket.addEventListener("open", handleOpenSuccess);
1981
+ function handleSocketMessage(message) {
1982
+ const hasValidAuth = message.data === "socket:auth:valid";
1983
+ if (hasValidAuth) {
1984
+ handleOpenSuccess();
1985
+ }
1986
+ }
1987
+ __name(handleSocketMessage, "handleSocketMessage");
1988
+ if (waitForAuthentication) {
1989
+ socket.addEventListener("message", handleSocketMessage);
1990
+ } else {
1991
+ socket.addEventListener("open", handleOpenSuccess);
1992
+ }
1859
1993
  socket.addEventListener("error", handleOpenError);
1994
+ socket.addEventListener("close", handleClose);
1860
1995
  });
1861
1996
  }
1862
1997
  __name(waitForOpenClientSocket, "waitForOpenClientSocket");
@@ -1867,28 +2002,36 @@ async function closeClientSocket(socket, options = {}) {
1867
2002
  return;
1868
2003
  }
1869
2004
  await new Promise((resolve, reject) => {
1870
- function handleCloseError(error) {
1871
- socket.removeEventListener("close", handleCloseSuccess);
2005
+ function removeAllSocketListeners() {
2006
+ socket.removeEventListener("error", handleError);
2007
+ socket.removeEventListener("close", handleClose);
2008
+ }
2009
+ __name(removeAllSocketListeners, "removeAllSocketListeners");
2010
+ function handleError(error) {
2011
+ removeAllSocketListeners();
1872
2012
  reject(error);
1873
2013
  }
1874
- __name(handleCloseError, "handleCloseError");
2014
+ __name(handleError, "handleError");
1875
2015
  const closeTimeout = setTimeout(() => {
1876
2016
  const timeoutError = new WebSocketCloseTimeoutError(timeoutDuration);
1877
- handleCloseError(timeoutError);
2017
+ handleError(timeoutError);
1878
2018
  }, timeoutDuration);
1879
- function handleCloseSuccess() {
1880
- socket.removeEventListener("error", handleCloseError);
2019
+ function handleClose() {
2020
+ removeAllSocketListeners();
1881
2021
  clearTimeout(closeTimeout);
1882
2022
  resolve();
1883
2023
  }
1884
- __name(handleCloseSuccess, "handleCloseSuccess");
1885
- socket.addEventListener("error", handleCloseError);
1886
- socket.addEventListener("close", handleCloseSuccess);
2024
+ __name(handleClose, "handleClose");
2025
+ socket.addEventListener("error", handleError);
2026
+ socket.addEventListener("close", handleClose);
1887
2027
  socket.close();
1888
2028
  });
1889
2029
  }
1890
2030
  __name(closeClientSocket, "closeClientSocket");
1891
2031
 
2032
+ // src/webSocket/constants.ts
2033
+ var WEB_SOCKET_CONTROL_MESSAGES = Object.freeze(["socket:auth:valid"]);
2034
+
1892
2035
  // src/webSocket/errors/InvalidWebSocketMessage.ts
1893
2036
  var InvalidWebSocketMessage = class extends Error {
1894
2037
  static {
@@ -1929,8 +2072,11 @@ var WebSocketHandler = class {
1929
2072
  this.socketTimeout = options.socketTimeout ?? DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT;
1930
2073
  this.messageTimeout = options.messageTimeout ?? DEFAULT_WEB_SOCKET_MESSAGE_TIMEOUT;
1931
2074
  }
1932
- async registerSocket(socket) {
1933
- const openPromise = waitForOpenClientSocket(socket, { timeout: this.socketTimeout });
2075
+ async registerSocket(socket, options = {}) {
2076
+ const openPromise = waitForOpenClientSocket(socket, {
2077
+ timeout: this.socketTimeout,
2078
+ waitForAuthentication: options.waitForAuthentication
2079
+ });
1934
2080
  const handleSocketMessage = /* @__PURE__ */ __name(async (rawMessage) => {
1935
2081
  await this.handleSocketMessage(socket, rawMessage);
1936
2082
  }, "handleSocketMessage");
@@ -1943,8 +2089,8 @@ var WebSocketHandler = class {
1943
2089
  socket.addEventListener("error", handleSocketError);
1944
2090
  const handleSocketClose = /* @__PURE__ */ __name(() => {
1945
2091
  socket.removeEventListener("message", handleSocketMessage);
1946
- socket.removeEventListener("error", handleSocketError);
1947
2092
  socket.removeEventListener("close", handleSocketClose);
2093
+ socket.removeEventListener("error", handleSocketError);
1948
2094
  this.removeSocket(socket);
1949
2095
  }, "handleSocketClose");
1950
2096
  socket.addEventListener("close", handleSocketClose);
@@ -1952,6 +2098,9 @@ var WebSocketHandler = class {
1952
2098
  }
1953
2099
  handleSocketMessage = /* @__PURE__ */ __name(async (socket, rawMessage) => {
1954
2100
  try {
2101
+ if (this.isControlMessageData(rawMessage.data)) {
2102
+ return;
2103
+ }
1955
2104
  const stringifiedMessageData = this.readRawMessageData(rawMessage.data);
1956
2105
  const parsedMessageData = this.parseMessage(stringifiedMessageData);
1957
2106
  await this.notifyListeners(parsedMessageData, socket);
@@ -1959,6 +2108,9 @@ var WebSocketHandler = class {
1959
2108
  console.error(error);
1960
2109
  }
1961
2110
  }, "handleSocketMessage");
2111
+ isControlMessageData(messageData) {
2112
+ return typeof messageData === "string" && WEB_SOCKET_CONTROL_MESSAGES.includes(messageData);
2113
+ }
1962
2114
  readRawMessageData(data) {
1963
2115
  if (typeof data === "string") {
1964
2116
  return data;
@@ -1973,7 +2125,7 @@ var WebSocketHandler = class {
1973
2125
  } catch {
1974
2126
  throw new InvalidWebSocketMessage_default(stringifiedMessage);
1975
2127
  }
1976
- if (!this.isValidMessage(parsedMessage)) {
2128
+ if (!this.isMessage(parsedMessage)) {
1977
2129
  throw new InvalidWebSocketMessage_default(stringifiedMessage);
1978
2130
  }
1979
2131
  if (this.isReplyMessage(parsedMessage)) {
@@ -1990,7 +2142,7 @@ var WebSocketHandler = class {
1990
2142
  data: parsedMessage.data
1991
2143
  };
1992
2144
  }
1993
- isValidMessage(message) {
2145
+ isMessage(message) {
1994
2146
  return typeof message === "object" && message !== null && "id" in message && typeof message.id === "string" && "channel" in message && typeof message.channel === "string" && (!("requestId" in message) || typeof message.requestId === "string");
1995
2147
  }
1996
2148
  async notifyListeners(message, socket) {
@@ -2172,10 +2324,11 @@ var WebSocketClient = class extends WebSocketHandler_default {
2172
2324
  get isRunning() {
2173
2325
  return this.socket !== void 0 && this.socket.readyState === this.socket.OPEN;
2174
2326
  }
2175
- async start() {
2176
- this.socket = new ClientSocket__default.default(this.url);
2327
+ async start(options = {}) {
2328
+ const parametersAsString = options.parameters ? Object.entries(options.parameters).map(([key, value]) => `${key}=${value}`).map(encodeURIComponent) : [];
2329
+ this.socket = new ClientSocket__default.default(this.url, parametersAsString);
2177
2330
  try {
2178
- await super.registerSocket(this.socket);
2331
+ await super.registerSocket(this.socket, options);
2179
2332
  } catch (error) {
2180
2333
  await this.stop();
2181
2334
  throw error;
@@ -2196,26 +2349,30 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
2196
2349
  static {
2197
2350
  __name(this, "RemoteHttpInterceptorWorker");
2198
2351
  }
2199
- webSocketClient;
2200
2352
  httpHandlers = /* @__PURE__ */ new Map();
2353
+ webSocketClient;
2354
+ auth;
2201
2355
  constructor(options) {
2202
2356
  super();
2203
- const webSocketServerURL = this.deriveWebSocketServerURL(options.serverURL);
2204
2357
  this.webSocketClient = new WebSocketClient_default({
2205
- url: webSocketServerURL.toString()
2358
+ url: this.getWebSocketServerURL(options.serverURL).toString()
2206
2359
  });
2360
+ this.auth = options.auth;
2207
2361
  }
2208
2362
  get type() {
2209
2363
  return "remote";
2210
2364
  }
2211
- deriveWebSocketServerURL(serverURL) {
2365
+ getWebSocketServerURL(serverURL) {
2212
2366
  const webSocketServerURL = new URL(serverURL);
2213
2367
  webSocketServerURL.protocol = serverURL.protocol.replace(/^http(s)?:$/, "ws$1:");
2214
2368
  return webSocketServerURL;
2215
2369
  }
2216
2370
  async start() {
2217
2371
  await super.sharedStart(async () => {
2218
- await this.webSocketClient.start();
2372
+ await this.webSocketClient.start({
2373
+ parameters: this.auth ? { token: this.auth.token } : void 0,
2374
+ waitForAuthentication: true
2375
+ });
2219
2376
  this.webSocketClient.onEvent("interceptors/responses/create", this.createResponse);
2220
2377
  this.webSocketClient.onEvent("interceptors/responses/unhandled", this.handleUnhandledServerRequest);
2221
2378
  this.platform = this.readPlatform();
@@ -2286,7 +2443,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
2286
2443
  }
2287
2444
  };
2288
2445
  this.httpHandlers.set(handler.id, handler);
2289
- await this.webSocketClient.request("interceptors/workers/use/commit", {
2446
+ await this.webSocketClient.request("interceptors/workers/commit", {
2290
2447
  id: handler.id,
2291
2448
  url: handler.url,
2292
2449
  method
@@ -2298,7 +2455,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
2298
2455
  }
2299
2456
  this.httpHandlers.clear();
2300
2457
  if (this.webSocketClient.isRunning) {
2301
- await this.webSocketClient.request("interceptors/workers/use/reset", void 0);
2458
+ await this.webSocketClient.request("interceptors/workers/reset", void 0);
2302
2459
  }
2303
2460
  }
2304
2461
  async clearInterceptorHandlers(interceptor) {
@@ -2316,7 +2473,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
2316
2473
  url: handler.url,
2317
2474
  method: handler.method
2318
2475
  }));
2319
- await this.webSocketClient.request("interceptors/workers/use/reset", groupsToRecommit);
2476
+ await this.webSocketClient.request("interceptors/workers/reset", groupsToRecommit);
2320
2477
  }
2321
2478
  }
2322
2479
  get interceptorsWithHandlers() {
@@ -2349,8 +2506,15 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
2349
2506
  get localWorker() {
2350
2507
  return this.class._localWorker;
2351
2508
  }
2352
- remoteWorker(baseURL) {
2353
- return this.class.remoteWorkers.get(baseURL.origin);
2509
+ getRemoteWorkerKey(baseURL, options) {
2510
+ if (!options.auth) {
2511
+ return baseURL.origin;
2512
+ }
2513
+ return `${baseURL.origin}:${options.auth.token}`;
2514
+ }
2515
+ remoteWorker(baseURL, options) {
2516
+ const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
2517
+ return this.class.remoteWorkers.get(remoteWorkerKey);
2354
2518
  }
2355
2519
  get numberOfRunningLocalInterceptors() {
2356
2520
  return this.class.runningLocalInterceptors.size;
@@ -2388,20 +2552,22 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
2388
2552
  this.class._localWorker = createdWorker;
2389
2553
  return createdWorker;
2390
2554
  }
2555
+ deleteLocalWorker() {
2556
+ this.class._localWorker = void 0;
2557
+ }
2391
2558
  getOrCreateRemoteWorker(workerOptions) {
2392
- const existingWorker = this.class.remoteWorkers.get(workerOptions.serverURL.origin);
2559
+ const remoteWorkerKey = this.getRemoteWorkerKey(workerOptions.serverURL, { auth: workerOptions.auth });
2560
+ const existingWorker = this.class.remoteWorkers.get(remoteWorkerKey);
2393
2561
  if (existingWorker) {
2394
2562
  return existingWorker;
2395
2563
  }
2396
2564
  const createdWorker = createHttpInterceptorWorker({ ...workerOptions, type: "remote" });
2397
- this.class.remoteWorkers.set(workerOptions.serverURL.origin, createdWorker);
2565
+ this.class.remoteWorkers.set(remoteWorkerKey, createdWorker);
2398
2566
  return createdWorker;
2399
2567
  }
2400
- clear() {
2401
- this.class._localWorker = void 0;
2402
- this.class.runningLocalInterceptors.clear();
2403
- this.class.remoteWorkers.clear();
2404
- this.class.runningRemoteInterceptors.clear();
2568
+ deleteRemoteWorker(baseURL, options) {
2569
+ const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
2570
+ this.class.remoteWorkers.delete(remoteWorkerKey);
2405
2571
  }
2406
2572
  };
2407
2573
  var HttpInterceptorStore_default = HttpInterceptorStore;
@@ -2415,11 +2581,15 @@ var LocalHttpInterceptor = class {
2415
2581
  client;
2416
2582
  constructor(options) {
2417
2583
  const baseURL = new URL(options.baseURL);
2418
- const worker = this.store.getOrCreateLocalWorker({});
2419
2584
  this.client = new HttpInterceptorClient_default({
2420
- worker,
2421
2585
  store: this.store,
2422
2586
  baseURL,
2587
+ createWorker: /* @__PURE__ */ __name(() => {
2588
+ return this.store.getOrCreateLocalWorker({});
2589
+ }, "createWorker"),
2590
+ deleteWorker: /* @__PURE__ */ __name(() => {
2591
+ this.store.deleteLocalWorker();
2592
+ }, "deleteWorker"),
2423
2593
  Handler: LocalHttpRequestHandler_default,
2424
2594
  onUnhandledRequest: options.onUnhandledRequest,
2425
2595
  requestSaving: options.requestSaving
@@ -2502,14 +2672,22 @@ var RemoteHttpInterceptor = class {
2502
2672
  }
2503
2673
  store = new HttpInterceptorStore_default();
2504
2674
  client;
2675
+ _auth;
2505
2676
  constructor(options) {
2677
+ this._auth = options.auth;
2506
2678
  const baseURL = new URL(options.baseURL);
2507
- const serverURL = new URL(baseURL.origin);
2508
- const worker = this.store.getOrCreateRemoteWorker({ serverURL });
2509
2679
  this.client = new HttpInterceptorClient_default({
2510
- worker,
2511
2680
  store: this.store,
2512
2681
  baseURL,
2682
+ createWorker: /* @__PURE__ */ __name(() => {
2683
+ return this.store.getOrCreateRemoteWorker({
2684
+ serverURL: new URL(baseURL.origin),
2685
+ auth: this._auth
2686
+ });
2687
+ }, "createWorker"),
2688
+ deleteWorker: /* @__PURE__ */ __name(() => {
2689
+ this.store.deleteRemoteWorker(baseURL, { auth: options.auth });
2690
+ }, "deleteWorker"),
2513
2691
  Handler: RemoteHttpRequestHandler_default,
2514
2692
  onUnhandledRequest: options.onUnhandledRequest,
2515
2693
  requestSaving: options.requestSaving
@@ -2530,6 +2708,27 @@ var RemoteHttpInterceptor = class {
2530
2708
  set requestSaving(requestSaving) {
2531
2709
  this.client.requestSaving = requestSaving;
2532
2710
  }
2711
+ get auth() {
2712
+ return this._auth;
2713
+ }
2714
+ set auth(auth) {
2715
+ const cannotChangeAuthWhileRunningMessage = "Did you forget to call `await interceptor.stop()` before changing the authentication parameters?";
2716
+ if (this.isRunning) {
2717
+ throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
2718
+ }
2719
+ if (!auth) {
2720
+ this._auth = void 0;
2721
+ return;
2722
+ }
2723
+ this._auth = new Proxy(auth, {
2724
+ set: /* @__PURE__ */ __name((target, property, value) => {
2725
+ if (this.isRunning) {
2726
+ throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
2727
+ }
2728
+ return Reflect.set(target, property, value);
2729
+ }, "set")
2730
+ });
2731
+ }
2533
2732
  get onUnhandledRequest() {
2534
2733
  return this.client.onUnhandledRequest;
2535
2734
  }
@@ -2616,13 +2815,17 @@ function createHttpInterceptor(options) {
2616
2815
  throw new UnknownHttpInterceptorTypeError_default(type);
2617
2816
  }
2618
2817
  __name(createHttpInterceptor, "createHttpInterceptor");
2818
+ /* istanbul ignore next -- @preserve
2819
+ * Ignoring because there will always be a handler for the given method and path at this point. */
2619
2820
  /* istanbul ignore else -- @preserve */
2620
2821
  /* istanbul ignore next -- @preserve
2621
2822
  * Ignoring because checking unknown platforms is not configured in our test setup. */
2622
- /* istanbul ignore next -- @preserve
2623
- * Ignoring because there will always be a handler for the given method and path at this point. */
2624
2823
  /* istanbul ignore next -- @preserve
2625
2824
  * Ignoring as Node.js >=20 provides a global crypto and the import fallback won't run. */
2825
+ /* istanbul ignore else -- @preserve
2826
+ * An unauthorized close event is the only one we expect to happen here. */
2827
+ /* istanbul ignore else -- @preserve
2828
+ * We currently only support the 'socket:auth:valid' message and it is the only possible control message here. */
2626
2829
  /* istanbul ignore next -- @preserve
2627
2830
  * It is difficult to reliably simulate socket errors in tests. */
2628
2831
  /* istanbul ignore else -- @preserve