@zimic/interceptor 1.2.7-canary.2 → 1.3.0-canary.0
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-6GEP6R3L.mjs → chunk-5CI37HTA.mjs} +75 -16
- package/dist/chunk-5CI37HTA.mjs.map +1 -0
- package/dist/{chunk-PB4TJVK3.js → chunk-KDM6Y6GO.js} +75 -16
- package/dist/chunk-KDM6Y6GO.js.map +1 -0
- package/dist/cli.js +17 -17
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/http.d.ts +18 -6
- package/dist/http.js +96 -15
- package/dist/http.js.map +1 -1
- package/dist/http.mjs +97 -16
- package/dist/http.mjs.map +1 -1
- package/dist/server.js +6 -6
- package/dist/server.mjs +1 -1
- package/package.json +2 -2
- package/src/http/interceptor/HttpInterceptorClient.ts +7 -7
- package/src/http/interceptor/types/options.ts +11 -5
- package/src/http/interceptorWorker/HttpInterceptorWorker.ts +72 -14
- package/src/http/interceptorWorker/LocalHttpInterceptorWorker.ts +35 -8
- package/src/http/interceptorWorker/RemoteHttpInterceptorWorker.ts +33 -12
- package/src/http/interceptorWorker/types/http.ts +6 -1
- package/src/http/interceptorWorker/types/msw.ts +0 -9
- package/src/http/requestHandler/types/requests.ts +16 -2
- package/src/server/InterceptorServer.ts +11 -2
- package/src/server/errors/UnsupportedResponseBypassError.ts +11 -0
- package/src/utils/fetch.ts +25 -6
- package/dist/chunk-6GEP6R3L.mjs.map +0 -1
- package/dist/chunk-PB4TJVK3.js.map +0 -1
package/dist/http.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { InvalidFormDataError as InvalidFormDataError$1, InvalidJSONError as InvalidJSONError$1, HTTP_METHODS, HttpHeaders, HttpSearchParams, HttpFormData, parseHttpBody } from '@zimic/http';
|
|
2
2
|
import color2 from 'picocolors';
|
|
3
|
-
import { http, passthrough } from 'msw';
|
|
3
|
+
import { http, bypass, passthrough } from 'msw';
|
|
4
4
|
import * as mswBrowser from 'msw/browser';
|
|
5
5
|
import * as mswNode from 'msw/node';
|
|
6
6
|
import ClientSocket from 'isomorphic-ws';
|
|
@@ -1042,6 +1042,7 @@ var DEFAULT_UNHANDLED_REQUEST_STRATEGY = Object.freeze({
|
|
|
1042
1042
|
});
|
|
1043
1043
|
|
|
1044
1044
|
// src/http/interceptorWorker/HttpInterceptorWorker.ts
|
|
1045
|
+
var RESPONSE_ACTION_SYMBOL = Symbol.for("HttpResponse.action");
|
|
1045
1046
|
var HttpInterceptorWorker = class _HttpInterceptorWorker {
|
|
1046
1047
|
platform = null;
|
|
1047
1048
|
isRunning = false;
|
|
@@ -1138,17 +1139,57 @@ var HttpInterceptorWorker = class _HttpInterceptorWorker {
|
|
|
1138
1139
|
}
|
|
1139
1140
|
return interceptor.onUnhandledRequest;
|
|
1140
1141
|
}
|
|
1141
|
-
static
|
|
1142
|
+
static setResponseAction(response, action) {
|
|
1143
|
+
Object.defineProperty(response, RESPONSE_ACTION_SYMBOL, {
|
|
1144
|
+
value: action,
|
|
1145
|
+
enumerable: false,
|
|
1146
|
+
configurable: false,
|
|
1147
|
+
writable: false
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
static getResponseAction(response) {
|
|
1151
|
+
if (!(RESPONSE_ACTION_SYMBOL in response)) {
|
|
1152
|
+
return void 0;
|
|
1153
|
+
}
|
|
1154
|
+
const action = response[RESPONSE_ACTION_SYMBOL];
|
|
1155
|
+
if (action !== "bypass" && action !== "reject") {
|
|
1156
|
+
return void 0;
|
|
1157
|
+
}
|
|
1158
|
+
return action;
|
|
1159
|
+
}
|
|
1160
|
+
createBypassedResponse() {
|
|
1161
|
+
const response = Response.redirect("about:blank", 302);
|
|
1162
|
+
_HttpInterceptorWorker.setResponseAction(response, "bypass");
|
|
1163
|
+
return response;
|
|
1164
|
+
}
|
|
1165
|
+
static isBypassedResponse(response) {
|
|
1166
|
+
return this.getResponseAction(response) === "bypass";
|
|
1167
|
+
}
|
|
1168
|
+
createRejectedResponse() {
|
|
1169
|
+
const response = Response.error();
|
|
1170
|
+
_HttpInterceptorWorker.setResponseAction(response, "reject");
|
|
1171
|
+
return response;
|
|
1172
|
+
}
|
|
1173
|
+
static isRejectedResponse(response) {
|
|
1174
|
+
return this.getResponseAction(response) === "reject";
|
|
1175
|
+
}
|
|
1176
|
+
createResponseFromDeclaration(request, declaration) {
|
|
1177
|
+
if ("action" in declaration) {
|
|
1178
|
+
if (declaration.action === "bypass") {
|
|
1179
|
+
return this.createBypassedResponse();
|
|
1180
|
+
} else {
|
|
1181
|
+
return this.createRejectedResponse();
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1142
1184
|
const headers = new HttpHeaders(declaration.headers);
|
|
1143
|
-
const
|
|
1144
|
-
const canHaveBody = methodCanHaveResponseBody(request.method) && status !== 204;
|
|
1185
|
+
const canHaveBody = methodCanHaveResponseBody(request.method) && declaration.status !== 204;
|
|
1145
1186
|
if (!canHaveBody) {
|
|
1146
|
-
return new Response(null, { headers, status });
|
|
1187
|
+
return new Response(null, { headers, status: declaration.status });
|
|
1147
1188
|
}
|
|
1148
1189
|
if (typeof declaration.body === "string" || declaration.body === null || declaration.body === void 0 || declaration.body instanceof FormData || declaration.body instanceof URLSearchParams || declaration.body instanceof Blob || declaration.body instanceof ArrayBuffer || declaration.body instanceof ReadableStream) {
|
|
1149
|
-
return new Response(declaration.body ?? null, { headers, status });
|
|
1190
|
+
return new Response(declaration.body ?? null, { headers, status: declaration.status });
|
|
1150
1191
|
}
|
|
1151
|
-
return Response.json(declaration.body, { headers, status });
|
|
1192
|
+
return Response.json(declaration.body, { headers, status: declaration.status });
|
|
1152
1193
|
}
|
|
1153
1194
|
static async parseRawUnhandledRequest(request) {
|
|
1154
1195
|
return this.parseRawRequest(
|
|
@@ -1577,8 +1618,9 @@ var HttpInterceptorClient = class {
|
|
|
1577
1618
|
if (!responseDeclaration) {
|
|
1578
1619
|
return null;
|
|
1579
1620
|
}
|
|
1580
|
-
const response =
|
|
1581
|
-
|
|
1621
|
+
const response = await this.workerOrThrow.createResponseFromDeclaration(request, responseDeclaration);
|
|
1622
|
+
const shouldSaveInterceptedRequest = this.requestSaving.enabled && response && !HttpInterceptorWorker_default.isRejectedResponse(response);
|
|
1623
|
+
if (shouldSaveInterceptedRequest) {
|
|
1582
1624
|
const responseClone = response.clone();
|
|
1583
1625
|
const parsedResponse = await HttpInterceptorWorker_default.parseRawResponse(responseClone);
|
|
1584
1626
|
matchedHandler.saveInterceptedRequest(parsedRequest, parsedResponse);
|
|
@@ -1795,7 +1837,7 @@ var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
1795
1837
|
const requestClone = request.clone();
|
|
1796
1838
|
let response = null;
|
|
1797
1839
|
try {
|
|
1798
|
-
response = await createResponse({
|
|
1840
|
+
response = await createResponse({ request });
|
|
1799
1841
|
} catch (error) {
|
|
1800
1842
|
console.error(error);
|
|
1801
1843
|
}
|
|
@@ -1814,6 +1856,23 @@ var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
1814
1856
|
};
|
|
1815
1857
|
methodHandlers.push(handler);
|
|
1816
1858
|
}
|
|
1859
|
+
async createResponseFromDeclaration(request, declaration) {
|
|
1860
|
+
const requestClone = request.clone();
|
|
1861
|
+
const response = await super.createResponseFromDeclaration(request, declaration);
|
|
1862
|
+
if (response && HttpInterceptorWorker_default.isBypassedResponse(response)) {
|
|
1863
|
+
try {
|
|
1864
|
+
const response2 = await fetch(bypass(requestClone));
|
|
1865
|
+
return response2;
|
|
1866
|
+
} catch (error) {
|
|
1867
|
+
console.error(error);
|
|
1868
|
+
return null;
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
if (response && HttpInterceptorWorker_default.isRejectedResponse(response)) {
|
|
1872
|
+
return response;
|
|
1873
|
+
}
|
|
1874
|
+
return response;
|
|
1875
|
+
}
|
|
1817
1876
|
async createResponseForRequest(request) {
|
|
1818
1877
|
const methodHandlers = this.httpHandlersByMethod[request.method];
|
|
1819
1878
|
const requestURL = excludeNonPathParams_default(new URL(request.url));
|
|
@@ -1871,6 +1930,17 @@ var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
1871
1930
|
};
|
|
1872
1931
|
var LocalHttpInterceptorWorker_default = LocalHttpInterceptorWorker;
|
|
1873
1932
|
|
|
1933
|
+
// src/server/errors/UnsupportedResponseBypassError.ts
|
|
1934
|
+
var UnsupportedResponseBypassError = class extends Error {
|
|
1935
|
+
constructor() {
|
|
1936
|
+
super(
|
|
1937
|
+
"Remote interceptors cannot bypass responses. Use `{ action: 'reject' }` instead.\n\nLearn more: https://zimic.dev/docs/interceptor/api/http-request-handler#handlerrespond"
|
|
1938
|
+
);
|
|
1939
|
+
this.name = "UnsupportedResponseBypassError";
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
var UnsupportedResponseBypassError_default = UnsupportedResponseBypassError;
|
|
1943
|
+
|
|
1874
1944
|
// src/utils/crypto.ts
|
|
1875
1945
|
var importCrypto = createCachedDynamicImport_default(async () => {
|
|
1876
1946
|
const globalCrypto = globalThis.crypto;
|
|
@@ -1898,6 +1968,8 @@ async function serializeResponse(response) {
|
|
|
1898
1968
|
const responseClone = response.clone();
|
|
1899
1969
|
const serializedBody = responseClone.body ? convertArrayBufferToBase64(await responseClone.arrayBuffer()) : null;
|
|
1900
1970
|
return {
|
|
1971
|
+
type: response.type,
|
|
1972
|
+
action: HttpInterceptorWorker_default.getResponseAction(response),
|
|
1901
1973
|
status: response.status,
|
|
1902
1974
|
statusText: response.statusText,
|
|
1903
1975
|
headers: Object.fromEntries(response.headers),
|
|
@@ -2374,8 +2446,8 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2374
2446
|
const request = deserializeRequest(serializedRequest);
|
|
2375
2447
|
try {
|
|
2376
2448
|
const rawResponse = await handler?.createResponse({ request }) ?? null;
|
|
2377
|
-
|
|
2378
|
-
|
|
2449
|
+
if (rawResponse) {
|
|
2450
|
+
const response = methodCanHaveResponseBody(request.method) ? rawResponse : new Response(null, rawResponse);
|
|
2379
2451
|
return { response: await serializeResponse(response) };
|
|
2380
2452
|
}
|
|
2381
2453
|
} catch (error) {
|
|
@@ -2422,10 +2494,7 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2422
2494
|
method,
|
|
2423
2495
|
path,
|
|
2424
2496
|
interceptor,
|
|
2425
|
-
|
|
2426
|
-
const response = await createResponse(context);
|
|
2427
|
-
return response;
|
|
2428
|
-
}
|
|
2497
|
+
createResponse
|
|
2429
2498
|
};
|
|
2430
2499
|
this.httpHandlers.set(handler.id, handler);
|
|
2431
2500
|
await this.webSocketClient.request("interceptors/workers/commit", {
|
|
@@ -2435,6 +2504,16 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
|
|
|
2435
2504
|
path: handler.path
|
|
2436
2505
|
});
|
|
2437
2506
|
}
|
|
2507
|
+
async createResponseFromDeclaration(request, declaration) {
|
|
2508
|
+
const response = await super.createResponseFromDeclaration(request, declaration);
|
|
2509
|
+
if (response && HttpInterceptorWorker_default.isBypassedResponse(response)) {
|
|
2510
|
+
throw new UnsupportedResponseBypassError_default();
|
|
2511
|
+
}
|
|
2512
|
+
if (response && HttpInterceptorWorker_default.isRejectedResponse(response)) {
|
|
2513
|
+
return response;
|
|
2514
|
+
}
|
|
2515
|
+
return response;
|
|
2516
|
+
}
|
|
2438
2517
|
async clearHandlers(options = {}) {
|
|
2439
2518
|
if (!this.isRunning) {
|
|
2440
2519
|
throw new NotRunningHttpInterceptorError_default();
|
|
@@ -2794,6 +2873,8 @@ var InvalidFormDataError = class extends InvalidFormDataError$1 {
|
|
|
2794
2873
|
};
|
|
2795
2874
|
var InvalidJSONError = class extends InvalidJSONError$1 {
|
|
2796
2875
|
};
|
|
2876
|
+
/* istanbul ignore if -- @preserve
|
|
2877
|
+
* This is just a type guard to ensure the value is valid. In practice, this condition should never be true. */
|
|
2797
2878
|
/* istanbul ignore next -- @preserve
|
|
2798
2879
|
* Ignoring because there will always be a handler for the given method and path at this point. */
|
|
2799
2880
|
/* istanbul ignore if -- @preserve
|