@zimic/interceptor 0.16.0-canary.1 → 0.16.0-canary.11
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/README.md +4 -5
- package/dist/{chunk-6TSSHQW5.mjs → chunk-NTRC2S4I.mjs} +253 -312
- package/dist/chunk-NTRC2S4I.mjs.map +1 -0
- package/dist/{chunk-R2ROSKU4.js → chunk-O6ZIPCUJ.js} +254 -313
- package/dist/chunk-O6ZIPCUJ.js.map +1 -0
- package/dist/cli.js +9 -9
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +5 -5
- package/dist/cli.mjs.map +1 -1
- package/dist/http.d.ts +156 -176
- package/dist/http.js +265 -324
- package/dist/http.js.map +1 -1
- package/dist/http.mjs +263 -323
- package/dist/http.mjs.map +1 -1
- package/dist/server.d.ts +20 -46
- package/dist/server.js +7 -7
- package/dist/server.mjs +1 -1
- package/package.json +8 -8
- package/src/cli/browser/init.ts +2 -2
- package/src/cli/server/start.ts +2 -2
- package/src/http/index.ts +6 -13
- package/src/http/interceptor/HttpInterceptorClient.ts +30 -15
- package/src/http/interceptor/LocalHttpInterceptor.ts +8 -8
- package/src/http/interceptor/RemoteHttpInterceptor.ts +8 -8
- package/src/http/interceptor/errors/RequestSavingSafeLimitExceededError.ts +22 -0
- package/src/http/interceptor/factory.ts +1 -1
- package/src/http/interceptor/types/options.ts +4 -11
- package/src/http/interceptor/types/public.ts +44 -12
- package/src/http/interceptor/types/schema.ts +2 -2
- package/src/http/interceptorWorker/HttpInterceptorWorker.ts +6 -31
- package/src/http/requestHandler/HttpRequestHandlerClient.ts +15 -5
- package/src/http/requestHandler/errors/DisabledRequestSavingError.ts +2 -2
- package/src/http/requestHandler/errors/TimesCheckError.ts +15 -14
- package/src/http/requestHandler/types/public.ts +16 -8
- package/src/server/index.ts +1 -11
- package/src/utils/console.ts +2 -2
- package/dist/chunk-6TSSHQW5.mjs.map +0 -1
- package/dist/chunk-R2ROSKU4.js.map +0 -1
- package/src/http/interceptorWorker/HttpInterceptorWorkerStore.ts +0 -34
- package/src/http/namespace/HttpInterceptorNamespace.ts +0 -81
- package/src/server/namespace/InterceptorServerNamespace.ts +0 -21
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
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
|
+
declare class RunningInterceptorServerError extends Error {
|
|
7
|
+
constructor(additionalMessage: string);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** An error thrown when the interceptor server is not running. */
|
|
11
|
+
declare class NotRunningInterceptorServerError extends Error {
|
|
12
|
+
constructor();
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
/**
|
|
2
16
|
* The options to create an
|
|
3
17
|
* {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server interceptor server}.
|
|
@@ -73,48 +87,6 @@ interface InterceptorServer {
|
|
|
73
87
|
stop: () => Promise<void>;
|
|
74
88
|
}
|
|
75
89
|
|
|
76
|
-
/**
|
|
77
|
-
* Creates an {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server interceptor server}.
|
|
78
|
-
*
|
|
79
|
-
* @param options The options to create the server.
|
|
80
|
-
* @returns The created server.
|
|
81
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server-programmatic-usage `zimic-interceptor server` programmatic usage}
|
|
82
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/getting‐started#remote-http-interceptors Remote HTTP Interceptors} .
|
|
83
|
-
*/
|
|
84
|
-
declare function createInterceptorServer(options?: InterceptorServerOptions): InterceptorServer;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* A namespace of interceptor server resources for handling HTTP requests.
|
|
88
|
-
*
|
|
89
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server-programmatic-usage `zimic-interceptor server` programmatic usage}
|
|
90
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/getting‐started#remote-http-interceptors Remote HTTP Interceptors} .
|
|
91
|
-
*/
|
|
92
|
-
declare class InterceptorServerNamespace {
|
|
93
|
-
/**
|
|
94
|
-
* Creates an {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server interceptor server}.
|
|
95
|
-
*
|
|
96
|
-
* @param options The options to create the server.
|
|
97
|
-
* @returns The created server.
|
|
98
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server-programmatic-usage `zimic-interceptor server` programmatic usage}
|
|
99
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/getting‐started#remote-http-interceptors Remote HTTP Interceptors} .
|
|
100
|
-
*/
|
|
101
|
-
create: typeof createInterceptorServer;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* An error thrown when the interceptor server is running and some operation requires it to be stopped first.
|
|
106
|
-
*
|
|
107
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐server `@zimic/interceptor/server` - API reference}
|
|
108
|
-
*/
|
|
109
|
-
declare class RunningInterceptorServerError extends Error {
|
|
110
|
-
constructor(additionalMessage: string);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/** An error thrown when the interceptor server is not running. */
|
|
114
|
-
declare class NotRunningInterceptorServerError extends Error {
|
|
115
|
-
constructor();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
90
|
/** The default access control headers for the server. */
|
|
119
91
|
declare const DEFAULT_ACCESS_CONTROL_HEADERS: Readonly<{
|
|
120
92
|
'access-control-allow-origin': "*";
|
|
@@ -127,11 +99,13 @@ declare const DEFAULT_ACCESS_CONTROL_HEADERS: Readonly<{
|
|
|
127
99
|
declare const DEFAULT_PREFLIGHT_STATUS_CODE = 204;
|
|
128
100
|
|
|
129
101
|
/**
|
|
130
|
-
*
|
|
102
|
+
* Creates an {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server interceptor server}.
|
|
131
103
|
*
|
|
132
|
-
* @
|
|
104
|
+
* @param options The options to create the server.
|
|
105
|
+
* @returns The created server.
|
|
106
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server-programmatic-usage `zimic-interceptor server` programmatic usage}
|
|
133
107
|
* @see {@link https://github.com/zimicjs/zimic/wiki/getting‐started#remote-http-interceptors Remote HTTP Interceptors} .
|
|
134
108
|
*/
|
|
135
|
-
declare
|
|
109
|
+
declare function createInterceptorServer(options?: InterceptorServerOptions): InterceptorServer;
|
|
136
110
|
|
|
137
|
-
export { DEFAULT_ACCESS_CONTROL_HEADERS, DEFAULT_PREFLIGHT_STATUS_CODE, type InterceptorServer,
|
|
111
|
+
export { DEFAULT_ACCESS_CONTROL_HEADERS, DEFAULT_PREFLIGHT_STATUS_CODE, type InterceptorServer, type InterceptorServerOptions, NotRunningInterceptorServerError, RunningInterceptorServerError, createInterceptorServer };
|
package/dist/server.js
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkO6ZIPCUJ_js = require('./chunk-O6ZIPCUJ.js');
|
|
4
4
|
require('./chunk-WCQVDF3K.js');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, "DEFAULT_ACCESS_CONTROL_HEADERS", {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunkO6ZIPCUJ_js.DEFAULT_ACCESS_CONTROL_HEADERS; }
|
|
11
11
|
});
|
|
12
12
|
Object.defineProperty(exports, "DEFAULT_PREFLIGHT_STATUS_CODE", {
|
|
13
13
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
14
|
+
get: function () { return chunkO6ZIPCUJ_js.DEFAULT_PREFLIGHT_STATUS_CODE; }
|
|
15
15
|
});
|
|
16
16
|
Object.defineProperty(exports, "NotRunningInterceptorServerError", {
|
|
17
17
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
18
|
+
get: function () { return chunkO6ZIPCUJ_js.NotRunningInterceptorServerError_default; }
|
|
19
19
|
});
|
|
20
20
|
Object.defineProperty(exports, "RunningInterceptorServerError", {
|
|
21
21
|
enumerable: true,
|
|
22
|
-
get: function () { return
|
|
22
|
+
get: function () { return chunkO6ZIPCUJ_js.RunningInterceptorServerError_default; }
|
|
23
23
|
});
|
|
24
|
-
Object.defineProperty(exports, "
|
|
24
|
+
Object.defineProperty(exports, "createInterceptorServer", {
|
|
25
25
|
enumerable: true,
|
|
26
|
-
get: function () { return
|
|
26
|
+
get: function () { return chunkO6ZIPCUJ_js.createInterceptorServer; }
|
|
27
27
|
});
|
|
28
28
|
//# sourceMappingURL=server.js.map
|
|
29
29
|
//# sourceMappingURL=server.js.map
|
package/dist/server.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DEFAULT_ACCESS_CONTROL_HEADERS, DEFAULT_PREFLIGHT_STATUS_CODE, NotRunningInterceptorServerError_default as NotRunningInterceptorServerError, RunningInterceptorServerError_default as RunningInterceptorServerError,
|
|
1
|
+
export { DEFAULT_ACCESS_CONTROL_HEADERS, DEFAULT_PREFLIGHT_STATUS_CODE, NotRunningInterceptorServerError_default as NotRunningInterceptorServerError, RunningInterceptorServerError_default as RunningInterceptorServerError, createInterceptorServer } from './chunk-NTRC2S4I.mjs';
|
|
2
2
|
import './chunk-CGILA3WO.mjs';
|
|
3
3
|
//# sourceMappingURL=server.mjs.map
|
|
4
4
|
//# sourceMappingURL=server.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zimic/interceptor",
|
|
3
|
-
"description": "TypeScript-first HTTP intercepting and mocking",
|
|
3
|
+
"description": "Next-gen, TypeScript-first HTTP intercepting and mocking",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"zimic",
|
|
6
6
|
"typescript",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"api",
|
|
15
15
|
"static"
|
|
16
16
|
],
|
|
17
|
-
"version": "0.16.0-canary.
|
|
17
|
+
"version": "0.16.0-canary.11",
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
20
|
"url": "https://github.com/zimicjs/zimic.git",
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@whatwg-node/server": "0.10.1",
|
|
78
|
-
"chalk": "4.1.2",
|
|
79
78
|
"execa": "9.5.2",
|
|
80
79
|
"isomorphic-ws": "5.0.0",
|
|
81
80
|
"msw": "2.7.3",
|
|
81
|
+
"picocolors": "^1.1.1",
|
|
82
82
|
"ws": "8.18.1",
|
|
83
83
|
"yargs": "17.7.2"
|
|
84
84
|
},
|
|
@@ -89,21 +89,21 @@
|
|
|
89
89
|
"@types/node": "^22.13.10",
|
|
90
90
|
"@types/ws": "^8.18.0",
|
|
91
91
|
"@types/yargs": "^17.0.33",
|
|
92
|
-
"@vitest/browser": "^3.0.
|
|
93
|
-
"@vitest/coverage-istanbul": "^3.0.
|
|
92
|
+
"@vitest/browser": "^3.0.9",
|
|
93
|
+
"@vitest/coverage-istanbul": "^3.0.9",
|
|
94
94
|
"dotenv-cli": "^8.0.0",
|
|
95
95
|
"eslint": "^9.22.0",
|
|
96
|
-
"playwright": "^1.51.
|
|
96
|
+
"playwright": "^1.51.1",
|
|
97
97
|
"tsup": "^8.4.0",
|
|
98
98
|
"typescript": "^5.8.2",
|
|
99
|
-
"vitest": "^3.0.
|
|
99
|
+
"vitest": "^3.0.9",
|
|
100
100
|
"@zimic/eslint-config-node": "0.0.0",
|
|
101
101
|
"@zimic/tsconfig": "0.0.0",
|
|
102
102
|
"@zimic/lint-staged-config": "0.0.0",
|
|
103
103
|
"@zimic/utils": "0.0.0"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
|
-
"@zimic/http": "^0.
|
|
106
|
+
"@zimic/http": "^0.2.0 || ^0.2.0-canary.0",
|
|
107
107
|
"typescript": ">=4.8.0"
|
|
108
108
|
},
|
|
109
109
|
"peerDependenciesMeta": {
|
package/src/cli/browser/init.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
1
|
import filesystem from 'fs/promises';
|
|
3
2
|
import path from 'path';
|
|
3
|
+
import color from 'picocolors';
|
|
4
4
|
|
|
5
5
|
import { logWithPrefix } from '@/utils/console';
|
|
6
6
|
|
|
@@ -20,7 +20,7 @@ async function initializeBrowserServiceWorker({ publicDirectory }: BrowserServic
|
|
|
20
20
|
const destinationPath = path.join(absolutePublicDirectory, SERVICE_WORKER_FILE_NAME);
|
|
21
21
|
await filesystem.copyFile(MOCK_SERVICE_WORKER_PATH, destinationPath);
|
|
22
22
|
|
|
23
|
-
logWithPrefix(`Service worker script saved to ${
|
|
23
|
+
logWithPrefix(`Service worker script saved to ${color.green(destinationPath)}!`);
|
|
24
24
|
logWithPrefix('You can now use browser interceptors!');
|
|
25
25
|
}
|
|
26
26
|
|
package/src/cli/server/start.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InterceptorServer,
|
|
1
|
+
import { InterceptorServer, createInterceptorServer } from '@/server';
|
|
2
2
|
import { InterceptorServerOptions } from '@/server/types/options';
|
|
3
3
|
import { logWithPrefix } from '@/utils/console';
|
|
4
4
|
import {
|
|
@@ -26,7 +26,7 @@ async function startInterceptorServer({
|
|
|
26
26
|
logUnhandledRequests,
|
|
27
27
|
onReady,
|
|
28
28
|
}: InterceptorServerStartOptions) {
|
|
29
|
-
const server =
|
|
29
|
+
const server = createInterceptorServer({
|
|
30
30
|
hostname,
|
|
31
31
|
port,
|
|
32
32
|
logUnhandledRequests,
|
package/src/http/index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import HttpInterceptorNamespace from './namespace/HttpInterceptorNamespace';
|
|
2
|
-
|
|
3
|
-
export { default as InvalidJSONError } from './interceptorWorker/errors/InvalidJSONError';
|
|
4
|
-
export { default as InvalidFormDataError } from './interceptorWorker/errors/InvalidFormDataError';
|
|
5
1
|
export { default as RunningHttpInterceptorError } from './interceptor/errors/RunningHttpInterceptorError';
|
|
6
2
|
export { default as NotRunningHttpInterceptorError } from './interceptor/errors/NotRunningHttpInterceptorError';
|
|
7
3
|
export { default as UnknownHttpInterceptorPlatformError } from './interceptor/errors/UnknownHttpInterceptorPlatformError';
|
|
8
4
|
export { default as UnknownHttpInterceptorTypeError } from './interceptor/errors/UnknownHttpInterceptorTypeError';
|
|
5
|
+
export { default as RequestSavingSafeLimitExceededError } from './interceptor/errors/RequestSavingSafeLimitExceededError';
|
|
6
|
+
|
|
7
|
+
export { default as InvalidFormDataError } from './interceptorWorker/errors/InvalidFormDataError';
|
|
8
|
+
export { default as InvalidJSONError } from './interceptorWorker/errors/InvalidJSONError';
|
|
9
9
|
export { default as UnregisteredBrowserServiceWorkerError } from './interceptorWorker/errors/UnregisteredBrowserServiceWorkerError';
|
|
10
|
+
|
|
10
11
|
export { default as DisabledRequestSavingError } from './requestHandler/errors/DisabledRequestSavingError';
|
|
11
12
|
export { default as TimesCheckError } from './requestHandler/errors/TimesCheckError';
|
|
12
13
|
|
|
@@ -49,12 +50,4 @@ export type { InferHttpInterceptorSchema } from './interceptor/types/schema';
|
|
|
49
50
|
|
|
50
51
|
export type { LocalHttpInterceptor, RemoteHttpInterceptor, HttpInterceptor } from './interceptor/types/public';
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
* A namespace of interceptor resources for mocking HTTP requests.
|
|
54
|
-
*
|
|
55
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httpinterceptor `HttpInterceptor` API reference}
|
|
56
|
-
*/
|
|
57
|
-
export const httpInterceptor = Object.freeze(new HttpInterceptorNamespace());
|
|
58
|
-
|
|
59
|
-
export type { default as HttpInterceptorNamespace } from './namespace/HttpInterceptorNamespace';
|
|
60
|
-
export type { HttpInterceptorNamespaceDefault } from './namespace/HttpInterceptorNamespace';
|
|
53
|
+
export { createHttpInterceptor } from './interceptor/factory';
|
|
@@ -23,13 +23,17 @@ import RemoteHttpRequestHandler from '../requestHandler/RemoteHttpRequestHandler
|
|
|
23
23
|
import { HttpRequestHandler, InternalHttpRequestHandler } from '../requestHandler/types/public';
|
|
24
24
|
import { HttpInterceptorRequest } from '../requestHandler/types/requests';
|
|
25
25
|
import NotRunningHttpInterceptorError from './errors/NotRunningHttpInterceptorError';
|
|
26
|
+
import RequestSavingSafeLimitExceededError from './errors/RequestSavingSafeLimitExceededError';
|
|
26
27
|
import RunningHttpInterceptorError from './errors/RunningHttpInterceptorError';
|
|
27
28
|
import HttpInterceptorStore from './HttpInterceptorStore';
|
|
28
29
|
import { UnhandledRequestStrategy } from './types/options';
|
|
30
|
+
import { HttpInterceptorRequestSaving } from './types/public';
|
|
29
31
|
import { HttpInterceptorRequestContext } from './types/requests';
|
|
30
32
|
|
|
31
33
|
export const SUPPORTED_BASE_URL_PROTOCOLS = Object.freeze(['http', 'https']);
|
|
32
34
|
|
|
35
|
+
export const DEFAULT_REQUEST_SAVING_SAFE_LIMIT = 1000;
|
|
36
|
+
|
|
33
37
|
class HttpInterceptorClient<
|
|
34
38
|
Schema extends HttpSchema,
|
|
35
39
|
HandlerConstructor extends HttpRequestHandlerConstructor = HttpRequestHandlerConstructor,
|
|
@@ -38,7 +42,9 @@ class HttpInterceptorClient<
|
|
|
38
42
|
private store: HttpInterceptorStore;
|
|
39
43
|
|
|
40
44
|
private _baseURL!: URL;
|
|
41
|
-
|
|
45
|
+
|
|
46
|
+
requestSaving: HttpInterceptorRequestSaving;
|
|
47
|
+
private numberOfSavedRequests = 0;
|
|
42
48
|
|
|
43
49
|
onUnhandledRequest?: HandlerConstructor extends typeof LocalHttpRequestHandler
|
|
44
50
|
? UnhandledRequestStrategy.Local
|
|
@@ -64,7 +70,7 @@ class HttpInterceptorClient<
|
|
|
64
70
|
worker: HttpInterceptorWorker;
|
|
65
71
|
store: HttpInterceptorStore;
|
|
66
72
|
baseURL: URL;
|
|
67
|
-
|
|
73
|
+
requestSaving?: Partial<HttpInterceptorRequestSaving>;
|
|
68
74
|
onUnhandledRequest?: UnhandledRequestStrategy;
|
|
69
75
|
Handler: HandlerConstructor;
|
|
70
76
|
}) {
|
|
@@ -72,7 +78,12 @@ class HttpInterceptorClient<
|
|
|
72
78
|
this.store = options.store;
|
|
73
79
|
|
|
74
80
|
this.baseURL = options.baseURL;
|
|
75
|
-
|
|
81
|
+
|
|
82
|
+
this.requestSaving = {
|
|
83
|
+
enabled: options.requestSaving?.enabled ?? this.getDefaultRequestSavingEnabled(),
|
|
84
|
+
safeLimit: options.requestSaving?.safeLimit ?? DEFAULT_REQUEST_SAVING_SAFE_LIMIT,
|
|
85
|
+
};
|
|
86
|
+
|
|
76
87
|
this.onUnhandledRequest = options.onUnhandledRequest satisfies
|
|
77
88
|
| UnhandledRequestStrategy
|
|
78
89
|
| undefined as this['onUnhandledRequest'];
|
|
@@ -80,6 +91,10 @@ class HttpInterceptorClient<
|
|
|
80
91
|
this.Handler = options.Handler;
|
|
81
92
|
}
|
|
82
93
|
|
|
94
|
+
private getDefaultRequestSavingEnabled(): boolean {
|
|
95
|
+
return isServerSide() ? process.env.NODE_ENV === 'test' : false;
|
|
96
|
+
}
|
|
97
|
+
|
|
83
98
|
get baseURL() {
|
|
84
99
|
return this._baseURL;
|
|
85
100
|
}
|
|
@@ -103,17 +118,6 @@ class HttpInterceptorClient<
|
|
|
103
118
|
return this.baseURL.href;
|
|
104
119
|
}
|
|
105
120
|
|
|
106
|
-
get saveRequests() {
|
|
107
|
-
if (this._saveRequests === undefined) {
|
|
108
|
-
return isServerSide() ? process.env.NODE_ENV === 'test' : false;
|
|
109
|
-
}
|
|
110
|
-
return this._saveRequests;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
set saveRequests(saveRequests: boolean) {
|
|
114
|
-
this._saveRequests = saveRequests;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
121
|
get platform() {
|
|
118
122
|
return this.worker.platform;
|
|
119
123
|
}
|
|
@@ -251,7 +255,7 @@ class HttpInterceptorClient<
|
|
|
251
255
|
const responseDeclaration = await matchedHandler.applyResponseDeclaration(parsedRequest);
|
|
252
256
|
const response = HttpInterceptorWorker.createResponseFromDeclaration(request, responseDeclaration);
|
|
253
257
|
|
|
254
|
-
if (this.
|
|
258
|
+
if (this.requestSaving.enabled) {
|
|
255
259
|
const responseClone = response.clone();
|
|
256
260
|
|
|
257
261
|
const parsedResponse = await HttpInterceptorWorker.parseRawResponse<
|
|
@@ -265,6 +269,17 @@ class HttpInterceptorClient<
|
|
|
265
269
|
return response;
|
|
266
270
|
}
|
|
267
271
|
|
|
272
|
+
incrementNumberOfSavedRequests(increment: number) {
|
|
273
|
+
this.numberOfSavedRequests = Math.max(this.numberOfSavedRequests + increment, 0);
|
|
274
|
+
|
|
275
|
+
const exceedsSafeLimit = this.numberOfSavedRequests > this.requestSaving.safeLimit;
|
|
276
|
+
|
|
277
|
+
if (increment > 0 && exceedsSafeLimit) {
|
|
278
|
+
const error = new RequestSavingSafeLimitExceededError(this.numberOfSavedRequests, this.requestSaving.safeLimit);
|
|
279
|
+
console.warn(error);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
268
283
|
private async findMatchedHandler<
|
|
269
284
|
Method extends HttpSchemaMethod<Schema>,
|
|
270
285
|
Path extends HttpSchemaPath<Schema, Method>,
|
|
@@ -4,8 +4,8 @@ import LocalHttpRequestHandler from '../requestHandler/LocalHttpRequestHandler';
|
|
|
4
4
|
import HttpInterceptorClient from './HttpInterceptorClient';
|
|
5
5
|
import HttpInterceptorStore from './HttpInterceptorStore';
|
|
6
6
|
import { SyncHttpInterceptorMethodHandler } from './types/handlers';
|
|
7
|
-
import { LocalHttpInterceptorOptions } from './types/options';
|
|
8
|
-
import { LocalHttpInterceptor as PublicLocalHttpInterceptor } from './types/public';
|
|
7
|
+
import { LocalHttpInterceptorOptions, UnhandledRequestStrategy } from './types/options';
|
|
8
|
+
import { HttpInterceptorRequestSaving, LocalHttpInterceptor as PublicLocalHttpInterceptor } from './types/public';
|
|
9
9
|
|
|
10
10
|
class LocalHttpInterceptor<Schema extends HttpSchema> implements PublicLocalHttpInterceptor<Schema> {
|
|
11
11
|
private store = new HttpInterceptorStore();
|
|
@@ -23,7 +23,7 @@ class LocalHttpInterceptor<Schema extends HttpSchema> implements PublicLocalHttp
|
|
|
23
23
|
baseURL,
|
|
24
24
|
Handler: LocalHttpRequestHandler,
|
|
25
25
|
onUnhandledRequest: options.onUnhandledRequest,
|
|
26
|
-
|
|
26
|
+
requestSaving: options.requestSaving,
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -39,19 +39,19 @@ class LocalHttpInterceptor<Schema extends HttpSchema> implements PublicLocalHttp
|
|
|
39
39
|
this.client.baseURL = new URL(baseURL);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
get
|
|
43
|
-
return this.client.
|
|
42
|
+
get requestSaving() {
|
|
43
|
+
return this.client.requestSaving;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
set
|
|
47
|
-
this.client.
|
|
46
|
+
set requestSaving(requestSaving: HttpInterceptorRequestSaving) {
|
|
47
|
+
this.client.requestSaving = requestSaving;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
get onUnhandledRequest() {
|
|
51
51
|
return this.client.onUnhandledRequest;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
set onUnhandledRequest(onUnhandledRequest:
|
|
54
|
+
set onUnhandledRequest(onUnhandledRequest: UnhandledRequestStrategy.Local | undefined) {
|
|
55
55
|
this.client.onUnhandledRequest = onUnhandledRequest;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -4,8 +4,8 @@ import RemoteHttpRequestHandler from '../requestHandler/RemoteHttpRequestHandler
|
|
|
4
4
|
import HttpInterceptorClient from './HttpInterceptorClient';
|
|
5
5
|
import HttpInterceptorStore from './HttpInterceptorStore';
|
|
6
6
|
import { AsyncHttpInterceptorMethodHandler } from './types/handlers';
|
|
7
|
-
import { RemoteHttpInterceptorOptions } from './types/options';
|
|
8
|
-
import { RemoteHttpInterceptor as PublicRemoteHttpInterceptor } from './types/public';
|
|
7
|
+
import { RemoteHttpInterceptorOptions, UnhandledRequestStrategy } from './types/options';
|
|
8
|
+
import { HttpInterceptorRequestSaving, RemoteHttpInterceptor as PublicRemoteHttpInterceptor } from './types/public';
|
|
9
9
|
|
|
10
10
|
class RemoteHttpInterceptor<Schema extends HttpSchema> implements PublicRemoteHttpInterceptor<Schema> {
|
|
11
11
|
private store = new HttpInterceptorStore();
|
|
@@ -24,7 +24,7 @@ class RemoteHttpInterceptor<Schema extends HttpSchema> implements PublicRemoteHt
|
|
|
24
24
|
baseURL,
|
|
25
25
|
Handler: RemoteHttpRequestHandler,
|
|
26
26
|
onUnhandledRequest: options.onUnhandledRequest,
|
|
27
|
-
|
|
27
|
+
requestSaving: options.requestSaving,
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -40,19 +40,19 @@ class RemoteHttpInterceptor<Schema extends HttpSchema> implements PublicRemoteHt
|
|
|
40
40
|
this.client.baseURL = new URL(baseURL);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
get
|
|
44
|
-
return this.client.
|
|
43
|
+
get requestSaving() {
|
|
44
|
+
return this.client.requestSaving;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
set
|
|
48
|
-
this.client.
|
|
47
|
+
set requestSaving(requestSaving: HttpInterceptorRequestSaving) {
|
|
48
|
+
this.client.requestSaving = requestSaving;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
get onUnhandledRequest() {
|
|
52
52
|
return this.client.onUnhandledRequest;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
set onUnhandledRequest(onUnhandledRequest:
|
|
55
|
+
set onUnhandledRequest(onUnhandledRequest: UnhandledRequestStrategy.Remote | undefined) {
|
|
56
56
|
this.client.onUnhandledRequest = onUnhandledRequest;
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error thrown when the safe limit of saved intercepted requests is exceeded.
|
|
3
|
+
*
|
|
4
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
5
|
+
*/
|
|
6
|
+
class RequestSavingSafeLimitExceededError extends TypeError {
|
|
7
|
+
constructor(numberOfSavedRequests: number, safeLimit: number) {
|
|
8
|
+
super(
|
|
9
|
+
`The number of intercepted requests saved in memory (${numberOfSavedRequests}) exceeded the safe limit of ` +
|
|
10
|
+
`${safeLimit}. Did you forget to call \`interceptor.clear()\`?\n\n` +
|
|
11
|
+
'If you need to save requests, make sure to regularly call `interceptor.clear()`. Alternatively, you can ' +
|
|
12
|
+
'hide this warning by increasing `requestSaving.safeLimit` in your interceptor. Note that saving too many ' +
|
|
13
|
+
'requests in memory can lead to performance issues.\n\n' +
|
|
14
|
+
'If you do not need to save requests, consider setting `requestSaving.enabled: false` in your ' +
|
|
15
|
+
'interceptor.\n\n' +
|
|
16
|
+
'Learn more: https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests',
|
|
17
|
+
);
|
|
18
|
+
this.name = 'RequestSavingSafeLimitExceededError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default RequestSavingSafeLimitExceededError;
|
|
@@ -24,7 +24,7 @@ function isRemoteHttpInterceptorOptions(options: HttpInterceptorOptions) {
|
|
|
24
24
|
* @returns The created HTTP interceptor.
|
|
25
25
|
* @throws {InvalidURLError} If the base URL is invalid.
|
|
26
26
|
* @throws {UnsupportedURLProtocolError} If the base URL protocol is not either `http` or `https`.
|
|
27
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#
|
|
27
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#createhttpinterceptoroptions `createHttpInterceptor(options)` API reference}
|
|
28
28
|
*/
|
|
29
29
|
export function createHttpInterceptor<Schema extends HttpSchema>(
|
|
30
30
|
options: LocalHttpInterceptorOptions,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PossiblePromise } from '@zimic/utils/types';
|
|
2
2
|
|
|
3
|
+
import { HttpInterceptorRequestSaving } from './public';
|
|
3
4
|
import { UnhandledHttpInterceptorRequest } from './requests';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -119,20 +120,12 @@ export interface SharedHttpInterceptorOptions {
|
|
|
119
120
|
baseURL: string;
|
|
120
121
|
|
|
121
122
|
/**
|
|
122
|
-
*
|
|
123
|
-
* should save their intercepted requests in memory and make them accessible through
|
|
124
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests`}.
|
|
123
|
+
* Configures if the intercepted requests are saved and how they are handled.
|
|
125
124
|
*
|
|
126
|
-
* **Important**: If `saveRequests` is true, make sure to regularly clear the interceptor to avoid that the requests
|
|
127
|
-
* accumulate in memory. A common practice is to call
|
|
128
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()`}
|
|
129
|
-
* after each test.
|
|
130
|
-
*
|
|
131
|
-
* @default false
|
|
132
125
|
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
133
126
|
* @see {@link https://github.com/zimicjs/zimic/wiki/guides‐testing‐interceptor Testing}
|
|
134
127
|
*/
|
|
135
|
-
|
|
128
|
+
requestSaving?: Partial<HttpInterceptorRequestSaving>;
|
|
136
129
|
}
|
|
137
130
|
|
|
138
131
|
/**
|
|
@@ -177,6 +170,6 @@ export interface RemoteHttpInterceptorOptions extends SharedHttpInterceptorOptio
|
|
|
177
170
|
* The options to create an
|
|
178
171
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httpinterceptor HTTP interceptor}.
|
|
179
172
|
*
|
|
180
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#
|
|
173
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#createhttpinterceptoroptions `createHttpInterceptor(options)` API reference}
|
|
181
174
|
*/
|
|
182
175
|
export type HttpInterceptorOptions = LocalHttpInterceptorOptions | RemoteHttpInterceptorOptions;
|
|
@@ -3,6 +3,45 @@ import { HttpSchema } from '@zimic/http';
|
|
|
3
3
|
import { SyncHttpInterceptorMethodHandler, AsyncHttpInterceptorMethodHandler } from './handlers';
|
|
4
4
|
import { HttpInterceptorPlatform, UnhandledRequestStrategy } from './options';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Configures if the intercepted requests are saved and how they are handled.
|
|
8
|
+
*
|
|
9
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
10
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/guides‐testing‐interceptor Testing}
|
|
11
|
+
*/
|
|
12
|
+
export interface HttpInterceptorRequestSaving {
|
|
13
|
+
/**
|
|
14
|
+
* Whether {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler request handlers}
|
|
15
|
+
* should save their intercepted requests in memory and make them accessible through
|
|
16
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests`}.
|
|
17
|
+
*
|
|
18
|
+
* If you are using
|
|
19
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorchecktimes `interceptor.checkTimes()`}
|
|
20
|
+
* or
|
|
21
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerchecktimes `handler.checkTimes()`}
|
|
22
|
+
* during tests, consider enabling this option to get more detailed information in `TimesCheckError` errors.
|
|
23
|
+
*
|
|
24
|
+
* **Important**: If `requestSaving.enabled` is `true`, make sure to regularly clear the interceptor to avoid requests
|
|
25
|
+
* accumulating in memory. A common practice is to call
|
|
26
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()`}
|
|
27
|
+
* after each test.
|
|
28
|
+
*
|
|
29
|
+
* @default process.env.NODE_ENV === 'test'
|
|
30
|
+
*/
|
|
31
|
+
enabled: boolean;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The safe number of requests to save in memory before logging warnings in the console. If `requestSaving.enabled` is
|
|
35
|
+
* `true` and the interceptor is not regularly cleared with
|
|
36
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()`},
|
|
37
|
+
* the requests may accumulate in memory and cause performance issues. This option does not limit the number of
|
|
38
|
+
* requests saved in memory, only when to log warnings.
|
|
39
|
+
*
|
|
40
|
+
* @default 1000
|
|
41
|
+
*/
|
|
42
|
+
safeLimit: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
6
45
|
/**
|
|
7
46
|
* An interceptor to handle HTTP requests and return mock responses. The methods, paths, status codes, parameters, and
|
|
8
47
|
* responses are statically-typed based on the provided service schema.
|
|
@@ -20,20 +59,12 @@ export interface HttpInterceptor<_Schema extends HttpSchema> {
|
|
|
20
59
|
baseURL: string;
|
|
21
60
|
|
|
22
61
|
/**
|
|
23
|
-
*
|
|
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.
|
|
62
|
+
* Configures if the intercepted requests are saved and how they are handled.
|
|
31
63
|
*
|
|
32
|
-
* @default process.env.NODE_ENV === 'test'
|
|
33
64
|
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
34
65
|
* @see {@link https://github.com/zimicjs/zimic/wiki/guides‐testing‐interceptor Testing}
|
|
35
66
|
*/
|
|
36
|
-
|
|
67
|
+
requestSaving: HttpInterceptorRequestSaving;
|
|
37
68
|
|
|
38
69
|
/**
|
|
39
70
|
* The platform the interceptor is running on.
|
|
@@ -86,8 +117,9 @@ export interface HttpInterceptor<_Schema extends HttpSchema> {
|
|
|
86
117
|
* of each test.
|
|
87
118
|
*
|
|
88
119
|
* When
|
|
89
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#
|
|
90
|
-
*
|
|
120
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
|
|
121
|
+
* `requestSaving.enabled`} is
|
|
122
|
+
* `true` in your interceptor, the `TimesCheckError` errors will also list each unmatched request with diff of the
|
|
91
123
|
* expected and received data. This is useful for debugging requests that did not match a handler with
|
|
92
124
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerwithrestriction restrictions}.
|
|
93
125
|
*
|
|
@@ -5,9 +5,9 @@ import { LocalHttpInterceptor, RemoteHttpInterceptor } from './public';
|
|
|
5
5
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httpinterceptor `HttpInterceptor`}.
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
|
-
* import {
|
|
8
|
+
* import { type InferHttpInterceptorSchema } from '@zimic/http';
|
|
9
9
|
*
|
|
10
|
-
* const interceptor =
|
|
10
|
+
* const interceptor = createHttpInterceptor<{
|
|
11
11
|
* '/users': {
|
|
12
12
|
* GET: {
|
|
13
13
|
* response: { 200: { body: User[] } };
|