@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.
- package/dist/{chunk-3O3YPVEG.mjs → chunk-6TSSHQW5.mjs} +50 -25
- package/dist/chunk-6TSSHQW5.mjs.map +1 -0
- package/dist/{chunk-CWBDZYUG.js → chunk-R2ROSKU4.js} +51 -25
- package/dist/chunk-R2ROSKU4.js.map +1 -0
- package/dist/cli.js +7 -7
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +3 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/http.d.ts +84 -40
- package/dist/http.js +144 -83
- package/dist/http.js.map +1 -1
- package/dist/http.mjs +143 -83
- package/dist/http.mjs.map +1 -1
- package/dist/server.d.ts +17 -11
- package/dist/server.js +10 -6
- package/dist/server.mjs +1 -1
- package/package.json +4 -4
- package/src/cli/server/start.ts +1 -1
- package/src/http/index.ts +2 -14
- package/src/http/interceptor/HttpInterceptorClient.ts +51 -19
- package/src/http/interceptor/LocalHttpInterceptor.ts +27 -11
- package/src/http/interceptor/RemoteHttpInterceptor.ts +25 -10
- package/src/http/interceptor/errors/{NotStartedHttpInterceptorError.ts → NotRunningHttpInterceptorError.ts} +3 -3
- package/src/http/interceptor/errors/RunningHttpInterceptorError.ts +15 -0
- package/src/http/interceptor/types/options.ts +4 -6
- package/src/http/interceptor/types/public.ts +58 -20
- package/src/http/interceptorWorker/LocalHttpInterceptorWorker.ts +7 -6
- package/src/http/interceptorWorker/RemoteHttpInterceptorWorker.ts +8 -7
- package/src/http/requestHandler/HttpRequestHandlerClient.ts +4 -6
- package/src/http/requestHandler/types/public.ts +12 -6
- package/src/server/InterceptorServer.ts +28 -11
- package/src/server/constants.ts +1 -0
- package/src/server/errors/NotRunningInterceptorServerError.ts +10 -0
- package/src/server/errors/RunningInterceptorServerError.ts +13 -0
- package/src/server/index.ts +2 -1
- package/src/server/types/public.ts +6 -10
- package/src/webSocket/WebSocketHandler.ts +2 -2
- package/src/webSocket/errors/NotRunningWebSocketHandlerError.ts +8 -0
- package/dist/chunk-3O3YPVEG.mjs.map +0 -1
- package/dist/chunk-CWBDZYUG.js.map +0 -1
- package/src/server/errors/NotStartedInterceptorServerError.ts +0 -10
- 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 {
|
|
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
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
41
|
-
|
|
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.
|
|
60
|
-
this.
|
|
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
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
105
|
+
throw new NotRunningInterceptorServerError();
|
|
89
106
|
}
|
|
90
107
|
return this.webSocketServer;
|
|
91
108
|
}
|
package/src/server/constants.ts
CHANGED
|
@@ -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;
|
package/src/server/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import InterceptorServerNamespace from './namespace/InterceptorServerNamespace';
|
|
2
2
|
|
|
3
|
-
export { default as
|
|
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
|
|
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
|
|
294
|
+
throw new NotRunningWebSocketHandlerError();
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
const stringifiedMessage = JSON.stringify(message);
|