@zimic/interceptor 0.15.0-canary.2 → 0.15.0-canary.3

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 (42) hide show
  1. package/dist/{chunk-3O3YPVEG.mjs → chunk-6TSSHQW5.mjs} +50 -25
  2. package/dist/chunk-6TSSHQW5.mjs.map +1 -0
  3. package/dist/{chunk-CWBDZYUG.js → chunk-R2ROSKU4.js} +51 -25
  4. package/dist/chunk-R2ROSKU4.js.map +1 -0
  5. package/dist/cli.js +7 -7
  6. package/dist/cli.js.map +1 -1
  7. package/dist/cli.mjs +3 -3
  8. package/dist/cli.mjs.map +1 -1
  9. package/dist/http.d.ts +84 -40
  10. package/dist/http.js +144 -83
  11. package/dist/http.js.map +1 -1
  12. package/dist/http.mjs +143 -83
  13. package/dist/http.mjs.map +1 -1
  14. package/dist/server.d.ts +17 -11
  15. package/dist/server.js +10 -6
  16. package/dist/server.mjs +1 -1
  17. package/package.json +4 -4
  18. package/src/cli/server/start.ts +1 -1
  19. package/src/http/index.ts +2 -14
  20. package/src/http/interceptor/HttpInterceptorClient.ts +51 -19
  21. package/src/http/interceptor/LocalHttpInterceptor.ts +27 -11
  22. package/src/http/interceptor/RemoteHttpInterceptor.ts +25 -10
  23. package/src/http/interceptor/errors/{NotStartedHttpInterceptorError.ts → NotRunningHttpInterceptorError.ts} +3 -3
  24. package/src/http/interceptor/errors/RunningHttpInterceptorError.ts +15 -0
  25. package/src/http/interceptor/types/options.ts +4 -6
  26. package/src/http/interceptor/types/public.ts +58 -20
  27. package/src/http/interceptorWorker/LocalHttpInterceptorWorker.ts +7 -6
  28. package/src/http/interceptorWorker/RemoteHttpInterceptorWorker.ts +8 -7
  29. package/src/http/requestHandler/HttpRequestHandlerClient.ts +4 -6
  30. package/src/http/requestHandler/types/public.ts +12 -6
  31. package/src/server/InterceptorServer.ts +28 -11
  32. package/src/server/constants.ts +1 -0
  33. package/src/server/errors/NotRunningInterceptorServerError.ts +10 -0
  34. package/src/server/errors/RunningInterceptorServerError.ts +13 -0
  35. package/src/server/index.ts +2 -1
  36. package/src/server/types/public.ts +6 -10
  37. package/src/webSocket/WebSocketHandler.ts +2 -2
  38. package/src/webSocket/errors/NotRunningWebSocketHandlerError.ts +8 -0
  39. package/dist/chunk-3O3YPVEG.mjs.map +0 -1
  40. package/dist/chunk-CWBDZYUG.js.map +0 -1
  41. package/src/server/errors/NotStartedInterceptorServerError.ts +0 -10
  42. package/src/webSocket/errors/NotStartedWebSocketHandlerError.ts +0 -8
@@ -1,7 +1,7 @@
1
1
  import { HttpSchema } from '@zimic/http';
2
2
 
3
3
  import { SyncHttpInterceptorMethodHandler, AsyncHttpInterceptorMethodHandler } from './handlers';
4
- import { HttpInterceptorPlatform } from './options';
4
+ import { HttpInterceptorPlatform, UnhandledRequestStrategy } from './options';
5
5
 
6
6
  /**
7
7
  * An interceptor to handle HTTP requests and return mock responses. The methods, paths, status codes, parameters, and
@@ -19,19 +19,37 @@ export interface HttpInterceptor<_Schema extends HttpSchema> {
19
19
  */
20
20
  baseURL: string;
21
21
 
22
+ /**
23
+ * Whether {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler request handlers}
24
+ * should save their intercepted requests in memory and make them accessible through
25
+ * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests`}.
26
+ *
27
+ * **Important**: If `saveRequests` is true, make sure to regularly clear the interceptor to avoid that the requests
28
+ * accumulate in memory. A common practice is to call
29
+ * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()`}
30
+ * after each test.
31
+ *
32
+ * @default false
33
+ * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
34
+ * @see {@link https://github.com/zimicjs/zimic/wiki/guides‐testing‐interceptor Testing}
35
+ */
36
+ saveRequests: boolean;
37
+
22
38
  /**
23
39
  * The platform the interceptor is running on.
24
40
  *
41
+ * @readonly
25
42
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorplatform `interceptor.platform` API reference}
26
43
  */
27
- platform: HttpInterceptorPlatform | null;
44
+ get platform(): HttpInterceptorPlatform | null;
28
45
 
29
46
  /**
30
47
  * Whether the interceptor is currently running and ready to use.
31
48
  *
49
+ * @readonly
32
50
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorisrunning `interceptor.isRunning` API reference}
33
51
  */
34
- isRunning: boolean;
52
+ get isRunning(): boolean;
35
53
 
36
54
  /**
37
55
  * Starts the interceptor, allowing it to intercept HTTP requests.
@@ -87,7 +105,7 @@ export interface HttpInterceptor<_Schema extends HttpSchema> {
87
105
  *
88
106
  * This method is useful to reset the interceptor mocks between tests.
89
107
  *
90
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
108
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
91
109
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()` API reference}
92
110
  */
93
111
  clear: (() => void) | (() => Promise<void>);
@@ -103,7 +121,17 @@ export interface HttpInterceptor<_Schema extends HttpSchema> {
103
121
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httpinterceptor `HttpInterceptor` API reference}
104
122
  */
105
123
  export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInterceptor<Schema> {
106
- readonly type: 'local';
124
+ /** @readonly */
125
+ get type(): 'local';
126
+
127
+ /**
128
+ * The strategy to use for unhandled requests. If a request starts with the base URL of the interceptor, but no
129
+ * matching handler exists, this strategy will be used. If a function is provided, it will be called with the
130
+ * unhandled request.
131
+ *
132
+ * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#unhandled-requests Unhandled requests}
133
+ */
134
+ onUnhandledRequest: UnhandledRequestStrategy.Local | undefined;
107
135
 
108
136
  /**
109
137
  * Creates a GET
@@ -126,7 +154,7 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
126
154
  * @returns A GET
127
155
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
128
156
  * for the provided path. The path and method must be declared in the interceptor schema.
129
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
157
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
130
158
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
131
159
  */
132
160
  get: SyncHttpInterceptorMethodHandler<Schema, 'GET'>;
@@ -152,7 +180,7 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
152
180
  * @returns A POST
153
181
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
154
182
  * for the provided path. The path and method must be declared in the interceptor schema.
155
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
183
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
156
184
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
157
185
  */
158
186
  post: SyncHttpInterceptorMethodHandler<Schema, 'POST'>;
@@ -178,7 +206,7 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
178
206
  * @returns A PATCH
179
207
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
180
208
  * for the provided path. The path and method must be declared in the interceptor schema.
181
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
209
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
182
210
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
183
211
  */
184
212
  patch: SyncHttpInterceptorMethodHandler<Schema, 'PATCH'>;
@@ -204,7 +232,7 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
204
232
  * @returns A PUT
205
233
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
206
234
  * for the provided path. The path and method must be declared in the interceptor schema.
207
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
235
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
208
236
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
209
237
  */
210
238
  put: SyncHttpInterceptorMethodHandler<Schema, 'PUT'>;
@@ -230,7 +258,7 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
230
258
  * @returns A DELETE
231
259
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
232
260
  * for the provided path. The path and method must be declared in the interceptor schema.
233
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
261
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
234
262
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
235
263
  */
236
264
  delete: SyncHttpInterceptorMethodHandler<Schema, 'DELETE'>;
@@ -256,7 +284,7 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
256
284
  * @returns A HEAD
257
285
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
258
286
  * for the provided path. The path and method must be declared in the interceptor schema.
259
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
287
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
260
288
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
261
289
  */
262
290
  head: SyncHttpInterceptorMethodHandler<Schema, 'HEAD'>;
@@ -282,7 +310,7 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
282
310
  * @returns An OPTIONS
283
311
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
284
312
  * for the provided path. The path and method must be declared in the interceptor schema.
285
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
313
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
286
314
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
287
315
  */
288
316
  options: SyncHttpInterceptorMethodHandler<Schema, 'OPTIONS'>;
@@ -304,7 +332,17 @@ export interface LocalHttpInterceptor<Schema extends HttpSchema> extends HttpInt
304
332
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httpinterceptor `HttpInterceptor` API reference}
305
333
  */
306
334
  export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpInterceptor<Schema> {
307
- readonly type: 'remote';
335
+ /** @readonly */
336
+ get type(): 'remote';
337
+
338
+ /**
339
+ * The strategy to use for unhandled requests. If a request starts with the base URL of the interceptor, but no
340
+ * matching handler exists, this strategy will be used. If a function is provided, it will be called with the
341
+ * unhandled request.
342
+ *
343
+ * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#unhandled-requests Unhandled requests}
344
+ */
345
+ onUnhandledRequest: UnhandledRequestStrategy.Remote | undefined;
308
346
 
309
347
  /**
310
348
  * Creates a GET
@@ -332,7 +370,7 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
332
370
  * @returns A GET
333
371
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
334
372
  * for the provided path. The path and method must be declared in the interceptor schema.
335
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
373
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
336
374
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
337
375
  */
338
376
  get: AsyncHttpInterceptorMethodHandler<Schema, 'GET'>;
@@ -363,7 +401,7 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
363
401
  * @returns A POST
364
402
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
365
403
  * for the provided path. The path and method must be declared in the interceptor schema.
366
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
404
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
367
405
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
368
406
  */
369
407
  post: AsyncHttpInterceptorMethodHandler<Schema, 'POST'>;
@@ -394,7 +432,7 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
394
432
  * @returns A PATCH
395
433
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
396
434
  * for the provided path. The path and method must be declared in the interceptor schema.
397
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
435
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
398
436
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
399
437
  */
400
438
  patch: AsyncHttpInterceptorMethodHandler<Schema, 'PATCH'>;
@@ -425,7 +463,7 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
425
463
  * @returns A PUT
426
464
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
427
465
  * for the provided path. The path and method must be declared in the interceptor schema.
428
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
466
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
429
467
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
430
468
  */
431
469
  put: AsyncHttpInterceptorMethodHandler<Schema, 'PUT'>;
@@ -456,7 +494,7 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
456
494
  * @returns A DELETE
457
495
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
458
496
  * for the provided path. The path and method must be declared in the interceptor schema.
459
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
497
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
460
498
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
461
499
  */
462
500
  delete: AsyncHttpInterceptorMethodHandler<Schema, 'DELETE'>;
@@ -487,7 +525,7 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
487
525
  * @returns A HEAD
488
526
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
489
527
  * for the provided path. The path and method must be declared in the interceptor schema.
490
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
528
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
491
529
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
492
530
  */
493
531
  head: AsyncHttpInterceptorMethodHandler<Schema, 'HEAD'>;
@@ -518,7 +556,7 @@ export interface RemoteHttpInterceptor<Schema extends HttpSchema> extends HttpIn
518
556
  * @returns An OPTIONS
519
557
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler `HttpRequestHandler`}
520
558
  * for the provided path. The path and method must be declared in the interceptor schema.
521
- * @throws {NotStartedHttpInterceptorError} If the interceptor is not running.
559
+ * @throws {NotRunningHttpInterceptorError} If the interceptor is not running.
522
560
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}
523
561
  */
524
562
  options: AsyncHttpInterceptorMethodHandler<Schema, 'OPTIONS'>;
@@ -8,7 +8,7 @@ import * as mswNode from 'msw/node';
8
8
  import { removeArrayIndex } from '@/utils/arrays';
9
9
  import { isClientSide, isServerSide } from '@/utils/environment';
10
10
 
11
- import NotStartedHttpInterceptorError from '../interceptor/errors/NotStartedHttpInterceptorError';
11
+ import NotRunningHttpInterceptorError from '../interceptor/errors/NotRunningHttpInterceptorError';
12
12
  import UnknownHttpInterceptorPlatformError from '../interceptor/errors/UnknownHttpInterceptorPlatformError';
13
13
  import HttpInterceptorClient from '../interceptor/HttpInterceptorClient';
14
14
  import UnregisteredBrowserServiceWorkerError from './errors/UnregisteredBrowserServiceWorkerError';
@@ -17,8 +17,6 @@ import { LocalHttpInterceptorWorkerOptions } from './types/options';
17
17
  import { BrowserHttpWorker, HttpResponseFactory, HttpWorker, NodeHttpWorker } from './types/requests';
18
18
 
19
19
  class LocalHttpInterceptorWorker extends HttpInterceptorWorker {
20
- readonly type: 'local';
21
-
22
20
  private internalWorker?: HttpWorker;
23
21
 
24
22
  private defaultHttpHandler: MSWHttpHandler;
@@ -28,9 +26,8 @@ class LocalHttpInterceptorWorker extends HttpInterceptorWorker {
28
26
  httpHandler: MSWHttpHandler;
29
27
  }[] = [];
30
28
 
31
- constructor(options: LocalHttpInterceptorWorkerOptions) {
29
+ constructor(_options: LocalHttpInterceptorWorkerOptions) {
32
30
  super();
33
- this.type = options.type;
34
31
 
35
32
  this.defaultHttpHandler = http.all('*', async (context) => {
36
33
  const request = context.request satisfies Request as HttpRequest;
@@ -38,9 +35,13 @@ class LocalHttpInterceptorWorker extends HttpInterceptorWorker {
38
35
  });
39
36
  }
40
37
 
38
+ get type() {
39
+ return 'local' as const;
40
+ }
41
+
41
42
  get internalWorkerOrThrow() {
42
43
  if (!this.internalWorker) {
43
- throw new NotStartedHttpInterceptorError();
44
+ throw new NotRunningHttpInterceptorError();
44
45
  }
45
46
  return this.internalWorker;
46
47
  }
@@ -9,7 +9,7 @@ import { deserializeRequest, serializeResponse } from '@/utils/fetch';
9
9
  import { WebSocket } from '@/webSocket/types';
10
10
  import WebSocketClient from '@/webSocket/WebSocketClient';
11
11
 
12
- import NotStartedHttpInterceptorError from '../interceptor/errors/NotStartedHttpInterceptorError';
12
+ import NotRunningHttpInterceptorError from '../interceptor/errors/NotRunningHttpInterceptorError';
13
13
  import UnknownHttpInterceptorPlatformError from '../interceptor/errors/UnknownHttpInterceptorPlatformError';
14
14
  import HttpInterceptorClient, { AnyHttpInterceptorClient } from '../interceptor/HttpInterceptorClient';
15
15
  import { HttpInterceptorPlatform } from '../interceptor/types/options';
@@ -26,15 +26,12 @@ interface HttpHandler {
26
26
  }
27
27
 
28
28
  class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
29
- readonly type: 'remote';
30
-
31
29
  webSocketClient: WebSocketClient<InterceptorServerWebSocketSchema>;
32
30
 
33
31
  private httpHandlers = new Map<HttpHandler['id'], HttpHandler>();
34
32
 
35
33
  constructor(options: RemoteHttpInterceptorWorkerOptions) {
36
34
  super();
37
- this.type = options.type;
38
35
 
39
36
  const webSocketServerURL = this.deriveWebSocketServerURL(options.serverURL);
40
37
  this.webSocketClient = new WebSocketClient({
@@ -42,6 +39,10 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
42
39
  });
43
40
  }
44
41
 
42
+ get type() {
43
+ return 'remote' as const;
44
+ }
45
+
45
46
  private deriveWebSocketServerURL(serverURL: URL) {
46
47
  const webSocketServerURL = new URL(serverURL);
47
48
  webSocketServerURL.protocol = serverURL.protocol.replace(/^http(s)?:$/, 'ws$1:');
@@ -130,7 +131,7 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
130
131
  createResponse: HttpResponseFactory,
131
132
  ) {
132
133
  if (!this.isRunning) {
133
- throw new NotStartedHttpInterceptorError();
134
+ throw new NotRunningHttpInterceptorError();
134
135
  }
135
136
 
136
137
  const crypto = await importCrypto();
@@ -164,7 +165,7 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
164
165
 
165
166
  async clearHandlers() {
166
167
  if (!this.isRunning) {
167
- throw new NotStartedHttpInterceptorError();
168
+ throw new NotRunningHttpInterceptorError();
168
169
  }
169
170
 
170
171
  this.httpHandlers.clear();
@@ -176,7 +177,7 @@ class RemoteHttpInterceptorWorker extends HttpInterceptorWorker {
176
177
 
177
178
  async clearInterceptorHandlers<Schema extends HttpSchema>(interceptor: HttpInterceptorClient<Schema>) {
178
179
  if (!this.isRunning) {
179
- throw new NotStartedHttpInterceptorError();
180
+ throw new NotRunningHttpInterceptorError();
180
181
  }
181
182
 
182
183
  for (const handler of this.httpHandlers.values()) {
@@ -132,7 +132,7 @@ class HttpRequestHandlerClient<
132
132
  declarationPointer: this.timesDeclarationPointer,
133
133
  unmatchedRequestGroups: this.unmatchedRequestGroups,
134
134
  hasRestrictions: this.restrictions.length > 0,
135
- hasSavedRequests: this.interceptor.shouldSaveRequests,
135
+ hasSavedRequests: this.interceptor.saveRequests,
136
136
  });
137
137
  }
138
138
  }
@@ -168,9 +168,7 @@ class HttpRequestHandlerClient<
168
168
  this.numberOfMatchedRequests++;
169
169
  } else {
170
170
  const shouldSaveUnmatchedGroup =
171
- this.interceptor.shouldSaveRequests &&
172
- this.restrictions.length > 0 &&
173
- this.timesDeclarationPointer !== undefined;
171
+ this.interceptor.saveRequests && this.restrictions.length > 0 && this.timesDeclarationPointer !== undefined;
174
172
 
175
173
  if (shouldSaveUnmatchedGroup) {
176
174
  this.unmatchedRequestGroups.push({ request, diff: restrictionsMatch.diff });
@@ -386,7 +384,7 @@ class HttpRequestHandlerClient<
386
384
  request: HttpInterceptorRequest<Path, Default<Schema[Path][Method]>>,
387
385
  response: HttpInterceptorResponse<Default<Schema[Path][Method]>, StatusCode>,
388
386
  ) {
389
- const interceptedRequest = request as unknown as InterceptedHttpInterceptorRequest<
387
+ const interceptedRequest = request as InterceptedHttpInterceptorRequest<
390
388
  Path,
391
389
  Default<Schema[Path][Method]>,
392
390
  StatusCode
@@ -403,7 +401,7 @@ class HttpRequestHandlerClient<
403
401
  }
404
402
 
405
403
  get requests(): readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[] {
406
- if (!this.interceptor.shouldSaveRequests) {
404
+ if (!this.interceptor.saveRequests) {
407
405
  throw new DisabledRequestSavingError();
408
406
  }
409
407
 
@@ -32,17 +32,19 @@ export interface HttpRequestHandler<
32
32
  /**
33
33
  * The method that matches this handler.
34
34
  *
35
+ * @readonly
35
36
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlermethod `handler.method` API reference}
36
37
  */
37
- method: Method;
38
+ get method(): Method;
38
39
 
39
40
  /**
40
41
  * The path that matches this handler. The base URL of the interceptor is not included, but it is used when matching
41
42
  * requests.
42
43
  *
44
+ * @readonly
43
45
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerpath `handler.path` API reference}
44
46
  */
45
- path: Path;
47
+ get path(): Path;
46
48
  }
47
49
 
48
50
  export interface InternalHttpRequestHandler<
@@ -70,7 +72,8 @@ export interface LocalHttpRequestHandler<
70
72
  Path extends HttpSchemaPath<Schema, Method>,
71
73
  StatusCode extends HttpStatusCode = never,
72
74
  > extends HttpRequestHandler<Schema, Method, Path> {
73
- readonly type: 'local';
75
+ /** @readonly */
76
+ get type(): 'local';
74
77
 
75
78
  /**
76
79
  * Declares a restriction to intercepted request matches. `headers`, `searchParams`, and `body` are supported to limit
@@ -180,9 +183,10 @@ export interface LocalHttpRequestHandler<
180
183
  * for more information.
181
184
  *
182
185
  * @throws {DisabledRequestSavingError} If the interceptor was not created with `saveRequests: true`.
186
+ * @readonly
183
187
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests` API reference}
184
188
  */
185
- requests: readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[];
189
+ get requests(): readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[];
186
190
  }
187
191
 
188
192
  /**
@@ -198,7 +202,8 @@ export interface SyncedRemoteHttpRequestHandler<
198
202
  Path extends HttpSchemaPath<Schema, Method>,
199
203
  StatusCode extends HttpStatusCode = never,
200
204
  > extends HttpRequestHandler<Schema, Method, Path> {
201
- readonly type: 'remote';
205
+ /** @readonly */
206
+ get type(): 'remote';
202
207
 
203
208
  /**
204
209
  * Declares a restriction to intercepted request matches. `headers`, `searchParams`, and `body` are supported to limit
@@ -315,9 +320,10 @@ export interface SyncedRemoteHttpRequestHandler<
315
320
  * for more information.
316
321
  *
317
322
  * @throws {DisabledRequestSavingError} If the interceptor was not created with `saveRequests: true`.
323
+ * @readonly
318
324
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests` API reference}
319
325
  */
320
- requests: readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[];
326
+ get requests(): readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[];
321
327
  }
322
328
 
323
329
  /**
@@ -17,8 +17,10 @@ import {
17
17
  DEFAULT_ACCESS_CONTROL_HEADERS,
18
18
  DEFAULT_PREFLIGHT_STATUS_CODE,
19
19
  DEFAULT_LOG_UNHANDLED_REQUESTS,
20
+ DEFAULT_HOSTNAME,
20
21
  } from './constants';
21
- import NotStartedInterceptorServerError from './errors/NotStartedInterceptorServerError';
22
+ import NotRunningInterceptorServerError from './errors/NotRunningInterceptorServerError';
23
+ import RunningInterceptorServerError from './errors/RunningInterceptorServerError';
22
24
  import { InterceptorServerOptions } from './types/options';
23
25
  import { InterceptorServer as PublicInterceptorServer } from './types/public';
24
26
  import { HttpHandlerCommit, InterceptorServerWebSocketSchema } from './types/schema';
@@ -37,8 +39,8 @@ class InterceptorServer implements PublicInterceptorServer {
37
39
  private httpServer?: HttpServer;
38
40
  private webSocketServer?: WebSocketServer<InterceptorServerWebSocketSchema>;
39
41
 
40
- hostname: string;
41
- port: number | undefined;
42
+ _hostname: string;
43
+ _port: number | undefined;
42
44
  logUnhandledRequests: boolean;
43
45
 
44
46
  private httpHandlerGroups: {
@@ -56,16 +58,31 @@ class InterceptorServer implements PublicInterceptorServer {
56
58
  private knownWorkerSockets = new Set<Socket>();
57
59
 
58
60
  constructor(options: InterceptorServerOptions) {
59
- this.hostname = options.hostname ?? 'localhost';
60
- this.port = options.port;
61
+ this._hostname = options.hostname ?? DEFAULT_HOSTNAME;
62
+ this._port = options.port;
61
63
  this.logUnhandledRequests = options.logUnhandledRequests ?? DEFAULT_LOG_UNHANDLED_REQUESTS;
62
64
  }
63
65
 
64
- get httpURL() {
65
- if (this.port === undefined) {
66
- return undefined;
66
+ get hostname() {
67
+ return this._hostname;
68
+ }
69
+
70
+ set hostname(newHostname: string) {
71
+ if (this.isRunning) {
72
+ throw new RunningInterceptorServerError('Did you forget to stop it before changing the hostname?');
73
+ }
74
+ this._hostname = newHostname;
75
+ }
76
+
77
+ get port() {
78
+ return this._port;
79
+ }
80
+
81
+ set port(newPort: number | undefined) {
82
+ if (this.isRunning) {
83
+ throw new RunningInterceptorServerError('Did you forget to stop it before changing the port?');
67
84
  }
68
- return `http://${this.hostname}:${this.port}`;
85
+ this._port = newPort;
69
86
  }
70
87
 
71
88
  get isRunning() {
@@ -76,7 +93,7 @@ class InterceptorServer implements PublicInterceptorServer {
76
93
  /* istanbul ignore if -- @preserve
77
94
  * The HTTP server is initialized before using this method in normal conditions. */
78
95
  if (!this.httpServer) {
79
- throw new NotStartedInterceptorServerError();
96
+ throw new NotRunningInterceptorServerError();
80
97
  }
81
98
  return this.httpServer;
82
99
  }
@@ -85,7 +102,7 @@ class InterceptorServer implements PublicInterceptorServer {
85
102
  /* istanbul ignore if -- @preserve
86
103
  * The web socket server is initialized before using this method in normal conditions. */
87
104
  if (!this.webSocketServer) {
88
- throw new NotStartedInterceptorServerError();
105
+ throw new NotRunningInterceptorServerError();
89
106
  }
90
107
  return this.webSocketServer;
91
108
  }
@@ -28,4 +28,5 @@ export const DEFAULT_ACCESS_CONTROL_HEADERS = Object.freeze({
28
28
  /** The default status code for the preflight request. */
29
29
  export const DEFAULT_PREFLIGHT_STATUS_CODE = 204;
30
30
 
31
+ export const DEFAULT_HOSTNAME = 'localhost';
31
32
  export const DEFAULT_LOG_UNHANDLED_REQUESTS = true;
@@ -0,0 +1,10 @@
1
+ /* istanbul ignore next -- @preserve */
2
+ /** An error thrown when the interceptor server is not running. */
3
+ class NotRunningInterceptorServerError extends Error {
4
+ constructor() {
5
+ super('The interceptor server is not running. Did you forget to start it?');
6
+ this.name = 'NotRunningInterceptorServerError';
7
+ }
8
+ }
9
+
10
+ export default NotRunningInterceptorServerError;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * An error thrown when the interceptor server is running and some operation requires it to be stopped first.
3
+ *
4
+ * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐server `@zimic/interceptor/server` - API reference}
5
+ */
6
+ class RunningInterceptorServerError extends Error {
7
+ constructor(additionalMessage: string) {
8
+ super(`The interceptor server is running.${additionalMessage}`);
9
+ this.name = 'RunningInterceptorServerError';
10
+ }
11
+ }
12
+
13
+ export default RunningInterceptorServerError;
@@ -1,6 +1,7 @@
1
1
  import InterceptorServerNamespace from './namespace/InterceptorServerNamespace';
2
2
 
3
- export { default as NotStartedInterceptorServerError } from './errors/NotStartedInterceptorServerError';
3
+ export { default as RunningInterceptorServerError } from './errors/RunningInterceptorServerError';
4
+ export { default as NotRunningInterceptorServerError } from './errors/NotRunningInterceptorServerError';
4
5
 
5
6
  export type { InterceptorServerOptions } from './types/options';
6
7
  export type { InterceptorServer } from './types/public';
@@ -6,15 +6,17 @@
6
6
  */
7
7
  export interface InterceptorServer {
8
8
  /**
9
- * The hostname of the server.
9
+ * The hostname of the server. It can be reassigned to a new value if the server is not running.
10
10
  *
11
+ * @throws {RunningInterceptorServerError} When trying to reassign a new hostname with the server still running.
11
12
  * @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
12
13
  */
13
14
  hostname: string;
14
15
 
15
16
  /**
16
- * The port of the server.
17
+ * The port of the server. It can be reassigned to a new value if the server is not running.
17
18
  *
19
+ * @throws {RunningInterceptorServerError} When trying to reassign a new port with the server still running.
18
20
  * @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
19
21
  */
20
22
  port: number | undefined;
@@ -27,19 +29,13 @@ export interface InterceptorServer {
27
29
  */
28
30
  logUnhandledRequests: boolean;
29
31
 
30
- /**
31
- * The HTTP URL of the server.
32
- *
33
- * @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
34
- */
35
- httpURL: string | undefined;
36
-
37
32
  /**
38
33
  * Whether the server is running.
39
34
  *
35
+ * @readonly
40
36
  * @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
41
37
  */
42
- isRunning: boolean;
38
+ get isRunning(): boolean;
43
39
 
44
40
  /**
45
41
  * Starts the server.
@@ -12,7 +12,7 @@ import {
12
12
  } from '@/utils/webSocket';
13
13
 
14
14
  import InvalidWebSocketMessage from './errors/InvalidWebSocketMessage';
15
- import NotStartedWebSocketHandlerError from './errors/NotStartedWebSocketHandlerError';
15
+ import NotRunningWebSocketHandlerError from './errors/NotRunningWebSocketHandlerError';
16
16
  import { WebSocket } from './types';
17
17
 
18
18
  abstract class WebSocketHandler<Schema extends WebSocket.ServiceSchema> {
@@ -291,7 +291,7 @@ abstract class WebSocketHandler<Schema extends WebSocket.ServiceSchema> {
291
291
  sockets: Collection<ClientSocket> = this.sockets,
292
292
  ) {
293
293
  if (!this.isRunning) {
294
- throw new NotStartedWebSocketHandlerError();
294
+ throw new NotRunningWebSocketHandlerError();
295
295
  }
296
296
 
297
297
  const stringifiedMessage = JSON.stringify(message);
@@ -0,0 +1,8 @@
1
+ class NotRunningWebSocketHandlerError extends Error {
2
+ constructor() {
3
+ super('Web socket handler is not running.');
4
+ this.name = 'NotRunningWebSocketHandlerError';
5
+ }
6
+ }
7
+
8
+ export default NotRunningWebSocketHandlerError;