@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
@@ -16,7 +16,6 @@ import validateURLProtocol from '@zimic/utils/url/validateURLProtocol';
16
16
  import { isServerSide } from '@/utils/environment';
17
17
 
18
18
  import HttpInterceptorWorker from '../interceptorWorker/HttpInterceptorWorker';
19
- import LocalHttpInterceptorWorker from '../interceptorWorker/LocalHttpInterceptorWorker';
20
19
  import HttpRequestHandlerClient, { AnyHttpRequestHandlerClient } from '../requestHandler/HttpRequestHandlerClient';
21
20
  import LocalHttpRequestHandler from '../requestHandler/LocalHttpRequestHandler';
22
21
  import RemoteHttpRequestHandler from '../requestHandler/RemoteHttpRequestHandler';
@@ -38,11 +37,13 @@ class HttpInterceptorClient<
38
37
  Schema extends HttpSchema,
39
38
  HandlerConstructor extends HttpRequestHandlerConstructor = HttpRequestHandlerConstructor,
40
39
  > {
41
- private worker: HttpInterceptorWorker;
42
40
  private store: HttpInterceptorStore;
43
-
44
41
  private _baseURL!: URL;
45
42
 
43
+ private createWorker: () => HttpInterceptorWorker;
44
+ private deleteWorker: () => void;
45
+ private worker?: HttpInterceptorWorker;
46
+
46
47
  requestSaving: HttpInterceptorRequestSaving;
47
48
  private numberOfSavedRequests = 0;
48
49
 
@@ -67,18 +68,20 @@ class HttpInterceptorClient<
67
68
  };
68
69
 
69
70
  constructor(options: {
70
- worker: HttpInterceptorWorker;
71
71
  store: HttpInterceptorStore;
72
72
  baseURL: URL;
73
+ createWorker: () => HttpInterceptorWorker;
74
+ deleteWorker: () => void;
73
75
  requestSaving?: Partial<HttpInterceptorRequestSaving>;
74
76
  onUnhandledRequest?: UnhandledRequestStrategy;
75
77
  Handler: HandlerConstructor;
76
78
  }) {
77
- this.worker = options.worker;
78
79
  this.store = options.store;
79
-
80
80
  this.baseURL = options.baseURL;
81
81
 
82
+ this.createWorker = options.createWorker;
83
+ this.deleteWorker = options.deleteWorker;
84
+
82
85
  this.requestSaving = {
83
86
  enabled: options.requestSaving?.enabled ?? this.getDefaultRequestSavingEnabled(),
84
87
  safeLimit: options.requestSaving?.safeLimit ?? DEFAULT_REQUEST_SAVING_SAFE_LIMIT,
@@ -108,6 +111,7 @@ class HttpInterceptorClient<
108
111
 
109
112
  validateURLProtocol(newBaseURL, SUPPORTED_BASE_URL_PROTOCOLS);
110
113
  excludeURLParams(newBaseURL);
114
+
111
115
  this._baseURL = newBaseURL;
112
116
  }
113
117
 
@@ -118,29 +122,48 @@ class HttpInterceptorClient<
118
122
  return this.baseURL.href;
119
123
  }
120
124
 
125
+ private get workerOrThrow() {
126
+ if (!this.worker) {
127
+ throw new NotRunningHttpInterceptorError();
128
+ }
129
+ return this.worker;
130
+ }
131
+
121
132
  get platform() {
122
- return this.worker.platform;
133
+ return this.worker?.platform ?? null;
123
134
  }
124
135
 
125
136
  async start() {
126
- await this.worker.start();
137
+ try {
138
+ this.worker = this.createWorker();
127
139
 
128
- this.worker.registerRunningInterceptor(this);
129
- this.markAsRunning(true);
140
+ await this.worker.start();
141
+ this.worker.registerRunningInterceptor(this);
142
+
143
+ this.markAsRunning(true);
144
+ } catch (error) {
145
+ await this.stop();
146
+ throw error;
147
+ }
130
148
  }
131
149
 
132
150
  async stop() {
133
- this.markAsRunning(false);
134
- this.worker.unregisterRunningInterceptor(this);
151
+ this.worker?.unregisterRunningInterceptor(this);
135
152
 
136
- const wasLastRunningInterceptor = this.numberOfRunningInterceptors() === 0;
137
- if (wasLastRunningInterceptor) {
138
- await this.worker.stop();
153
+ // The number of interceptors will be 0 if the first client could not start due to an error.
154
+ const isLastRunningInterceptor = this.numberOfRunningInterceptors === 0 || this.numberOfRunningInterceptors === 1;
155
+
156
+ if (isLastRunningInterceptor) {
157
+ await this.worker?.stop();
158
+ this.deleteWorker();
139
159
  }
160
+
161
+ this.markAsRunning(false);
162
+ this.worker = undefined;
140
163
  }
141
164
 
142
165
  private markAsRunning(isRunning: boolean) {
143
- if (this.worker instanceof LocalHttpInterceptorWorker) {
166
+ if (this.workerOrThrow.type === 'local') {
144
167
  this.store.markLocalInterceptorAsRunning(this, isRunning);
145
168
  } else {
146
169
  this.store.markRemoteInterceptorAsRunning(this, isRunning, this.baseURL);
@@ -148,8 +171,12 @@ class HttpInterceptorClient<
148
171
  this.isRunning = isRunning;
149
172
  }
150
173
 
151
- private numberOfRunningInterceptors() {
152
- if (this.worker instanceof LocalHttpInterceptorWorker) {
174
+ get numberOfRunningInterceptors() {
175
+ if (!this.isRunning) {
176
+ return 0;
177
+ }
178
+
179
+ if (this.workerOrThrow.type === 'local') {
153
180
  return this.store.numberOfRunningLocalInterceptors;
154
181
  } else {
155
182
  return this.store.numberOfRunningRemoteInterceptors(this.baseURL);
@@ -222,7 +249,7 @@ class HttpInterceptorClient<
222
249
  const url = joinURL(this.baseURLAsString, handler.path);
223
250
  const urlRegex = createRegExpFromURL(url);
224
251
 
225
- const registrationResult = this.worker.use(this, handler.method, url, async (context) => {
252
+ const registrationResult = this.workerOrThrow.use(this, handler.method, url, async (context) => {
226
253
  const response = await this.handleInterceptedRequest(
227
254
  urlRegex,
228
255
  handler.method,
@@ -316,11 +343,9 @@ class HttpInterceptorClient<
316
343
  }
317
344
 
318
345
  clear(options: { onCommitSuccess?: () => void; onCommitError?: () => void } = {}) {
319
- if (!this.isRunning) {
320
- throw new NotRunningHttpInterceptorError();
321
- }
322
-
323
- const clearResults: PossiblePromise<AnyHttpRequestHandlerClient | void>[] = [];
346
+ const clearResults: PossiblePromise<AnyHttpRequestHandlerClient | void>[] = [
347
+ this.workerOrThrow.clearInterceptorHandlers(this),
348
+ ];
324
349
 
325
350
  for (const method of HTTP_METHODS) {
326
351
  const newClearResults = this.clearMethodHandlers(method);
@@ -333,9 +358,6 @@ class HttpInterceptorClient<
333
358
  handlersByPath.clear();
334
359
  }
335
360
 
336
- const clearResult = this.worker.clearInterceptorHandlers(this);
337
- clearResults.push(clearResult);
338
-
339
361
  if (options.onCommitSuccess) {
340
362
  void Promise.all(clearResults).then(options.onCommitSuccess, options.onCommitError);
341
363
  }
@@ -7,6 +7,10 @@ import {
7
7
  } from '../interceptorWorker/types/options';
8
8
  import { AnyHttpInterceptorClient } from './HttpInterceptorClient';
9
9
 
10
+ interface RemoteWorkerKeyOptions {
11
+ auth: RemoteHttpInterceptorWorkerOptions['auth'];
12
+ }
13
+
10
14
  class HttpInterceptorStore {
11
15
  private static _localWorker?: LocalHttpInterceptorWorker;
12
16
  private static runningLocalInterceptors = new Set<AnyHttpInterceptorClient>();
@@ -20,8 +24,16 @@ class HttpInterceptorStore {
20
24
  return this.class._localWorker;
21
25
  }
22
26
 
23
- remoteWorker(baseURL: URL) {
24
- return this.class.remoteWorkers.get(baseURL.origin);
27
+ private getRemoteWorkerKey(baseURL: URL, options: RemoteWorkerKeyOptions) {
28
+ if (!options.auth) {
29
+ return baseURL.origin;
30
+ }
31
+ return `${baseURL.origin}:${options.auth.token}`;
32
+ }
33
+
34
+ remoteWorker(baseURL: URL, options: RemoteWorkerKeyOptions) {
35
+ const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
36
+ return this.class.remoteWorkers.get(remoteWorkerKey);
25
37
  }
26
38
 
27
39
  get numberOfRunningLocalInterceptors() {
@@ -70,23 +82,27 @@ class HttpInterceptorStore {
70
82
  return createdWorker;
71
83
  }
72
84
 
85
+ deleteLocalWorker() {
86
+ this.class._localWorker = undefined;
87
+ }
88
+
73
89
  getOrCreateRemoteWorker(workerOptions: Omit<RemoteHttpInterceptorWorkerOptions, 'type'>) {
74
- const existingWorker = this.class.remoteWorkers.get(workerOptions.serverURL.origin);
90
+ const remoteWorkerKey = this.getRemoteWorkerKey(workerOptions.serverURL, { auth: workerOptions.auth });
91
+ const existingWorker = this.class.remoteWorkers.get(remoteWorkerKey);
92
+
75
93
  if (existingWorker) {
76
94
  return existingWorker;
77
95
  }
78
96
 
79
97
  const createdWorker = createHttpInterceptorWorker({ ...workerOptions, type: 'remote' });
80
- this.class.remoteWorkers.set(workerOptions.serverURL.origin, createdWorker);
98
+ this.class.remoteWorkers.set(remoteWorkerKey, createdWorker);
81
99
 
82
100
  return createdWorker;
83
101
  }
84
102
 
85
- clear() {
86
- this.class._localWorker = undefined;
87
- this.class.runningLocalInterceptors.clear();
88
- this.class.remoteWorkers.clear();
89
- this.class.runningRemoteInterceptors.clear();
103
+ deleteRemoteWorker(baseURL: URL, options: RemoteWorkerKeyOptions) {
104
+ const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
105
+ this.class.remoteWorkers.delete(remoteWorkerKey);
90
106
  }
91
107
  }
92
108
 
@@ -15,12 +15,15 @@ class LocalHttpInterceptor<Schema extends HttpSchema> implements PublicLocalHttp
15
15
  constructor(options: LocalHttpInterceptorOptions) {
16
16
  const baseURL = new URL(options.baseURL);
17
17
 
18
- const worker = this.store.getOrCreateLocalWorker({});
19
-
20
18
  this.client = new HttpInterceptorClient<Schema, typeof LocalHttpRequestHandler>({
21
- worker,
22
19
  store: this.store,
23
20
  baseURL,
21
+ createWorker: () => {
22
+ return this.store.getOrCreateLocalWorker({});
23
+ },
24
+ deleteWorker: () => {
25
+ this.store.deleteLocalWorker();
26
+ },
24
27
  Handler: LocalHttpRequestHandler,
25
28
  onUnhandledRequest: options.onUnhandledRequest,
26
29
  requestSaving: options.requestSaving,
@@ -1,6 +1,7 @@
1
1
  import { HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';
2
2
 
3
3
  import RemoteHttpRequestHandler from '../requestHandler/RemoteHttpRequestHandler';
4
+ import RunningHttpInterceptorError from './errors/RunningHttpInterceptorError';
4
5
  import HttpInterceptorClient from './HttpInterceptorClient';
5
6
  import HttpInterceptorStore from './HttpInterceptorStore';
6
7
  import { AsyncHttpInterceptorMethodHandler } from './types/handlers';
@@ -9,19 +10,27 @@ import { HttpInterceptorRequestSaving, RemoteHttpInterceptor as PublicRemoteHttp
9
10
 
10
11
  class RemoteHttpInterceptor<Schema extends HttpSchema> implements PublicRemoteHttpInterceptor<Schema> {
11
12
  private store = new HttpInterceptorStore();
12
-
13
13
  client: HttpInterceptorClient<Schema, typeof RemoteHttpRequestHandler>;
14
14
 
15
+ private _auth?: RemoteHttpInterceptorOptions['auth'];
16
+
15
17
  constructor(options: RemoteHttpInterceptorOptions) {
16
- const baseURL = new URL(options.baseURL);
18
+ this._auth = options.auth;
17
19
 
18
- const serverURL = new URL(baseURL.origin);
19
- const worker = this.store.getOrCreateRemoteWorker({ serverURL });
20
+ const baseURL = new URL(options.baseURL);
20
21
 
21
22
  this.client = new HttpInterceptorClient<Schema, typeof RemoteHttpRequestHandler>({
22
- worker,
23
23
  store: this.store,
24
24
  baseURL,
25
+ createWorker: () => {
26
+ return this.store.getOrCreateRemoteWorker({
27
+ serverURL: new URL(baseURL.origin),
28
+ auth: this._auth,
29
+ });
30
+ },
31
+ deleteWorker: () => {
32
+ this.store.deleteRemoteWorker(baseURL, { auth: options.auth });
33
+ },
25
34
  Handler: RemoteHttpRequestHandler,
26
35
  onUnhandledRequest: options.onUnhandledRequest,
27
36
  requestSaving: options.requestSaving,
@@ -48,6 +57,33 @@ class RemoteHttpInterceptor<Schema extends HttpSchema> implements PublicRemoteHt
48
57
  this.client.requestSaving = requestSaving;
49
58
  }
50
59
 
60
+ get auth() {
61
+ return this._auth;
62
+ }
63
+
64
+ set auth(auth: RemoteHttpInterceptorOptions['auth'] | undefined) {
65
+ const cannotChangeAuthWhileRunningMessage =
66
+ 'Did you forget to call `await interceptor.stop()` before changing the authentication parameters?';
67
+
68
+ if (this.isRunning) {
69
+ throw new RunningHttpInterceptorError(cannotChangeAuthWhileRunningMessage);
70
+ }
71
+
72
+ if (!auth) {
73
+ this._auth = undefined;
74
+ return;
75
+ }
76
+
77
+ this._auth = new Proxy(auth, {
78
+ set: (target, property, value) => {
79
+ if (this.isRunning) {
80
+ throw new RunningHttpInterceptorError(cannotChangeAuthWhileRunningMessage);
81
+ }
82
+ return Reflect.set(target, property, value);
83
+ },
84
+ });
85
+ }
86
+
51
87
  get onUnhandledRequest() {
52
88
  return this.client.onUnhandledRequest;
53
89
  }
@@ -7,7 +7,7 @@
7
7
  */
8
8
  class RunningHttpInterceptorError extends Error {
9
9
  constructor(additionalMessage: string) {
10
- super(`The interceptor is running.${additionalMessage}`);
10
+ super(`The interceptor is running. ${additionalMessage}`);
11
11
  this.name = 'RunningHttpInterceptorError';
12
12
  }
13
13
  }
@@ -160,6 +160,21 @@ export interface LocalHttpInterceptorOptions extends SharedHttpInterceptorOption
160
160
  export interface RemoteHttpInterceptorOptions extends SharedHttpInterceptorOptions {
161
161
  type: 'remote';
162
162
 
163
+ /**
164
+ * Options to authenticate the interceptor when connecting to an interceptor server. This is required if the
165
+ * interceptor server was started with the `--tokens-dir` option.
166
+ *
167
+ * @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐interceptor‐server#authentication Interceptor server authentication}
168
+ */
169
+ auth?: {
170
+ /**
171
+ * The authentication token to use.
172
+ *
173
+ * @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐interceptor‐server#authentication Interceptor server authentication}
174
+ */
175
+ token: string;
176
+ };
177
+
163
178
  /**
164
179
  * The strategy to use for unhandled requests. If a request starts with the base URL of the interceptor, but no
165
180
  * matching handler exists, this strategy will be used. If a function is provided, it will be called with the
@@ -1,7 +1,7 @@
1
1
  import { HttpSchema } from '@zimic/http';
2
2
 
3
3
  import { SyncHttpInterceptorMethodHandler, AsyncHttpInterceptorMethodHandler } from './handlers';
4
- import { HttpInterceptorPlatform, UnhandledRequestStrategy } from './options';
4
+ import { HttpInterceptorPlatform, RemoteHttpInterceptorOptions, UnhandledRequestStrategy } from './options';
5
5
 
6
6
  /**
7
7
  * Configures if the intercepted requests are saved and how they are handled.
@@ -163,7 +163,7 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
163
163
  *
164
164
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#unhandled-requests Unhandled requests}
165
165
  */
166
- onUnhandledRequest: UnhandledRequestStrategy.Local | undefined;
166
+ onUnhandledRequest?: UnhandledRequestStrategy.Local;
167
167
 
168
168
  /**
169
169
  * Creates a GET
@@ -367,6 +367,14 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
367
367
  /** @readonly */
368
368
  get type(): 'remote';
369
369
 
370
+ /**
371
+ * Options to authenticate the interceptor when connecting to an interceptor server. This is required if the
372
+ * interceptor server was started with the `--tokens-dir` option.
373
+ *
374
+ * @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐interceptor‐server#authentication Interceptor server authentication}
375
+ */
376
+ auth?: RemoteHttpInterceptorOptions['auth'];
377
+
370
378
  /**
371
379
  * The strategy to use for unhandled requests. If a request starts with the base URL of the interceptor, but no
372
380
  * matching handler exists, this strategy will be used. If a function is provided, it will be called with the
@@ -374,7 +382,7 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
374
382
  *
375
383
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#unhandled-requests Unhandled requests}
376
384
  */
377
- onUnhandledRequest: UnhandledRequestStrategy.Remote | undefined;
385
+ onUnhandledRequest?: UnhandledRequestStrategy.Remote;
378
386
 
379
387
  /**
380
388
  * Creates a GET
@@ -16,9 +16,9 @@ import { Default, PossiblePromise } from '@zimic/utils/types';
16
16
  import color from 'picocolors';
17
17
 
18
18
  import { removeArrayElement } from '@/utils/arrays';
19
- import { formatValueToLog, logWithPrefix } from '@/utils/console';
20
19
  import { isClientSide } from '@/utils/environment';
21
20
  import { methodCanHaveResponseBody } from '@/utils/http';
21
+ import { formatValueToLog, logger } from '@/utils/logging';
22
22
 
23
23
  import HttpInterceptorClient, { AnyHttpInterceptorClient } from '../interceptor/HttpInterceptorClient';
24
24
  import { HttpInterceptorPlatform, HttpInterceptorType, UnhandledRequestStrategy } from '../interceptor/types/options';
@@ -35,10 +35,11 @@ import {
35
35
  import { DEFAULT_UNHANDLED_REQUEST_STRATEGY } from './constants';
36
36
  import InvalidFormDataError from './errors/InvalidFormDataError';
37
37
  import InvalidJSONError from './errors/InvalidJSONError';
38
+ import { HttpInterceptorWorkerType } from './types/options';
38
39
  import { HttpResponseFactory } from './types/requests';
39
40
 
40
41
  abstract class HttpInterceptorWorker {
41
- abstract readonly type: 'local' | 'remote';
42
+ abstract get type(): HttpInterceptorWorkerType;
42
43
 
43
44
  platform: HttpInterceptorPlatform | null = null;
44
45
  isRunning = false;
@@ -474,20 +475,17 @@ abstract class HttpInterceptorWorker {
474
475
  formatValueToLog(request.body),
475
476
  ]);
476
477
 
477
- logWithPrefix(
478
- [
479
- `${action === 'bypass' ? 'Warning:' : 'Error:'} Request was not handled and was ` +
480
- `${action === 'bypass' ? color.yellow('bypassed') : color.red('rejected')}.\n\n `,
481
- `${request.method} ${request.url}`,
482
- '\n Headers:',
483
- formattedHeaders,
484
- '\n Search params:',
485
- formattedSearchParams,
486
- '\n Body:',
487
- formattedBody,
488
- '\n\nLearn more: https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#unhandled-requests',
489
- ],
490
- { method: action === 'bypass' ? 'warn' : 'error' },
478
+ logger[action === 'bypass' ? 'warn' : 'error'](
479
+ `${action === 'bypass' ? 'Warning:' : 'Error:'} Request was not handled and was ` +
480
+ `${action === 'bypass' ? color.yellow('bypassed') : color.red('rejected')}.\n\n `,
481
+ `${request.method} ${request.url}`,
482
+ '\n Headers:',
483
+ formattedHeaders,
484
+ '\n Search params:',
485
+ formattedSearchParams,
486
+ '\n Body:',
487
+ formattedBody,
488
+ '\n\nLearn more: https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#unhandled-requests',
491
489
  );
492
490
  }
493
491
  }
@@ -6,7 +6,7 @@ import { HttpHandlerCommit, InterceptorServerWebSocketSchema } from '@/server/ty
6
6
  import { importCrypto } from '@/utils/crypto';
7
7
  import { isClientSide, isServerSide } from '@/utils/environment';
8
8
  import { deserializeRequest, serializeResponse } from '@/utils/fetch';
9
- import { WebSocket } from '@/webSocket/types';
9
+ import { WebSocketEventMessage } from '@/webSocket/types';
10
10
  import WebSocketClient from '@/webSocket/WebSocketClient';
11
11
 
12
12
  import NotRunningHttpInterceptorError from '../interceptor/errors/NotRunningHttpInterceptorError';
@@ -26,24 +26,26 @@ interface HttpHandler {
26
26
  }
27
27
 
28
28
  class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
29
- webSocketClient: WebSocketClient<InterceptorServerWebSocketSchema>;
30
-
31
29
  private httpHandlers = new Map<HttpHandler['id'], HttpHandler>();
32
30
 
31
+ webSocketClient: WebSocketClient<InterceptorServerWebSocketSchema>;
32
+ private auth?: RemoteHttpInterceptorWorkerOptions['auth'];
33
+
33
34
  constructor(options: RemoteHttpInterceptorWorkerOptions) {
34
35
  super();
35
36
 
36
- const webSocketServerURL = this.deriveWebSocketServerURL(options.serverURL);
37
37
  this.webSocketClient = new WebSocketClient({
38
- url: webSocketServerURL.toString(),
38
+ url: this.getWebSocketServerURL(options.serverURL).toString(),
39
39
  });
40
+
41
+ this.auth = options.auth;
40
42
  }
41
43
 
42
44
  get type() {
43
45
  return 'remote' as const;
44
46
  }
45
47
 
46
- private deriveWebSocketServerURL(serverURL: URL) {
48
+ private getWebSocketServerURL(serverURL: URL) {
47
49
  const webSocketServerURL = new URL(serverURL);
48
50
  webSocketServerURL.protocol = serverURL.protocol.replace(/^http(s)?:$/, 'ws$1:');
49
51
  return webSocketServerURL;
@@ -51,7 +53,10 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
51
53
 
52
54
  async start() {
53
55
  await super.sharedStart(async () => {
54
- await this.webSocketClient.start();
56
+ await this.webSocketClient.start({
57
+ parameters: this.auth ? { token: this.auth.token } : undefined,
58
+ waitForAuthentication: true,
59
+ });
55
60
 
56
61
  this.webSocketClient.onEvent('interceptors/responses/create', this.createResponse);
57
62
  this.webSocketClient.onEvent('interceptors/responses/unhandled', this.handleUnhandledServerRequest);
@@ -62,7 +67,7 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
62
67
  }
63
68
 
64
69
  private createResponse = async (
65
- message: WebSocket.ServiceEventMessage<InterceptorServerWebSocketSchema, 'interceptors/responses/create'>,
70
+ message: WebSocketEventMessage<InterceptorServerWebSocketSchema, 'interceptors/responses/create'>,
66
71
  ) => {
67
72
  const { handlerId, request: serializedRequest } = message.data;
68
73
 
@@ -87,7 +92,7 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
87
92
  };
88
93
 
89
94
  private handleUnhandledServerRequest = async (
90
- message: WebSocket.ServiceEventMessage<InterceptorServerWebSocketSchema, 'interceptors/responses/unhandled'>,
95
+ message: WebSocketEventMessage<InterceptorServerWebSocketSchema, 'interceptors/responses/unhandled'>,
91
96
  ) => {
92
97
  const { request: serializedRequest } = message.data;
93
98
  const request = deserializeRequest(serializedRequest);
@@ -156,7 +161,7 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
156
161
 
157
162
  this.httpHandlers.set(handler.id, handler);
158
163
 
159
- await this.webSocketClient.request('interceptors/workers/use/commit', {
164
+ await this.webSocketClient.request('interceptors/workers/commit', {
160
165
  id: handler.id,
161
166
  url: handler.url,
162
167
  method,
@@ -171,7 +176,7 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
171
176
  this.httpHandlers.clear();
172
177
 
173
178
  if (this.webSocketClient.isRunning) {
174
- await this.webSocketClient.request('interceptors/workers/use/reset', undefined);
179
+ await this.webSocketClient.request('interceptors/workers/reset', undefined);
175
180
  }
176
181
  }
177
182
 
@@ -193,7 +198,7 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
193
198
  method: handler.method,
194
199
  }));
195
200
 
196
- await this.webSocketClient.request('interceptors/workers/use/reset', groupsToRecommit);
201
+ await this.webSocketClient.request('interceptors/workers/reset', groupsToRecommit);
197
202
  }
198
203
  }
199
204
 
@@ -5,6 +5,7 @@ export interface LocalHttpInterceptorWorkerOptions {
5
5
  export interface RemoteHttpInterceptorWorkerOptions {
6
6
  type: 'remote';
7
7
  serverURL: URL;
8
+ auth?: { token: string };
8
9
  }
9
10
 
10
11
  export type HttpInterceptorWorkerOptions = LocalHttpInterceptorWorkerOptions | RemoteHttpInterceptorWorkerOptions;
@@ -3,7 +3,7 @@ import { Range } from '@zimic/utils/types';
3
3
  import color from 'picocolors';
4
4
 
5
5
  import { HttpInterceptorRequestSaving } from '@/http/interceptor/types/public';
6
- import { stringifyValueToLog } from '@/utils/console';
6
+ import { stringifyValueToLog } from '@/utils/logging';
7
7
 
8
8
  import { UnmatchedHttpInterceptorRequestGroup } from '../types/restrictions';
9
9
  import TimesDeclarationPointer from './TimesDeclarationPointer';