@mswjs/interceptors 0.34.3 → 0.35.1
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/lib/browser/{chunk-FXSPMSSQ.js → chunk-2CAGU4FT.js} +10 -2
- package/lib/browser/chunk-2CAGU4FT.js.map +1 -0
- package/lib/browser/{chunk-EJYZ4HR3.js → chunk-FYSUKT3F.js} +4 -4
- package/lib/browser/{chunk-W7UG7MBM.mjs → chunk-G5SOR3ND.mjs} +92 -9
- package/lib/browser/chunk-G5SOR3ND.mjs.map +1 -0
- package/lib/browser/{chunk-KOFJYPUE.mjs → chunk-PRBA3ES4.mjs} +3 -3
- package/lib/browser/{chunk-TPZUQHHY.js → chunk-T5Q47QLJ.js} +97 -14
- package/lib/browser/chunk-T5Q47QLJ.js.map +1 -0
- package/lib/browser/{chunk-73X2CAEH.mjs → chunk-THPGBWJQ.mjs} +2 -2
- package/lib/browser/{chunk-GGUENBDN.mjs → chunk-XVPRNJO7.mjs} +9 -1
- package/lib/browser/chunk-XVPRNJO7.mjs.map +1 -0
- package/lib/browser/{chunk-NBHFK2DJ.js → chunk-YU6EJD6U.js} +9 -9
- package/lib/browser/index.js +2 -2
- package/lib/browser/index.mjs +1 -1
- package/lib/browser/interceptors/XMLHttpRequest/index.js +4 -4
- package/lib/browser/interceptors/XMLHttpRequest/index.mjs +3 -3
- package/lib/browser/interceptors/fetch/index.js +4 -4
- package/lib/browser/interceptors/fetch/index.mjs +3 -3
- package/lib/browser/presets/browser.js +6 -6
- package/lib/browser/presets/browser.mjs +4 -4
- package/lib/node/RemoteHttpInterceptor.js +11 -11
- package/lib/node/RemoteHttpInterceptor.mjs +5 -5
- package/lib/node/{chunk-HGQLG7KE.mjs → chunk-3NMVZQIH.mjs} +2 -2
- package/lib/node/{chunk-KA2KMHFU.mjs → chunk-77GKBGPN.mjs} +3 -3
- package/lib/node/{chunk-YGM3BCJU.js → chunk-AABH3XLQ.js} +10 -2
- package/lib/node/chunk-AABH3XLQ.js.map +1 -0
- package/lib/node/{chunk-W4AQXISM.js → chunk-BCUXF7NZ.js} +96 -13
- package/lib/node/chunk-BCUXF7NZ.js.map +1 -0
- package/lib/node/{chunk-WTJL7BRV.js → chunk-BMRE2LOX.js} +14 -14
- package/lib/node/{chunk-WGBCEHTV.mjs → chunk-C7JQJSAI.mjs} +3 -3
- package/lib/node/{chunk-6L3UERDR.js → chunk-FFSJ6QLA.js} +9 -9
- package/lib/node/{chunk-BUCULLYM.mjs → chunk-FQQAJBI2.mjs} +9 -1
- package/lib/node/{chunk-BUCULLYM.mjs.map → chunk-FQQAJBI2.mjs.map} +1 -1
- package/lib/node/{chunk-XSXCGXEY.mjs → chunk-M4WQE4TR.mjs} +2 -2
- package/lib/node/{chunk-42632LKH.js → chunk-PGTBKPWN.js} +3 -3
- package/lib/node/{chunk-GILG336Y.mjs → chunk-T5YM7SUV.mjs} +91 -8
- package/lib/node/chunk-T5YM7SUV.mjs.map +1 -0
- package/lib/node/{chunk-TQD7SQGP.js → chunk-VCUEA4PL.js} +4 -4
- package/lib/node/index.js +3 -3
- package/lib/node/index.mjs +2 -2
- package/lib/node/interceptors/ClientRequest/index.js +4 -4
- package/lib/node/interceptors/ClientRequest/index.mjs +3 -3
- package/lib/node/interceptors/XMLHttpRequest/index.js +4 -4
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +3 -3
- package/lib/node/interceptors/fetch/index.js +4 -4
- package/lib/node/interceptors/fetch/index.mjs +3 -3
- package/lib/node/presets/node.js +8 -8
- package/lib/node/presets/node.mjs +5 -5
- package/package.json +1 -1
- package/src/interceptors/fetch/index.ts +30 -6
- package/src/interceptors/fetch/utils/createNetworkError.ts +5 -0
- package/src/interceptors/fetch/utils/followRedirect.ts +108 -0
- package/src/utils/responseUtils.ts +4 -0
- package/lib/browser/chunk-FXSPMSSQ.js.map +0 -1
- package/lib/browser/chunk-GGUENBDN.mjs.map +0 -1
- package/lib/browser/chunk-TPZUQHHY.js.map +0 -1
- package/lib/browser/chunk-W7UG7MBM.mjs.map +0 -1
- package/lib/node/chunk-GILG336Y.mjs.map +0 -1
- package/lib/node/chunk-W4AQXISM.js.map +0 -1
- package/lib/node/chunk-YGM3BCJU.js.map +0 -1
- /package/lib/browser/{chunk-EJYZ4HR3.js.map → chunk-FYSUKT3F.js.map} +0 -0
- /package/lib/browser/{chunk-KOFJYPUE.mjs.map → chunk-PRBA3ES4.mjs.map} +0 -0
- /package/lib/browser/{chunk-73X2CAEH.mjs.map → chunk-THPGBWJQ.mjs.map} +0 -0
- /package/lib/browser/{chunk-NBHFK2DJ.js.map → chunk-YU6EJD6U.js.map} +0 -0
- /package/lib/node/{chunk-HGQLG7KE.mjs.map → chunk-3NMVZQIH.mjs.map} +0 -0
- /package/lib/node/{chunk-KA2KMHFU.mjs.map → chunk-77GKBGPN.mjs.map} +0 -0
- /package/lib/node/{chunk-WTJL7BRV.js.map → chunk-BMRE2LOX.js.map} +0 -0
- /package/lib/node/{chunk-WGBCEHTV.mjs.map → chunk-C7JQJSAI.mjs.map} +0 -0
- /package/lib/node/{chunk-6L3UERDR.js.map → chunk-FFSJ6QLA.js.map} +0 -0
- /package/lib/node/{chunk-XSXCGXEY.mjs.map → chunk-M4WQE4TR.mjs.map} +0 -0
- /package/lib/node/{chunk-42632LKH.js.map → chunk-PGTBKPWN.js.map} +0 -0
- /package/lib/node/{chunk-TQD7SQGP.js.map → chunk-VCUEA4PL.js.map} +0 -0
|
@@ -19,6 +19,13 @@ var RESPONSE_STATUS_CODES_WITHOUT_BODY = /* @__PURE__ */ new Set([
|
|
|
19
19
|
205,
|
|
20
20
|
304
|
|
21
21
|
]);
|
|
22
|
+
var RESPONSE_STATUS_CODES_WITH_REDIRECT = /* @__PURE__ */ new Set([
|
|
23
|
+
301,
|
|
24
|
+
302,
|
|
25
|
+
303,
|
|
26
|
+
307,
|
|
27
|
+
308
|
|
28
|
+
]);
|
|
22
29
|
function isResponseWithoutBody(status) {
|
|
23
30
|
return RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status);
|
|
24
31
|
}
|
|
@@ -49,5 +56,6 @@ function isResponseError(response) {
|
|
|
49
56
|
|
|
50
57
|
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
|
|
60
|
+
exports.IS_PATCHED_MODULE = IS_PATCHED_MODULE; exports.RESPONSE_STATUS_CODES_WITH_REDIRECT = RESPONSE_STATUS_CODES_WITH_REDIRECT; exports.isResponseWithoutBody = isResponseWithoutBody; exports.createServerErrorResponse = createServerErrorResponse; exports.isResponseError = isResponseError;
|
|
61
|
+
//# sourceMappingURL=chunk-2CAGU4FT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/glossary.ts","../../src/utils/isPropertyAccessible.ts","../../src/utils/responseUtils.ts"],"names":[],"mappings":";AAEO,IAAM,oBAAmC,OAAO,iBAAiB;;;ACMjE,SAAS,qBACd,KACA,KACA;AACA,MAAI;AACF,QAAI,GAAG;AACP,WAAO;AAAA,EACT,SAAQ,GAAN;AACA,WAAO;AAAA,EACT;AACF;;;ACZO,IAAM,qCAAqC,oBAAI,IAAI;AAAA,EACxD;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACtB,CAAC;AAEM,IAAM,sCAAsC,oBAAI,IAAI;AAAA,EACzD;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACtB,CAAC;AAMM,SAAS,sBAAsB,QAAyB;AAC7D,SAAO,mCAAmC,IAAI,MAAM;AACtD;AAKO,SAAS,0BAA0B,MAAyB;AACjE,SAAO,IAAI;AAAA,IACT,KAAK;AAAA,MACH,gBAAgB,QACZ;AAAA,QACE,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,QACd,OAAO,KAAK;AAAA,MACd,IACA;AAAA,IACN;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;AAYO,SAAS,gBAAgB,UAA+C;AAC7E,SAAO,qBAAqB,UAAU,MAAM,KAAK,SAAS,SAAS;AACrE","sourcesContent":["import type { RequestController } from './RequestController'\n\nexport const IS_PATCHED_MODULE: unique symbol = Symbol('isPatchedModule')\n\nexport type RequestCredentials = 'omit' | 'include' | 'same-origin'\n\nexport type HttpRequestEventMap = {\n request: [\n args: {\n request: Request\n requestId: string\n controller: RequestController\n }\n ]\n response: [\n args: {\n response: Response\n isMockedResponse: boolean\n request: Request\n requestId: string\n }\n ]\n unhandledException: [\n args: {\n error: unknown\n request: Request\n requestId: string\n controller: RequestController\n }\n ]\n}\n","/**\n * A function that validates if property access is possible on an object\n * without throwing. It returns `true` if the property access is possible\n * and `false` otherwise.\n *\n * Environments like miniflare will throw on property access on certain objects\n * like Request and Response, for unimplemented properties.\n */\nexport function isPropertyAccessible<Obj extends Record<string, any>>(\n obj: Obj,\n key: keyof Obj\n) {\n try {\n obj[key]\n return true\n } catch {\n return false\n }\n}\n","import { isPropertyAccessible } from './isPropertyAccessible'\n\n/**\n * Response status codes for responses that cannot have body.\n * @see https://fetch.spec.whatwg.org/#statuses\n */\nexport const RESPONSE_STATUS_CODES_WITHOUT_BODY = new Set([\n 101, 103, 204, 205, 304,\n])\n\nexport const RESPONSE_STATUS_CODES_WITH_REDIRECT = new Set([\n 301, 302, 303, 307, 308,\n])\n\n/**\n * Returns a boolean indicating whether the given response status\n * code represents a response that cannot have a body.\n */\nexport function isResponseWithoutBody(status: number): boolean {\n return RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status)\n}\n\n/**\n * Creates a generic 500 Unhandled Exception response.\n */\nexport function createServerErrorResponse(body: unknown): Response {\n return new Response(\n JSON.stringify(\n body instanceof Error\n ? {\n name: body.name,\n message: body.message,\n stack: body.stack,\n }\n : body\n ),\n {\n status: 500,\n statusText: 'Unhandled Exception',\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n )\n}\n\nexport type ResponseError = Response & { type: 'error' }\n\n/**\n * Check if the given response is a `Response.error()`.\n *\n * @note Some environments, like Miniflare (Cloudflare) do not\n * implement the \"Response.type\" property and throw on its access.\n * Safely check if we can access \"type\" on \"Response\" before continuing.\n * @see https://github.com/mswjs/msw/issues/1834\n */\nexport function isResponseError(response: Response): response is ResponseError {\n return isPropertyAccessible(response, 'type') && response.type === 'error'\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunk2CAGU4FTjs = require('./chunk-2CAGU4FT.js');
|
|
5
5
|
|
|
6
6
|
// src/RequestController.ts
|
|
7
7
|
var _outvariant = require('outvariant');
|
|
@@ -94,7 +94,7 @@ async function handleRequest(options) {
|
|
|
94
94
|
const handleResponse = async (response) => {
|
|
95
95
|
if (response instanceof Error) {
|
|
96
96
|
options.onError(response);
|
|
97
|
-
} else if (
|
|
97
|
+
} else if (_chunk2CAGU4FTjs.isResponseError.call(void 0, response)) {
|
|
98
98
|
options.onRequestError(response);
|
|
99
99
|
} else {
|
|
100
100
|
await options.onResponse(response);
|
|
@@ -179,7 +179,7 @@ async function handleRequest(options) {
|
|
|
179
179
|
return handleResponse(nextResult.data);
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
-
options.onResponse(
|
|
182
|
+
options.onResponse(_chunk2CAGU4FTjs.createServerErrorResponse.call(void 0, result.error));
|
|
183
183
|
return true;
|
|
184
184
|
}
|
|
185
185
|
if (result.data) {
|
|
@@ -193,4 +193,4 @@ async function handleRequest(options) {
|
|
|
193
193
|
|
|
194
194
|
|
|
195
195
|
exports.RequestController = RequestController; exports.emitAsync = emitAsync; exports.handleRequest = handleRequest;
|
|
196
|
-
//# sourceMappingURL=chunk-
|
|
196
|
+
//# sourceMappingURL=chunk-FYSUKT3F.js.map
|
|
@@ -2,10 +2,11 @@ import {
|
|
|
2
2
|
RequestController,
|
|
3
3
|
emitAsync,
|
|
4
4
|
handleRequest
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-THPGBWJQ.mjs";
|
|
6
6
|
import {
|
|
7
|
-
IS_PATCHED_MODULE
|
|
8
|
-
|
|
7
|
+
IS_PATCHED_MODULE,
|
|
8
|
+
RESPONSE_STATUS_CODES_WITH_REDIRECT
|
|
9
|
+
} from "./chunk-XVPRNJO7.mjs";
|
|
9
10
|
import {
|
|
10
11
|
Interceptor,
|
|
11
12
|
createRequestId
|
|
@@ -25,6 +26,76 @@ function canParseUrl(url) {
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
// src/interceptors/fetch/utils/createNetworkError.ts
|
|
30
|
+
function createNetworkError(cause) {
|
|
31
|
+
return Object.assign(new TypeError("Failed to fetch"), {
|
|
32
|
+
cause
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/interceptors/fetch/utils/followRedirect.ts
|
|
37
|
+
var REQUEST_BODY_HEADERS = [
|
|
38
|
+
"content-encoding",
|
|
39
|
+
"content-language",
|
|
40
|
+
"content-location",
|
|
41
|
+
"content-type",
|
|
42
|
+
"content-length"
|
|
43
|
+
];
|
|
44
|
+
var kRedirectCount = Symbol("kRedirectCount");
|
|
45
|
+
async function followFetchRedirect(request, response) {
|
|
46
|
+
if (response.status !== 303 && request.body != null) {
|
|
47
|
+
return Promise.reject(createNetworkError());
|
|
48
|
+
}
|
|
49
|
+
const requestUrl = new URL(request.url);
|
|
50
|
+
let locationUrl;
|
|
51
|
+
try {
|
|
52
|
+
locationUrl = new URL(response.headers.get("location"), request.url);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return Promise.reject(createNetworkError(error));
|
|
55
|
+
}
|
|
56
|
+
if (!(locationUrl.protocol === "http:" || locationUrl.protocol === "https:")) {
|
|
57
|
+
return Promise.reject(
|
|
58
|
+
createNetworkError("URL scheme must be a HTTP(S) scheme")
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
if (Reflect.get(request, kRedirectCount) > 20) {
|
|
62
|
+
return Promise.reject(createNetworkError("redirect count exceeded"));
|
|
63
|
+
}
|
|
64
|
+
Object.defineProperty(request, kRedirectCount, {
|
|
65
|
+
value: (Reflect.get(request, kRedirectCount) || 0) + 1
|
|
66
|
+
});
|
|
67
|
+
if (request.mode === "cors" && (locationUrl.username || locationUrl.password) && !sameOrigin(requestUrl, locationUrl)) {
|
|
68
|
+
return Promise.reject(
|
|
69
|
+
createNetworkError('cross origin not allowed for request mode "cors"')
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const requestInit = {};
|
|
73
|
+
if ([301, 302].includes(response.status) && request.method === "POST" || response.status === 303 && !["HEAD", "GET"].includes(request.method)) {
|
|
74
|
+
requestInit.method = "GET";
|
|
75
|
+
requestInit.body = null;
|
|
76
|
+
REQUEST_BODY_HEADERS.forEach((headerName) => {
|
|
77
|
+
request.headers.delete(headerName);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (!sameOrigin(requestUrl, locationUrl)) {
|
|
81
|
+
request.headers.delete("authorization");
|
|
82
|
+
request.headers.delete("proxy-authorization");
|
|
83
|
+
request.headers.delete("cookie");
|
|
84
|
+
request.headers.delete("host");
|
|
85
|
+
}
|
|
86
|
+
requestInit.headers = request.headers;
|
|
87
|
+
return fetch(new Request(locationUrl, requestInit));
|
|
88
|
+
}
|
|
89
|
+
function sameOrigin(left, right) {
|
|
90
|
+
if (left.origin === right.origin && left.origin === "null") {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
if (left.protocol === right.protocol && left.hostname === right.hostname && left.port === right.port) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
28
99
|
// src/interceptors/fetch/index.ts
|
|
29
100
|
var _FetchInterceptor = class extends Interceptor {
|
|
30
101
|
constructor() {
|
|
@@ -60,6 +131,23 @@ var _FetchInterceptor = class extends Interceptor {
|
|
|
60
131
|
this.logger.info("received mocked response!", {
|
|
61
132
|
response
|
|
62
133
|
});
|
|
134
|
+
if (RESPONSE_STATUS_CODES_WITH_REDIRECT.has(response.status)) {
|
|
135
|
+
if (request.redirect === "error") {
|
|
136
|
+
responsePromise.reject(createNetworkError("unexpected redirect"));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (request.redirect === "follow") {
|
|
140
|
+
followFetchRedirect(request, response).then(
|
|
141
|
+
(response2) => {
|
|
142
|
+
responsePromise.resolve(response2);
|
|
143
|
+
},
|
|
144
|
+
(reason) => {
|
|
145
|
+
responsePromise.reject(reason);
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
63
151
|
if (this.emitter.listenerCount("response") > 0) {
|
|
64
152
|
this.logger.info('emitting the "response" event...');
|
|
65
153
|
await emitAsync(this.emitter, "response", {
|
|
@@ -130,13 +218,8 @@ var _FetchInterceptor = class extends Interceptor {
|
|
|
130
218
|
};
|
|
131
219
|
var FetchInterceptor = _FetchInterceptor;
|
|
132
220
|
FetchInterceptor.symbol = Symbol("fetch");
|
|
133
|
-
function createNetworkError(cause) {
|
|
134
|
-
return Object.assign(new TypeError("Failed to fetch"), {
|
|
135
|
-
cause
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
221
|
|
|
139
222
|
export {
|
|
140
223
|
FetchInterceptor
|
|
141
224
|
};
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
225
|
+
//# sourceMappingURL=chunk-G5SOR3ND.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/interceptors/fetch/index.ts","../../src/utils/canParseUrl.ts","../../src/interceptors/fetch/utils/createNetworkError.ts","../../src/interceptors/fetch/utils/followRedirect.ts"],"sourcesContent":["import { invariant } from 'outvariant'\nimport { DeferredPromise } from '@open-draft/deferred-promise'\nimport { HttpRequestEventMap, IS_PATCHED_MODULE } from '../../glossary'\nimport { Interceptor } from '../../Interceptor'\nimport { RequestController } from '../../RequestController'\nimport { emitAsync } from '../../utils/emitAsync'\nimport { handleRequest } from '../../utils/handleRequest'\nimport { canParseUrl } from '../../utils/canParseUrl'\nimport { createRequestId } from '../../createRequestId'\nimport { RESPONSE_STATUS_CODES_WITH_REDIRECT } from '../../utils/responseUtils'\nimport { createNetworkError } from './utils/createNetworkError'\nimport { followFetchRedirect } from './utils/followRedirect'\n\nexport class FetchInterceptor extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('fetch')\n\n constructor() {\n super(FetchInterceptor.symbol)\n }\n\n protected checkEnvironment() {\n return (\n typeof globalThis !== 'undefined' &&\n typeof globalThis.fetch !== 'undefined'\n )\n }\n\n protected async setup() {\n const pureFetch = globalThis.fetch\n\n invariant(\n !(pureFetch as any)[IS_PATCHED_MODULE],\n 'Failed to patch the \"fetch\" module: already patched.'\n )\n\n globalThis.fetch = async (input, init) => {\n const requestId = createRequestId()\n\n /**\n * @note Resolve potentially relative request URL\n * against the present `location`. This is mainly\n * for native `fetch` in JSDOM.\n * @see https://github.com/mswjs/msw/issues/1625\n */\n const resolvedInput =\n typeof input === 'string' &&\n typeof location !== 'undefined' &&\n !canParseUrl(input)\n ? new URL(input, location.origin)\n : input\n\n const request = new Request(resolvedInput, init)\n const responsePromise = new DeferredPromise<Response>()\n const controller = new RequestController(request)\n\n this.logger.info('[%s] %s', request.method, request.url)\n this.logger.info('awaiting for the mocked response...')\n\n this.logger.info(\n 'emitting the \"request\" event for %s listener(s)...',\n this.emitter.listenerCount('request')\n )\n\n const isRequestHandled = await handleRequest({\n request,\n requestId,\n emitter: this.emitter,\n controller,\n onResponse: async (response) => {\n this.logger.info('received mocked response!', {\n response,\n })\n\n /**\n * Undici's handling of following redirect responses.\n * Treat the \"manual\" redirect mode as a regular mocked response.\n * This way, the client can manually follow the redirect it receives.\n * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1173\n */\n if (RESPONSE_STATUS_CODES_WITH_REDIRECT.has(response.status)) {\n // Reject the request promise if its `redirect` is set to `error`\n // and it receives a mocked redirect response.\n if (request.redirect === 'error') {\n responsePromise.reject(createNetworkError('unexpected redirect'))\n return\n }\n\n if (request.redirect === 'follow') {\n followFetchRedirect(request, response).then(\n (response) => {\n responsePromise.resolve(response)\n },\n (reason) => {\n responsePromise.reject(reason)\n }\n )\n return\n }\n }\n\n if (this.emitter.listenerCount('response') > 0) {\n this.logger.info('emitting the \"response\" event...')\n\n // Await the response listeners to finish before resolving\n // the response promise. This ensures all your logic finishes\n // before the interceptor resolves the pending response.\n await emitAsync(this.emitter, 'response', {\n // Clone the mocked response for the \"response\" event listener.\n // This way, the listener can read the response and not lock its body\n // for the actual fetch consumer.\n response: response.clone(),\n isMockedResponse: true,\n request,\n requestId,\n })\n }\n\n // Set the \"response.url\" property to equal the intercepted request URL.\n Object.defineProperty(response, 'url', {\n writable: false,\n enumerable: true,\n configurable: false,\n value: request.url,\n })\n\n responsePromise.resolve(response)\n },\n onRequestError: (response) => {\n this.logger.info('request has errored!', { response })\n responsePromise.reject(createNetworkError(response))\n },\n onError: (error) => {\n this.logger.info('request has been aborted!', { error })\n responsePromise.reject(error)\n },\n })\n\n if (isRequestHandled) {\n this.logger.info('request has been handled, returning mock promise...')\n return responsePromise\n }\n\n this.logger.info(\n 'no mocked response received, performing request as-is...'\n )\n\n return pureFetch(request).then((response) => {\n this.logger.info('original fetch performed', response)\n\n if (this.emitter.listenerCount('response') > 0) {\n this.logger.info('emitting the \"response\" event...')\n\n const responseClone = response.clone()\n\n this.emitter.emit('response', {\n response: responseClone,\n isMockedResponse: false,\n request,\n requestId,\n })\n }\n\n return response\n })\n }\n\n Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {\n enumerable: true,\n configurable: true,\n value: true,\n })\n\n this.subscriptions.push(() => {\n Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {\n value: undefined,\n })\n\n globalThis.fetch = pureFetch\n\n this.logger.info(\n 'restored native \"globalThis.fetch\"!',\n globalThis.fetch.name\n )\n })\n }\n}\n","/**\n * Returns a boolean indicating whether the given URL string\n * can be parsed into a `URL` instance.\n * A substitute for `URL.canParse()` for Node.js 18.\n */\nexport function canParseUrl(url: string): boolean {\n try {\n new URL(url)\n return true\n } catch (_error) {\n return false\n }\n}\n","export function createNetworkError(cause?: unknown) {\n return Object.assign(new TypeError('Failed to fetch'), {\n cause,\n })\n}\n","import { createNetworkError } from './createNetworkError'\n\nconst REQUEST_BODY_HEADERS = [\n 'content-encoding',\n 'content-language',\n 'content-location',\n 'content-type',\n 'content-length',\n]\n\nconst kRedirectCount = Symbol('kRedirectCount')\n\n/**\n * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1210\n */\nexport async function followFetchRedirect(\n request: Request,\n response: Response\n): Promise<Response> {\n if (response.status !== 303 && request.body != null) {\n return Promise.reject(createNetworkError())\n }\n\n const requestUrl = new URL(request.url)\n\n let locationUrl: URL\n try {\n // If the location is a relative URL, use the request URL as the base URL.\n locationUrl = new URL(response.headers.get('location')!, request.url) \n } catch (error) {\n return Promise.reject(createNetworkError(error))\n }\n\n if (\n !(locationUrl.protocol === 'http:' || locationUrl.protocol === 'https:')\n ) {\n return Promise.reject(\n createNetworkError('URL scheme must be a HTTP(S) scheme')\n )\n }\n\n if (Reflect.get(request, kRedirectCount) > 20) {\n return Promise.reject(createNetworkError('redirect count exceeded'))\n }\n\n Object.defineProperty(request, kRedirectCount, {\n value: (Reflect.get(request, kRedirectCount) || 0) + 1,\n })\n\n if (\n request.mode === 'cors' &&\n (locationUrl.username || locationUrl.password) &&\n !sameOrigin(requestUrl, locationUrl)\n ) {\n return Promise.reject(\n createNetworkError('cross origin not allowed for request mode \"cors\"')\n )\n }\n\n const requestInit: RequestInit = {}\n\n if (\n ([301, 302].includes(response.status) && request.method === 'POST') ||\n (response.status === 303 && !['HEAD', 'GET'].includes(request.method))\n ) {\n requestInit.method = 'GET'\n requestInit.body = null\n\n REQUEST_BODY_HEADERS.forEach((headerName) => {\n request.headers.delete(headerName)\n })\n }\n\n if (!sameOrigin(requestUrl, locationUrl)) {\n request.headers.delete('authorization')\n request.headers.delete('proxy-authorization')\n request.headers.delete('cookie')\n request.headers.delete('host')\n }\n\n /**\n * @note Undici \"safely\" extracts the request body.\n * I suspect we cannot dispatch this request again\n * since its body has been read and the stream is locked.\n */\n\n requestInit.headers = request.headers\n return fetch(new Request(locationUrl, requestInit))\n}\n\n/**\n * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/util.js#L761\n */\nfunction sameOrigin(left: URL, right: URL): boolean {\n if (left.origin === right.origin && left.origin === 'null') {\n return true\n }\n\n if (\n left.protocol === right.protocol &&\n left.hostname === right.hostname &&\n left.port === right.port\n ) {\n return true\n }\n\n return false\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;;;ACIzB,SAAS,YAAY,KAAsB;AAChD,MAAI;AACF,QAAI,IAAI,GAAG;AACX,WAAO;AAAA,EACT,SAAS,QAAP;AACA,WAAO;AAAA,EACT;AACF;;;ACZO,SAAS,mBAAmB,OAAiB;AAClD,SAAO,OAAO,OAAO,IAAI,UAAU,iBAAiB,GAAG;AAAA,IACrD;AAAA,EACF,CAAC;AACH;;;ACFA,IAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,iBAAiB,OAAO,gBAAgB;AAK9C,eAAsB,oBACpB,SACA,UACmB;AACnB,MAAI,SAAS,WAAW,OAAO,QAAQ,QAAQ,MAAM;AACnD,WAAO,QAAQ,OAAO,mBAAmB,CAAC;AAAA,EAC5C;AAEA,QAAM,aAAa,IAAI,IAAI,QAAQ,GAAG;AAEtC,MAAI;AACJ,MAAI;AAEF,kBAAc,IAAI,IAAI,SAAS,QAAQ,IAAI,UAAU,GAAI,QAAQ,GAAG;AAAA,EACtE,SAAS,OAAP;AACA,WAAO,QAAQ,OAAO,mBAAmB,KAAK,CAAC;AAAA,EACjD;AAEA,MACE,EAAE,YAAY,aAAa,WAAW,YAAY,aAAa,WAC/D;AACA,WAAO,QAAQ;AAAA,MACb,mBAAmB,qCAAqC;AAAA,IAC1D;AAAA,EACF;AAEA,MAAI,QAAQ,IAAI,SAAS,cAAc,IAAI,IAAI;AAC7C,WAAO,QAAQ,OAAO,mBAAmB,yBAAyB,CAAC;AAAA,EACrE;AAEA,SAAO,eAAe,SAAS,gBAAgB;AAAA,IAC7C,QAAQ,QAAQ,IAAI,SAAS,cAAc,KAAK,KAAK;AAAA,EACvD,CAAC;AAED,MACE,QAAQ,SAAS,WAChB,YAAY,YAAY,YAAY,aACrC,CAAC,WAAW,YAAY,WAAW,GACnC;AACA,WAAO,QAAQ;AAAA,MACb,mBAAmB,kDAAkD;AAAA,IACvE;AAAA,EACF;AAEA,QAAM,cAA2B,CAAC;AAElC,MACG,CAAC,KAAK,GAAG,EAAE,SAAS,SAAS,MAAM,KAAK,QAAQ,WAAW,UAC3D,SAAS,WAAW,OAAO,CAAC,CAAC,QAAQ,KAAK,EAAE,SAAS,QAAQ,MAAM,GACpE;AACA,gBAAY,SAAS;AACrB,gBAAY,OAAO;AAEnB,yBAAqB,QAAQ,CAAC,eAAe;AAC3C,cAAQ,QAAQ,OAAO,UAAU;AAAA,IACnC,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,WAAW,YAAY,WAAW,GAAG;AACxC,YAAQ,QAAQ,OAAO,eAAe;AACtC,YAAQ,QAAQ,OAAO,qBAAqB;AAC5C,YAAQ,QAAQ,OAAO,QAAQ;AAC/B,YAAQ,QAAQ,OAAO,MAAM;AAAA,EAC/B;AAQA,cAAY,UAAU,QAAQ;AAC9B,SAAO,MAAM,IAAI,QAAQ,aAAa,WAAW,CAAC;AACpD;AAKA,SAAS,WAAW,MAAW,OAAqB;AAClD,MAAI,KAAK,WAAW,MAAM,UAAU,KAAK,WAAW,QAAQ;AAC1D,WAAO;AAAA,EACT;AAEA,MACE,KAAK,aAAa,MAAM,YACxB,KAAK,aAAa,MAAM,YACxB,KAAK,SAAS,MAAM,MACpB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AH9FO,IAAM,oBAAN,cAA+B,YAAiC;AAAA,EAGrE,cAAc;AACZ,UAAM,kBAAiB,MAAM;AAAA,EAC/B;AAAA,EAEU,mBAAmB;AAC3B,WACE,OAAO,eAAe,eACtB,OAAO,WAAW,UAAU;AAAA,EAEhC;AAAA,EAEA,MAAgB,QAAQ;AACtB,UAAM,YAAY,WAAW;AAE7B;AAAA,MACE,CAAE,UAAkB,iBAAiB;AAAA,MACrC;AAAA,IACF;AAEA,eAAW,QAAQ,OAAO,OAAO,SAAS;AACxC,YAAM,YAAY,gBAAgB;AAQlC,YAAM,gBACJ,OAAO,UAAU,YACjB,OAAO,aAAa,eACpB,CAAC,YAAY,KAAK,IACd,IAAI,IAAI,OAAO,SAAS,MAAM,IAC9B;AAEN,YAAM,UAAU,IAAI,QAAQ,eAAe,IAAI;AAC/C,YAAM,kBAAkB,IAAI,gBAA0B;AACtD,YAAM,aAAa,IAAI,kBAAkB,OAAO;AAEhD,WAAK,OAAO,KAAK,WAAW,QAAQ,QAAQ,QAAQ,GAAG;AACvD,WAAK,OAAO,KAAK,qCAAqC;AAEtD,WAAK,OAAO;AAAA,QACV;AAAA,QACA,KAAK,QAAQ,cAAc,SAAS;AAAA,MACtC;AAEA,YAAM,mBAAmB,MAAM,cAAc;AAAA,QAC3C;AAAA,QACA;AAAA,QACA,SAAS,KAAK;AAAA,QACd;AAAA,QACA,YAAY,OAAO,aAAa;AAC9B,eAAK,OAAO,KAAK,6BAA6B;AAAA,YAC5C;AAAA,UACF,CAAC;AAQD,cAAI,oCAAoC,IAAI,SAAS,MAAM,GAAG;AAG5D,gBAAI,QAAQ,aAAa,SAAS;AAChC,8BAAgB,OAAO,mBAAmB,qBAAqB,CAAC;AAChE;AAAA,YACF;AAEA,gBAAI,QAAQ,aAAa,UAAU;AACjC,kCAAoB,SAAS,QAAQ,EAAE;AAAA,gBACrC,CAACA,cAAa;AACZ,kCAAgB,QAAQA,SAAQ;AAAA,gBAClC;AAAA,gBACA,CAAC,WAAW;AACV,kCAAgB,OAAO,MAAM;AAAA,gBAC/B;AAAA,cACF;AACA;AAAA,YACF;AAAA,UACF;AAEA,cAAI,KAAK,QAAQ,cAAc,UAAU,IAAI,GAAG;AAC9C,iBAAK,OAAO,KAAK,kCAAkC;AAKnD,kBAAM,UAAU,KAAK,SAAS,YAAY;AAAA;AAAA;AAAA;AAAA,cAIxC,UAAU,SAAS,MAAM;AAAA,cACzB,kBAAkB;AAAA,cAClB;AAAA,cACA;AAAA,YACF,CAAC;AAAA,UACH;AAGA,iBAAO,eAAe,UAAU,OAAO;AAAA,YACrC,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,cAAc;AAAA,YACd,OAAO,QAAQ;AAAA,UACjB,CAAC;AAED,0BAAgB,QAAQ,QAAQ;AAAA,QAClC;AAAA,QACA,gBAAgB,CAAC,aAAa;AAC5B,eAAK,OAAO,KAAK,wBAAwB,EAAE,SAAS,CAAC;AACrD,0BAAgB,OAAO,mBAAmB,QAAQ,CAAC;AAAA,QACrD;AAAA,QACA,SAAS,CAAC,UAAU;AAClB,eAAK,OAAO,KAAK,6BAA6B,EAAE,MAAM,CAAC;AACvD,0BAAgB,OAAO,KAAK;AAAA,QAC9B;AAAA,MACF,CAAC;AAED,UAAI,kBAAkB;AACpB,aAAK,OAAO,KAAK,qDAAqD;AACtE,eAAO;AAAA,MACT;AAEA,WAAK,OAAO;AAAA,QACV;AAAA,MACF;AAEA,aAAO,UAAU,OAAO,EAAE,KAAK,CAAC,aAAa;AAC3C,aAAK,OAAO,KAAK,4BAA4B,QAAQ;AAErD,YAAI,KAAK,QAAQ,cAAc,UAAU,IAAI,GAAG;AAC9C,eAAK,OAAO,KAAK,kCAAkC;AAEnD,gBAAM,gBAAgB,SAAS,MAAM;AAErC,eAAK,QAAQ,KAAK,YAAY;AAAA,YAC5B,UAAU;AAAA,YACV,kBAAkB;AAAA,YAClB;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,WAAO,eAAe,WAAW,OAAO,mBAAmB;AAAA,MACzD,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,OAAO;AAAA,IACT,CAAC;AAED,SAAK,cAAc,KAAK,MAAM;AAC5B,aAAO,eAAe,WAAW,OAAO,mBAAmB;AAAA,QACzD,OAAO;AAAA,MACT,CAAC;AAED,iBAAW,QAAQ;AAEnB,WAAK,OAAO;AAAA,QACV;AAAA,QACA,WAAW,MAAM;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AA5KO,IAAM,mBAAN;AAAM,iBACJ,SAAS,OAAO,OAAO;","names":["response"]}
|
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
RequestController,
|
|
8
8
|
handleRequest
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-THPGBWJQ.mjs";
|
|
10
10
|
import {
|
|
11
11
|
IS_PATCHED_MODULE,
|
|
12
12
|
isResponseWithoutBody
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XVPRNJO7.mjs";
|
|
14
14
|
import {
|
|
15
15
|
INTERNAL_REQUEST_ID_HEADER_NAME,
|
|
16
16
|
Interceptor,
|
|
@@ -837,4 +837,4 @@ XMLHttpRequestInterceptor.interceptorSymbol = Symbol("xhr");
|
|
|
837
837
|
export {
|
|
838
838
|
XMLHttpRequestInterceptor
|
|
839
839
|
};
|
|
840
|
-
//# sourceMappingURL=chunk-
|
|
840
|
+
//# sourceMappingURL=chunk-PRBA3ES4.mjs.map
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkFYSUKT3Fjs = require('./chunk-FYSUKT3F.js');
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
var _chunk2CAGU4FTjs = require('./chunk-2CAGU4FT.js');
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
|
|
@@ -25,6 +26,76 @@ function canParseUrl(url) {
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
// src/interceptors/fetch/utils/createNetworkError.ts
|
|
30
|
+
function createNetworkError(cause) {
|
|
31
|
+
return Object.assign(new TypeError("Failed to fetch"), {
|
|
32
|
+
cause
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/interceptors/fetch/utils/followRedirect.ts
|
|
37
|
+
var REQUEST_BODY_HEADERS = [
|
|
38
|
+
"content-encoding",
|
|
39
|
+
"content-language",
|
|
40
|
+
"content-location",
|
|
41
|
+
"content-type",
|
|
42
|
+
"content-length"
|
|
43
|
+
];
|
|
44
|
+
var kRedirectCount = Symbol("kRedirectCount");
|
|
45
|
+
async function followFetchRedirect(request, response) {
|
|
46
|
+
if (response.status !== 303 && request.body != null) {
|
|
47
|
+
return Promise.reject(createNetworkError());
|
|
48
|
+
}
|
|
49
|
+
const requestUrl = new URL(request.url);
|
|
50
|
+
let locationUrl;
|
|
51
|
+
try {
|
|
52
|
+
locationUrl = new URL(response.headers.get("location"), request.url);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return Promise.reject(createNetworkError(error));
|
|
55
|
+
}
|
|
56
|
+
if (!(locationUrl.protocol === "http:" || locationUrl.protocol === "https:")) {
|
|
57
|
+
return Promise.reject(
|
|
58
|
+
createNetworkError("URL scheme must be a HTTP(S) scheme")
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
if (Reflect.get(request, kRedirectCount) > 20) {
|
|
62
|
+
return Promise.reject(createNetworkError("redirect count exceeded"));
|
|
63
|
+
}
|
|
64
|
+
Object.defineProperty(request, kRedirectCount, {
|
|
65
|
+
value: (Reflect.get(request, kRedirectCount) || 0) + 1
|
|
66
|
+
});
|
|
67
|
+
if (request.mode === "cors" && (locationUrl.username || locationUrl.password) && !sameOrigin(requestUrl, locationUrl)) {
|
|
68
|
+
return Promise.reject(
|
|
69
|
+
createNetworkError('cross origin not allowed for request mode "cors"')
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const requestInit = {};
|
|
73
|
+
if ([301, 302].includes(response.status) && request.method === "POST" || response.status === 303 && !["HEAD", "GET"].includes(request.method)) {
|
|
74
|
+
requestInit.method = "GET";
|
|
75
|
+
requestInit.body = null;
|
|
76
|
+
REQUEST_BODY_HEADERS.forEach((headerName) => {
|
|
77
|
+
request.headers.delete(headerName);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (!sameOrigin(requestUrl, locationUrl)) {
|
|
81
|
+
request.headers.delete("authorization");
|
|
82
|
+
request.headers.delete("proxy-authorization");
|
|
83
|
+
request.headers.delete("cookie");
|
|
84
|
+
request.headers.delete("host");
|
|
85
|
+
}
|
|
86
|
+
requestInit.headers = request.headers;
|
|
87
|
+
return fetch(new Request(locationUrl, requestInit));
|
|
88
|
+
}
|
|
89
|
+
function sameOrigin(left, right) {
|
|
90
|
+
if (left.origin === right.origin && left.origin === "null") {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
if (left.protocol === right.protocol && left.hostname === right.hostname && left.port === right.port) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
28
99
|
// src/interceptors/fetch/index.ts
|
|
29
100
|
var _FetchInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
|
|
30
101
|
constructor() {
|
|
@@ -36,7 +107,7 @@ var _FetchInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
|
|
|
36
107
|
async setup() {
|
|
37
108
|
const pureFetch = globalThis.fetch;
|
|
38
109
|
_outvariant.invariant.call(void 0,
|
|
39
|
-
!pureFetch[
|
|
110
|
+
!pureFetch[_chunk2CAGU4FTjs.IS_PATCHED_MODULE],
|
|
40
111
|
'Failed to patch the "fetch" module: already patched.'
|
|
41
112
|
);
|
|
42
113
|
globalThis.fetch = async (input, init) => {
|
|
@@ -44,14 +115,14 @@ var _FetchInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
|
|
|
44
115
|
const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !canParseUrl(input) ? new URL(input, location.origin) : input;
|
|
45
116
|
const request = new Request(resolvedInput, init);
|
|
46
117
|
const responsePromise = new (0, _deferredpromise.DeferredPromise)();
|
|
47
|
-
const controller = new (0,
|
|
118
|
+
const controller = new (0, _chunkFYSUKT3Fjs.RequestController)(request);
|
|
48
119
|
this.logger.info("[%s] %s", request.method, request.url);
|
|
49
120
|
this.logger.info("awaiting for the mocked response...");
|
|
50
121
|
this.logger.info(
|
|
51
122
|
'emitting the "request" event for %s listener(s)...',
|
|
52
123
|
this.emitter.listenerCount("request")
|
|
53
124
|
);
|
|
54
|
-
const isRequestHandled = await
|
|
125
|
+
const isRequestHandled = await _chunkFYSUKT3Fjs.handleRequest.call(void 0, {
|
|
55
126
|
request,
|
|
56
127
|
requestId,
|
|
57
128
|
emitter: this.emitter,
|
|
@@ -60,9 +131,26 @@ var _FetchInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
|
|
|
60
131
|
this.logger.info("received mocked response!", {
|
|
61
132
|
response
|
|
62
133
|
});
|
|
134
|
+
if (_chunk2CAGU4FTjs.RESPONSE_STATUS_CODES_WITH_REDIRECT.has(response.status)) {
|
|
135
|
+
if (request.redirect === "error") {
|
|
136
|
+
responsePromise.reject(createNetworkError("unexpected redirect"));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (request.redirect === "follow") {
|
|
140
|
+
followFetchRedirect(request, response).then(
|
|
141
|
+
(response2) => {
|
|
142
|
+
responsePromise.resolve(response2);
|
|
143
|
+
},
|
|
144
|
+
(reason) => {
|
|
145
|
+
responsePromise.reject(reason);
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
63
151
|
if (this.emitter.listenerCount("response") > 0) {
|
|
64
152
|
this.logger.info('emitting the "response" event...');
|
|
65
|
-
await
|
|
153
|
+
await _chunkFYSUKT3Fjs.emitAsync.call(void 0, this.emitter, "response", {
|
|
66
154
|
// Clone the mocked response for the "response" event listener.
|
|
67
155
|
// This way, the listener can read the response and not lock its body
|
|
68
156
|
// for the actual fetch consumer.
|
|
@@ -111,13 +199,13 @@ var _FetchInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
|
|
|
111
199
|
return response;
|
|
112
200
|
});
|
|
113
201
|
};
|
|
114
|
-
Object.defineProperty(globalThis.fetch,
|
|
202
|
+
Object.defineProperty(globalThis.fetch, _chunk2CAGU4FTjs.IS_PATCHED_MODULE, {
|
|
115
203
|
enumerable: true,
|
|
116
204
|
configurable: true,
|
|
117
205
|
value: true
|
|
118
206
|
});
|
|
119
207
|
this.subscriptions.push(() => {
|
|
120
|
-
Object.defineProperty(globalThis.fetch,
|
|
208
|
+
Object.defineProperty(globalThis.fetch, _chunk2CAGU4FTjs.IS_PATCHED_MODULE, {
|
|
121
209
|
value: void 0
|
|
122
210
|
});
|
|
123
211
|
globalThis.fetch = pureFetch;
|
|
@@ -130,13 +218,8 @@ var _FetchInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
|
|
|
130
218
|
};
|
|
131
219
|
var FetchInterceptor = _FetchInterceptor;
|
|
132
220
|
FetchInterceptor.symbol = Symbol("fetch");
|
|
133
|
-
function createNetworkError(cause) {
|
|
134
|
-
return Object.assign(new TypeError("Failed to fetch"), {
|
|
135
|
-
cause
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
221
|
|
|
139
222
|
|
|
140
223
|
|
|
141
224
|
exports.FetchInterceptor = FetchInterceptor;
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
225
|
+
//# sourceMappingURL=chunk-T5Q47QLJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/interceptors/fetch/index.ts","../../src/utils/canParseUrl.ts","../../src/interceptors/fetch/utils/createNetworkError.ts","../../src/interceptors/fetch/utils/followRedirect.ts"],"names":["response"],"mappings":"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","sourcesContent":["import { invariant } from 'outvariant'\nimport { DeferredPromise } from '@open-draft/deferred-promise'\nimport { HttpRequestEventMap, IS_PATCHED_MODULE } from '../../glossary'\nimport { Interceptor } from '../../Interceptor'\nimport { RequestController } from '../../RequestController'\nimport { emitAsync } from '../../utils/emitAsync'\nimport { handleRequest } from '../../utils/handleRequest'\nimport { canParseUrl } from '../../utils/canParseUrl'\nimport { createRequestId } from '../../createRequestId'\nimport { RESPONSE_STATUS_CODES_WITH_REDIRECT } from '../../utils/responseUtils'\nimport { createNetworkError } from './utils/createNetworkError'\nimport { followFetchRedirect } from './utils/followRedirect'\n\nexport class FetchInterceptor extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('fetch')\n\n constructor() {\n super(FetchInterceptor.symbol)\n }\n\n protected checkEnvironment() {\n return (\n typeof globalThis !== 'undefined' &&\n typeof globalThis.fetch !== 'undefined'\n )\n }\n\n protected async setup() {\n const pureFetch = globalThis.fetch\n\n invariant(\n !(pureFetch as any)[IS_PATCHED_MODULE],\n 'Failed to patch the \"fetch\" module: already patched.'\n )\n\n globalThis.fetch = async (input, init) => {\n const requestId = createRequestId()\n\n /**\n * @note Resolve potentially relative request URL\n * against the present `location`. This is mainly\n * for native `fetch` in JSDOM.\n * @see https://github.com/mswjs/msw/issues/1625\n */\n const resolvedInput =\n typeof input === 'string' &&\n typeof location !== 'undefined' &&\n !canParseUrl(input)\n ? new URL(input, location.origin)\n : input\n\n const request = new Request(resolvedInput, init)\n const responsePromise = new DeferredPromise<Response>()\n const controller = new RequestController(request)\n\n this.logger.info('[%s] %s', request.method, request.url)\n this.logger.info('awaiting for the mocked response...')\n\n this.logger.info(\n 'emitting the \"request\" event for %s listener(s)...',\n this.emitter.listenerCount('request')\n )\n\n const isRequestHandled = await handleRequest({\n request,\n requestId,\n emitter: this.emitter,\n controller,\n onResponse: async (response) => {\n this.logger.info('received mocked response!', {\n response,\n })\n\n /**\n * Undici's handling of following redirect responses.\n * Treat the \"manual\" redirect mode as a regular mocked response.\n * This way, the client can manually follow the redirect it receives.\n * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1173\n */\n if (RESPONSE_STATUS_CODES_WITH_REDIRECT.has(response.status)) {\n // Reject the request promise if its `redirect` is set to `error`\n // and it receives a mocked redirect response.\n if (request.redirect === 'error') {\n responsePromise.reject(createNetworkError('unexpected redirect'))\n return\n }\n\n if (request.redirect === 'follow') {\n followFetchRedirect(request, response).then(\n (response) => {\n responsePromise.resolve(response)\n },\n (reason) => {\n responsePromise.reject(reason)\n }\n )\n return\n }\n }\n\n if (this.emitter.listenerCount('response') > 0) {\n this.logger.info('emitting the \"response\" event...')\n\n // Await the response listeners to finish before resolving\n // the response promise. This ensures all your logic finishes\n // before the interceptor resolves the pending response.\n await emitAsync(this.emitter, 'response', {\n // Clone the mocked response for the \"response\" event listener.\n // This way, the listener can read the response and not lock its body\n // for the actual fetch consumer.\n response: response.clone(),\n isMockedResponse: true,\n request,\n requestId,\n })\n }\n\n // Set the \"response.url\" property to equal the intercepted request URL.\n Object.defineProperty(response, 'url', {\n writable: false,\n enumerable: true,\n configurable: false,\n value: request.url,\n })\n\n responsePromise.resolve(response)\n },\n onRequestError: (response) => {\n this.logger.info('request has errored!', { response })\n responsePromise.reject(createNetworkError(response))\n },\n onError: (error) => {\n this.logger.info('request has been aborted!', { error })\n responsePromise.reject(error)\n },\n })\n\n if (isRequestHandled) {\n this.logger.info('request has been handled, returning mock promise...')\n return responsePromise\n }\n\n this.logger.info(\n 'no mocked response received, performing request as-is...'\n )\n\n return pureFetch(request).then((response) => {\n this.logger.info('original fetch performed', response)\n\n if (this.emitter.listenerCount('response') > 0) {\n this.logger.info('emitting the \"response\" event...')\n\n const responseClone = response.clone()\n\n this.emitter.emit('response', {\n response: responseClone,\n isMockedResponse: false,\n request,\n requestId,\n })\n }\n\n return response\n })\n }\n\n Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {\n enumerable: true,\n configurable: true,\n value: true,\n })\n\n this.subscriptions.push(() => {\n Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {\n value: undefined,\n })\n\n globalThis.fetch = pureFetch\n\n this.logger.info(\n 'restored native \"globalThis.fetch\"!',\n globalThis.fetch.name\n )\n })\n }\n}\n","/**\n * Returns a boolean indicating whether the given URL string\n * can be parsed into a `URL` instance.\n * A substitute for `URL.canParse()` for Node.js 18.\n */\nexport function canParseUrl(url: string): boolean {\n try {\n new URL(url)\n return true\n } catch (_error) {\n return false\n }\n}\n","export function createNetworkError(cause?: unknown) {\n return Object.assign(new TypeError('Failed to fetch'), {\n cause,\n })\n}\n","import { createNetworkError } from './createNetworkError'\n\nconst REQUEST_BODY_HEADERS = [\n 'content-encoding',\n 'content-language',\n 'content-location',\n 'content-type',\n 'content-length',\n]\n\nconst kRedirectCount = Symbol('kRedirectCount')\n\n/**\n * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1210\n */\nexport async function followFetchRedirect(\n request: Request,\n response: Response\n): Promise<Response> {\n if (response.status !== 303 && request.body != null) {\n return Promise.reject(createNetworkError())\n }\n\n const requestUrl = new URL(request.url)\n\n let locationUrl: URL\n try {\n // If the location is a relative URL, use the request URL as the base URL.\n locationUrl = new URL(response.headers.get('location')!, request.url) \n } catch (error) {\n return Promise.reject(createNetworkError(error))\n }\n\n if (\n !(locationUrl.protocol === 'http:' || locationUrl.protocol === 'https:')\n ) {\n return Promise.reject(\n createNetworkError('URL scheme must be a HTTP(S) scheme')\n )\n }\n\n if (Reflect.get(request, kRedirectCount) > 20) {\n return Promise.reject(createNetworkError('redirect count exceeded'))\n }\n\n Object.defineProperty(request, kRedirectCount, {\n value: (Reflect.get(request, kRedirectCount) || 0) + 1,\n })\n\n if (\n request.mode === 'cors' &&\n (locationUrl.username || locationUrl.password) &&\n !sameOrigin(requestUrl, locationUrl)\n ) {\n return Promise.reject(\n createNetworkError('cross origin not allowed for request mode \"cors\"')\n )\n }\n\n const requestInit: RequestInit = {}\n\n if (\n ([301, 302].includes(response.status) && request.method === 'POST') ||\n (response.status === 303 && !['HEAD', 'GET'].includes(request.method))\n ) {\n requestInit.method = 'GET'\n requestInit.body = null\n\n REQUEST_BODY_HEADERS.forEach((headerName) => {\n request.headers.delete(headerName)\n })\n }\n\n if (!sameOrigin(requestUrl, locationUrl)) {\n request.headers.delete('authorization')\n request.headers.delete('proxy-authorization')\n request.headers.delete('cookie')\n request.headers.delete('host')\n }\n\n /**\n * @note Undici \"safely\" extracts the request body.\n * I suspect we cannot dispatch this request again\n * since its body has been read and the stream is locked.\n */\n\n requestInit.headers = request.headers\n return fetch(new Request(locationUrl, requestInit))\n}\n\n/**\n * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/util.js#L761\n */\nfunction sameOrigin(left: URL, right: URL): boolean {\n if (left.origin === right.origin && left.origin === 'null') {\n return true\n }\n\n if (\n left.protocol === right.protocol &&\n left.hostname === right.hostname &&\n left.port === right.port\n ) {\n return true\n }\n\n return false\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServerErrorResponse,
|
|
3
3
|
isResponseError
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XVPRNJO7.mjs";
|
|
5
5
|
|
|
6
6
|
// src/RequestController.ts
|
|
7
7
|
import { invariant } from "outvariant";
|
|
@@ -193,4 +193,4 @@ export {
|
|
|
193
193
|
emitAsync,
|
|
194
194
|
handleRequest
|
|
195
195
|
};
|
|
196
|
-
//# sourceMappingURL=chunk-
|
|
196
|
+
//# sourceMappingURL=chunk-THPGBWJQ.mjs.map
|
|
@@ -19,6 +19,13 @@ var RESPONSE_STATUS_CODES_WITHOUT_BODY = /* @__PURE__ */ new Set([
|
|
|
19
19
|
205,
|
|
20
20
|
304
|
|
21
21
|
]);
|
|
22
|
+
var RESPONSE_STATUS_CODES_WITH_REDIRECT = /* @__PURE__ */ new Set([
|
|
23
|
+
301,
|
|
24
|
+
302,
|
|
25
|
+
303,
|
|
26
|
+
307,
|
|
27
|
+
308
|
|
28
|
+
]);
|
|
22
29
|
function isResponseWithoutBody(status) {
|
|
23
30
|
return RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status);
|
|
24
31
|
}
|
|
@@ -46,8 +53,9 @@ function isResponseError(response) {
|
|
|
46
53
|
|
|
47
54
|
export {
|
|
48
55
|
IS_PATCHED_MODULE,
|
|
56
|
+
RESPONSE_STATUS_CODES_WITH_REDIRECT,
|
|
49
57
|
isResponseWithoutBody,
|
|
50
58
|
createServerErrorResponse,
|
|
51
59
|
isResponseError
|
|
52
60
|
};
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
61
|
+
//# sourceMappingURL=chunk-XVPRNJO7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/glossary.ts","../../src/utils/isPropertyAccessible.ts","../../src/utils/responseUtils.ts"],"sourcesContent":["import type { RequestController } from './RequestController'\n\nexport const IS_PATCHED_MODULE: unique symbol = Symbol('isPatchedModule')\n\nexport type RequestCredentials = 'omit' | 'include' | 'same-origin'\n\nexport type HttpRequestEventMap = {\n request: [\n args: {\n request: Request\n requestId: string\n controller: RequestController\n }\n ]\n response: [\n args: {\n response: Response\n isMockedResponse: boolean\n request: Request\n requestId: string\n }\n ]\n unhandledException: [\n args: {\n error: unknown\n request: Request\n requestId: string\n controller: RequestController\n }\n ]\n}\n","/**\n * A function that validates if property access is possible on an object\n * without throwing. It returns `true` if the property access is possible\n * and `false` otherwise.\n *\n * Environments like miniflare will throw on property access on certain objects\n * like Request and Response, for unimplemented properties.\n */\nexport function isPropertyAccessible<Obj extends Record<string, any>>(\n obj: Obj,\n key: keyof Obj\n) {\n try {\n obj[key]\n return true\n } catch {\n return false\n }\n}\n","import { isPropertyAccessible } from './isPropertyAccessible'\n\n/**\n * Response status codes for responses that cannot have body.\n * @see https://fetch.spec.whatwg.org/#statuses\n */\nexport const RESPONSE_STATUS_CODES_WITHOUT_BODY = new Set([\n 101, 103, 204, 205, 304,\n])\n\nexport const RESPONSE_STATUS_CODES_WITH_REDIRECT = new Set([\n 301, 302, 303, 307, 308,\n])\n\n/**\n * Returns a boolean indicating whether the given response status\n * code represents a response that cannot have a body.\n */\nexport function isResponseWithoutBody(status: number): boolean {\n return RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status)\n}\n\n/**\n * Creates a generic 500 Unhandled Exception response.\n */\nexport function createServerErrorResponse(body: unknown): Response {\n return new Response(\n JSON.stringify(\n body instanceof Error\n ? {\n name: body.name,\n message: body.message,\n stack: body.stack,\n }\n : body\n ),\n {\n status: 500,\n statusText: 'Unhandled Exception',\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n )\n}\n\nexport type ResponseError = Response & { type: 'error' }\n\n/**\n * Check if the given response is a `Response.error()`.\n *\n * @note Some environments, like Miniflare (Cloudflare) do not\n * implement the \"Response.type\" property and throw on its access.\n * Safely check if we can access \"type\" on \"Response\" before continuing.\n * @see https://github.com/mswjs/msw/issues/1834\n */\nexport function isResponseError(response: Response): response is ResponseError {\n return isPropertyAccessible(response, 'type') && response.type === 'error'\n}\n"],"mappings":";AAEO,IAAM,oBAAmC,OAAO,iBAAiB;;;ACMjE,SAAS,qBACd,KACA,KACA;AACA,MAAI;AACF,QAAI,GAAG;AACP,WAAO;AAAA,EACT,SAAQ,GAAN;AACA,WAAO;AAAA,EACT;AACF;;;ACZO,IAAM,qCAAqC,oBAAI,IAAI;AAAA,EACxD;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACtB,CAAC;AAEM,IAAM,sCAAsC,oBAAI,IAAI;AAAA,EACzD;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACtB,CAAC;AAMM,SAAS,sBAAsB,QAAyB;AAC7D,SAAO,mCAAmC,IAAI,MAAM;AACtD;AAKO,SAAS,0BAA0B,MAAyB;AACjE,SAAO,IAAI;AAAA,IACT,KAAK;AAAA,MACH,gBAAgB,QACZ;AAAA,QACE,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,QACd,OAAO,KAAK;AAAA,MACd,IACA;AAAA,IACN;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;AAYO,SAAS,gBAAgB,UAA+C;AAC7E,SAAO,qBAAqB,UAAU,MAAM,KAAK,SAAS,SAAS;AACrE;","names":[]}
|
|
@@ -6,11 +6,11 @@ var _chunkLK6DILFKjs = require('./chunk-LK6DILFK.js');
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkFYSUKT3Fjs = require('./chunk-FYSUKT3F.js');
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunk2CAGU4FTjs = require('./chunk-2CAGU4FT.js');
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
@@ -203,7 +203,7 @@ function parseJson(data) {
|
|
|
203
203
|
|
|
204
204
|
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
|
205
205
|
function createResponse(request, body) {
|
|
206
|
-
const responseBodyOrNull =
|
|
206
|
+
const responseBodyOrNull = _chunk2CAGU4FTjs.isResponseWithoutBody.call(void 0, request.status) ? null : body;
|
|
207
207
|
return new Response(responseBodyOrNull, {
|
|
208
208
|
status: request.status,
|
|
209
209
|
statusText: request.statusText,
|
|
@@ -737,13 +737,13 @@ function createXMLHttpRequestProxy({
|
|
|
737
737
|
logger
|
|
738
738
|
);
|
|
739
739
|
xhrRequestController.onRequest = async function({ request, requestId }) {
|
|
740
|
-
const controller = new (0,
|
|
740
|
+
const controller = new (0, _chunkFYSUKT3Fjs.RequestController)(request);
|
|
741
741
|
this.logger.info("awaiting mocked response...");
|
|
742
742
|
this.logger.info(
|
|
743
743
|
'emitting the "request" event for %s listener(s)...',
|
|
744
744
|
emitter.listenerCount("request")
|
|
745
745
|
);
|
|
746
|
-
const isRequestHandled = await
|
|
746
|
+
const isRequestHandled = await _chunkFYSUKT3Fjs.handleRequest.call(void 0, {
|
|
747
747
|
request,
|
|
748
748
|
requestId,
|
|
749
749
|
controller,
|
|
@@ -803,7 +803,7 @@ var _XMLHttpRequestInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
|
|
|
803
803
|
logger.info('patching "XMLHttpRequest" module...');
|
|
804
804
|
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
|
|
805
805
|
_outvariant.invariant.call(void 0,
|
|
806
|
-
!PureXMLHttpRequest[
|
|
806
|
+
!PureXMLHttpRequest[_chunk2CAGU4FTjs.IS_PATCHED_MODULE],
|
|
807
807
|
'Failed to patch the "XMLHttpRequest" module: already patched.'
|
|
808
808
|
);
|
|
809
809
|
globalThis.XMLHttpRequest = createXMLHttpRequestProxy({
|
|
@@ -814,13 +814,13 @@ var _XMLHttpRequestInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
|
|
|
814
814
|
'native "XMLHttpRequest" module patched!',
|
|
815
815
|
globalThis.XMLHttpRequest.name
|
|
816
816
|
);
|
|
817
|
-
Object.defineProperty(globalThis.XMLHttpRequest,
|
|
817
|
+
Object.defineProperty(globalThis.XMLHttpRequest, _chunk2CAGU4FTjs.IS_PATCHED_MODULE, {
|
|
818
818
|
enumerable: true,
|
|
819
819
|
configurable: true,
|
|
820
820
|
value: true
|
|
821
821
|
});
|
|
822
822
|
this.subscriptions.push(() => {
|
|
823
|
-
Object.defineProperty(globalThis.XMLHttpRequest,
|
|
823
|
+
Object.defineProperty(globalThis.XMLHttpRequest, _chunk2CAGU4FTjs.IS_PATCHED_MODULE, {
|
|
824
824
|
value: void 0
|
|
825
825
|
});
|
|
826
826
|
globalThis.XMLHttpRequest = PureXMLHttpRequest;
|
|
@@ -837,4 +837,4 @@ XMLHttpRequestInterceptor.interceptorSymbol = Symbol("xhr");
|
|
|
837
837
|
|
|
838
838
|
|
|
839
839
|
exports.XMLHttpRequestInterceptor = XMLHttpRequestInterceptor;
|
|
840
|
-
//# sourceMappingURL=chunk-
|
|
840
|
+
//# sourceMappingURL=chunk-YU6EJD6U.js.map
|
package/lib/browser/index.js
CHANGED
|
@@ -5,7 +5,7 @@ var _chunkLK6DILFKjs = require('./chunk-LK6DILFK.js');
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _chunk2CAGU4FTjs = require('./chunk-2CAGU4FT.js');
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
@@ -75,5 +75,5 @@ function getCleanUrl(url, isAbsolute = true) {
|
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
|
|
78
|
-
exports.BatchInterceptor = BatchInterceptor; exports.INTERNAL_REQUEST_ID_HEADER_NAME = _chunkTIPR373Rjs.INTERNAL_REQUEST_ID_HEADER_NAME; exports.IS_PATCHED_MODULE =
|
|
78
|
+
exports.BatchInterceptor = BatchInterceptor; exports.INTERNAL_REQUEST_ID_HEADER_NAME = _chunkTIPR373Rjs.INTERNAL_REQUEST_ID_HEADER_NAME; exports.IS_PATCHED_MODULE = _chunk2CAGU4FTjs.IS_PATCHED_MODULE; exports.Interceptor = _chunkTIPR373Rjs.Interceptor; exports.InterceptorReadyState = _chunkTIPR373Rjs.InterceptorReadyState; exports.createRequestId = _chunkTIPR373Rjs.createRequestId; exports.decodeBuffer = _chunkLK6DILFKjs.decodeBuffer; exports.deleteGlobalSymbol = _chunkTIPR373Rjs.deleteGlobalSymbol; exports.encodeBuffer = _chunkLK6DILFKjs.encodeBuffer; exports.getCleanUrl = getCleanUrl; exports.getGlobalSymbol = _chunkTIPR373Rjs.getGlobalSymbol; exports.isResponseWithoutBody = _chunk2CAGU4FTjs.isResponseWithoutBody;
|
|
79
79
|
//# sourceMappingURL=index.js.map
|
package/lib/browser/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkYU6EJD6Ujs = require('../../chunk-YU6EJD6U.js');
|
|
4
4
|
require('../../chunk-LK6DILFK.js');
|
|
5
|
-
require('../../chunk-
|
|
6
|
-
require('../../chunk-
|
|
5
|
+
require('../../chunk-FYSUKT3F.js');
|
|
6
|
+
require('../../chunk-2CAGU4FT.js');
|
|
7
7
|
require('../../chunk-TIPR373R.js');
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
exports.XMLHttpRequestInterceptor =
|
|
10
|
+
exports.XMLHttpRequestInterceptor = _chunkYU6EJD6Ujs.XMLHttpRequestInterceptor;
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
XMLHttpRequestInterceptor
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-PRBA3ES4.mjs";
|
|
4
4
|
import "../../chunk-6HYIRFX2.mjs";
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
5
|
+
import "../../chunk-THPGBWJQ.mjs";
|
|
6
|
+
import "../../chunk-XVPRNJO7.mjs";
|
|
7
7
|
import "../../chunk-QED3Q6Z2.mjs";
|
|
8
8
|
export {
|
|
9
9
|
XMLHttpRequestInterceptor
|