Update checked-in dependencies

This commit is contained in:
github-actions[bot] 2025-01-27 17:21:38 +00:00
parent 7fdbca3ba3
commit 357e0ceaa9
360 changed files with 25673 additions and 917 deletions

View file

@ -0,0 +1,63 @@
import { Logger } from '@open-draft/logger';
import { Emitter, Listener } from 'strict-event-emitter';
type InterceptorEventMap = Record<string, any>;
type InterceptorSubscription = () => void;
/**
* Request header name to detect when a single request
* is being handled by nested interceptors (XHR -> ClientRequest).
* Obscure by design to prevent collisions with user-defined headers.
* Ideally, come up with the Interceptor-level mechanism for this.
* @see https://github.com/mswjs/interceptors/issues/378
*/
declare const INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
declare function getGlobalSymbol<V>(symbol: Symbol): V | undefined;
declare function deleteGlobalSymbol(symbol: Symbol): void;
declare enum InterceptorReadyState {
INACTIVE = "INACTIVE",
APPLYING = "APPLYING",
APPLIED = "APPLIED",
DISPOSING = "DISPOSING",
DISPOSED = "DISPOSED"
}
type ExtractEventNames<Events extends Record<string, any>> = Events extends Record<infer EventName, any> ? EventName : never;
declare class Interceptor<Events extends InterceptorEventMap> {
private readonly symbol;
protected emitter: Emitter<Events>;
protected subscriptions: Array<InterceptorSubscription>;
protected logger: Logger;
readyState: InterceptorReadyState;
constructor(symbol: symbol);
/**
* Determine if this interceptor can be applied
* in the current environment.
*/
protected checkEnvironment(): boolean;
/**
* Apply this interceptor to the current process.
* Returns an already running interceptor instance if it's present.
*/
apply(): void;
/**
* Setup the module augments and stubs necessary for this interceptor.
* This method is not run if there's a running interceptor instance
* to prevent instantiating an interceptor multiple times.
*/
protected setup(): void;
/**
* Listen to the interceptor's public events.
*/
on<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
once<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
off<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
removeAllListeners<EventName extends ExtractEventNames<Events>>(event?: EventName): this;
/**
* Disposes of any side-effects this interceptor has introduced.
*/
dispose(): void;
private getInstance;
private setInstance;
private clearInstance;
}
export { ExtractEventNames as E, Interceptor as I, InterceptorEventMap as a, InterceptorSubscription as b, INTERNAL_REQUEST_ID_HEADER_NAME as c, deleteGlobalSymbol as d, InterceptorReadyState as e, getGlobalSymbol as g };

View file

@ -0,0 +1,83 @@
// src/glossary.ts
var IS_PATCHED_MODULE = Symbol("isPatchedModule");
// src/utils/fetchUtils.ts
var _FetchResponse = class extends Response {
static isConfigurableStatusCode(status) {
return status >= 200 && status <= 599;
}
static isRedirectResponse(status) {
return _FetchResponse.STATUS_CODES_WITH_REDIRECT.includes(status);
}
/**
* Returns a boolean indicating whether the given response status
* code represents a response that can have a body.
*/
static isResponseWithBody(status) {
return !_FetchResponse.STATUS_CODES_WITHOUT_BODY.includes(status);
}
static setUrl(url, response) {
if (!url) {
return;
}
if (response.url != "") {
return;
}
Object.defineProperty(response, "url", {
value: url,
enumerable: true,
configurable: true,
writable: false
});
}
/**
* Parses the given raw HTTP headers into a Fetch API `Headers` instance.
*/
static parseRawHeaders(rawHeaders) {
const headers = new Headers();
for (let line = 0; line < rawHeaders.length; line += 2) {
headers.append(rawHeaders[line], rawHeaders[line + 1]);
}
return headers;
}
constructor(body, init = {}) {
var _a;
const status = (_a = init.status) != null ? _a : 200;
const safeStatus = _FetchResponse.isConfigurableStatusCode(status) ? status : 200;
const finalBody = _FetchResponse.isResponseWithBody(status) ? body : null;
super(finalBody, {
...init,
status: safeStatus
});
if (status !== safeStatus) {
const stateSymbol = Object.getOwnPropertySymbols(this).find(
(symbol) => symbol.description === "state"
);
if (stateSymbol) {
const state = Reflect.get(this, stateSymbol);
Reflect.set(state, "status", status);
} else {
Object.defineProperty(this, "status", {
value: status,
enumerable: true,
configurable: true,
writable: false
});
}
}
_FetchResponse.setUrl(init.url, this);
}
};
var FetchResponse = _FetchResponse;
/**
* Response status codes for responses that cannot have body.
* @see https://fetch.spec.whatwg.org/#statuses
*/
FetchResponse.STATUS_CODES_WITHOUT_BODY = [101, 103, 204, 205, 304];
FetchResponse.STATUS_CODES_WITH_REDIRECT = [301, 302, 303, 307, 308];
export {
IS_PATCHED_MODULE,
FetchResponse
};
//# sourceMappingURL=chunk-5UK33FSU.mjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,22 @@
// src/utils/bufferUtils.ts
var encoder = new TextEncoder();
function encodeBuffer(text) {
return encoder.encode(text);
}
function decodeBuffer(buffer, encoding) {
const decoder = new TextDecoder(encoding);
return decoder.decode(buffer);
}
function toArrayBuffer(array) {
return array.buffer.slice(
array.byteOffset,
array.byteOffset + array.byteLength
);
}
export {
encodeBuffer,
decodeBuffer,
toArrayBuffer
};
//# sourceMappingURL=chunk-6HYIRFX2.mjs.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../../src/utils/bufferUtils.ts"],"sourcesContent":["const encoder = new TextEncoder()\n\nexport function encodeBuffer(text: string): Uint8Array {\n return encoder.encode(text)\n}\n\nexport function decodeBuffer(buffer: ArrayBuffer, encoding?: string): string {\n const decoder = new TextDecoder(encoding)\n return decoder.decode(buffer)\n}\n\n/**\n * Create an `ArrayBuffer` from the given `Uint8Array`.\n * Takes the byte offset into account to produce the right buffer\n * in the case when the buffer is bigger than the data view.\n */\nexport function toArrayBuffer(array: Uint8Array): ArrayBuffer {\n return array.buffer.slice(\n array.byteOffset,\n array.byteOffset + array.byteLength\n )\n}\n"],"mappings":";AAAA,IAAM,UAAU,IAAI,YAAY;AAEzB,SAAS,aAAa,MAA0B;AACrD,SAAO,QAAQ,OAAO,IAAI;AAC5B;AAEO,SAAS,aAAa,QAAqB,UAA2B;AAC3E,QAAM,UAAU,IAAI,YAAY,QAAQ;AACxC,SAAO,QAAQ,OAAO,MAAM;AAC9B;AAOO,SAAS,cAAc,OAAgC;AAC5D,SAAO,MAAM,OAAO;AAAA,IAClB,MAAM;AAAA,IACN,MAAM,aAAa,MAAM;AAAA,EAC3B;AACF;","names":[]}

View file

@ -0,0 +1,83 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/glossary.ts
var IS_PATCHED_MODULE = Symbol("isPatchedModule");
// src/utils/fetchUtils.ts
var _FetchResponse = class extends Response {
static isConfigurableStatusCode(status) {
return status >= 200 && status <= 599;
}
static isRedirectResponse(status) {
return _FetchResponse.STATUS_CODES_WITH_REDIRECT.includes(status);
}
/**
* Returns a boolean indicating whether the given response status
* code represents a response that can have a body.
*/
static isResponseWithBody(status) {
return !_FetchResponse.STATUS_CODES_WITHOUT_BODY.includes(status);
}
static setUrl(url, response) {
if (!url) {
return;
}
if (response.url != "") {
return;
}
Object.defineProperty(response, "url", {
value: url,
enumerable: true,
configurable: true,
writable: false
});
}
/**
* Parses the given raw HTTP headers into a Fetch API `Headers` instance.
*/
static parseRawHeaders(rawHeaders) {
const headers = new Headers();
for (let line = 0; line < rawHeaders.length; line += 2) {
headers.append(rawHeaders[line], rawHeaders[line + 1]);
}
return headers;
}
constructor(body, init = {}) {
var _a;
const status = (_a = init.status) != null ? _a : 200;
const safeStatus = _FetchResponse.isConfigurableStatusCode(status) ? status : 200;
const finalBody = _FetchResponse.isResponseWithBody(status) ? body : null;
super(finalBody, {
...init,
status: safeStatus
});
if (status !== safeStatus) {
const stateSymbol = Object.getOwnPropertySymbols(this).find(
(symbol) => symbol.description === "state"
);
if (stateSymbol) {
const state = Reflect.get(this, stateSymbol);
Reflect.set(state, "status", status);
} else {
Object.defineProperty(this, "status", {
value: status,
enumerable: true,
configurable: true,
writable: false
});
}
}
_FetchResponse.setUrl(init.url, this);
}
};
var FetchResponse = _FetchResponse;
/**
* Response status codes for responses that cannot have body.
* @see https://fetch.spec.whatwg.org/#statuses
*/
FetchResponse.STATUS_CODES_WITHOUT_BODY = [101, 103, 204, 205, 304];
FetchResponse.STATUS_CODES_WITH_REDIRECT = [301, 302, 303, 307, 308];
exports.IS_PATCHED_MODULE = IS_PATCHED_MODULE; exports.FetchResponse = FetchResponse;
//# sourceMappingURL=chunk-BC2BLJQN.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,844 @@
import {
decodeBuffer,
encodeBuffer,
toArrayBuffer
} from "./chunk-6HYIRFX2.mjs";
import {
RequestController,
handleRequest
} from "./chunk-H5O73WD2.mjs";
import {
FetchResponse,
IS_PATCHED_MODULE
} from "./chunk-5UK33FSU.mjs";
import {
hasConfigurableGlobal
} from "./chunk-TX5GBTFY.mjs";
import {
INTERNAL_REQUEST_ID_HEADER_NAME,
Interceptor,
createRequestId
} from "./chunk-QED3Q6Z2.mjs";
// src/interceptors/XMLHttpRequest/index.ts
import { invariant as invariant2 } from "outvariant";
// src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
import { invariant } from "outvariant";
import { isNodeProcess } from "is-node-process";
// src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts
function concatArrayBuffer(left, right) {
const result = new Uint8Array(left.byteLength + right.byteLength);
result.set(left, 0);
result.set(right, left.byteLength);
return result;
}
// src/interceptors/XMLHttpRequest/polyfills/EventPolyfill.ts
var EventPolyfill = class {
constructor(type, options) {
this.NONE = 0;
this.CAPTURING_PHASE = 1;
this.AT_TARGET = 2;
this.BUBBLING_PHASE = 3;
this.type = "";
this.srcElement = null;
this.currentTarget = null;
this.eventPhase = 0;
this.isTrusted = true;
this.composed = false;
this.cancelable = true;
this.defaultPrevented = false;
this.bubbles = true;
this.lengthComputable = true;
this.loaded = 0;
this.total = 0;
this.cancelBubble = false;
this.returnValue = true;
this.type = type;
this.target = (options == null ? void 0 : options.target) || null;
this.currentTarget = (options == null ? void 0 : options.currentTarget) || null;
this.timeStamp = Date.now();
}
composedPath() {
return [];
}
initEvent(type, bubbles, cancelable) {
this.type = type;
this.bubbles = !!bubbles;
this.cancelable = !!cancelable;
}
preventDefault() {
this.defaultPrevented = true;
}
stopPropagation() {
}
stopImmediatePropagation() {
}
};
// src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts
var ProgressEventPolyfill = class extends EventPolyfill {
constructor(type, init) {
super(type);
this.lengthComputable = (init == null ? void 0 : init.lengthComputable) || false;
this.composed = (init == null ? void 0 : init.composed) || false;
this.loaded = (init == null ? void 0 : init.loaded) || 0;
this.total = (init == null ? void 0 : init.total) || 0;
}
};
// src/interceptors/XMLHttpRequest/utils/createEvent.ts
var SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== "undefined";
function createEvent(target, type, init) {
const progressEvents = [
"error",
"progress",
"loadstart",
"loadend",
"load",
"timeout",
"abort"
];
const ProgressEventClass = SUPPORTS_PROGRESS_EVENT ? ProgressEvent : ProgressEventPolyfill;
const event = progressEvents.includes(type) ? new ProgressEventClass(type, {
lengthComputable: true,
loaded: (init == null ? void 0 : init.loaded) || 0,
total: (init == null ? void 0 : init.total) || 0
}) : new EventPolyfill(type, {
target,
currentTarget: target
});
return event;
}
// src/utils/findPropertySource.ts
function findPropertySource(target, propertyName) {
if (!(propertyName in target)) {
return null;
}
const hasProperty = Object.prototype.hasOwnProperty.call(target, propertyName);
if (hasProperty) {
return target;
}
const prototype = Reflect.getPrototypeOf(target);
return prototype ? findPropertySource(prototype, propertyName) : null;
}
// src/utils/createProxy.ts
function createProxy(target, options) {
const proxy = new Proxy(target, optionsToProxyHandler(options));
return proxy;
}
function optionsToProxyHandler(options) {
const { constructorCall, methodCall, getProperty, setProperty } = options;
const handler = {};
if (typeof constructorCall !== "undefined") {
handler.construct = function(target, args, newTarget) {
const next = Reflect.construct.bind(null, target, args, newTarget);
return constructorCall.call(newTarget, args, next);
};
}
handler.set = function(target, propertyName, nextValue) {
const next = () => {
const propertySource = findPropertySource(target, propertyName) || target;
const ownDescriptors = Reflect.getOwnPropertyDescriptor(
propertySource,
propertyName
);
if (typeof (ownDescriptors == null ? void 0 : ownDescriptors.set) !== "undefined") {
ownDescriptors.set.apply(target, [nextValue]);
return true;
}
return Reflect.defineProperty(propertySource, propertyName, {
writable: true,
enumerable: true,
configurable: true,
value: nextValue
});
};
if (typeof setProperty !== "undefined") {
return setProperty.call(target, [propertyName, nextValue], next);
}
return next();
};
handler.get = function(target, propertyName, receiver) {
const next = () => target[propertyName];
const value = typeof getProperty !== "undefined" ? getProperty.call(target, [propertyName, receiver], next) : next();
if (typeof value === "function") {
return (...args) => {
const next2 = value.bind(target, ...args);
if (typeof methodCall !== "undefined") {
return methodCall.call(target, [propertyName, args], next2);
}
return next2();
};
}
return value;
};
return handler;
}
// src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts
function isDomParserSupportedType(type) {
const supportedTypes = [
"application/xhtml+xml",
"application/xml",
"image/svg+xml",
"text/html",
"text/xml"
];
return supportedTypes.some((supportedType) => {
return type.startsWith(supportedType);
});
}
// src/utils/parseJson.ts
function parseJson(data) {
try {
const json = JSON.parse(data);
return json;
} catch (_) {
return null;
}
}
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
function createResponse(request, body) {
const responseBodyOrNull = FetchResponse.isResponseWithBody(request.status) ? body : null;
return new FetchResponse(responseBodyOrNull, {
url: request.responseURL,
status: request.status,
statusText: request.statusText,
headers: createHeadersFromXMLHttpReqestHeaders(
request.getAllResponseHeaders()
)
});
}
function createHeadersFromXMLHttpReqestHeaders(headersString) {
const headers = new Headers();
const lines = headersString.split(/[\r\n]+/);
for (const line of lines) {
if (line.trim() === "") {
continue;
}
const [name, ...parts] = line.split(": ");
const value = parts.join(": ");
headers.append(name, value);
}
return headers;
}
// src/interceptors/XMLHttpRequest/utils/getBodyByteLength.ts
async function getBodyByteLength(input) {
const explicitContentLength = input.headers.get("content-length");
if (explicitContentLength != null && explicitContentLength !== "") {
return Number(explicitContentLength);
}
const buffer = await input.arrayBuffer();
return buffer.byteLength;
}
// src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
var kIsRequestHandled = Symbol("kIsRequestHandled");
var IS_NODE = isNodeProcess();
var kFetchRequest = Symbol("kFetchRequest");
var XMLHttpRequestController = class {
constructor(initialRequest, logger) {
this.initialRequest = initialRequest;
this.logger = logger;
this.method = "GET";
this.url = null;
this[kIsRequestHandled] = false;
this.events = /* @__PURE__ */ new Map();
this.uploadEvents = /* @__PURE__ */ new Map();
this.requestId = createRequestId();
this.requestHeaders = new Headers();
this.responseBuffer = new Uint8Array();
this.request = createProxy(initialRequest, {
setProperty: ([propertyName, nextValue], invoke) => {
switch (propertyName) {
case "ontimeout": {
const eventName = propertyName.slice(
2
);
this.request.addEventListener(eventName, nextValue);
return invoke();
}
default: {
return invoke();
}
}
},
methodCall: ([methodName, args], invoke) => {
var _a;
switch (methodName) {
case "open": {
const [method, url] = args;
if (typeof url === "undefined") {
this.method = "GET";
this.url = toAbsoluteUrl(method);
} else {
this.method = method;
this.url = toAbsoluteUrl(url);
}
this.logger = this.logger.extend(`${this.method} ${this.url.href}`);
this.logger.info("open", this.method, this.url.href);
return invoke();
}
case "addEventListener": {
const [eventName, listener] = args;
this.registerEvent(eventName, listener);
this.logger.info("addEventListener", eventName, listener);
return invoke();
}
case "setRequestHeader": {
const [name, value] = args;
this.requestHeaders.set(name, value);
this.logger.info("setRequestHeader", name, value);
return invoke();
}
case "send": {
const [body] = args;
this.request.addEventListener("load", () => {
if (typeof this.onResponse !== "undefined") {
const fetchResponse = createResponse(
this.request,
/**
* The `response` property is the right way to read
* the ambiguous response body, as the request's "responseType" may differ.
* @see https://xhr.spec.whatwg.org/#the-response-attribute
*/
this.request.response
);
this.onResponse.call(this, {
response: fetchResponse,
isMockedResponse: this[kIsRequestHandled],
request: fetchRequest,
requestId: this.requestId
});
}
});
const requestBody = typeof body === "string" ? encodeBuffer(body) : body;
const fetchRequest = this.toFetchApiRequest(requestBody);
this[kFetchRequest] = fetchRequest.clone();
const onceRequestSettled = ((_a = this.onRequest) == null ? void 0 : _a.call(this, {
request: fetchRequest,
requestId: this.requestId
})) || Promise.resolve();
onceRequestSettled.finally(() => {
if (!this[kIsRequestHandled]) {
this.logger.info(
"request callback settled but request has not been handled (readystate %d), performing as-is...",
this.request.readyState
);
if (IS_NODE) {
this.request.setRequestHeader(
INTERNAL_REQUEST_ID_HEADER_NAME,
this.requestId
);
}
return invoke();
}
});
break;
}
default: {
return invoke();
}
}
}
});
define(
this.request,
"upload",
createProxy(this.request.upload, {
setProperty: ([propertyName, nextValue], invoke) => {
switch (propertyName) {
case "onloadstart":
case "onprogress":
case "onaboart":
case "onerror":
case "onload":
case "ontimeout":
case "onloadend": {
const eventName = propertyName.slice(
2
);
this.registerUploadEvent(eventName, nextValue);
}
}
return invoke();
},
methodCall: ([methodName, args], invoke) => {
switch (methodName) {
case "addEventListener": {
const [eventName, listener] = args;
this.registerUploadEvent(eventName, listener);
this.logger.info("upload.addEventListener", eventName, listener);
return invoke();
}
}
}
})
);
}
registerEvent(eventName, listener) {
const prevEvents = this.events.get(eventName) || [];
const nextEvents = prevEvents.concat(listener);
this.events.set(eventName, nextEvents);
this.logger.info('registered event "%s"', eventName, listener);
}
registerUploadEvent(eventName, listener) {
const prevEvents = this.uploadEvents.get(eventName) || [];
const nextEvents = prevEvents.concat(listener);
this.uploadEvents.set(eventName, nextEvents);
this.logger.info('registered upload event "%s"', eventName, listener);
}
/**
* Responds to the current request with the given
* Fetch API `Response` instance.
*/
async respondWith(response) {
this[kIsRequestHandled] = true;
if (this[kFetchRequest]) {
const totalRequestBodyLength = await getBodyByteLength(
this[kFetchRequest]
);
this.trigger("loadstart", this.request.upload, {
loaded: 0,
total: totalRequestBodyLength
});
this.trigger("progress", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
this.trigger("load", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
this.trigger("loadend", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
}
this.logger.info(
"responding with a mocked response: %d %s",
response.status,
response.statusText
);
define(this.request, "status", response.status);
define(this.request, "statusText", response.statusText);
define(this.request, "responseURL", this.url.href);
this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {
apply: (_, __, args) => {
this.logger.info("getResponseHeader", args[0]);
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
this.logger.info("headers not received yet, returning null");
return null;
}
const headerValue = response.headers.get(args[0]);
this.logger.info(
'resolved response header "%s" to',
args[0],
headerValue
);
return headerValue;
}
});
this.request.getAllResponseHeaders = new Proxy(
this.request.getAllResponseHeaders,
{
apply: () => {
this.logger.info("getAllResponseHeaders");
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
this.logger.info("headers not received yet, returning empty string");
return "";
}
const headersList = Array.from(response.headers.entries());
const allHeaders = headersList.map(([headerName, headerValue]) => {
return `${headerName}: ${headerValue}`;
}).join("\r\n");
this.logger.info("resolved all response headers to", allHeaders);
return allHeaders;
}
}
);
Object.defineProperties(this.request, {
response: {
enumerable: true,
configurable: false,
get: () => this.response
},
responseText: {
enumerable: true,
configurable: false,
get: () => this.responseText
},
responseXML: {
enumerable: true,
configurable: false,
get: () => this.responseXML
}
});
const totalResponseBodyLength = await getBodyByteLength(response.clone());
this.logger.info("calculated response body length", totalResponseBodyLength);
this.trigger("loadstart", this.request, {
loaded: 0,
total: totalResponseBodyLength
});
this.setReadyState(this.request.HEADERS_RECEIVED);
this.setReadyState(this.request.LOADING);
const finalizeResponse = () => {
this.logger.info("finalizing the mocked response...");
this.setReadyState(this.request.DONE);
this.trigger("load", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
this.trigger("loadend", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
};
if (response.body) {
this.logger.info("mocked response has body, streaming...");
const reader = response.body.getReader();
const readNextResponseBodyChunk = async () => {
const { value, done } = await reader.read();
if (done) {
this.logger.info("response body stream done!");
finalizeResponse();
return;
}
if (value) {
this.logger.info("read response body chunk:", value);
this.responseBuffer = concatArrayBuffer(this.responseBuffer, value);
this.trigger("progress", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
}
readNextResponseBodyChunk();
};
readNextResponseBodyChunk();
} else {
finalizeResponse();
}
}
responseBufferToText() {
return decodeBuffer(this.responseBuffer);
}
get response() {
this.logger.info(
"getResponse (responseType: %s)",
this.request.responseType
);
if (this.request.readyState !== this.request.DONE) {
return null;
}
switch (this.request.responseType) {
case "json": {
const responseJson = parseJson(this.responseBufferToText());
this.logger.info("resolved response JSON", responseJson);
return responseJson;
}
case "arraybuffer": {
const arrayBuffer = toArrayBuffer(this.responseBuffer);
this.logger.info("resolved response ArrayBuffer", arrayBuffer);
return arrayBuffer;
}
case "blob": {
const mimeType = this.request.getResponseHeader("Content-Type") || "text/plain";
const responseBlob = new Blob([this.responseBufferToText()], {
type: mimeType
});
this.logger.info(
"resolved response Blob (mime type: %s)",
responseBlob,
mimeType
);
return responseBlob;
}
default: {
const responseText = this.responseBufferToText();
this.logger.info(
'resolving "%s" response type as text',
this.request.responseType,
responseText
);
return responseText;
}
}
}
get responseText() {
invariant(
this.request.responseType === "" || this.request.responseType === "text",
"InvalidStateError: The object is in invalid state."
);
if (this.request.readyState !== this.request.LOADING && this.request.readyState !== this.request.DONE) {
return "";
}
const responseText = this.responseBufferToText();
this.logger.info('getResponseText: "%s"', responseText);
return responseText;
}
get responseXML() {
invariant(
this.request.responseType === "" || this.request.responseType === "document",
"InvalidStateError: The object is in invalid state."
);
if (this.request.readyState !== this.request.DONE) {
return null;
}
const contentType = this.request.getResponseHeader("Content-Type") || "";
if (typeof DOMParser === "undefined") {
console.warn(
"Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly."
);
return null;
}
if (isDomParserSupportedType(contentType)) {
return new DOMParser().parseFromString(
this.responseBufferToText(),
contentType
);
}
return null;
}
errorWith(error) {
this[kIsRequestHandled] = true;
this.logger.info("responding with an error");
this.setReadyState(this.request.DONE);
this.trigger("error", this.request);
this.trigger("loadend", this.request);
}
/**
* Transitions this request's `readyState` to the given one.
*/
setReadyState(nextReadyState) {
this.logger.info(
"setReadyState: %d -> %d",
this.request.readyState,
nextReadyState
);
if (this.request.readyState === nextReadyState) {
this.logger.info("ready state identical, skipping transition...");
return;
}
define(this.request, "readyState", nextReadyState);
this.logger.info("set readyState to: %d", nextReadyState);
if (nextReadyState !== this.request.UNSENT) {
this.logger.info('triggerring "readystatechange" event...');
this.trigger("readystatechange", this.request);
}
}
/**
* Triggers given event on the `XMLHttpRequest` instance.
*/
trigger(eventName, target, options) {
const callback = target[`on${eventName}`];
const event = createEvent(target, eventName, options);
this.logger.info('trigger "%s"', eventName, options || "");
if (typeof callback === "function") {
this.logger.info('found a direct "%s" callback, calling...', eventName);
callback.call(target, event);
}
const events = target instanceof XMLHttpRequestUpload ? this.uploadEvents : this.events;
for (const [registeredEventName, listeners] of events) {
if (registeredEventName === eventName) {
this.logger.info(
'found %d listener(s) for "%s" event, calling...',
listeners.length,
eventName
);
listeners.forEach((listener) => listener.call(target, event));
}
}
}
/**
* Converts this `XMLHttpRequest` instance into a Fetch API `Request` instance.
*/
toFetchApiRequest(body) {
this.logger.info("converting request to a Fetch API Request...");
const resolvedBody = body instanceof Document ? body.documentElement.innerText : body;
const fetchRequest = new Request(this.url.href, {
method: this.method,
headers: this.requestHeaders,
/**
* @see https://xhr.spec.whatwg.org/#cross-origin-credentials
*/
credentials: this.request.withCredentials ? "include" : "same-origin",
body: ["GET", "HEAD"].includes(this.method.toUpperCase()) ? null : resolvedBody
});
const proxyHeaders = createProxy(fetchRequest.headers, {
methodCall: ([methodName, args], invoke) => {
switch (methodName) {
case "append":
case "set": {
const [headerName, headerValue] = args;
this.request.setRequestHeader(headerName, headerValue);
break;
}
case "delete": {
const [headerName] = args;
console.warn(
`XMLHttpRequest: Cannot remove a "${headerName}" header from the Fetch API representation of the "${fetchRequest.method} ${fetchRequest.url}" request. XMLHttpRequest headers cannot be removed.`
);
break;
}
}
return invoke();
}
});
define(fetchRequest, "headers", proxyHeaders);
this.logger.info("converted request to a Fetch API Request!", fetchRequest);
return fetchRequest;
}
};
kIsRequestHandled, kFetchRequest;
function toAbsoluteUrl(url) {
if (typeof location === "undefined") {
return new URL(url);
}
return new URL(url.toString(), location.href);
}
function define(target, property, value) {
Reflect.defineProperty(target, property, {
// Ensure writable properties to allow redefining readonly properties.
writable: true,
enumerable: true,
value
});
}
// src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
function createXMLHttpRequestProxy({
emitter,
logger
}) {
const XMLHttpRequestProxy = new Proxy(globalThis.XMLHttpRequest, {
construct(target, args, newTarget) {
logger.info("constructed new XMLHttpRequest");
const originalRequest = Reflect.construct(
target,
args,
newTarget
);
const prototypeDescriptors = Object.getOwnPropertyDescriptors(
target.prototype
);
for (const propertyName in prototypeDescriptors) {
Reflect.defineProperty(
originalRequest,
propertyName,
prototypeDescriptors[propertyName]
);
}
const xhrRequestController = new XMLHttpRequestController(
originalRequest,
logger
);
xhrRequestController.onRequest = async function({ request, requestId }) {
const controller = new RequestController(request);
this.logger.info("awaiting mocked response...");
this.logger.info(
'emitting the "request" event for %s listener(s)...',
emitter.listenerCount("request")
);
const isRequestHandled = await handleRequest({
request,
requestId,
controller,
emitter,
onResponse: async (response) => {
await this.respondWith(response);
},
onRequestError: () => {
this.errorWith(new TypeError("Network error"));
},
onError: (error) => {
this.logger.info("request errored!", { error });
if (error instanceof Error) {
this.errorWith(error);
}
}
});
if (!isRequestHandled) {
this.logger.info(
"no mocked response received, performing request as-is..."
);
}
};
xhrRequestController.onResponse = async function({
response,
isMockedResponse,
request,
requestId
}) {
this.logger.info(
'emitting the "response" event for %s listener(s)...',
emitter.listenerCount("response")
);
emitter.emit("response", {
response,
isMockedResponse,
request,
requestId
});
};
return xhrRequestController.request;
}
});
return XMLHttpRequestProxy;
}
// src/interceptors/XMLHttpRequest/index.ts
var _XMLHttpRequestInterceptor = class extends Interceptor {
constructor() {
super(_XMLHttpRequestInterceptor.interceptorSymbol);
}
checkEnvironment() {
return hasConfigurableGlobal("XMLHttpRequest");
}
setup() {
const logger = this.logger.extend("setup");
logger.info('patching "XMLHttpRequest" module...');
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
invariant2(
!PureXMLHttpRequest[IS_PATCHED_MODULE],
'Failed to patch the "XMLHttpRequest" module: already patched.'
);
globalThis.XMLHttpRequest = createXMLHttpRequestProxy({
emitter: this.emitter,
logger: this.logger
});
logger.info(
'native "XMLHttpRequest" module patched!',
globalThis.XMLHttpRequest.name
);
Object.defineProperty(globalThis.XMLHttpRequest, IS_PATCHED_MODULE, {
enumerable: true,
configurable: true,
value: true
});
this.subscriptions.push(() => {
Object.defineProperty(globalThis.XMLHttpRequest, IS_PATCHED_MODULE, {
value: void 0
});
globalThis.XMLHttpRequest = PureXMLHttpRequest;
logger.info(
'native "XMLHttpRequest" module restored!',
globalThis.XMLHttpRequest.name
);
});
}
};
var XMLHttpRequestInterceptor = _XMLHttpRequestInterceptor;
XMLHttpRequestInterceptor.interceptorSymbol = Symbol("xhr");
export {
XMLHttpRequestInterceptor
};
//# sourceMappingURL=chunk-DODHRDV6.mjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,228 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/RequestController.ts
var _outvariant = require('outvariant');
var _deferredpromise = require('@open-draft/deferred-promise');
// src/InterceptorError.ts
var InterceptorError = class extends Error {
constructor(message) {
super(message);
this.name = "InterceptorError";
Object.setPrototypeOf(this, InterceptorError.prototype);
}
};
// src/RequestController.ts
var kRequestHandled = Symbol("kRequestHandled");
var kResponsePromise = Symbol("kResponsePromise");
var RequestController = class {
constructor(request) {
this.request = request;
this[kRequestHandled] = false;
this[kResponsePromise] = new (0, _deferredpromise.DeferredPromise)();
}
/**
* Respond to this request with the given `Response` instance.
* @example
* controller.respondWith(new Response())
* controller.respondWith(Response.json({ id }))
* controller.respondWith(Response.error())
*/
respondWith(response) {
_outvariant.invariant.as(
InterceptorError,
!this[kRequestHandled],
'Failed to respond to the "%s %s" request: the "request" event has already been handled.',
this.request.method,
this.request.url
);
this[kRequestHandled] = true;
this[kResponsePromise].resolve(response);
}
/**
* Error this request with the given error.
* @example
* controller.errorWith()
* controller.errorWith(new Error('Oops!'))
*/
errorWith(error) {
_outvariant.invariant.as(
InterceptorError,
!this[kRequestHandled],
'Failed to error the "%s %s" request: the "request" event has already been handled.',
this.request.method,
this.request.url
);
this[kRequestHandled] = true;
this[kResponsePromise].resolve(error);
}
};
kResponsePromise, kRequestHandled;
// src/utils/emitAsync.ts
async function emitAsync(emitter, eventName, ...data) {
const listners = emitter.listeners(eventName);
if (listners.length === 0) {
return;
}
for (const listener of listners) {
await listener.apply(emitter, data);
}
}
// src/utils/handleRequest.ts
var _until = require('@open-draft/until');
// src/utils/isPropertyAccessible.ts
function isPropertyAccessible(obj, key) {
try {
obj[key];
return true;
} catch (e) {
return false;
}
}
// src/utils/responseUtils.ts
function createServerErrorResponse(body) {
return new Response(
JSON.stringify(
body instanceof Error ? {
name: body.name,
message: body.message,
stack: body.stack
} : body
),
{
status: 500,
statusText: "Unhandled Exception",
headers: {
"Content-Type": "application/json"
}
}
);
}
function isResponseError(response) {
return isPropertyAccessible(response, "type") && response.type === "error";
}
// src/utils/isNodeLikeError.ts
function isNodeLikeError(error) {
if (error == null) {
return false;
}
if (!(error instanceof Error)) {
return false;
}
return "code" in error && "errno" in error;
}
// src/utils/handleRequest.ts
async function handleRequest(options) {
const handleResponse = async (response) => {
if (response instanceof Error) {
options.onError(response);
} else if (isResponseError(response)) {
options.onRequestError(response);
} else {
await options.onResponse(response);
}
return true;
};
const handleResponseError = async (error) => {
if (error instanceof InterceptorError) {
throw result.error;
}
if (isNodeLikeError(error)) {
options.onError(error);
return true;
}
if (error instanceof Response) {
return await handleResponse(error);
}
return false;
};
options.emitter.once("request", ({ requestId: pendingRequestId }) => {
if (pendingRequestId !== options.requestId) {
return;
}
if (options.controller[kResponsePromise].state === "pending") {
options.controller[kResponsePromise].resolve(void 0);
}
});
const requestAbortPromise = new (0, _deferredpromise.DeferredPromise)();
if (options.request.signal) {
if (options.request.signal.aborted) {
requestAbortPromise.reject(options.request.signal.reason);
} else {
options.request.signal.addEventListener(
"abort",
() => {
requestAbortPromise.reject(options.request.signal.reason);
},
{ once: true }
);
}
}
const result = await _until.until.call(void 0, async () => {
const requestListtenersPromise = emitAsync(options.emitter, "request", {
requestId: options.requestId,
request: options.request,
controller: options.controller
});
await Promise.race([
// Short-circuit the request handling promise if the request gets aborted.
requestAbortPromise,
requestListtenersPromise,
options.controller[kResponsePromise]
]);
const mockedResponse = await options.controller[kResponsePromise];
return mockedResponse;
});
if (requestAbortPromise.state === "rejected") {
options.onError(requestAbortPromise.rejectionReason);
return true;
}
if (result.error) {
if (await handleResponseError(result.error)) {
return true;
}
if (options.emitter.listenerCount("unhandledException") > 0) {
const unhandledExceptionController = new RequestController(
options.request
);
await emitAsync(options.emitter, "unhandledException", {
error: result.error,
request: options.request,
requestId: options.requestId,
controller: unhandledExceptionController
}).then(() => {
if (unhandledExceptionController[kResponsePromise].state === "pending") {
unhandledExceptionController[kResponsePromise].resolve(void 0);
}
});
const nextResult = await _until.until.call(void 0,
() => unhandledExceptionController[kResponsePromise]
);
if (nextResult.error) {
return handleResponseError(nextResult.error);
}
if (nextResult.data) {
return handleResponse(nextResult.data);
}
}
options.onResponse(createServerErrorResponse(result.error));
return true;
}
if (result.data) {
return handleResponse(result.data);
}
return false;
}
exports.RequestController = RequestController; exports.emitAsync = emitAsync; exports.handleRequest = handleRequest;
//# sourceMappingURL=chunk-FGSEOIC4.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,228 @@
// src/RequestController.ts
import { invariant } from "outvariant";
import { DeferredPromise } from "@open-draft/deferred-promise";
// src/InterceptorError.ts
var InterceptorError = class extends Error {
constructor(message) {
super(message);
this.name = "InterceptorError";
Object.setPrototypeOf(this, InterceptorError.prototype);
}
};
// src/RequestController.ts
var kRequestHandled = Symbol("kRequestHandled");
var kResponsePromise = Symbol("kResponsePromise");
var RequestController = class {
constructor(request) {
this.request = request;
this[kRequestHandled] = false;
this[kResponsePromise] = new DeferredPromise();
}
/**
* Respond to this request with the given `Response` instance.
* @example
* controller.respondWith(new Response())
* controller.respondWith(Response.json({ id }))
* controller.respondWith(Response.error())
*/
respondWith(response) {
invariant.as(
InterceptorError,
!this[kRequestHandled],
'Failed to respond to the "%s %s" request: the "request" event has already been handled.',
this.request.method,
this.request.url
);
this[kRequestHandled] = true;
this[kResponsePromise].resolve(response);
}
/**
* Error this request with the given error.
* @example
* controller.errorWith()
* controller.errorWith(new Error('Oops!'))
*/
errorWith(error) {
invariant.as(
InterceptorError,
!this[kRequestHandled],
'Failed to error the "%s %s" request: the "request" event has already been handled.',
this.request.method,
this.request.url
);
this[kRequestHandled] = true;
this[kResponsePromise].resolve(error);
}
};
kResponsePromise, kRequestHandled;
// src/utils/emitAsync.ts
async function emitAsync(emitter, eventName, ...data) {
const listners = emitter.listeners(eventName);
if (listners.length === 0) {
return;
}
for (const listener of listners) {
await listener.apply(emitter, data);
}
}
// src/utils/handleRequest.ts
import { DeferredPromise as DeferredPromise2 } from "@open-draft/deferred-promise";
import { until } from "@open-draft/until";
// src/utils/isPropertyAccessible.ts
function isPropertyAccessible(obj, key) {
try {
obj[key];
return true;
} catch (e) {
return false;
}
}
// src/utils/responseUtils.ts
function createServerErrorResponse(body) {
return new Response(
JSON.stringify(
body instanceof Error ? {
name: body.name,
message: body.message,
stack: body.stack
} : body
),
{
status: 500,
statusText: "Unhandled Exception",
headers: {
"Content-Type": "application/json"
}
}
);
}
function isResponseError(response) {
return isPropertyAccessible(response, "type") && response.type === "error";
}
// src/utils/isNodeLikeError.ts
function isNodeLikeError(error) {
if (error == null) {
return false;
}
if (!(error instanceof Error)) {
return false;
}
return "code" in error && "errno" in error;
}
// src/utils/handleRequest.ts
async function handleRequest(options) {
const handleResponse = async (response) => {
if (response instanceof Error) {
options.onError(response);
} else if (isResponseError(response)) {
options.onRequestError(response);
} else {
await options.onResponse(response);
}
return true;
};
const handleResponseError = async (error) => {
if (error instanceof InterceptorError) {
throw result.error;
}
if (isNodeLikeError(error)) {
options.onError(error);
return true;
}
if (error instanceof Response) {
return await handleResponse(error);
}
return false;
};
options.emitter.once("request", ({ requestId: pendingRequestId }) => {
if (pendingRequestId !== options.requestId) {
return;
}
if (options.controller[kResponsePromise].state === "pending") {
options.controller[kResponsePromise].resolve(void 0);
}
});
const requestAbortPromise = new DeferredPromise2();
if (options.request.signal) {
if (options.request.signal.aborted) {
requestAbortPromise.reject(options.request.signal.reason);
} else {
options.request.signal.addEventListener(
"abort",
() => {
requestAbortPromise.reject(options.request.signal.reason);
},
{ once: true }
);
}
}
const result = await until(async () => {
const requestListtenersPromise = emitAsync(options.emitter, "request", {
requestId: options.requestId,
request: options.request,
controller: options.controller
});
await Promise.race([
// Short-circuit the request handling promise if the request gets aborted.
requestAbortPromise,
requestListtenersPromise,
options.controller[kResponsePromise]
]);
const mockedResponse = await options.controller[kResponsePromise];
return mockedResponse;
});
if (requestAbortPromise.state === "rejected") {
options.onError(requestAbortPromise.rejectionReason);
return true;
}
if (result.error) {
if (await handleResponseError(result.error)) {
return true;
}
if (options.emitter.listenerCount("unhandledException") > 0) {
const unhandledExceptionController = new RequestController(
options.request
);
await emitAsync(options.emitter, "unhandledException", {
error: result.error,
request: options.request,
requestId: options.requestId,
controller: unhandledExceptionController
}).then(() => {
if (unhandledExceptionController[kResponsePromise].state === "pending") {
unhandledExceptionController[kResponsePromise].resolve(void 0);
}
});
const nextResult = await until(
() => unhandledExceptionController[kResponsePromise]
);
if (nextResult.error) {
return handleResponseError(nextResult.error);
}
if (nextResult.data) {
return handleResponse(nextResult.data);
}
}
options.onResponse(createServerErrorResponse(result.error));
return true;
}
if (result.data) {
return handleResponse(result.data);
}
return false;
}
export {
RequestController,
emitAsync,
handleRequest
};
//# sourceMappingURL=chunk-H5O73WD2.mjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,22 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/utils/bufferUtils.ts
var encoder = new TextEncoder();
function encodeBuffer(text) {
return encoder.encode(text);
}
function decodeBuffer(buffer, encoding) {
const decoder = new TextDecoder(encoding);
return decoder.decode(buffer);
}
function toArrayBuffer(array) {
return array.buffer.slice(
array.byteOffset,
array.byteOffset + array.byteLength
);
}
exports.encodeBuffer = encodeBuffer; exports.decodeBuffer = decodeBuffer; exports.toArrayBuffer = toArrayBuffer;
//# sourceMappingURL=chunk-LK6DILFK.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../../src/utils/bufferUtils.ts"],"names":[],"mappings":";AAAA,IAAM,UAAU,IAAI,YAAY;AAEzB,SAAS,aAAa,MAA0B;AACrD,SAAO,QAAQ,OAAO,IAAI;AAC5B;AAEO,SAAS,aAAa,QAAqB,UAA2B;AAC3E,QAAM,UAAU,IAAI,YAAY,QAAQ;AACxC,SAAO,QAAQ,OAAO,MAAM;AAC9B;AAOO,SAAS,cAAc,OAAgC;AAC5D,SAAO,MAAM,OAAO;AAAA,IAClB,MAAM;AAAA,IACN,MAAM,aAAa,MAAM;AAAA,EAC3B;AACF","sourcesContent":["const encoder = new TextEncoder()\n\nexport function encodeBuffer(text: string): Uint8Array {\n return encoder.encode(text)\n}\n\nexport function decodeBuffer(buffer: ArrayBuffer, encoding?: string): string {\n const decoder = new TextDecoder(encoding)\n return decoder.decode(buffer)\n}\n\n/**\n * Create an `ArrayBuffer` from the given `Uint8Array`.\n * Takes the byte offset into account to produce the right buffer\n * in the case when the buffer is bigger than the data view.\n */\nexport function toArrayBuffer(array: Uint8Array): ArrayBuffer {\n return array.buffer.slice(\n array.byteOffset,\n array.byteOffset + array.byteLength\n )\n}\n"]}

View file

@ -0,0 +1,25 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/utils/hasConfigurableGlobal.ts
function hasConfigurableGlobal(propertyName) {
const descriptor = Object.getOwnPropertyDescriptor(globalThis, propertyName);
if (typeof descriptor === "undefined") {
return false;
}
if (typeof descriptor.get === "function" && typeof descriptor.get() === "undefined") {
return false;
}
if (typeof descriptor.get === "undefined" && descriptor.value == null) {
return false;
}
if (typeof descriptor.set === "undefined" && !descriptor.configurable) {
console.error(
`[MSW] Failed to apply interceptor: the global \`${propertyName}\` property is non-configurable. This is likely an issue with your environment. If you are using a framework, please open an issue about this in their repository.`
);
return false;
}
return true;
}
exports.hasConfigurableGlobal = hasConfigurableGlobal;
//# sourceMappingURL=chunk-PFGO5BSM.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../../src/utils/hasConfigurableGlobal.ts"],"names":[],"mappings":";AAIO,SAAS,sBAAsB,cAA+B;AACnE,QAAM,aAAa,OAAO,yBAAyB,YAAY,YAAY;AAG3E,MAAI,OAAO,eAAe,aAAa;AACrC,WAAO;AAAA,EACT;AAGA,MACE,OAAO,WAAW,QAAQ,cAC1B,OAAO,WAAW,IAAI,MAAM,aAC5B;AACA,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,WAAW,QAAQ,eAAe,WAAW,SAAS,MAAM;AACrE,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,QAAQ,eAAe,CAAC,WAAW,cAAc;AACrE,YAAQ;AAAA,MACN,mDAAmD;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT","sourcesContent":["/**\n * Returns a boolean indicating whether the given global property\n * is defined and is configurable.\n */\nexport function hasConfigurableGlobal(propertyName: string): boolean {\n const descriptor = Object.getOwnPropertyDescriptor(globalThis, propertyName)\n\n // The property is not set at all.\n if (typeof descriptor === 'undefined') {\n return false\n }\n\n // The property is set to a getter that returns undefined.\n if (\n typeof descriptor.get === 'function' &&\n typeof descriptor.get() === 'undefined'\n ) {\n return false\n }\n\n // The property is set to a value equal to undefined.\n if (typeof descriptor.get === 'undefined' && descriptor.value == null) {\n return false\n }\n\n if (typeof descriptor.set === 'undefined' && !descriptor.configurable) {\n console.error(\n `[MSW] Failed to apply interceptor: the global \\`${propertyName}\\` property is non-configurable. This is likely an issue with your environment. If you are using a framework, please open an issue about this in their repository.`\n )\n return false\n }\n\n return true\n}\n"]}

View file

@ -0,0 +1,169 @@
// src/Interceptor.ts
import { Logger } from "@open-draft/logger";
import { Emitter } from "strict-event-emitter";
var INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
function getGlobalSymbol(symbol) {
return (
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587
globalThis[symbol] || void 0
);
}
function setGlobalSymbol(symbol, value) {
globalThis[symbol] = value;
}
function deleteGlobalSymbol(symbol) {
delete globalThis[symbol];
}
var InterceptorReadyState = /* @__PURE__ */ ((InterceptorReadyState2) => {
InterceptorReadyState2["INACTIVE"] = "INACTIVE";
InterceptorReadyState2["APPLYING"] = "APPLYING";
InterceptorReadyState2["APPLIED"] = "APPLIED";
InterceptorReadyState2["DISPOSING"] = "DISPOSING";
InterceptorReadyState2["DISPOSED"] = "DISPOSED";
return InterceptorReadyState2;
})(InterceptorReadyState || {});
var Interceptor = class {
constructor(symbol) {
this.symbol = symbol;
this.readyState = "INACTIVE" /* INACTIVE */;
this.emitter = new Emitter();
this.subscriptions = [];
this.logger = new Logger(symbol.description);
this.emitter.setMaxListeners(0);
this.logger.info("constructing the interceptor...");
}
/**
* Determine if this interceptor can be applied
* in the current environment.
*/
checkEnvironment() {
return true;
}
/**
* Apply this interceptor to the current process.
* Returns an already running interceptor instance if it's present.
*/
apply() {
const logger = this.logger.extend("apply");
logger.info("applying the interceptor...");
if (this.readyState === "APPLIED" /* APPLIED */) {
logger.info("intercepted already applied!");
return;
}
const shouldApply = this.checkEnvironment();
if (!shouldApply) {
logger.info("the interceptor cannot be applied in this environment!");
return;
}
this.readyState = "APPLYING" /* APPLYING */;
const runningInstance = this.getInstance();
if (runningInstance) {
logger.info("found a running instance, reusing...");
this.on = (event, listener) => {
logger.info('proxying the "%s" listener', event);
runningInstance.emitter.addListener(event, listener);
this.subscriptions.push(() => {
runningInstance.emitter.removeListener(event, listener);
logger.info('removed proxied "%s" listener!', event);
});
return this;
};
this.readyState = "APPLIED" /* APPLIED */;
return;
}
logger.info("no running instance found, setting up a new instance...");
this.setup();
this.setInstance();
this.readyState = "APPLIED" /* APPLIED */;
}
/**
* Setup the module augments and stubs necessary for this interceptor.
* This method is not run if there's a running interceptor instance
* to prevent instantiating an interceptor multiple times.
*/
setup() {
}
/**
* Listen to the interceptor's public events.
*/
on(event, listener) {
const logger = this.logger.extend("on");
if (this.readyState === "DISPOSING" /* DISPOSING */ || this.readyState === "DISPOSED" /* DISPOSED */) {
logger.info("cannot listen to events, already disposed!");
return this;
}
logger.info('adding "%s" event listener:', event, listener);
this.emitter.on(event, listener);
return this;
}
once(event, listener) {
this.emitter.once(event, listener);
return this;
}
off(event, listener) {
this.emitter.off(event, listener);
return this;
}
removeAllListeners(event) {
this.emitter.removeAllListeners(event);
return this;
}
/**
* Disposes of any side-effects this interceptor has introduced.
*/
dispose() {
const logger = this.logger.extend("dispose");
if (this.readyState === "DISPOSED" /* DISPOSED */) {
logger.info("cannot dispose, already disposed!");
return;
}
logger.info("disposing the interceptor...");
this.readyState = "DISPOSING" /* DISPOSING */;
if (!this.getInstance()) {
logger.info("no interceptors running, skipping dispose...");
return;
}
this.clearInstance();
logger.info("global symbol deleted:", getGlobalSymbol(this.symbol));
if (this.subscriptions.length > 0) {
logger.info("disposing of %d subscriptions...", this.subscriptions.length);
for (const dispose of this.subscriptions) {
dispose();
}
this.subscriptions = [];
logger.info("disposed of all subscriptions!", this.subscriptions.length);
}
this.emitter.removeAllListeners();
logger.info("destroyed the listener!");
this.readyState = "DISPOSED" /* DISPOSED */;
}
getInstance() {
var _a;
const instance = getGlobalSymbol(this.symbol);
this.logger.info("retrieved global instance:", (_a = instance == null ? void 0 : instance.constructor) == null ? void 0 : _a.name);
return instance;
}
setInstance() {
setGlobalSymbol(this.symbol, this);
this.logger.info("set global instance!", this.symbol.description);
}
clearInstance() {
deleteGlobalSymbol(this.symbol);
this.logger.info("cleared global instance!", this.symbol.description);
}
};
// src/createRequestId.ts
function createRequestId() {
return Math.random().toString(16).slice(2);
}
export {
INTERNAL_REQUEST_ID_HEADER_NAME,
getGlobalSymbol,
deleteGlobalSymbol,
InterceptorReadyState,
Interceptor,
createRequestId
};
//# sourceMappingURL=chunk-QED3Q6Z2.mjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,295 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _chunkFGSEOIC4js = require('./chunk-FGSEOIC4.js');
var _chunkBC2BLJQNjs = require('./chunk-BC2BLJQN.js');
var _chunkPFGO5BSMjs = require('./chunk-PFGO5BSM.js');
var _chunkTIPR373Rjs = require('./chunk-TIPR373R.js');
// src/interceptors/fetch/index.ts
var _outvariant = require('outvariant');
var _deferredpromise = require('@open-draft/deferred-promise');
// src/utils/canParseUrl.ts
function canParseUrl(url) {
try {
new URL(url);
return true;
} catch (_error) {
return false;
}
}
// src/interceptors/fetch/utils/createNetworkError.ts
function createNetworkError(cause) {
return Object.assign(new TypeError("Failed to fetch"), {
cause
});
}
// src/interceptors/fetch/utils/followRedirect.ts
var REQUEST_BODY_HEADERS = [
"content-encoding",
"content-language",
"content-location",
"content-type",
"content-length"
];
var kRedirectCount = Symbol("kRedirectCount");
async function followFetchRedirect(request, response) {
if (response.status !== 303 && request.body != null) {
return Promise.reject(createNetworkError());
}
const requestUrl = new URL(request.url);
let locationUrl;
try {
locationUrl = new URL(response.headers.get("location"), request.url);
} catch (error) {
return Promise.reject(createNetworkError(error));
}
if (!(locationUrl.protocol === "http:" || locationUrl.protocol === "https:")) {
return Promise.reject(
createNetworkError("URL scheme must be a HTTP(S) scheme")
);
}
if (Reflect.get(request, kRedirectCount) > 20) {
return Promise.reject(createNetworkError("redirect count exceeded"));
}
Object.defineProperty(request, kRedirectCount, {
value: (Reflect.get(request, kRedirectCount) || 0) + 1
});
if (request.mode === "cors" && (locationUrl.username || locationUrl.password) && !sameOrigin(requestUrl, locationUrl)) {
return Promise.reject(
createNetworkError('cross origin not allowed for request mode "cors"')
);
}
const requestInit = {};
if ([301, 302].includes(response.status) && request.method === "POST" || response.status === 303 && !["HEAD", "GET"].includes(request.method)) {
requestInit.method = "GET";
requestInit.body = null;
REQUEST_BODY_HEADERS.forEach((headerName) => {
request.headers.delete(headerName);
});
}
if (!sameOrigin(requestUrl, locationUrl)) {
request.headers.delete("authorization");
request.headers.delete("proxy-authorization");
request.headers.delete("cookie");
request.headers.delete("host");
}
requestInit.headers = request.headers;
return fetch(new Request(locationUrl, requestInit));
}
function sameOrigin(left, right) {
if (left.origin === right.origin && left.origin === "null") {
return true;
}
if (left.protocol === right.protocol && left.hostname === right.hostname && left.port === right.port) {
return true;
}
return false;
}
// src/interceptors/fetch/utils/brotli-decompress.browser.ts
var BrotliDecompressionStream = class extends TransformStream {
constructor() {
console.warn(
"[Interceptors]: Brotli decompression of response streams is not supported in the browser"
);
super({
transform(chunk, controller) {
controller.enqueue(chunk);
}
});
}
};
// src/interceptors/fetch/utils/decompression.ts
var PipelineStream = class extends TransformStream {
constructor(transformStreams, ...strategies) {
super({}, ...strategies);
const readable = [super.readable, ...transformStreams].reduce(
(readable2, transform) => readable2.pipeThrough(transform)
);
Object.defineProperty(this, "readable", {
get() {
return readable;
}
});
}
};
function parseContentEncoding(contentEncoding) {
return contentEncoding.toLowerCase().split(",").map((coding) => coding.trim());
}
function createDecompressionStream(contentEncoding) {
if (contentEncoding === "") {
return null;
}
const codings = parseContentEncoding(contentEncoding);
if (codings.length === 0) {
return null;
}
const transformers = codings.reduceRight(
(transformers2, coding) => {
if (coding === "gzip" || coding === "x-gzip") {
return transformers2.concat(new DecompressionStream("gzip"));
} else if (coding === "deflate") {
return transformers2.concat(new DecompressionStream("deflate"));
} else if (coding === "br") {
return transformers2.concat(new BrotliDecompressionStream());
} else {
transformers2.length = 0;
}
return transformers2;
},
[]
);
return new PipelineStream(transformers);
}
function decompressResponse(response) {
if (response.body === null) {
return null;
}
const decompressionStream = createDecompressionStream(
response.headers.get("content-encoding") || ""
);
if (!decompressionStream) {
return null;
}
response.body.pipeTo(decompressionStream.writable);
return decompressionStream.readable;
}
// src/interceptors/fetch/index.ts
var _FetchInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
constructor() {
super(_FetchInterceptor.symbol);
}
checkEnvironment() {
return _chunkPFGO5BSMjs.hasConfigurableGlobal.call(void 0, "fetch");
}
async setup() {
const pureFetch = globalThis.fetch;
_outvariant.invariant.call(void 0,
!pureFetch[_chunkBC2BLJQNjs.IS_PATCHED_MODULE],
'Failed to patch the "fetch" module: already patched.'
);
globalThis.fetch = async (input, init) => {
const requestId = _chunkTIPR373Rjs.createRequestId.call(void 0, );
const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !canParseUrl(input) ? new URL(input, location.origin) : input;
const request = new Request(resolvedInput, init);
const responsePromise = new (0, _deferredpromise.DeferredPromise)();
const controller = new (0, _chunkFGSEOIC4js.RequestController)(request);
this.logger.info("[%s] %s", request.method, request.url);
this.logger.info("awaiting for the mocked response...");
this.logger.info(
'emitting the "request" event for %s listener(s)...',
this.emitter.listenerCount("request")
);
const isRequestHandled = await _chunkFGSEOIC4js.handleRequest.call(void 0, {
request,
requestId,
emitter: this.emitter,
controller,
onResponse: async (rawResponse) => {
this.logger.info("received mocked response!", {
rawResponse
});
const decompressedStream = decompressResponse(rawResponse);
const response = decompressedStream === null ? rawResponse : new (0, _chunkBC2BLJQNjs.FetchResponse)(decompressedStream, rawResponse);
_chunkBC2BLJQNjs.FetchResponse.setUrl(request.url, response);
if (_chunkBC2BLJQNjs.FetchResponse.isRedirectResponse(response.status)) {
if (request.redirect === "error") {
responsePromise.reject(createNetworkError("unexpected redirect"));
return;
}
if (request.redirect === "follow") {
followFetchRedirect(request, response).then(
(response2) => {
responsePromise.resolve(response2);
},
(reason) => {
responsePromise.reject(reason);
}
);
return;
}
}
if (this.emitter.listenerCount("response") > 0) {
this.logger.info('emitting the "response" event...');
await _chunkFGSEOIC4js.emitAsync.call(void 0, this.emitter, "response", {
// Clone the mocked response for the "response" event listener.
// This way, the listener can read the response and not lock its body
// for the actual fetch consumer.
response: response.clone(),
isMockedResponse: true,
request,
requestId
});
}
responsePromise.resolve(response);
},
onRequestError: (response) => {
this.logger.info("request has errored!", { response });
responsePromise.reject(createNetworkError(response));
},
onError: (error) => {
this.logger.info("request has been aborted!", { error });
responsePromise.reject(error);
}
});
if (isRequestHandled) {
this.logger.info("request has been handled, returning mock promise...");
return responsePromise;
}
this.logger.info(
"no mocked response received, performing request as-is..."
);
return pureFetch(request).then(async (response) => {
this.logger.info("original fetch performed", response);
if (this.emitter.listenerCount("response") > 0) {
this.logger.info('emitting the "response" event...');
const responseClone = response.clone();
await _chunkFGSEOIC4js.emitAsync.call(void 0, this.emitter, "response", {
response: responseClone,
isMockedResponse: false,
request,
requestId
});
}
return response;
});
};
Object.defineProperty(globalThis.fetch, _chunkBC2BLJQNjs.IS_PATCHED_MODULE, {
enumerable: true,
configurable: true,
value: true
});
this.subscriptions.push(() => {
Object.defineProperty(globalThis.fetch, _chunkBC2BLJQNjs.IS_PATCHED_MODULE, {
value: void 0
});
globalThis.fetch = pureFetch;
this.logger.info(
'restored native "globalThis.fetch"!',
globalThis.fetch.name
);
});
}
};
var FetchInterceptor = _FetchInterceptor;
FetchInterceptor.symbol = Symbol("fetch");
exports.FetchInterceptor = FetchInterceptor;
//# sourceMappingURL=chunk-QVOTKFTB.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,169 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/Interceptor.ts
var _logger = require('@open-draft/logger');
var _stricteventemitter = require('strict-event-emitter');
var INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
function getGlobalSymbol(symbol) {
return (
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587
globalThis[symbol] || void 0
);
}
function setGlobalSymbol(symbol, value) {
globalThis[symbol] = value;
}
function deleteGlobalSymbol(symbol) {
delete globalThis[symbol];
}
var InterceptorReadyState = /* @__PURE__ */ ((InterceptorReadyState2) => {
InterceptorReadyState2["INACTIVE"] = "INACTIVE";
InterceptorReadyState2["APPLYING"] = "APPLYING";
InterceptorReadyState2["APPLIED"] = "APPLIED";
InterceptorReadyState2["DISPOSING"] = "DISPOSING";
InterceptorReadyState2["DISPOSED"] = "DISPOSED";
return InterceptorReadyState2;
})(InterceptorReadyState || {});
var Interceptor = class {
constructor(symbol) {
this.symbol = symbol;
this.readyState = "INACTIVE" /* INACTIVE */;
this.emitter = new (0, _stricteventemitter.Emitter)();
this.subscriptions = [];
this.logger = new (0, _logger.Logger)(symbol.description);
this.emitter.setMaxListeners(0);
this.logger.info("constructing the interceptor...");
}
/**
* Determine if this interceptor can be applied
* in the current environment.
*/
checkEnvironment() {
return true;
}
/**
* Apply this interceptor to the current process.
* Returns an already running interceptor instance if it's present.
*/
apply() {
const logger = this.logger.extend("apply");
logger.info("applying the interceptor...");
if (this.readyState === "APPLIED" /* APPLIED */) {
logger.info("intercepted already applied!");
return;
}
const shouldApply = this.checkEnvironment();
if (!shouldApply) {
logger.info("the interceptor cannot be applied in this environment!");
return;
}
this.readyState = "APPLYING" /* APPLYING */;
const runningInstance = this.getInstance();
if (runningInstance) {
logger.info("found a running instance, reusing...");
this.on = (event, listener) => {
logger.info('proxying the "%s" listener', event);
runningInstance.emitter.addListener(event, listener);
this.subscriptions.push(() => {
runningInstance.emitter.removeListener(event, listener);
logger.info('removed proxied "%s" listener!', event);
});
return this;
};
this.readyState = "APPLIED" /* APPLIED */;
return;
}
logger.info("no running instance found, setting up a new instance...");
this.setup();
this.setInstance();
this.readyState = "APPLIED" /* APPLIED */;
}
/**
* Setup the module augments and stubs necessary for this interceptor.
* This method is not run if there's a running interceptor instance
* to prevent instantiating an interceptor multiple times.
*/
setup() {
}
/**
* Listen to the interceptor's public events.
*/
on(event, listener) {
const logger = this.logger.extend("on");
if (this.readyState === "DISPOSING" /* DISPOSING */ || this.readyState === "DISPOSED" /* DISPOSED */) {
logger.info("cannot listen to events, already disposed!");
return this;
}
logger.info('adding "%s" event listener:', event, listener);
this.emitter.on(event, listener);
return this;
}
once(event, listener) {
this.emitter.once(event, listener);
return this;
}
off(event, listener) {
this.emitter.off(event, listener);
return this;
}
removeAllListeners(event) {
this.emitter.removeAllListeners(event);
return this;
}
/**
* Disposes of any side-effects this interceptor has introduced.
*/
dispose() {
const logger = this.logger.extend("dispose");
if (this.readyState === "DISPOSED" /* DISPOSED */) {
logger.info("cannot dispose, already disposed!");
return;
}
logger.info("disposing the interceptor...");
this.readyState = "DISPOSING" /* DISPOSING */;
if (!this.getInstance()) {
logger.info("no interceptors running, skipping dispose...");
return;
}
this.clearInstance();
logger.info("global symbol deleted:", getGlobalSymbol(this.symbol));
if (this.subscriptions.length > 0) {
logger.info("disposing of %d subscriptions...", this.subscriptions.length);
for (const dispose of this.subscriptions) {
dispose();
}
this.subscriptions = [];
logger.info("disposed of all subscriptions!", this.subscriptions.length);
}
this.emitter.removeAllListeners();
logger.info("destroyed the listener!");
this.readyState = "DISPOSED" /* DISPOSED */;
}
getInstance() {
var _a;
const instance = getGlobalSymbol(this.symbol);
this.logger.info("retrieved global instance:", (_a = instance == null ? void 0 : instance.constructor) == null ? void 0 : _a.name);
return instance;
}
setInstance() {
setGlobalSymbol(this.symbol, this);
this.logger.info("set global instance!", this.symbol.description);
}
clearInstance() {
deleteGlobalSymbol(this.symbol);
this.logger.info("cleared global instance!", this.symbol.description);
}
};
// src/createRequestId.ts
function createRequestId() {
return Math.random().toString(16).slice(2);
}
exports.INTERNAL_REQUEST_ID_HEADER_NAME = INTERNAL_REQUEST_ID_HEADER_NAME; exports.getGlobalSymbol = getGlobalSymbol; exports.deleteGlobalSymbol = deleteGlobalSymbol; exports.InterceptorReadyState = InterceptorReadyState; exports.Interceptor = Interceptor; exports.createRequestId = createRequestId;
//# sourceMappingURL=chunk-TIPR373R.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,25 @@
// src/utils/hasConfigurableGlobal.ts
function hasConfigurableGlobal(propertyName) {
const descriptor = Object.getOwnPropertyDescriptor(globalThis, propertyName);
if (typeof descriptor === "undefined") {
return false;
}
if (typeof descriptor.get === "function" && typeof descriptor.get() === "undefined") {
return false;
}
if (typeof descriptor.get === "undefined" && descriptor.value == null) {
return false;
}
if (typeof descriptor.set === "undefined" && !descriptor.configurable) {
console.error(
`[MSW] Failed to apply interceptor: the global \`${propertyName}\` property is non-configurable. This is likely an issue with your environment. If you are using a framework, please open an issue about this in their repository.`
);
return false;
}
return true;
}
export {
hasConfigurableGlobal
};
//# sourceMappingURL=chunk-TX5GBTFY.mjs.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../../src/utils/hasConfigurableGlobal.ts"],"sourcesContent":["/**\n * Returns a boolean indicating whether the given global property\n * is defined and is configurable.\n */\nexport function hasConfigurableGlobal(propertyName: string): boolean {\n const descriptor = Object.getOwnPropertyDescriptor(globalThis, propertyName)\n\n // The property is not set at all.\n if (typeof descriptor === 'undefined') {\n return false\n }\n\n // The property is set to a getter that returns undefined.\n if (\n typeof descriptor.get === 'function' &&\n typeof descriptor.get() === 'undefined'\n ) {\n return false\n }\n\n // The property is set to a value equal to undefined.\n if (typeof descriptor.get === 'undefined' && descriptor.value == null) {\n return false\n }\n\n if (typeof descriptor.set === 'undefined' && !descriptor.configurable) {\n console.error(\n `[MSW] Failed to apply interceptor: the global \\`${propertyName}\\` property is non-configurable. This is likely an issue with your environment. If you are using a framework, please open an issue about this in their repository.`\n )\n return false\n }\n\n return true\n}\n"],"mappings":";AAIO,SAAS,sBAAsB,cAA+B;AACnE,QAAM,aAAa,OAAO,yBAAyB,YAAY,YAAY;AAG3E,MAAI,OAAO,eAAe,aAAa;AACrC,WAAO;AAAA,EACT;AAGA,MACE,OAAO,WAAW,QAAQ,cAC1B,OAAO,WAAW,IAAI,MAAM,aAC5B;AACA,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,WAAW,QAAQ,eAAe,WAAW,SAAS,MAAM;AACrE,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,QAAQ,eAAe,CAAC,WAAW,cAAc;AACrE,YAAQ;AAAA,MACN,mDAAmD;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}

View file

@ -0,0 +1,295 @@
import {
RequestController,
emitAsync,
handleRequest
} from "./chunk-H5O73WD2.mjs";
import {
FetchResponse,
IS_PATCHED_MODULE
} from "./chunk-5UK33FSU.mjs";
import {
hasConfigurableGlobal
} from "./chunk-TX5GBTFY.mjs";
import {
Interceptor,
createRequestId
} from "./chunk-QED3Q6Z2.mjs";
// src/interceptors/fetch/index.ts
import { invariant } from "outvariant";
import { DeferredPromise } from "@open-draft/deferred-promise";
// src/utils/canParseUrl.ts
function canParseUrl(url) {
try {
new URL(url);
return true;
} catch (_error) {
return false;
}
}
// src/interceptors/fetch/utils/createNetworkError.ts
function createNetworkError(cause) {
return Object.assign(new TypeError("Failed to fetch"), {
cause
});
}
// src/interceptors/fetch/utils/followRedirect.ts
var REQUEST_BODY_HEADERS = [
"content-encoding",
"content-language",
"content-location",
"content-type",
"content-length"
];
var kRedirectCount = Symbol("kRedirectCount");
async function followFetchRedirect(request, response) {
if (response.status !== 303 && request.body != null) {
return Promise.reject(createNetworkError());
}
const requestUrl = new URL(request.url);
let locationUrl;
try {
locationUrl = new URL(response.headers.get("location"), request.url);
} catch (error) {
return Promise.reject(createNetworkError(error));
}
if (!(locationUrl.protocol === "http:" || locationUrl.protocol === "https:")) {
return Promise.reject(
createNetworkError("URL scheme must be a HTTP(S) scheme")
);
}
if (Reflect.get(request, kRedirectCount) > 20) {
return Promise.reject(createNetworkError("redirect count exceeded"));
}
Object.defineProperty(request, kRedirectCount, {
value: (Reflect.get(request, kRedirectCount) || 0) + 1
});
if (request.mode === "cors" && (locationUrl.username || locationUrl.password) && !sameOrigin(requestUrl, locationUrl)) {
return Promise.reject(
createNetworkError('cross origin not allowed for request mode "cors"')
);
}
const requestInit = {};
if ([301, 302].includes(response.status) && request.method === "POST" || response.status === 303 && !["HEAD", "GET"].includes(request.method)) {
requestInit.method = "GET";
requestInit.body = null;
REQUEST_BODY_HEADERS.forEach((headerName) => {
request.headers.delete(headerName);
});
}
if (!sameOrigin(requestUrl, locationUrl)) {
request.headers.delete("authorization");
request.headers.delete("proxy-authorization");
request.headers.delete("cookie");
request.headers.delete("host");
}
requestInit.headers = request.headers;
return fetch(new Request(locationUrl, requestInit));
}
function sameOrigin(left, right) {
if (left.origin === right.origin && left.origin === "null") {
return true;
}
if (left.protocol === right.protocol && left.hostname === right.hostname && left.port === right.port) {
return true;
}
return false;
}
// src/interceptors/fetch/utils/brotli-decompress.browser.ts
var BrotliDecompressionStream = class extends TransformStream {
constructor() {
console.warn(
"[Interceptors]: Brotli decompression of response streams is not supported in the browser"
);
super({
transform(chunk, controller) {
controller.enqueue(chunk);
}
});
}
};
// src/interceptors/fetch/utils/decompression.ts
var PipelineStream = class extends TransformStream {
constructor(transformStreams, ...strategies) {
super({}, ...strategies);
const readable = [super.readable, ...transformStreams].reduce(
(readable2, transform) => readable2.pipeThrough(transform)
);
Object.defineProperty(this, "readable", {
get() {
return readable;
}
});
}
};
function parseContentEncoding(contentEncoding) {
return contentEncoding.toLowerCase().split(",").map((coding) => coding.trim());
}
function createDecompressionStream(contentEncoding) {
if (contentEncoding === "") {
return null;
}
const codings = parseContentEncoding(contentEncoding);
if (codings.length === 0) {
return null;
}
const transformers = codings.reduceRight(
(transformers2, coding) => {
if (coding === "gzip" || coding === "x-gzip") {
return transformers2.concat(new DecompressionStream("gzip"));
} else if (coding === "deflate") {
return transformers2.concat(new DecompressionStream("deflate"));
} else if (coding === "br") {
return transformers2.concat(new BrotliDecompressionStream());
} else {
transformers2.length = 0;
}
return transformers2;
},
[]
);
return new PipelineStream(transformers);
}
function decompressResponse(response) {
if (response.body === null) {
return null;
}
const decompressionStream = createDecompressionStream(
response.headers.get("content-encoding") || ""
);
if (!decompressionStream) {
return null;
}
response.body.pipeTo(decompressionStream.writable);
return decompressionStream.readable;
}
// src/interceptors/fetch/index.ts
var _FetchInterceptor = class extends Interceptor {
constructor() {
super(_FetchInterceptor.symbol);
}
checkEnvironment() {
return hasConfigurableGlobal("fetch");
}
async setup() {
const pureFetch = globalThis.fetch;
invariant(
!pureFetch[IS_PATCHED_MODULE],
'Failed to patch the "fetch" module: already patched.'
);
globalThis.fetch = async (input, init) => {
const requestId = createRequestId();
const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !canParseUrl(input) ? new URL(input, location.origin) : input;
const request = new Request(resolvedInput, init);
const responsePromise = new DeferredPromise();
const controller = new RequestController(request);
this.logger.info("[%s] %s", request.method, request.url);
this.logger.info("awaiting for the mocked response...");
this.logger.info(
'emitting the "request" event for %s listener(s)...',
this.emitter.listenerCount("request")
);
const isRequestHandled = await handleRequest({
request,
requestId,
emitter: this.emitter,
controller,
onResponse: async (rawResponse) => {
this.logger.info("received mocked response!", {
rawResponse
});
const decompressedStream = decompressResponse(rawResponse);
const response = decompressedStream === null ? rawResponse : new FetchResponse(decompressedStream, rawResponse);
FetchResponse.setUrl(request.url, response);
if (FetchResponse.isRedirectResponse(response.status)) {
if (request.redirect === "error") {
responsePromise.reject(createNetworkError("unexpected redirect"));
return;
}
if (request.redirect === "follow") {
followFetchRedirect(request, response).then(
(response2) => {
responsePromise.resolve(response2);
},
(reason) => {
responsePromise.reject(reason);
}
);
return;
}
}
if (this.emitter.listenerCount("response") > 0) {
this.logger.info('emitting the "response" event...');
await emitAsync(this.emitter, "response", {
// Clone the mocked response for the "response" event listener.
// This way, the listener can read the response and not lock its body
// for the actual fetch consumer.
response: response.clone(),
isMockedResponse: true,
request,
requestId
});
}
responsePromise.resolve(response);
},
onRequestError: (response) => {
this.logger.info("request has errored!", { response });
responsePromise.reject(createNetworkError(response));
},
onError: (error) => {
this.logger.info("request has been aborted!", { error });
responsePromise.reject(error);
}
});
if (isRequestHandled) {
this.logger.info("request has been handled, returning mock promise...");
return responsePromise;
}
this.logger.info(
"no mocked response received, performing request as-is..."
);
return pureFetch(request).then(async (response) => {
this.logger.info("original fetch performed", response);
if (this.emitter.listenerCount("response") > 0) {
this.logger.info('emitting the "response" event...');
const responseClone = response.clone();
await emitAsync(this.emitter, "response", {
response: responseClone,
isMockedResponse: false,
request,
requestId
});
}
return response;
});
};
Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {
enumerable: true,
configurable: true,
value: true
});
this.subscriptions.push(() => {
Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {
value: void 0
});
globalThis.fetch = pureFetch;
this.logger.info(
'restored native "globalThis.fetch"!',
globalThis.fetch.name
);
});
}
};
var FetchInterceptor = _FetchInterceptor;
FetchInterceptor.symbol = Symbol("fetch");
export {
FetchInterceptor
};
//# sourceMappingURL=chunk-XTX2SIN6.mjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,844 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _chunkLK6DILFKjs = require('./chunk-LK6DILFK.js');
var _chunkFGSEOIC4js = require('./chunk-FGSEOIC4.js');
var _chunkBC2BLJQNjs = require('./chunk-BC2BLJQN.js');
var _chunkPFGO5BSMjs = require('./chunk-PFGO5BSM.js');
var _chunkTIPR373Rjs = require('./chunk-TIPR373R.js');
// src/interceptors/XMLHttpRequest/index.ts
var _outvariant = require('outvariant');
// src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
var _isnodeprocess = require('is-node-process');
// src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts
function concatArrayBuffer(left, right) {
const result = new Uint8Array(left.byteLength + right.byteLength);
result.set(left, 0);
result.set(right, left.byteLength);
return result;
}
// src/interceptors/XMLHttpRequest/polyfills/EventPolyfill.ts
var EventPolyfill = class {
constructor(type, options) {
this.NONE = 0;
this.CAPTURING_PHASE = 1;
this.AT_TARGET = 2;
this.BUBBLING_PHASE = 3;
this.type = "";
this.srcElement = null;
this.currentTarget = null;
this.eventPhase = 0;
this.isTrusted = true;
this.composed = false;
this.cancelable = true;
this.defaultPrevented = false;
this.bubbles = true;
this.lengthComputable = true;
this.loaded = 0;
this.total = 0;
this.cancelBubble = false;
this.returnValue = true;
this.type = type;
this.target = (options == null ? void 0 : options.target) || null;
this.currentTarget = (options == null ? void 0 : options.currentTarget) || null;
this.timeStamp = Date.now();
}
composedPath() {
return [];
}
initEvent(type, bubbles, cancelable) {
this.type = type;
this.bubbles = !!bubbles;
this.cancelable = !!cancelable;
}
preventDefault() {
this.defaultPrevented = true;
}
stopPropagation() {
}
stopImmediatePropagation() {
}
};
// src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts
var ProgressEventPolyfill = class extends EventPolyfill {
constructor(type, init) {
super(type);
this.lengthComputable = (init == null ? void 0 : init.lengthComputable) || false;
this.composed = (init == null ? void 0 : init.composed) || false;
this.loaded = (init == null ? void 0 : init.loaded) || 0;
this.total = (init == null ? void 0 : init.total) || 0;
}
};
// src/interceptors/XMLHttpRequest/utils/createEvent.ts
var SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== "undefined";
function createEvent(target, type, init) {
const progressEvents = [
"error",
"progress",
"loadstart",
"loadend",
"load",
"timeout",
"abort"
];
const ProgressEventClass = SUPPORTS_PROGRESS_EVENT ? ProgressEvent : ProgressEventPolyfill;
const event = progressEvents.includes(type) ? new ProgressEventClass(type, {
lengthComputable: true,
loaded: (init == null ? void 0 : init.loaded) || 0,
total: (init == null ? void 0 : init.total) || 0
}) : new EventPolyfill(type, {
target,
currentTarget: target
});
return event;
}
// src/utils/findPropertySource.ts
function findPropertySource(target, propertyName) {
if (!(propertyName in target)) {
return null;
}
const hasProperty = Object.prototype.hasOwnProperty.call(target, propertyName);
if (hasProperty) {
return target;
}
const prototype = Reflect.getPrototypeOf(target);
return prototype ? findPropertySource(prototype, propertyName) : null;
}
// src/utils/createProxy.ts
function createProxy(target, options) {
const proxy = new Proxy(target, optionsToProxyHandler(options));
return proxy;
}
function optionsToProxyHandler(options) {
const { constructorCall, methodCall, getProperty, setProperty } = options;
const handler = {};
if (typeof constructorCall !== "undefined") {
handler.construct = function(target, args, newTarget) {
const next = Reflect.construct.bind(null, target, args, newTarget);
return constructorCall.call(newTarget, args, next);
};
}
handler.set = function(target, propertyName, nextValue) {
const next = () => {
const propertySource = findPropertySource(target, propertyName) || target;
const ownDescriptors = Reflect.getOwnPropertyDescriptor(
propertySource,
propertyName
);
if (typeof (ownDescriptors == null ? void 0 : ownDescriptors.set) !== "undefined") {
ownDescriptors.set.apply(target, [nextValue]);
return true;
}
return Reflect.defineProperty(propertySource, propertyName, {
writable: true,
enumerable: true,
configurable: true,
value: nextValue
});
};
if (typeof setProperty !== "undefined") {
return setProperty.call(target, [propertyName, nextValue], next);
}
return next();
};
handler.get = function(target, propertyName, receiver) {
const next = () => target[propertyName];
const value = typeof getProperty !== "undefined" ? getProperty.call(target, [propertyName, receiver], next) : next();
if (typeof value === "function") {
return (...args) => {
const next2 = value.bind(target, ...args);
if (typeof methodCall !== "undefined") {
return methodCall.call(target, [propertyName, args], next2);
}
return next2();
};
}
return value;
};
return handler;
}
// src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts
function isDomParserSupportedType(type) {
const supportedTypes = [
"application/xhtml+xml",
"application/xml",
"image/svg+xml",
"text/html",
"text/xml"
];
return supportedTypes.some((supportedType) => {
return type.startsWith(supportedType);
});
}
// src/utils/parseJson.ts
function parseJson(data) {
try {
const json = JSON.parse(data);
return json;
} catch (_) {
return null;
}
}
// src/interceptors/XMLHttpRequest/utils/createResponse.ts
function createResponse(request, body) {
const responseBodyOrNull = _chunkBC2BLJQNjs.FetchResponse.isResponseWithBody(request.status) ? body : null;
return new (0, _chunkBC2BLJQNjs.FetchResponse)(responseBodyOrNull, {
url: request.responseURL,
status: request.status,
statusText: request.statusText,
headers: createHeadersFromXMLHttpReqestHeaders(
request.getAllResponseHeaders()
)
});
}
function createHeadersFromXMLHttpReqestHeaders(headersString) {
const headers = new Headers();
const lines = headersString.split(/[\r\n]+/);
for (const line of lines) {
if (line.trim() === "") {
continue;
}
const [name, ...parts] = line.split(": ");
const value = parts.join(": ");
headers.append(name, value);
}
return headers;
}
// src/interceptors/XMLHttpRequest/utils/getBodyByteLength.ts
async function getBodyByteLength(input) {
const explicitContentLength = input.headers.get("content-length");
if (explicitContentLength != null && explicitContentLength !== "") {
return Number(explicitContentLength);
}
const buffer = await input.arrayBuffer();
return buffer.byteLength;
}
// src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
var kIsRequestHandled = Symbol("kIsRequestHandled");
var IS_NODE = _isnodeprocess.isNodeProcess.call(void 0, );
var kFetchRequest = Symbol("kFetchRequest");
var XMLHttpRequestController = class {
constructor(initialRequest, logger) {
this.initialRequest = initialRequest;
this.logger = logger;
this.method = "GET";
this.url = null;
this[kIsRequestHandled] = false;
this.events = /* @__PURE__ */ new Map();
this.uploadEvents = /* @__PURE__ */ new Map();
this.requestId = _chunkTIPR373Rjs.createRequestId.call(void 0, );
this.requestHeaders = new Headers();
this.responseBuffer = new Uint8Array();
this.request = createProxy(initialRequest, {
setProperty: ([propertyName, nextValue], invoke) => {
switch (propertyName) {
case "ontimeout": {
const eventName = propertyName.slice(
2
);
this.request.addEventListener(eventName, nextValue);
return invoke();
}
default: {
return invoke();
}
}
},
methodCall: ([methodName, args], invoke) => {
var _a;
switch (methodName) {
case "open": {
const [method, url] = args;
if (typeof url === "undefined") {
this.method = "GET";
this.url = toAbsoluteUrl(method);
} else {
this.method = method;
this.url = toAbsoluteUrl(url);
}
this.logger = this.logger.extend(`${this.method} ${this.url.href}`);
this.logger.info("open", this.method, this.url.href);
return invoke();
}
case "addEventListener": {
const [eventName, listener] = args;
this.registerEvent(eventName, listener);
this.logger.info("addEventListener", eventName, listener);
return invoke();
}
case "setRequestHeader": {
const [name, value] = args;
this.requestHeaders.set(name, value);
this.logger.info("setRequestHeader", name, value);
return invoke();
}
case "send": {
const [body] = args;
this.request.addEventListener("load", () => {
if (typeof this.onResponse !== "undefined") {
const fetchResponse = createResponse(
this.request,
/**
* The `response` property is the right way to read
* the ambiguous response body, as the request's "responseType" may differ.
* @see https://xhr.spec.whatwg.org/#the-response-attribute
*/
this.request.response
);
this.onResponse.call(this, {
response: fetchResponse,
isMockedResponse: this[kIsRequestHandled],
request: fetchRequest,
requestId: this.requestId
});
}
});
const requestBody = typeof body === "string" ? _chunkLK6DILFKjs.encodeBuffer.call(void 0, body) : body;
const fetchRequest = this.toFetchApiRequest(requestBody);
this[kFetchRequest] = fetchRequest.clone();
const onceRequestSettled = ((_a = this.onRequest) == null ? void 0 : _a.call(this, {
request: fetchRequest,
requestId: this.requestId
})) || Promise.resolve();
onceRequestSettled.finally(() => {
if (!this[kIsRequestHandled]) {
this.logger.info(
"request callback settled but request has not been handled (readystate %d), performing as-is...",
this.request.readyState
);
if (IS_NODE) {
this.request.setRequestHeader(
_chunkTIPR373Rjs.INTERNAL_REQUEST_ID_HEADER_NAME,
this.requestId
);
}
return invoke();
}
});
break;
}
default: {
return invoke();
}
}
}
});
define(
this.request,
"upload",
createProxy(this.request.upload, {
setProperty: ([propertyName, nextValue], invoke) => {
switch (propertyName) {
case "onloadstart":
case "onprogress":
case "onaboart":
case "onerror":
case "onload":
case "ontimeout":
case "onloadend": {
const eventName = propertyName.slice(
2
);
this.registerUploadEvent(eventName, nextValue);
}
}
return invoke();
},
methodCall: ([methodName, args], invoke) => {
switch (methodName) {
case "addEventListener": {
const [eventName, listener] = args;
this.registerUploadEvent(eventName, listener);
this.logger.info("upload.addEventListener", eventName, listener);
return invoke();
}
}
}
})
);
}
registerEvent(eventName, listener) {
const prevEvents = this.events.get(eventName) || [];
const nextEvents = prevEvents.concat(listener);
this.events.set(eventName, nextEvents);
this.logger.info('registered event "%s"', eventName, listener);
}
registerUploadEvent(eventName, listener) {
const prevEvents = this.uploadEvents.get(eventName) || [];
const nextEvents = prevEvents.concat(listener);
this.uploadEvents.set(eventName, nextEvents);
this.logger.info('registered upload event "%s"', eventName, listener);
}
/**
* Responds to the current request with the given
* Fetch API `Response` instance.
*/
async respondWith(response) {
this[kIsRequestHandled] = true;
if (this[kFetchRequest]) {
const totalRequestBodyLength = await getBodyByteLength(
this[kFetchRequest]
);
this.trigger("loadstart", this.request.upload, {
loaded: 0,
total: totalRequestBodyLength
});
this.trigger("progress", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
this.trigger("load", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
this.trigger("loadend", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
}
this.logger.info(
"responding with a mocked response: %d %s",
response.status,
response.statusText
);
define(this.request, "status", response.status);
define(this.request, "statusText", response.statusText);
define(this.request, "responseURL", this.url.href);
this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {
apply: (_, __, args) => {
this.logger.info("getResponseHeader", args[0]);
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
this.logger.info("headers not received yet, returning null");
return null;
}
const headerValue = response.headers.get(args[0]);
this.logger.info(
'resolved response header "%s" to',
args[0],
headerValue
);
return headerValue;
}
});
this.request.getAllResponseHeaders = new Proxy(
this.request.getAllResponseHeaders,
{
apply: () => {
this.logger.info("getAllResponseHeaders");
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
this.logger.info("headers not received yet, returning empty string");
return "";
}
const headersList = Array.from(response.headers.entries());
const allHeaders = headersList.map(([headerName, headerValue]) => {
return `${headerName}: ${headerValue}`;
}).join("\r\n");
this.logger.info("resolved all response headers to", allHeaders);
return allHeaders;
}
}
);
Object.defineProperties(this.request, {
response: {
enumerable: true,
configurable: false,
get: () => this.response
},
responseText: {
enumerable: true,
configurable: false,
get: () => this.responseText
},
responseXML: {
enumerable: true,
configurable: false,
get: () => this.responseXML
}
});
const totalResponseBodyLength = await getBodyByteLength(response.clone());
this.logger.info("calculated response body length", totalResponseBodyLength);
this.trigger("loadstart", this.request, {
loaded: 0,
total: totalResponseBodyLength
});
this.setReadyState(this.request.HEADERS_RECEIVED);
this.setReadyState(this.request.LOADING);
const finalizeResponse = () => {
this.logger.info("finalizing the mocked response...");
this.setReadyState(this.request.DONE);
this.trigger("load", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
this.trigger("loadend", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
};
if (response.body) {
this.logger.info("mocked response has body, streaming...");
const reader = response.body.getReader();
const readNextResponseBodyChunk = async () => {
const { value, done } = await reader.read();
if (done) {
this.logger.info("response body stream done!");
finalizeResponse();
return;
}
if (value) {
this.logger.info("read response body chunk:", value);
this.responseBuffer = concatArrayBuffer(this.responseBuffer, value);
this.trigger("progress", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
}
readNextResponseBodyChunk();
};
readNextResponseBodyChunk();
} else {
finalizeResponse();
}
}
responseBufferToText() {
return _chunkLK6DILFKjs.decodeBuffer.call(void 0, this.responseBuffer);
}
get response() {
this.logger.info(
"getResponse (responseType: %s)",
this.request.responseType
);
if (this.request.readyState !== this.request.DONE) {
return null;
}
switch (this.request.responseType) {
case "json": {
const responseJson = parseJson(this.responseBufferToText());
this.logger.info("resolved response JSON", responseJson);
return responseJson;
}
case "arraybuffer": {
const arrayBuffer = _chunkLK6DILFKjs.toArrayBuffer.call(void 0, this.responseBuffer);
this.logger.info("resolved response ArrayBuffer", arrayBuffer);
return arrayBuffer;
}
case "blob": {
const mimeType = this.request.getResponseHeader("Content-Type") || "text/plain";
const responseBlob = new Blob([this.responseBufferToText()], {
type: mimeType
});
this.logger.info(
"resolved response Blob (mime type: %s)",
responseBlob,
mimeType
);
return responseBlob;
}
default: {
const responseText = this.responseBufferToText();
this.logger.info(
'resolving "%s" response type as text',
this.request.responseType,
responseText
);
return responseText;
}
}
}
get responseText() {
_outvariant.invariant.call(void 0,
this.request.responseType === "" || this.request.responseType === "text",
"InvalidStateError: The object is in invalid state."
);
if (this.request.readyState !== this.request.LOADING && this.request.readyState !== this.request.DONE) {
return "";
}
const responseText = this.responseBufferToText();
this.logger.info('getResponseText: "%s"', responseText);
return responseText;
}
get responseXML() {
_outvariant.invariant.call(void 0,
this.request.responseType === "" || this.request.responseType === "document",
"InvalidStateError: The object is in invalid state."
);
if (this.request.readyState !== this.request.DONE) {
return null;
}
const contentType = this.request.getResponseHeader("Content-Type") || "";
if (typeof DOMParser === "undefined") {
console.warn(
"Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly."
);
return null;
}
if (isDomParserSupportedType(contentType)) {
return new DOMParser().parseFromString(
this.responseBufferToText(),
contentType
);
}
return null;
}
errorWith(error) {
this[kIsRequestHandled] = true;
this.logger.info("responding with an error");
this.setReadyState(this.request.DONE);
this.trigger("error", this.request);
this.trigger("loadend", this.request);
}
/**
* Transitions this request's `readyState` to the given one.
*/
setReadyState(nextReadyState) {
this.logger.info(
"setReadyState: %d -> %d",
this.request.readyState,
nextReadyState
);
if (this.request.readyState === nextReadyState) {
this.logger.info("ready state identical, skipping transition...");
return;
}
define(this.request, "readyState", nextReadyState);
this.logger.info("set readyState to: %d", nextReadyState);
if (nextReadyState !== this.request.UNSENT) {
this.logger.info('triggerring "readystatechange" event...');
this.trigger("readystatechange", this.request);
}
}
/**
* Triggers given event on the `XMLHttpRequest` instance.
*/
trigger(eventName, target, options) {
const callback = target[`on${eventName}`];
const event = createEvent(target, eventName, options);
this.logger.info('trigger "%s"', eventName, options || "");
if (typeof callback === "function") {
this.logger.info('found a direct "%s" callback, calling...', eventName);
callback.call(target, event);
}
const events = target instanceof XMLHttpRequestUpload ? this.uploadEvents : this.events;
for (const [registeredEventName, listeners] of events) {
if (registeredEventName === eventName) {
this.logger.info(
'found %d listener(s) for "%s" event, calling...',
listeners.length,
eventName
);
listeners.forEach((listener) => listener.call(target, event));
}
}
}
/**
* Converts this `XMLHttpRequest` instance into a Fetch API `Request` instance.
*/
toFetchApiRequest(body) {
this.logger.info("converting request to a Fetch API Request...");
const resolvedBody = body instanceof Document ? body.documentElement.innerText : body;
const fetchRequest = new Request(this.url.href, {
method: this.method,
headers: this.requestHeaders,
/**
* @see https://xhr.spec.whatwg.org/#cross-origin-credentials
*/
credentials: this.request.withCredentials ? "include" : "same-origin",
body: ["GET", "HEAD"].includes(this.method.toUpperCase()) ? null : resolvedBody
});
const proxyHeaders = createProxy(fetchRequest.headers, {
methodCall: ([methodName, args], invoke) => {
switch (methodName) {
case "append":
case "set": {
const [headerName, headerValue] = args;
this.request.setRequestHeader(headerName, headerValue);
break;
}
case "delete": {
const [headerName] = args;
console.warn(
`XMLHttpRequest: Cannot remove a "${headerName}" header from the Fetch API representation of the "${fetchRequest.method} ${fetchRequest.url}" request. XMLHttpRequest headers cannot be removed.`
);
break;
}
}
return invoke();
}
});
define(fetchRequest, "headers", proxyHeaders);
this.logger.info("converted request to a Fetch API Request!", fetchRequest);
return fetchRequest;
}
};
kIsRequestHandled, kFetchRequest;
function toAbsoluteUrl(url) {
if (typeof location === "undefined") {
return new URL(url);
}
return new URL(url.toString(), location.href);
}
function define(target, property, value) {
Reflect.defineProperty(target, property, {
// Ensure writable properties to allow redefining readonly properties.
writable: true,
enumerable: true,
value
});
}
// src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
function createXMLHttpRequestProxy({
emitter,
logger
}) {
const XMLHttpRequestProxy = new Proxy(globalThis.XMLHttpRequest, {
construct(target, args, newTarget) {
logger.info("constructed new XMLHttpRequest");
const originalRequest = Reflect.construct(
target,
args,
newTarget
);
const prototypeDescriptors = Object.getOwnPropertyDescriptors(
target.prototype
);
for (const propertyName in prototypeDescriptors) {
Reflect.defineProperty(
originalRequest,
propertyName,
prototypeDescriptors[propertyName]
);
}
const xhrRequestController = new XMLHttpRequestController(
originalRequest,
logger
);
xhrRequestController.onRequest = async function({ request, requestId }) {
const controller = new (0, _chunkFGSEOIC4js.RequestController)(request);
this.logger.info("awaiting mocked response...");
this.logger.info(
'emitting the "request" event for %s listener(s)...',
emitter.listenerCount("request")
);
const isRequestHandled = await _chunkFGSEOIC4js.handleRequest.call(void 0, {
request,
requestId,
controller,
emitter,
onResponse: async (response) => {
await this.respondWith(response);
},
onRequestError: () => {
this.errorWith(new TypeError("Network error"));
},
onError: (error) => {
this.logger.info("request errored!", { error });
if (error instanceof Error) {
this.errorWith(error);
}
}
});
if (!isRequestHandled) {
this.logger.info(
"no mocked response received, performing request as-is..."
);
}
};
xhrRequestController.onResponse = async function({
response,
isMockedResponse,
request,
requestId
}) {
this.logger.info(
'emitting the "response" event for %s listener(s)...',
emitter.listenerCount("response")
);
emitter.emit("response", {
response,
isMockedResponse,
request,
requestId
});
};
return xhrRequestController.request;
}
});
return XMLHttpRequestProxy;
}
// src/interceptors/XMLHttpRequest/index.ts
var _XMLHttpRequestInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
constructor() {
super(_XMLHttpRequestInterceptor.interceptorSymbol);
}
checkEnvironment() {
return _chunkPFGO5BSMjs.hasConfigurableGlobal.call(void 0, "XMLHttpRequest");
}
setup() {
const logger = this.logger.extend("setup");
logger.info('patching "XMLHttpRequest" module...');
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
_outvariant.invariant.call(void 0,
!PureXMLHttpRequest[_chunkBC2BLJQNjs.IS_PATCHED_MODULE],
'Failed to patch the "XMLHttpRequest" module: already patched.'
);
globalThis.XMLHttpRequest = createXMLHttpRequestProxy({
emitter: this.emitter,
logger: this.logger
});
logger.info(
'native "XMLHttpRequest" module patched!',
globalThis.XMLHttpRequest.name
);
Object.defineProperty(globalThis.XMLHttpRequest, _chunkBC2BLJQNjs.IS_PATCHED_MODULE, {
enumerable: true,
configurable: true,
value: true
});
this.subscriptions.push(() => {
Object.defineProperty(globalThis.XMLHttpRequest, _chunkBC2BLJQNjs.IS_PATCHED_MODULE, {
value: void 0
});
globalThis.XMLHttpRequest = PureXMLHttpRequest;
logger.info(
'native "XMLHttpRequest" module restored!',
globalThis.XMLHttpRequest.name
);
});
}
};
var XMLHttpRequestInterceptor = _XMLHttpRequestInterceptor;
XMLHttpRequestInterceptor.interceptorSymbol = Symbol("xhr");
exports.XMLHttpRequestInterceptor = XMLHttpRequestInterceptor;
//# sourceMappingURL=chunk-ZIT2QX7D.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,67 @@
import { DeferredPromise } from '@open-draft/deferred-promise';
declare const kRequestHandled: unique symbol;
declare const kResponsePromise: unique symbol;
declare class RequestController {
private request;
/**
* Internal response promise.
* Available only for the library internals to grab the
* response instance provided by the developer.
* @note This promise cannot be rejected. It's either infinitely
* pending or resolved with whichever Response was passed to `respondWith()`.
*/
[kResponsePromise]: DeferredPromise<Response | Error | undefined>;
/**
* Internal flag indicating if this request has been handled.
* @note The response promise becomes "fulfilled" on the next tick.
*/
[kRequestHandled]: boolean;
constructor(request: Request);
/**
* Respond to this request with the given `Response` instance.
* @example
* controller.respondWith(new Response())
* controller.respondWith(Response.json({ id }))
* controller.respondWith(Response.error())
*/
respondWith(response: Response): void;
/**
* Error this request with the given error.
* @example
* controller.errorWith()
* controller.errorWith(new Error('Oops!'))
*/
errorWith(error?: Error): void;
}
declare const IS_PATCHED_MODULE: unique symbol;
type RequestCredentials = 'omit' | 'include' | 'same-origin';
type HttpRequestEventMap = {
request: [
args: {
request: Request;
requestId: string;
controller: RequestController;
}
];
response: [
args: {
response: Response;
isMockedResponse: boolean;
request: Request;
requestId: string;
}
];
unhandledException: [
args: {
error: unknown;
request: Request;
requestId: string;
controller: RequestController;
}
];
};
export { HttpRequestEventMap as H, IS_PATCHED_MODULE as I, RequestController as R, RequestCredentials as a };

View file

@ -0,0 +1,69 @@
export { H as HttpRequestEventMap, I as IS_PATCHED_MODULE, R as RequestController, a as RequestCredentials } from './glossary-6564c252.js';
import { I as Interceptor, E as ExtractEventNames } from './Interceptor-af98b768.js';
export { c as INTERNAL_REQUEST_ID_HEADER_NAME, a as InterceptorEventMap, e as InterceptorReadyState, b as InterceptorSubscription, d as deleteGlobalSymbol, g as getGlobalSymbol } from './Interceptor-af98b768.js';
import { EventMap, Listener } from 'strict-event-emitter';
import '@open-draft/deferred-promise';
import '@open-draft/logger';
interface BatchInterceptorOptions<InterceptorList extends ReadonlyArray<Interceptor<any>>> {
name: string;
interceptors: InterceptorList;
}
type ExtractEventMapType<InterceptorList extends ReadonlyArray<Interceptor<any>>> = InterceptorList extends ReadonlyArray<infer InterceptorType> ? InterceptorType extends Interceptor<infer EventMap> ? EventMap : never : never;
/**
* A batch interceptor that exposes a single interface
* to apply and operate with multiple interceptors at once.
*/
declare class BatchInterceptor<InterceptorList extends ReadonlyArray<Interceptor<any>>, Events extends EventMap = ExtractEventMapType<InterceptorList>> extends Interceptor<Events> {
static symbol: symbol;
private interceptors;
constructor(options: BatchInterceptorOptions<InterceptorList>);
protected setup(): void;
on<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
once<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
off<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
removeAllListeners<EventName extends ExtractEventNames<Events>>(event?: EventName | undefined): this;
}
/**
* Generate a random ID string to represent a request.
* @example
* createRequestId()
* // "f774b6c9c600f"
*/
declare function createRequestId(): string;
/**
* Removes query parameters and hashes from a given URL.
*/
declare function getCleanUrl(url: URL, isAbsolute?: boolean): string;
declare function encodeBuffer(text: string): Uint8Array;
declare function decodeBuffer(buffer: ArrayBuffer, encoding?: string): string;
interface FetchResponseInit extends ResponseInit {
url?: string;
}
declare class FetchResponse extends Response {
/**
* Response status codes for responses that cannot have body.
* @see https://fetch.spec.whatwg.org/#statuses
*/
static readonly STATUS_CODES_WITHOUT_BODY: number[];
static readonly STATUS_CODES_WITH_REDIRECT: number[];
static isConfigurableStatusCode(status: number): boolean;
static isRedirectResponse(status: number): boolean;
/**
* Returns a boolean indicating whether the given response status
* code represents a response that can have a body.
*/
static isResponseWithBody(status: number): boolean;
static setUrl(url: string | undefined, response: Response): void;
/**
* Parses the given raw HTTP headers into a Fetch API `Headers` instance.
*/
static parseRawHeaders(rawHeaders: Array<string>): Headers;
constructor(body?: BodyInit | null, init?: FetchResponseInit);
}
export { BatchInterceptor, BatchInterceptorOptions, ExtractEventMapType, ExtractEventNames, FetchResponse, Interceptor, createRequestId, decodeBuffer, encodeBuffer, getCleanUrl };

79
node_modules/@mswjs/interceptors/lib/browser/index.js generated vendored Normal file
View file

@ -0,0 +1,79 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _chunkLK6DILFKjs = require('./chunk-LK6DILFK.js');
var _chunkBC2BLJQNjs = require('./chunk-BC2BLJQN.js');
var _chunkTIPR373Rjs = require('./chunk-TIPR373R.js');
// src/BatchInterceptor.ts
var BatchInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
constructor(options) {
BatchInterceptor.symbol = Symbol(options.name);
super(BatchInterceptor.symbol);
this.interceptors = options.interceptors;
}
setup() {
const logger = this.logger.extend("setup");
logger.info("applying all %d interceptors...", this.interceptors.length);
for (const interceptor of this.interceptors) {
logger.info('applying "%s" interceptor...', interceptor.constructor.name);
interceptor.apply();
logger.info("adding interceptor dispose subscription");
this.subscriptions.push(() => interceptor.dispose());
}
}
on(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.on(event, listener);
}
return this;
}
once(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.once(event, listener);
}
return this;
}
off(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.off(event, listener);
}
return this;
}
removeAllListeners(event) {
for (const interceptors of this.interceptors) {
interceptors.removeAllListeners(event);
}
return this;
}
};
// src/utils/getCleanUrl.ts
function getCleanUrl(url, isAbsolute = true) {
return [isAbsolute && url.origin, url.pathname].filter(Boolean).join("");
}
exports.BatchInterceptor = BatchInterceptor; exports.FetchResponse = _chunkBC2BLJQNjs.FetchResponse; exports.INTERNAL_REQUEST_ID_HEADER_NAME = _chunkTIPR373Rjs.INTERNAL_REQUEST_ID_HEADER_NAME; exports.IS_PATCHED_MODULE = _chunkBC2BLJQNjs.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;
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../../src/BatchInterceptor.ts","../../src/utils/getCleanUrl.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBO,IAAM,mBAAN,cAGG,YAAoB;AAAA,EAK5B,YAAY,SAAmD;AAC7D,qBAAiB,SAAS,OAAO,QAAQ,IAAI;AAC7C,UAAM,iBAAiB,MAAM;AAC7B,SAAK,eAAe,QAAQ;AAAA,EAC9B;AAAA,EAEU,QAAQ;AAChB,UAAM,SAAS,KAAK,OAAO,OAAO,OAAO;AAEzC,WAAO,KAAK,mCAAmC,KAAK,aAAa,MAAM;AAEvE,eAAW,eAAe,KAAK,cAAc;AAC3C,aAAO,KAAK,gCAAgC,YAAY,YAAY,IAAI;AACxE,kBAAY,MAAM;AAElB,aAAO,KAAK,yCAAyC;AACrD,WAAK,cAAc,KAAK,MAAM,YAAY,QAAQ,CAAC;AAAA,IACrD;AAAA,EACF;AAAA,EAEO,GACL,OACA,UACM;AAGN,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,GAAG,OAAO,QAAQ;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,KACL,OACA,UACM;AACN,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,KAAK,OAAO,QAAQ;AAAA,IAClC;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,IACL,OACA,UACM;AACN,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,IAAI,OAAO,QAAQ;AAAA,IACjC;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,mBACL,OACM;AACN,eAAW,gBAAgB,KAAK,cAAc;AAC5C,mBAAa,mBAAmB,KAAK;AAAA,IACvC;AAEA,WAAO;AAAA,EACT;AACF;;;AC3FO,SAAS,YAAY,KAAU,aAAsB,MAAc;AACxE,SAAO,CAAC,cAAc,IAAI,QAAQ,IAAI,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE;AACzE","sourcesContent":["import { EventMap, Listener } from 'strict-event-emitter'\nimport { Interceptor, ExtractEventNames } from './Interceptor'\n\nexport interface BatchInterceptorOptions<\n InterceptorList extends ReadonlyArray<Interceptor<any>>\n> {\n name: string\n interceptors: InterceptorList\n}\n\nexport type ExtractEventMapType<\n InterceptorList extends ReadonlyArray<Interceptor<any>>\n> = InterceptorList extends ReadonlyArray<infer InterceptorType>\n ? InterceptorType extends Interceptor<infer EventMap>\n ? EventMap\n : never\n : never\n\n/**\n * A batch interceptor that exposes a single interface\n * to apply and operate with multiple interceptors at once.\n */\nexport class BatchInterceptor<\n InterceptorList extends ReadonlyArray<Interceptor<any>>,\n Events extends EventMap = ExtractEventMapType<InterceptorList>\n> extends Interceptor<Events> {\n static symbol: symbol\n\n private interceptors: InterceptorList\n\n constructor(options: BatchInterceptorOptions<InterceptorList>) {\n BatchInterceptor.symbol = Symbol(options.name)\n super(BatchInterceptor.symbol)\n this.interceptors = options.interceptors\n }\n\n protected setup() {\n const logger = this.logger.extend('setup')\n\n logger.info('applying all %d interceptors...', this.interceptors.length)\n\n for (const interceptor of this.interceptors) {\n logger.info('applying \"%s\" interceptor...', interceptor.constructor.name)\n interceptor.apply()\n\n logger.info('adding interceptor dispose subscription')\n this.subscriptions.push(() => interceptor.dispose())\n }\n }\n\n public on<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n // Instead of adding a listener to the batch interceptor,\n // propagate the listener to each of the individual interceptors.\n for (const interceptor of this.interceptors) {\n interceptor.on(event, listener)\n }\n\n return this\n }\n\n public once<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n for (const interceptor of this.interceptors) {\n interceptor.once(event, listener)\n }\n\n return this\n }\n\n public off<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n for (const interceptor of this.interceptors) {\n interceptor.off(event, listener)\n }\n\n return this\n }\n\n public removeAllListeners<EventName extends ExtractEventNames<Events>>(\n event?: EventName | undefined\n ): this {\n for (const interceptors of this.interceptors) {\n interceptors.removeAllListeners(event)\n }\n\n return this\n }\n}\n","/**\n * Removes query parameters and hashes from a given URL.\n */\nexport function getCleanUrl(url: URL, isAbsolute: boolean = true): string {\n return [isAbsolute && url.origin, url.pathname].filter(Boolean).join('')\n}\n"]}

79
node_modules/@mswjs/interceptors/lib/browser/index.mjs generated vendored Normal file
View file

@ -0,0 +1,79 @@
import {
decodeBuffer,
encodeBuffer
} from "./chunk-6HYIRFX2.mjs";
import {
FetchResponse,
IS_PATCHED_MODULE
} from "./chunk-5UK33FSU.mjs";
import {
INTERNAL_REQUEST_ID_HEADER_NAME,
Interceptor,
InterceptorReadyState,
createRequestId,
deleteGlobalSymbol,
getGlobalSymbol
} from "./chunk-QED3Q6Z2.mjs";
// src/BatchInterceptor.ts
var BatchInterceptor = class extends Interceptor {
constructor(options) {
BatchInterceptor.symbol = Symbol(options.name);
super(BatchInterceptor.symbol);
this.interceptors = options.interceptors;
}
setup() {
const logger = this.logger.extend("setup");
logger.info("applying all %d interceptors...", this.interceptors.length);
for (const interceptor of this.interceptors) {
logger.info('applying "%s" interceptor...', interceptor.constructor.name);
interceptor.apply();
logger.info("adding interceptor dispose subscription");
this.subscriptions.push(() => interceptor.dispose());
}
}
on(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.on(event, listener);
}
return this;
}
once(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.once(event, listener);
}
return this;
}
off(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.off(event, listener);
}
return this;
}
removeAllListeners(event) {
for (const interceptors of this.interceptors) {
interceptors.removeAllListeners(event);
}
return this;
}
};
// src/utils/getCleanUrl.ts
function getCleanUrl(url, isAbsolute = true) {
return [isAbsolute && url.origin, url.pathname].filter(Boolean).join("");
}
export {
BatchInterceptor,
FetchResponse,
INTERNAL_REQUEST_ID_HEADER_NAME,
IS_PATCHED_MODULE,
Interceptor,
InterceptorReadyState,
createRequestId,
decodeBuffer,
deleteGlobalSymbol,
encodeBuffer,
getCleanUrl,
getGlobalSymbol
};
//# sourceMappingURL=index.mjs.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../../src/BatchInterceptor.ts","../../src/utils/getCleanUrl.ts"],"sourcesContent":["import { EventMap, Listener } from 'strict-event-emitter'\nimport { Interceptor, ExtractEventNames } from './Interceptor'\n\nexport interface BatchInterceptorOptions<\n InterceptorList extends ReadonlyArray<Interceptor<any>>\n> {\n name: string\n interceptors: InterceptorList\n}\n\nexport type ExtractEventMapType<\n InterceptorList extends ReadonlyArray<Interceptor<any>>\n> = InterceptorList extends ReadonlyArray<infer InterceptorType>\n ? InterceptorType extends Interceptor<infer EventMap>\n ? EventMap\n : never\n : never\n\n/**\n * A batch interceptor that exposes a single interface\n * to apply and operate with multiple interceptors at once.\n */\nexport class BatchInterceptor<\n InterceptorList extends ReadonlyArray<Interceptor<any>>,\n Events extends EventMap = ExtractEventMapType<InterceptorList>\n> extends Interceptor<Events> {\n static symbol: symbol\n\n private interceptors: InterceptorList\n\n constructor(options: BatchInterceptorOptions<InterceptorList>) {\n BatchInterceptor.symbol = Symbol(options.name)\n super(BatchInterceptor.symbol)\n this.interceptors = options.interceptors\n }\n\n protected setup() {\n const logger = this.logger.extend('setup')\n\n logger.info('applying all %d interceptors...', this.interceptors.length)\n\n for (const interceptor of this.interceptors) {\n logger.info('applying \"%s\" interceptor...', interceptor.constructor.name)\n interceptor.apply()\n\n logger.info('adding interceptor dispose subscription')\n this.subscriptions.push(() => interceptor.dispose())\n }\n }\n\n public on<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n // Instead of adding a listener to the batch interceptor,\n // propagate the listener to each of the individual interceptors.\n for (const interceptor of this.interceptors) {\n interceptor.on(event, listener)\n }\n\n return this\n }\n\n public once<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n for (const interceptor of this.interceptors) {\n interceptor.once(event, listener)\n }\n\n return this\n }\n\n public off<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n for (const interceptor of this.interceptors) {\n interceptor.off(event, listener)\n }\n\n return this\n }\n\n public removeAllListeners<EventName extends ExtractEventNames<Events>>(\n event?: EventName | undefined\n ): this {\n for (const interceptors of this.interceptors) {\n interceptors.removeAllListeners(event)\n }\n\n return this\n }\n}\n","/**\n * Removes query parameters and hashes from a given URL.\n */\nexport function getCleanUrl(url: URL, isAbsolute: boolean = true): string {\n return [isAbsolute && url.origin, url.pathname].filter(Boolean).join('')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsBO,IAAM,mBAAN,cAGG,YAAoB;AAAA,EAK5B,YAAY,SAAmD;AAC7D,qBAAiB,SAAS,OAAO,QAAQ,IAAI;AAC7C,UAAM,iBAAiB,MAAM;AAC7B,SAAK,eAAe,QAAQ;AAAA,EAC9B;AAAA,EAEU,QAAQ;AAChB,UAAM,SAAS,KAAK,OAAO,OAAO,OAAO;AAEzC,WAAO,KAAK,mCAAmC,KAAK,aAAa,MAAM;AAEvE,eAAW,eAAe,KAAK,cAAc;AAC3C,aAAO,KAAK,gCAAgC,YAAY,YAAY,IAAI;AACxE,kBAAY,MAAM;AAElB,aAAO,KAAK,yCAAyC;AACrD,WAAK,cAAc,KAAK,MAAM,YAAY,QAAQ,CAAC;AAAA,IACrD;AAAA,EACF;AAAA,EAEO,GACL,OACA,UACM;AAGN,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,GAAG,OAAO,QAAQ;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,KACL,OACA,UACM;AACN,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,KAAK,OAAO,QAAQ;AAAA,IAClC;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,IACL,OACA,UACM;AACN,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,IAAI,OAAO,QAAQ;AAAA,IACjC;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,mBACL,OACM;AACN,eAAW,gBAAgB,KAAK,cAAc;AAC5C,mBAAa,mBAAmB,KAAK;AAAA,IACvC;AAEA,WAAO;AAAA,EACT;AACF;;;AC3FO,SAAS,YAAY,KAAU,aAAsB,MAAc;AACxE,SAAO,CAAC,cAAc,IAAI,QAAQ,IAAI,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE;AACzE;","names":[]}

View file

@ -0,0 +1,233 @@
import { I as Interceptor } from '../../Interceptor-af98b768.js';
import '@open-draft/logger';
import 'strict-event-emitter';
interface CloseEventInit extends EventInit {
code?: number;
reason?: string;
wasClean?: boolean;
}
declare class CloseEvent extends Event {
code: number;
reason: string;
wasClean: boolean;
constructor(type: string, init?: CloseEventInit);
}
type WebSocketData = string | ArrayBufferLike | Blob | ArrayBufferView;
type WebSocketTransportEventMap = {
incoming: MessageEvent<WebSocketData>;
outgoing: MessageEvent<WebSocketData>;
close: CloseEvent;
};
type StrictEventListenerOrEventListenerObject<EventType extends Event> = ((this: WebSocket, event: EventType) => void) | {
handleEvent(this: WebSocket, event: EventType): void;
};
interface WebSocketTransport {
addEventListener<EventType extends keyof WebSocketTransportEventMap>(event: EventType, listener: StrictEventListenerOrEventListenerObject<WebSocketTransportEventMap[EventType]> | null, options?: boolean | AddEventListenerOptions): void;
dispatchEvent<EventType extends keyof WebSocketTransportEventMap>(event: WebSocketTransportEventMap[EventType]): boolean;
/**
* Send the data from the server to this client.
*/
send(data: WebSocketData): void;
/**
* Close the client connection.
*/
close(code?: number, reason?: string): void;
}
type WebSocketEventListener<EventType extends WebSocketEventMap[keyof WebSocketEventMap] = Event> = (this: WebSocket, event: EventType) => void;
declare const kPassthroughPromise: unique symbol;
declare const kOnSend: unique symbol;
declare const kClose: unique symbol;
declare class WebSocketOverride extends EventTarget implements WebSocket {
static readonly CONNECTING = 0;
static readonly OPEN = 1;
static readonly CLOSING = 2;
static readonly CLOSED = 3;
readonly CONNECTING = 0;
readonly OPEN = 1;
readonly CLOSING = 2;
readonly CLOSED = 3;
url: string;
protocol: string;
extensions: string;
binaryType: BinaryType;
readyState: number;
bufferedAmount: number;
private _onopen;
private _onmessage;
private _onerror;
private _onclose;
private [kPassthroughPromise];
private [kOnSend]?;
constructor(url: string | URL, protocols?: string | Array<string>);
set onopen(listener: WebSocketEventListener | null);
get onopen(): WebSocketEventListener | null;
set onmessage(listener: WebSocketEventListener<MessageEvent<WebSocketData>> | null);
get onmessage(): WebSocketEventListener<MessageEvent<WebSocketData>> | null;
set onerror(listener: WebSocketEventListener | null);
get onerror(): WebSocketEventListener | null;
set onclose(listener: WebSocketEventListener<CloseEvent> | null);
get onclose(): WebSocketEventListener<CloseEvent> | null;
/**
* @see https://websockets.spec.whatwg.org/#ref-for-dom-websocket-send%E2%91%A0
*/
send(data: WebSocketData): void;
close(code?: number, reason?: string): void;
private [kClose];
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, event: WebSocketEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof WebSocketEventMap>(type: K, callback: EventListenerOrEventListenerObject | null, options?: boolean | EventListenerOptions): void;
}
declare const kEmitter$1: unique symbol;
interface WebSocketClientEventMap {
message: MessageEvent<WebSocketData>;
close: CloseEvent;
}
interface WebSocketClientConnectionProtocol {
id: string;
url: URL;
send(data: WebSocketData): void;
close(code?: number, reason?: string): void;
}
/**
* The WebSocket client instance represents an incoming
* client connection. The user can control the connection,
* send and receive events.
*/
declare class WebSocketClientConnection implements WebSocketClientConnectionProtocol {
readonly socket: WebSocket;
private readonly transport;
readonly id: string;
readonly url: URL;
private [kEmitter$1];
constructor(socket: WebSocket, transport: WebSocketTransport);
/**
* Listen for the outgoing events from the connected WebSocket client.
*/
addEventListener<EventType extends keyof WebSocketClientEventMap>(type: EventType, listener: WebSocketEventListener<WebSocketClientEventMap[EventType]>, options?: AddEventListenerOptions | boolean): void;
/**
* Removes the listener for the given event.
*/
removeEventListener<EventType extends keyof WebSocketClientEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketClientEventMap[EventType]>, options?: EventListenerOptions | boolean): void;
/**
* Send data to the connected client.
*/
send(data: WebSocketData): void;
/**
* Close the WebSocket connection.
* @param {number} code A status code (see https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1).
* @param {string} reason A custom connection close reason.
*/
close(code?: number, reason?: string): void;
}
/**
* Abstraction over the given mock `WebSocket` instance that allows
* for controlling that instance (e.g. sending and receiving messages).
*/
declare class WebSocketClassTransport extends EventTarget implements WebSocketTransport {
protected readonly socket: WebSocketOverride;
constructor(socket: WebSocketOverride);
addEventListener<EventType extends keyof WebSocketTransportEventMap>(type: EventType, callback: StrictEventListenerOrEventListenerObject<WebSocketTransportEventMap[EventType]> | null, options?: boolean | AddEventListenerOptions): void;
dispatchEvent<EventType extends keyof WebSocketTransportEventMap>(event: WebSocketTransportEventMap[EventType]): boolean;
send(data: WebSocketData): void;
close(code: number, reason?: string): void;
}
declare const kEmitter: unique symbol;
declare const kSend: unique symbol;
interface WebSocketServerEventMap {
open: Event;
message: MessageEvent<WebSocketData>;
error: Event;
close: CloseEvent;
}
/**
* The WebSocket server instance represents the actual production
* WebSocket server connection. It's idle by default but you can
* establish it by calling `server.connect()`.
*/
declare class WebSocketServerConnection {
private readonly client;
private readonly transport;
private readonly createConnection;
/**
* A WebSocket instance connected to the original server.
*/
private realWebSocket?;
private mockCloseController;
private realCloseController;
private [kEmitter];
constructor(client: WebSocketOverride, transport: WebSocketClassTransport, createConnection: () => WebSocket);
/**
* The `WebSocket` instance connected to the original server.
* Accessing this before calling `server.connect()` will throw.
*/
get socket(): WebSocket;
/**
* Open connection to the original WebSocket server.
*/
connect(): void;
/**
* Listen for the incoming events from the original WebSocket server.
*/
addEventListener<EventType extends keyof WebSocketServerEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketServerEventMap[EventType]>, options?: AddEventListenerOptions | boolean): void;
/**
* Remove the listener for the given event.
*/
removeEventListener<EventType extends keyof WebSocketServerEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketServerEventMap[EventType]>, options?: EventListenerOptions | boolean): void;
/**
* Send data to the original WebSocket server.
* @example
* server.send('hello')
* server.send(new Blob(['hello']))
* server.send(new TextEncoder().encode('hello'))
*/
send(data: WebSocketData): void;
private [kSend];
/**
* Close the actual server connection.
*/
close(): void;
private handleIncomingMessage;
private handleMockClose;
private handleRealClose;
}
type WebSocketEventMap$1 = {
connection: [args: WebSocketConnectionData];
};
type WebSocketConnectionData = {
/**
* The incoming WebSocket client connection.
*/
client: WebSocketClientConnection;
/**
* The original WebSocket server connection.
*/
server: WebSocketServerConnection;
/**
* The connection information.
*/
info: {
/**
* The protocols supported by the WebSocket client.
*/
protocols: string | Array<string> | undefined;
};
};
/**
* Intercept the outgoing WebSocket connections created using
* the global `WebSocket` class.
*/
declare class WebSocketInterceptor extends Interceptor<WebSocketEventMap$1> {
static symbol: symbol;
constructor();
protected checkEnvironment(): boolean;
protected setup(): void;
}
export { WebSocketClientConnection, WebSocketClientConnectionProtocol, WebSocketConnectionData, WebSocketData, WebSocketEventMap$1 as WebSocketEventMap, WebSocketInterceptor, WebSocketServerConnection, WebSocketTransport };

View file

@ -0,0 +1,710 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _chunkPFGO5BSMjs = require('../../chunk-PFGO5BSM.js');
var _chunkTIPR373Rjs = require('../../chunk-TIPR373R.js');
// src/interceptors/WebSocket/utils/bindEvent.ts
function bindEvent(target, event) {
Object.defineProperties(event, {
target: {
value: target,
enumerable: true,
writable: true
},
currentTarget: {
value: target,
enumerable: true,
writable: true
}
});
return event;
}
// src/interceptors/WebSocket/utils/events.ts
var kCancelable = Symbol("kCancelable");
var kDefaultPrevented = Symbol("kDefaultPrevented");
var CancelableMessageEvent = class extends MessageEvent {
constructor(type, init) {
super(type, init);
this[kCancelable] = !!init.cancelable;
this[kDefaultPrevented] = false;
}
get cancelable() {
return this[kCancelable];
}
set cancelable(nextCancelable) {
this[kCancelable] = nextCancelable;
}
get defaultPrevented() {
return this[kDefaultPrevented];
}
set defaultPrevented(nextDefaultPrevented) {
this[kDefaultPrevented] = nextDefaultPrevented;
}
preventDefault() {
if (this.cancelable && !this[kDefaultPrevented]) {
this[kDefaultPrevented] = true;
}
}
};
kCancelable, kDefaultPrevented;
var CloseEvent = class extends Event {
constructor(type, init = {}) {
super(type, init);
this.code = init.code === void 0 ? 0 : init.code;
this.reason = init.reason === void 0 ? "" : init.reason;
this.wasClean = init.wasClean === void 0 ? false : init.wasClean;
}
};
var CancelableCloseEvent = class extends CloseEvent {
constructor(type, init = {}) {
super(type, init);
this[kCancelable] = !!init.cancelable;
this[kDefaultPrevented] = false;
}
get cancelable() {
return this[kCancelable];
}
set cancelable(nextCancelable) {
this[kCancelable] = nextCancelable;
}
get defaultPrevented() {
return this[kDefaultPrevented];
}
set defaultPrevented(nextDefaultPrevented) {
this[kDefaultPrevented] = nextDefaultPrevented;
}
preventDefault() {
if (this.cancelable && !this[kDefaultPrevented]) {
this[kDefaultPrevented] = true;
}
}
};
kCancelable, kDefaultPrevented;
// src/interceptors/WebSocket/WebSocketClientConnection.ts
var kEmitter = Symbol("kEmitter");
var kBoundListener = Symbol("kBoundListener");
var WebSocketClientConnection = class {
constructor(socket, transport) {
this.socket = socket;
this.transport = transport;
this.id = _chunkTIPR373Rjs.createRequestId.call(void 0, );
this.url = new URL(socket.url);
this[kEmitter] = new EventTarget();
this.transport.addEventListener("outgoing", (event) => {
const message = bindEvent(
this.socket,
new CancelableMessageEvent("message", {
data: event.data,
origin: event.origin,
cancelable: true
})
);
this[kEmitter].dispatchEvent(message);
if (message.defaultPrevented) {
event.preventDefault();
}
});
this.transport.addEventListener("close", (event) => {
this[kEmitter].dispatchEvent(
bindEvent(this.socket, new CloseEvent("close", event))
);
});
}
/**
* Listen for the outgoing events from the connected WebSocket client.
*/
addEventListener(type, listener, options) {
if (!Reflect.has(listener, kBoundListener)) {
const boundListener = listener.bind(this.socket);
Object.defineProperty(listener, kBoundListener, {
value: boundListener,
enumerable: false,
configurable: false
});
}
this[kEmitter].addEventListener(
type,
Reflect.get(listener, kBoundListener),
options
);
}
/**
* Removes the listener for the given event.
*/
removeEventListener(event, listener, options) {
this[kEmitter].removeEventListener(
event,
Reflect.get(listener, kBoundListener),
options
);
}
/**
* Send data to the connected client.
*/
send(data) {
this.transport.send(data);
}
/**
* Close the WebSocket connection.
* @param {number} code A status code (see https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1).
* @param {string} reason A custom connection close reason.
*/
close(code, reason) {
this.transport.close(code, reason);
}
};
kEmitter;
// src/interceptors/WebSocket/WebSocketServerConnection.ts
var _outvariant = require('outvariant');
// src/interceptors/WebSocket/WebSocketOverride.ts
var _deferredpromise = require('@open-draft/deferred-promise');
var WEBSOCKET_CLOSE_CODE_RANGE_ERROR = "InvalidAccessError: close code out of user configurable range";
var kPassthroughPromise = Symbol("kPassthroughPromise");
var kOnSend = Symbol("kOnSend");
var kClose = Symbol("kClose");
var WebSocketOverride = class extends EventTarget {
constructor(url, protocols) {
super();
this.CONNECTING = 0;
this.OPEN = 1;
this.CLOSING = 2;
this.CLOSED = 3;
this._onopen = null;
this._onmessage = null;
this._onerror = null;
this._onclose = null;
this.url = url.toString();
this.protocol = "";
this.extensions = "";
this.binaryType = "blob";
this.readyState = this.CONNECTING;
this.bufferedAmount = 0;
this[kPassthroughPromise] = new (0, _deferredpromise.DeferredPromise)();
queueMicrotask(async () => {
if (await this[kPassthroughPromise]) {
return;
}
this.protocol = typeof protocols === "string" ? protocols : Array.isArray(protocols) && protocols.length > 0 ? protocols[0] : "";
if (this.readyState === this.CONNECTING) {
this.readyState = this.OPEN;
this.dispatchEvent(bindEvent(this, new Event("open")));
}
});
}
set onopen(listener) {
this.removeEventListener("open", this._onopen);
this._onopen = listener;
if (listener !== null) {
this.addEventListener("open", listener);
}
}
get onopen() {
return this._onopen;
}
set onmessage(listener) {
this.removeEventListener(
"message",
this._onmessage
);
this._onmessage = listener;
if (listener !== null) {
this.addEventListener("message", listener);
}
}
get onmessage() {
return this._onmessage;
}
set onerror(listener) {
this.removeEventListener("error", this._onerror);
this._onerror = listener;
if (listener !== null) {
this.addEventListener("error", listener);
}
}
get onerror() {
return this._onerror;
}
set onclose(listener) {
this.removeEventListener("close", this._onclose);
this._onclose = listener;
if (listener !== null) {
this.addEventListener("close", listener);
}
}
get onclose() {
return this._onclose;
}
/**
* @see https://websockets.spec.whatwg.org/#ref-for-dom-websocket-send%E2%91%A0
*/
send(data) {
if (this.readyState === this.CONNECTING) {
this.close();
throw new DOMException("InvalidStateError");
}
if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) {
return;
}
this.bufferedAmount += getDataSize(data);
queueMicrotask(() => {
var _a;
this.bufferedAmount = 0;
(_a = this[kOnSend]) == null ? void 0 : _a.call(this, data);
});
}
close(code = 1e3, reason) {
_outvariant.invariant.call(void 0, code, WEBSOCKET_CLOSE_CODE_RANGE_ERROR);
_outvariant.invariant.call(void 0,
code === 1e3 || code >= 3e3 && code <= 4999,
WEBSOCKET_CLOSE_CODE_RANGE_ERROR
);
this[kClose](code, reason);
}
[(kPassthroughPromise, kOnSend, kClose)](code = 1e3, reason, wasClean = true) {
if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) {
return;
}
this.readyState = this.CLOSING;
queueMicrotask(() => {
this.readyState = this.CLOSED;
this.dispatchEvent(
bindEvent(
this,
new CloseEvent("close", {
code,
reason,
wasClean
})
)
);
this._onopen = null;
this._onmessage = null;
this._onerror = null;
this._onclose = null;
});
}
addEventListener(type, listener, options) {
return super.addEventListener(
type,
listener,
options
);
}
removeEventListener(type, callback, options) {
return super.removeEventListener(type, callback, options);
}
};
WebSocketOverride.CONNECTING = 0;
WebSocketOverride.OPEN = 1;
WebSocketOverride.CLOSING = 2;
WebSocketOverride.CLOSED = 3;
function getDataSize(data) {
if (typeof data === "string") {
return data.length;
}
if (data instanceof Blob) {
return data.size;
}
return data.byteLength;
}
// src/interceptors/WebSocket/WebSocketServerConnection.ts
var kEmitter2 = Symbol("kEmitter");
var kBoundListener2 = Symbol("kBoundListener");
var kSend = Symbol("kSend");
var WebSocketServerConnection = class {
constructor(client, transport, createConnection) {
this.client = client;
this.transport = transport;
this.createConnection = createConnection;
this[kEmitter2] = new EventTarget();
this.mockCloseController = new AbortController();
this.realCloseController = new AbortController();
this.transport.addEventListener("outgoing", (event) => {
if (typeof this.realWebSocket === "undefined") {
return;
}
queueMicrotask(() => {
if (!event.defaultPrevented) {
this[kSend](event.data);
}
});
});
this.transport.addEventListener(
"incoming",
this.handleIncomingMessage.bind(this)
);
}
/**
* The `WebSocket` instance connected to the original server.
* Accessing this before calling `server.connect()` will throw.
*/
get socket() {
_outvariant.invariant.call(void 0,
this.realWebSocket,
'Cannot access "socket" on the original WebSocket server object: the connection is not open. Did you forget to call `server.connect()`?'
);
return this.realWebSocket;
}
/**
* Open connection to the original WebSocket server.
*/
connect() {
_outvariant.invariant.call(void 0,
!this.realWebSocket || this.realWebSocket.readyState !== WebSocket.OPEN,
'Failed to call "connect()" on the original WebSocket instance: the connection already open'
);
const realWebSocket = this.createConnection();
realWebSocket.binaryType = this.client.binaryType;
realWebSocket.addEventListener(
"open",
(event) => {
this[kEmitter2].dispatchEvent(
bindEvent(this.realWebSocket, new Event("open", event))
);
},
{ once: true }
);
realWebSocket.addEventListener("message", (event) => {
this.transport.dispatchEvent(
bindEvent(
this.realWebSocket,
new MessageEvent("incoming", {
data: event.data,
origin: event.origin
})
)
);
});
this.client.addEventListener(
"close",
(event) => {
this.handleMockClose(event);
},
{
signal: this.mockCloseController.signal
}
);
realWebSocket.addEventListener(
"close",
(event) => {
this.handleRealClose(event);
},
{
signal: this.realCloseController.signal
}
);
realWebSocket.addEventListener("error", () => {
const errorEvent = bindEvent(
realWebSocket,
new Event("error", { cancelable: true })
);
this[kEmitter2].dispatchEvent(errorEvent);
if (!errorEvent.defaultPrevented) {
this.client.dispatchEvent(bindEvent(this.client, new Event("error")));
}
});
this.realWebSocket = realWebSocket;
}
/**
* Listen for the incoming events from the original WebSocket server.
*/
addEventListener(event, listener, options) {
if (!Reflect.has(listener, kBoundListener2)) {
const boundListener = listener.bind(this.client);
Object.defineProperty(listener, kBoundListener2, {
value: boundListener,
enumerable: false
});
}
this[kEmitter2].addEventListener(
event,
Reflect.get(listener, kBoundListener2),
options
);
}
/**
* Remove the listener for the given event.
*/
removeEventListener(event, listener, options) {
this[kEmitter2].removeEventListener(
event,
Reflect.get(listener, kBoundListener2),
options
);
}
/**
* Send data to the original WebSocket server.
* @example
* server.send('hello')
* server.send(new Blob(['hello']))
* server.send(new TextEncoder().encode('hello'))
*/
send(data) {
this[kSend](data);
}
[(kEmitter2, kSend)](data) {
const { realWebSocket } = this;
_outvariant.invariant.call(void 0,
realWebSocket,
'Failed to call "server.send()" for "%s": the connection is not open. Did you forget to call "server.connect()"?',
this.client.url
);
if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) {
return;
}
if (realWebSocket.readyState === WebSocket.CONNECTING) {
realWebSocket.addEventListener(
"open",
() => {
realWebSocket.send(data);
},
{ once: true }
);
return;
}
realWebSocket.send(data);
}
/**
* Close the actual server connection.
*/
close() {
const { realWebSocket } = this;
_outvariant.invariant.call(void 0,
realWebSocket,
'Failed to close server connection for "%s": the connection is not open. Did you forget to call "server.connect()"?',
this.client.url
);
this.realCloseController.abort();
if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) {
return;
}
realWebSocket.close();
queueMicrotask(() => {
this[kEmitter2].dispatchEvent(
bindEvent(
this.realWebSocket,
new CancelableCloseEvent("close", {
/**
* @note `server.close()` in the interceptor
* always results in clean closures.
*/
code: 1e3,
cancelable: true
})
)
);
});
}
handleIncomingMessage(event) {
const messageEvent = bindEvent(
event.target,
new CancelableMessageEvent("message", {
data: event.data,
origin: event.origin,
cancelable: true
})
);
this[kEmitter2].dispatchEvent(messageEvent);
if (!messageEvent.defaultPrevented) {
this.client.dispatchEvent(
bindEvent(
/**
* @note Bind the forwarded original server events
* to the mock WebSocket instance so it would
* dispatch them straight away.
*/
this.client,
// Clone the message event again to prevent
// the "already being dispatched" exception.
new MessageEvent("message", {
data: event.data,
origin: event.origin
})
)
);
}
}
handleMockClose(_event) {
if (this.realWebSocket) {
this.realWebSocket.close();
}
}
handleRealClose(event) {
this.mockCloseController.abort();
const closeEvent = bindEvent(
this.realWebSocket,
new CancelableCloseEvent("close", {
code: event.code,
reason: event.reason,
wasClean: event.wasClean,
cancelable: true
})
);
this[kEmitter2].dispatchEvent(closeEvent);
if (!closeEvent.defaultPrevented) {
this.client[kClose](event.code, event.reason);
}
}
};
// src/interceptors/WebSocket/WebSocketClassTransport.ts
var WebSocketClassTransport = class extends EventTarget {
constructor(socket) {
super();
this.socket = socket;
this.socket.addEventListener("close", (event) => {
this.dispatchEvent(bindEvent(this.socket, new CloseEvent("close", event)));
});
this.socket[kOnSend] = (data) => {
this.dispatchEvent(
bindEvent(
this.socket,
// Dispatch this as cancelable because "client" connection
// re-creates this message event (cannot dispatch the same event).
new CancelableMessageEvent("outgoing", {
data,
origin: this.socket.url,
cancelable: true
})
)
);
};
}
addEventListener(type, callback, options) {
return super.addEventListener(type, callback, options);
}
dispatchEvent(event) {
return super.dispatchEvent(event);
}
send(data) {
queueMicrotask(() => {
if (this.socket.readyState === this.socket.CLOSING || this.socket.readyState === this.socket.CLOSED) {
return;
}
const dispatchEvent = () => {
this.socket.dispatchEvent(
bindEvent(
/**
* @note Setting this event's "target" to the
* WebSocket override instance is important.
* This way it can tell apart original incoming events
* (must be forwarded to the transport) from the
* mocked message events like the one below
* (must be dispatched on the client instance).
*/
this.socket,
new MessageEvent("message", {
data,
origin: this.socket.url
})
)
);
};
if (this.socket.readyState === this.socket.CONNECTING) {
this.socket.addEventListener(
"open",
() => {
dispatchEvent();
},
{ once: true }
);
} else {
dispatchEvent();
}
});
}
close(code, reason) {
this.socket[kClose](code, reason);
}
};
// src/interceptors/WebSocket/index.ts
var _WebSocketInterceptor = class extends _chunkTIPR373Rjs.Interceptor {
constructor() {
super(_WebSocketInterceptor.symbol);
}
checkEnvironment() {
return _chunkPFGO5BSMjs.hasConfigurableGlobal.call(void 0, "WebSocket");
}
setup() {
const originalWebSocketDescriptor = Object.getOwnPropertyDescriptor(
globalThis,
"WebSocket"
);
const WebSocketProxy = new Proxy(globalThis.WebSocket, {
construct: (target, args, newTarget) => {
const [url, protocols] = args;
const createConnection = () => {
return Reflect.construct(target, args, newTarget);
};
const socket = new WebSocketOverride(url, protocols);
const transport = new WebSocketClassTransport(socket);
queueMicrotask(() => {
try {
const server = new WebSocketServerConnection(
socket,
transport,
createConnection
);
const hasConnectionListeners = this.emitter.emit("connection", {
client: new WebSocketClientConnection(socket, transport),
server,
info: {
protocols
}
});
if (hasConnectionListeners) {
socket[kPassthroughPromise].resolve(false);
} else {
socket[kPassthroughPromise].resolve(true);
server.connect();
server.addEventListener("open", () => {
socket.dispatchEvent(bindEvent(socket, new Event("open")));
if (server["realWebSocket"]) {
socket.protocol = server["realWebSocket"].protocol;
}
});
}
} catch (error) {
if (error instanceof Error) {
socket.dispatchEvent(new Event("error"));
if (socket.readyState !== WebSocket.CLOSING && socket.readyState !== WebSocket.CLOSED) {
socket[kClose](1011, error.message, false);
}
console.error(error);
}
}
});
return socket;
}
});
Object.defineProperty(globalThis, "WebSocket", {
value: WebSocketProxy,
configurable: true
});
this.subscriptions.push(() => {
Object.defineProperty(
globalThis,
"WebSocket",
originalWebSocketDescriptor
);
});
}
};
var WebSocketInterceptor = _WebSocketInterceptor;
WebSocketInterceptor.symbol = Symbol("websocket");
exports.WebSocketClientConnection = WebSocketClientConnection; exports.WebSocketInterceptor = WebSocketInterceptor; exports.WebSocketServerConnection = WebSocketServerConnection;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,710 @@
import {
hasConfigurableGlobal
} from "../../chunk-TX5GBTFY.mjs";
import {
Interceptor,
createRequestId
} from "../../chunk-QED3Q6Z2.mjs";
// src/interceptors/WebSocket/utils/bindEvent.ts
function bindEvent(target, event) {
Object.defineProperties(event, {
target: {
value: target,
enumerable: true,
writable: true
},
currentTarget: {
value: target,
enumerable: true,
writable: true
}
});
return event;
}
// src/interceptors/WebSocket/utils/events.ts
var kCancelable = Symbol("kCancelable");
var kDefaultPrevented = Symbol("kDefaultPrevented");
var CancelableMessageEvent = class extends MessageEvent {
constructor(type, init) {
super(type, init);
this[kCancelable] = !!init.cancelable;
this[kDefaultPrevented] = false;
}
get cancelable() {
return this[kCancelable];
}
set cancelable(nextCancelable) {
this[kCancelable] = nextCancelable;
}
get defaultPrevented() {
return this[kDefaultPrevented];
}
set defaultPrevented(nextDefaultPrevented) {
this[kDefaultPrevented] = nextDefaultPrevented;
}
preventDefault() {
if (this.cancelable && !this[kDefaultPrevented]) {
this[kDefaultPrevented] = true;
}
}
};
kCancelable, kDefaultPrevented;
var CloseEvent = class extends Event {
constructor(type, init = {}) {
super(type, init);
this.code = init.code === void 0 ? 0 : init.code;
this.reason = init.reason === void 0 ? "" : init.reason;
this.wasClean = init.wasClean === void 0 ? false : init.wasClean;
}
};
var CancelableCloseEvent = class extends CloseEvent {
constructor(type, init = {}) {
super(type, init);
this[kCancelable] = !!init.cancelable;
this[kDefaultPrevented] = false;
}
get cancelable() {
return this[kCancelable];
}
set cancelable(nextCancelable) {
this[kCancelable] = nextCancelable;
}
get defaultPrevented() {
return this[kDefaultPrevented];
}
set defaultPrevented(nextDefaultPrevented) {
this[kDefaultPrevented] = nextDefaultPrevented;
}
preventDefault() {
if (this.cancelable && !this[kDefaultPrevented]) {
this[kDefaultPrevented] = true;
}
}
};
kCancelable, kDefaultPrevented;
// src/interceptors/WebSocket/WebSocketClientConnection.ts
var kEmitter = Symbol("kEmitter");
var kBoundListener = Symbol("kBoundListener");
var WebSocketClientConnection = class {
constructor(socket, transport) {
this.socket = socket;
this.transport = transport;
this.id = createRequestId();
this.url = new URL(socket.url);
this[kEmitter] = new EventTarget();
this.transport.addEventListener("outgoing", (event) => {
const message = bindEvent(
this.socket,
new CancelableMessageEvent("message", {
data: event.data,
origin: event.origin,
cancelable: true
})
);
this[kEmitter].dispatchEvent(message);
if (message.defaultPrevented) {
event.preventDefault();
}
});
this.transport.addEventListener("close", (event) => {
this[kEmitter].dispatchEvent(
bindEvent(this.socket, new CloseEvent("close", event))
);
});
}
/**
* Listen for the outgoing events from the connected WebSocket client.
*/
addEventListener(type, listener, options) {
if (!Reflect.has(listener, kBoundListener)) {
const boundListener = listener.bind(this.socket);
Object.defineProperty(listener, kBoundListener, {
value: boundListener,
enumerable: false,
configurable: false
});
}
this[kEmitter].addEventListener(
type,
Reflect.get(listener, kBoundListener),
options
);
}
/**
* Removes the listener for the given event.
*/
removeEventListener(event, listener, options) {
this[kEmitter].removeEventListener(
event,
Reflect.get(listener, kBoundListener),
options
);
}
/**
* Send data to the connected client.
*/
send(data) {
this.transport.send(data);
}
/**
* Close the WebSocket connection.
* @param {number} code A status code (see https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1).
* @param {string} reason A custom connection close reason.
*/
close(code, reason) {
this.transport.close(code, reason);
}
};
kEmitter;
// src/interceptors/WebSocket/WebSocketServerConnection.ts
import { invariant as invariant2 } from "outvariant";
// src/interceptors/WebSocket/WebSocketOverride.ts
import { invariant } from "outvariant";
import { DeferredPromise } from "@open-draft/deferred-promise";
var WEBSOCKET_CLOSE_CODE_RANGE_ERROR = "InvalidAccessError: close code out of user configurable range";
var kPassthroughPromise = Symbol("kPassthroughPromise");
var kOnSend = Symbol("kOnSend");
var kClose = Symbol("kClose");
var WebSocketOverride = class extends EventTarget {
constructor(url, protocols) {
super();
this.CONNECTING = 0;
this.OPEN = 1;
this.CLOSING = 2;
this.CLOSED = 3;
this._onopen = null;
this._onmessage = null;
this._onerror = null;
this._onclose = null;
this.url = url.toString();
this.protocol = "";
this.extensions = "";
this.binaryType = "blob";
this.readyState = this.CONNECTING;
this.bufferedAmount = 0;
this[kPassthroughPromise] = new DeferredPromise();
queueMicrotask(async () => {
if (await this[kPassthroughPromise]) {
return;
}
this.protocol = typeof protocols === "string" ? protocols : Array.isArray(protocols) && protocols.length > 0 ? protocols[0] : "";
if (this.readyState === this.CONNECTING) {
this.readyState = this.OPEN;
this.dispatchEvent(bindEvent(this, new Event("open")));
}
});
}
set onopen(listener) {
this.removeEventListener("open", this._onopen);
this._onopen = listener;
if (listener !== null) {
this.addEventListener("open", listener);
}
}
get onopen() {
return this._onopen;
}
set onmessage(listener) {
this.removeEventListener(
"message",
this._onmessage
);
this._onmessage = listener;
if (listener !== null) {
this.addEventListener("message", listener);
}
}
get onmessage() {
return this._onmessage;
}
set onerror(listener) {
this.removeEventListener("error", this._onerror);
this._onerror = listener;
if (listener !== null) {
this.addEventListener("error", listener);
}
}
get onerror() {
return this._onerror;
}
set onclose(listener) {
this.removeEventListener("close", this._onclose);
this._onclose = listener;
if (listener !== null) {
this.addEventListener("close", listener);
}
}
get onclose() {
return this._onclose;
}
/**
* @see https://websockets.spec.whatwg.org/#ref-for-dom-websocket-send%E2%91%A0
*/
send(data) {
if (this.readyState === this.CONNECTING) {
this.close();
throw new DOMException("InvalidStateError");
}
if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) {
return;
}
this.bufferedAmount += getDataSize(data);
queueMicrotask(() => {
var _a;
this.bufferedAmount = 0;
(_a = this[kOnSend]) == null ? void 0 : _a.call(this, data);
});
}
close(code = 1e3, reason) {
invariant(code, WEBSOCKET_CLOSE_CODE_RANGE_ERROR);
invariant(
code === 1e3 || code >= 3e3 && code <= 4999,
WEBSOCKET_CLOSE_CODE_RANGE_ERROR
);
this[kClose](code, reason);
}
[(kPassthroughPromise, kOnSend, kClose)](code = 1e3, reason, wasClean = true) {
if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) {
return;
}
this.readyState = this.CLOSING;
queueMicrotask(() => {
this.readyState = this.CLOSED;
this.dispatchEvent(
bindEvent(
this,
new CloseEvent("close", {
code,
reason,
wasClean
})
)
);
this._onopen = null;
this._onmessage = null;
this._onerror = null;
this._onclose = null;
});
}
addEventListener(type, listener, options) {
return super.addEventListener(
type,
listener,
options
);
}
removeEventListener(type, callback, options) {
return super.removeEventListener(type, callback, options);
}
};
WebSocketOverride.CONNECTING = 0;
WebSocketOverride.OPEN = 1;
WebSocketOverride.CLOSING = 2;
WebSocketOverride.CLOSED = 3;
function getDataSize(data) {
if (typeof data === "string") {
return data.length;
}
if (data instanceof Blob) {
return data.size;
}
return data.byteLength;
}
// src/interceptors/WebSocket/WebSocketServerConnection.ts
var kEmitter2 = Symbol("kEmitter");
var kBoundListener2 = Symbol("kBoundListener");
var kSend = Symbol("kSend");
var WebSocketServerConnection = class {
constructor(client, transport, createConnection) {
this.client = client;
this.transport = transport;
this.createConnection = createConnection;
this[kEmitter2] = new EventTarget();
this.mockCloseController = new AbortController();
this.realCloseController = new AbortController();
this.transport.addEventListener("outgoing", (event) => {
if (typeof this.realWebSocket === "undefined") {
return;
}
queueMicrotask(() => {
if (!event.defaultPrevented) {
this[kSend](event.data);
}
});
});
this.transport.addEventListener(
"incoming",
this.handleIncomingMessage.bind(this)
);
}
/**
* The `WebSocket` instance connected to the original server.
* Accessing this before calling `server.connect()` will throw.
*/
get socket() {
invariant2(
this.realWebSocket,
'Cannot access "socket" on the original WebSocket server object: the connection is not open. Did you forget to call `server.connect()`?'
);
return this.realWebSocket;
}
/**
* Open connection to the original WebSocket server.
*/
connect() {
invariant2(
!this.realWebSocket || this.realWebSocket.readyState !== WebSocket.OPEN,
'Failed to call "connect()" on the original WebSocket instance: the connection already open'
);
const realWebSocket = this.createConnection();
realWebSocket.binaryType = this.client.binaryType;
realWebSocket.addEventListener(
"open",
(event) => {
this[kEmitter2].dispatchEvent(
bindEvent(this.realWebSocket, new Event("open", event))
);
},
{ once: true }
);
realWebSocket.addEventListener("message", (event) => {
this.transport.dispatchEvent(
bindEvent(
this.realWebSocket,
new MessageEvent("incoming", {
data: event.data,
origin: event.origin
})
)
);
});
this.client.addEventListener(
"close",
(event) => {
this.handleMockClose(event);
},
{
signal: this.mockCloseController.signal
}
);
realWebSocket.addEventListener(
"close",
(event) => {
this.handleRealClose(event);
},
{
signal: this.realCloseController.signal
}
);
realWebSocket.addEventListener("error", () => {
const errorEvent = bindEvent(
realWebSocket,
new Event("error", { cancelable: true })
);
this[kEmitter2].dispatchEvent(errorEvent);
if (!errorEvent.defaultPrevented) {
this.client.dispatchEvent(bindEvent(this.client, new Event("error")));
}
});
this.realWebSocket = realWebSocket;
}
/**
* Listen for the incoming events from the original WebSocket server.
*/
addEventListener(event, listener, options) {
if (!Reflect.has(listener, kBoundListener2)) {
const boundListener = listener.bind(this.client);
Object.defineProperty(listener, kBoundListener2, {
value: boundListener,
enumerable: false
});
}
this[kEmitter2].addEventListener(
event,
Reflect.get(listener, kBoundListener2),
options
);
}
/**
* Remove the listener for the given event.
*/
removeEventListener(event, listener, options) {
this[kEmitter2].removeEventListener(
event,
Reflect.get(listener, kBoundListener2),
options
);
}
/**
* Send data to the original WebSocket server.
* @example
* server.send('hello')
* server.send(new Blob(['hello']))
* server.send(new TextEncoder().encode('hello'))
*/
send(data) {
this[kSend](data);
}
[(kEmitter2, kSend)](data) {
const { realWebSocket } = this;
invariant2(
realWebSocket,
'Failed to call "server.send()" for "%s": the connection is not open. Did you forget to call "server.connect()"?',
this.client.url
);
if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) {
return;
}
if (realWebSocket.readyState === WebSocket.CONNECTING) {
realWebSocket.addEventListener(
"open",
() => {
realWebSocket.send(data);
},
{ once: true }
);
return;
}
realWebSocket.send(data);
}
/**
* Close the actual server connection.
*/
close() {
const { realWebSocket } = this;
invariant2(
realWebSocket,
'Failed to close server connection for "%s": the connection is not open. Did you forget to call "server.connect()"?',
this.client.url
);
this.realCloseController.abort();
if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) {
return;
}
realWebSocket.close();
queueMicrotask(() => {
this[kEmitter2].dispatchEvent(
bindEvent(
this.realWebSocket,
new CancelableCloseEvent("close", {
/**
* @note `server.close()` in the interceptor
* always results in clean closures.
*/
code: 1e3,
cancelable: true
})
)
);
});
}
handleIncomingMessage(event) {
const messageEvent = bindEvent(
event.target,
new CancelableMessageEvent("message", {
data: event.data,
origin: event.origin,
cancelable: true
})
);
this[kEmitter2].dispatchEvent(messageEvent);
if (!messageEvent.defaultPrevented) {
this.client.dispatchEvent(
bindEvent(
/**
* @note Bind the forwarded original server events
* to the mock WebSocket instance so it would
* dispatch them straight away.
*/
this.client,
// Clone the message event again to prevent
// the "already being dispatched" exception.
new MessageEvent("message", {
data: event.data,
origin: event.origin
})
)
);
}
}
handleMockClose(_event) {
if (this.realWebSocket) {
this.realWebSocket.close();
}
}
handleRealClose(event) {
this.mockCloseController.abort();
const closeEvent = bindEvent(
this.realWebSocket,
new CancelableCloseEvent("close", {
code: event.code,
reason: event.reason,
wasClean: event.wasClean,
cancelable: true
})
);
this[kEmitter2].dispatchEvent(closeEvent);
if (!closeEvent.defaultPrevented) {
this.client[kClose](event.code, event.reason);
}
}
};
// src/interceptors/WebSocket/WebSocketClassTransport.ts
var WebSocketClassTransport = class extends EventTarget {
constructor(socket) {
super();
this.socket = socket;
this.socket.addEventListener("close", (event) => {
this.dispatchEvent(bindEvent(this.socket, new CloseEvent("close", event)));
});
this.socket[kOnSend] = (data) => {
this.dispatchEvent(
bindEvent(
this.socket,
// Dispatch this as cancelable because "client" connection
// re-creates this message event (cannot dispatch the same event).
new CancelableMessageEvent("outgoing", {
data,
origin: this.socket.url,
cancelable: true
})
)
);
};
}
addEventListener(type, callback, options) {
return super.addEventListener(type, callback, options);
}
dispatchEvent(event) {
return super.dispatchEvent(event);
}
send(data) {
queueMicrotask(() => {
if (this.socket.readyState === this.socket.CLOSING || this.socket.readyState === this.socket.CLOSED) {
return;
}
const dispatchEvent = () => {
this.socket.dispatchEvent(
bindEvent(
/**
* @note Setting this event's "target" to the
* WebSocket override instance is important.
* This way it can tell apart original incoming events
* (must be forwarded to the transport) from the
* mocked message events like the one below
* (must be dispatched on the client instance).
*/
this.socket,
new MessageEvent("message", {
data,
origin: this.socket.url
})
)
);
};
if (this.socket.readyState === this.socket.CONNECTING) {
this.socket.addEventListener(
"open",
() => {
dispatchEvent();
},
{ once: true }
);
} else {
dispatchEvent();
}
});
}
close(code, reason) {
this.socket[kClose](code, reason);
}
};
// src/interceptors/WebSocket/index.ts
var _WebSocketInterceptor = class extends Interceptor {
constructor() {
super(_WebSocketInterceptor.symbol);
}
checkEnvironment() {
return hasConfigurableGlobal("WebSocket");
}
setup() {
const originalWebSocketDescriptor = Object.getOwnPropertyDescriptor(
globalThis,
"WebSocket"
);
const WebSocketProxy = new Proxy(globalThis.WebSocket, {
construct: (target, args, newTarget) => {
const [url, protocols] = args;
const createConnection = () => {
return Reflect.construct(target, args, newTarget);
};
const socket = new WebSocketOverride(url, protocols);
const transport = new WebSocketClassTransport(socket);
queueMicrotask(() => {
try {
const server = new WebSocketServerConnection(
socket,
transport,
createConnection
);
const hasConnectionListeners = this.emitter.emit("connection", {
client: new WebSocketClientConnection(socket, transport),
server,
info: {
protocols
}
});
if (hasConnectionListeners) {
socket[kPassthroughPromise].resolve(false);
} else {
socket[kPassthroughPromise].resolve(true);
server.connect();
server.addEventListener("open", () => {
socket.dispatchEvent(bindEvent(socket, new Event("open")));
if (server["realWebSocket"]) {
socket.protocol = server["realWebSocket"].protocol;
}
});
}
} catch (error) {
if (error instanceof Error) {
socket.dispatchEvent(new Event("error"));
if (socket.readyState !== WebSocket.CLOSING && socket.readyState !== WebSocket.CLOSED) {
socket[kClose](1011, error.message, false);
}
console.error(error);
}
}
});
return socket;
}
});
Object.defineProperty(globalThis, "WebSocket", {
value: WebSocketProxy,
configurable: true
});
this.subscriptions.push(() => {
Object.defineProperty(
globalThis,
"WebSocket",
originalWebSocketDescriptor
);
});
}
};
var WebSocketInterceptor = _WebSocketInterceptor;
WebSocketInterceptor.symbol = Symbol("websocket");
export {
WebSocketClientConnection,
WebSocketInterceptor,
WebSocketServerConnection
};
//# sourceMappingURL=index.mjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,15 @@
import { Emitter } from 'strict-event-emitter';
import { H as HttpRequestEventMap } from '../../glossary-6564c252.js';
import { I as Interceptor } from '../../Interceptor-af98b768.js';
import '@open-draft/deferred-promise';
import '@open-draft/logger';
type XMLHttpRequestEmitter = Emitter<HttpRequestEventMap>;
declare class XMLHttpRequestInterceptor extends Interceptor<HttpRequestEventMap> {
static interceptorSymbol: symbol;
constructor();
protected checkEnvironment(): boolean;
protected setup(): void;
}
export { XMLHttpRequestEmitter, XMLHttpRequestInterceptor };

View file

@ -0,0 +1,12 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _chunkZIT2QX7Djs = require('../../chunk-ZIT2QX7D.js');
require('../../chunk-LK6DILFK.js');
require('../../chunk-FGSEOIC4.js');
require('../../chunk-BC2BLJQN.js');
require('../../chunk-PFGO5BSM.js');
require('../../chunk-TIPR373R.js');
exports.XMLHttpRequestInterceptor = _chunkZIT2QX7Djs.XMLHttpRequestInterceptor;
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":""}

View file

@ -0,0 +1,12 @@
import {
XMLHttpRequestInterceptor
} from "../../chunk-DODHRDV6.mjs";
import "../../chunk-6HYIRFX2.mjs";
import "../../chunk-H5O73WD2.mjs";
import "../../chunk-5UK33FSU.mjs";
import "../../chunk-TX5GBTFY.mjs";
import "../../chunk-QED3Q6Z2.mjs";
export {
XMLHttpRequestInterceptor
};
//# sourceMappingURL=index.mjs.map

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}

View file

@ -0,0 +1,14 @@
import { H as HttpRequestEventMap } from '../../glossary-6564c252.js';
import { I as Interceptor } from '../../Interceptor-af98b768.js';
import '@open-draft/deferred-promise';
import '@open-draft/logger';
import 'strict-event-emitter';
declare class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
static symbol: symbol;
constructor();
protected checkEnvironment(): boolean;
protected setup(): Promise<void>;
}
export { FetchInterceptor };

View file

@ -0,0 +1,11 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _chunkQVOTKFTBjs = require('../../chunk-QVOTKFTB.js');
require('../../chunk-FGSEOIC4.js');
require('../../chunk-BC2BLJQN.js');
require('../../chunk-PFGO5BSM.js');
require('../../chunk-TIPR373R.js');
exports.FetchInterceptor = _chunkQVOTKFTBjs.FetchInterceptor;
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":""}

View file

@ -0,0 +1,11 @@
import {
FetchInterceptor
} from "../../chunk-XTX2SIN6.mjs";
import "../../chunk-H5O73WD2.mjs";
import "../../chunk-5UK33FSU.mjs";
import "../../chunk-TX5GBTFY.mjs";
import "../../chunk-QED3Q6Z2.mjs";
export {
FetchInterceptor
};
//# sourceMappingURL=index.mjs.map

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}

View file

@ -0,0 +1,15 @@
import { FetchInterceptor } from '../interceptors/fetch/index.js';
import { XMLHttpRequestInterceptor } from '../interceptors/XMLHttpRequest/index.js';
import '../glossary-6564c252.js';
import '@open-draft/deferred-promise';
import '../Interceptor-af98b768.js';
import '@open-draft/logger';
import 'strict-event-emitter';
/**
* The default preset provisions the interception of requests
* regardless of their type (fetch/XMLHttpRequest).
*/
declare const _default: readonly [FetchInterceptor, XMLHttpRequestInterceptor];
export { _default as default };

View file

@ -0,0 +1,21 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _chunkZIT2QX7Djs = require('../chunk-ZIT2QX7D.js');
require('../chunk-LK6DILFK.js');
var _chunkQVOTKFTBjs = require('../chunk-QVOTKFTB.js');
require('../chunk-FGSEOIC4.js');
require('../chunk-BC2BLJQN.js');
require('../chunk-PFGO5BSM.js');
require('../chunk-TIPR373R.js');
// src/presets/browser.ts
var browser_default = [
new (0, _chunkQVOTKFTBjs.FetchInterceptor)(),
new (0, _chunkZIT2QX7Djs.XMLHttpRequestInterceptor)()
];
exports.default = browser_default;
//# sourceMappingURL=browser.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../../../src/presets/browser.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAOA,IAAO,kBAAQ;AAAA,EACb,IAAI,iBAAiB;AAAA,EACrB,IAAI,0BAA0B;AAChC","sourcesContent":["import { FetchInterceptor } from '../interceptors/fetch'\nimport { XMLHttpRequestInterceptor } from '../interceptors/XMLHttpRequest'\n\n/**\n * The default preset provisions the interception of requests\n * regardless of their type (fetch/XMLHttpRequest).\n */\nexport default [\n new FetchInterceptor(),\n new XMLHttpRequestInterceptor(),\n] as const\n"]}

View file

@ -0,0 +1,21 @@
import {
XMLHttpRequestInterceptor
} from "../chunk-DODHRDV6.mjs";
import "../chunk-6HYIRFX2.mjs";
import {
FetchInterceptor
} from "../chunk-XTX2SIN6.mjs";
import "../chunk-H5O73WD2.mjs";
import "../chunk-5UK33FSU.mjs";
import "../chunk-TX5GBTFY.mjs";
import "../chunk-QED3Q6Z2.mjs";
// src/presets/browser.ts
var browser_default = [
new FetchInterceptor(),
new XMLHttpRequestInterceptor()
];
export {
browser_default as default
};
//# sourceMappingURL=browser.mjs.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../../../src/presets/browser.ts"],"sourcesContent":["import { FetchInterceptor } from '../interceptors/fetch'\nimport { XMLHttpRequestInterceptor } from '../interceptors/XMLHttpRequest'\n\n/**\n * The default preset provisions the interception of requests\n * regardless of their type (fetch/XMLHttpRequest).\n */\nexport default [\n new FetchInterceptor(),\n new XMLHttpRequestInterceptor(),\n] as const\n"],"mappings":";;;;;;;;;;;;;AAOA,IAAO,kBAAQ;AAAA,EACb,IAAI,iBAAiB;AAAA,EACrB,IAAI,0BAA0B;AAChC;","names":[]}