修改后台权限
This commit is contained in:
65
node_modules/@mswjs/interceptors/lib/browser/Interceptor-Deczogc8.d.cts
generated
vendored
Normal file
65
node_modules/@mswjs/interceptors/lib/browser/Interceptor-Deczogc8.d.cts
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Logger } from "@open-draft/logger";
|
||||
import { Emitter, Listener } from "strict-event-emitter";
|
||||
|
||||
//#region src/Interceptor.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
export { InterceptorReadyState as a, getGlobalSymbol as c, InterceptorEventMap as i, INTERNAL_REQUEST_ID_HEADER_NAME as n, InterceptorSubscription as o, Interceptor as r, deleteGlobalSymbol as s, ExtractEventNames as t };
|
||||
//# sourceMappingURL=Interceptor-Deczogc8.d.cts.map
|
||||
65
node_modules/@mswjs/interceptors/lib/browser/Interceptor-gqKgs-aF.d.mts
generated
vendored
Normal file
65
node_modules/@mswjs/interceptors/lib/browser/Interceptor-gqKgs-aF.d.mts
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Logger } from "@open-draft/logger";
|
||||
import { Emitter, Listener } from "strict-event-emitter";
|
||||
|
||||
//#region src/Interceptor.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
export { InterceptorReadyState as a, getGlobalSymbol as c, InterceptorEventMap as i, INTERNAL_REQUEST_ID_HEADER_NAME as n, InterceptorSubscription as o, Interceptor as r, deleteGlobalSymbol as s, ExtractEventNames as t };
|
||||
//# sourceMappingURL=Interceptor-gqKgs-aF.d.mts.map
|
||||
761
node_modules/@mswjs/interceptors/lib/browser/XMLHttpRequest-BACqefB-.cjs
generated
vendored
Normal file
761
node_modules/@mswjs/interceptors/lib/browser/XMLHttpRequest-BACqefB-.cjs
generated
vendored
Normal file
@@ -0,0 +1,761 @@
|
||||
const require_getRawRequest = require('./getRawRequest-zx8rUJL2.cjs');
|
||||
const require_createRequestId = require('./createRequestId-Cs4oXfa1.cjs');
|
||||
const require_bufferUtils = require('./bufferUtils-Uc0eRItL.cjs');
|
||||
const require_hasConfigurableGlobal = require('./hasConfigurableGlobal-BvCTG97d.cjs');
|
||||
const require_handleRequest = require('./handleRequest-CvX2G-Lz.cjs');
|
||||
let outvariant = require("outvariant");
|
||||
let is_node_process = require("is-node-process");
|
||||
|
||||
//#region src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts
|
||||
/**
|
||||
* Concatenate two `Uint8Array` buffers.
|
||||
*/
|
||||
function concatArrayBuffer(left, right) {
|
||||
const result = new Uint8Array(left.byteLength + right.byteLength);
|
||||
result.set(left, 0);
|
||||
result.set(right, left.byteLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region 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?.target || null;
|
||||
this.currentTarget = 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() {}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts
|
||||
var ProgressEventPolyfill = class extends EventPolyfill {
|
||||
constructor(type, init) {
|
||||
super(type);
|
||||
this.lengthComputable = init?.lengthComputable || false;
|
||||
this.composed = init?.composed || false;
|
||||
this.loaded = init?.loaded || 0;
|
||||
this.total = init?.total || 0;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/createEvent.ts
|
||||
const SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== "undefined";
|
||||
function createEvent(target, type, init) {
|
||||
const progressEvents = [
|
||||
"error",
|
||||
"progress",
|
||||
"loadstart",
|
||||
"loadend",
|
||||
"load",
|
||||
"timeout",
|
||||
"abort"
|
||||
];
|
||||
/**
|
||||
* `ProgressEvent` is not supported in React Native.
|
||||
* @see https://github.com/mswjs/interceptors/issues/40
|
||||
*/
|
||||
const ProgressEventClass = SUPPORTS_PROGRESS_EVENT ? ProgressEvent : ProgressEventPolyfill;
|
||||
return progressEvents.includes(type) ? new ProgressEventClass(type, {
|
||||
lengthComputable: true,
|
||||
loaded: init?.loaded || 0,
|
||||
total: init?.total || 0
|
||||
}) : new EventPolyfill(type, {
|
||||
target,
|
||||
currentTarget: target
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/findPropertySource.ts
|
||||
/**
|
||||
* Returns the source object of the given property on the target object
|
||||
* (the target itself, any parent in its prototype, or null).
|
||||
*/
|
||||
function findPropertySource(target, propertyName) {
|
||||
if (!(propertyName in target)) return null;
|
||||
if (Object.prototype.hasOwnProperty.call(target, propertyName)) return target;
|
||||
const prototype = Reflect.getPrototypeOf(target);
|
||||
return prototype ? findPropertySource(prototype, propertyName) : null;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/createProxy.ts
|
||||
function createProxy(target, options) {
|
||||
return new Proxy(target, optionsToProxyHandler(options));
|
||||
}
|
||||
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?.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) {
|
||||
/**
|
||||
* @note Using `Reflect.get()` here causes "TypeError: Illegal invocation".
|
||||
*/
|
||||
const next = () => target[propertyName];
|
||||
const value = typeof getProperty !== "undefined" ? getProperty.call(target, [propertyName, receiver], next) : next();
|
||||
if (typeof value === "function") return (...args) => {
|
||||
const next$1 = value.bind(target, ...args);
|
||||
if (typeof methodCall !== "undefined") return methodCall.call(target, [propertyName, args], next$1);
|
||||
return next$1();
|
||||
};
|
||||
return value;
|
||||
};
|
||||
return handler;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts
|
||||
function isDomParserSupportedType(type) {
|
||||
return [
|
||||
"application/xhtml+xml",
|
||||
"application/xml",
|
||||
"image/svg+xml",
|
||||
"text/html",
|
||||
"text/xml"
|
||||
].some((supportedType) => {
|
||||
return type.startsWith(supportedType);
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/parseJson.ts
|
||||
/**
|
||||
* Parses a given string into JSON.
|
||||
* Gracefully handles invalid JSON by returning `null`.
|
||||
*/
|
||||
function parseJson(data) {
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
||||
/**
|
||||
* Creates a Fetch API `Response` instance from the given
|
||||
* `XMLHttpRequest` instance and a response body.
|
||||
*/
|
||||
function createResponse(request, body) {
|
||||
return new require_getRawRequest.FetchResponse(require_getRawRequest.FetchResponse.isResponseWithBody(request.status) ? body : null, {
|
||||
url: request.responseURL,
|
||||
status: request.status,
|
||||
statusText: request.statusText,
|
||||
headers: createHeadersFromXMLHttpRequestHeaders(request.getAllResponseHeaders())
|
||||
});
|
||||
}
|
||||
function createHeadersFromXMLHttpRequestHeaders(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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/getBodyByteLength.ts
|
||||
/**
|
||||
* Return a total byte length of the given request/response body.
|
||||
* If the `Content-Length` header is present, it will be used as the byte length.
|
||||
*/
|
||||
async function getBodyByteLength(input) {
|
||||
const explicitContentLength = input.headers.get("content-length");
|
||||
if (explicitContentLength != null && explicitContentLength !== "") return Number(explicitContentLength);
|
||||
return (await input.arrayBuffer()).byteLength;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
|
||||
const kIsRequestHandled = Symbol("kIsRequestHandled");
|
||||
const IS_NODE = (0, is_node_process.isNodeProcess)();
|
||||
const kFetchRequest = Symbol("kFetchRequest");
|
||||
/**
|
||||
* An `XMLHttpRequest` instance controller that allows us
|
||||
* to handle any given request instance (e.g. responding to it).
|
||||
*/
|
||||
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 = require_createRequestId.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);
|
||||
/**
|
||||
* @note Proxy callbacks to event listeners because JSDOM has trouble
|
||||
* translating these properties to callbacks. It seemed to be operating
|
||||
* on events exclusively.
|
||||
*/
|
||||
this.request.addEventListener(eventName, nextValue);
|
||||
return invoke();
|
||||
}
|
||||
default: return invoke();
|
||||
}
|
||||
},
|
||||
methodCall: ([methodName, args], invoke) => {
|
||||
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" ? require_bufferUtils.encodeBuffer(body) : body;
|
||||
const fetchRequest = this.toFetchApiRequest(requestBody);
|
||||
this[kFetchRequest] = fetchRequest.clone();
|
||||
/**
|
||||
* @note Start request handling on the next tick so that the user
|
||||
* could add event listeners for "loadend" before the interceptor fires it.
|
||||
*/
|
||||
queueMicrotask(() => {
|
||||
(this.onRequest?.call(this, {
|
||||
request: fetchRequest,
|
||||
requestId: this.requestId
|
||||
}) || Promise.resolve()).finally(() => {
|
||||
if (!this[kIsRequestHandled]) {
|
||||
this.logger.info("request callback settled but request has not been handled (readystate %d), performing as-is...", this.request.readyState);
|
||||
/**
|
||||
* @note Set the intercepted request ID on the original request in Node.js
|
||||
* so that if it triggers any other interceptors, they don't attempt
|
||||
* to process it once again.
|
||||
*
|
||||
* For instance, XMLHttpRequest is often implemented via "http.ClientRequest"
|
||||
* and we don't want for both XHR and ClientRequest interceptors to
|
||||
* handle the same request at the same time (e.g. emit the "response" event twice).
|
||||
*/
|
||||
if (IS_NODE) this.request.setRequestHeader(require_createRequestId.INTERNAL_REQUEST_ID_HEADER_NAME, this.requestId);
|
||||
return invoke();
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: return invoke();
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Proxy the `.upload` property to gather the event listeners/callbacks.
|
||||
*/
|
||||
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 nextEvents = (this.events.get(eventName) || []).concat(listener);
|
||||
this.events.set(eventName, nextEvents);
|
||||
this.logger.info("registered event \"%s\"", eventName, listener);
|
||||
}
|
||||
registerUploadEvent(eventName, listener) {
|
||||
const nextEvents = (this.uploadEvents.get(eventName) || []).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) {
|
||||
/**
|
||||
* @note Since `XMLHttpRequestController` delegates the handling of the responses
|
||||
* to the "load" event listener that doesn't distinguish between the mocked and original
|
||||
* responses, mark the request that had a mocked response with a corresponding symbol.
|
||||
*
|
||||
* Mark this request as having a mocked response immediately since
|
||||
* calculating request/response total body length is asynchronous.
|
||||
*/
|
||||
this[kIsRequestHandled] = true;
|
||||
/**
|
||||
* Dispatch request upload events for requests with a body.
|
||||
* @see https://github.com/mswjs/interceptors/issues/573
|
||||
*/
|
||||
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 allHeaders = Array.from(response.headers.entries()).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 require_bufferUtils.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 = require_bufferUtils.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() {
|
||||
/**
|
||||
* Throw when trying to read the response body as text when the
|
||||
* "responseType" doesn't expect text. This just respects the spec better.
|
||||
* @see https://xhr.spec.whatwg.org/#the-responsetext-attribute
|
||||
*/
|
||||
(0, outvariant.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() {
|
||||
(0, outvariant.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) {
|
||||
/**
|
||||
* @note Mark this request as handled even if it received a mock error.
|
||||
* This prevents the controller from trying to perform this request as-is.
|
||||
*/
|
||||
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("triggering \"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,
|
||||
credentials: this.request.withCredentials ? "include" : "same-origin",
|
||||
body: ["GET", "HEAD"].includes(this.method.toUpperCase()) ? null : resolvedBody
|
||||
});
|
||||
define(fetchRequest, "headers", 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();
|
||||
} }));
|
||||
require_getRawRequest.setRawRequest(fetchRequest, this.request);
|
||||
this.logger.info("converted request to a Fetch API Request!", fetchRequest);
|
||||
return fetchRequest;
|
||||
}
|
||||
};
|
||||
function toAbsoluteUrl(url) {
|
||||
/**
|
||||
* @note XMLHttpRequest interceptor may run in environments
|
||||
* that implement XMLHttpRequest but don't implement "location"
|
||||
* (for example, React Native). If that's the case, return the
|
||||
* input URL as-is (nothing to be relative to).
|
||||
* @see https://github.com/mswjs/msw/issues/1777
|
||||
*/
|
||||
if (typeof location === "undefined") return new URL(url);
|
||||
return new URL(url.toString(), location.href);
|
||||
}
|
||||
function define(target, property, value) {
|
||||
Reflect.defineProperty(target, property, {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
|
||||
/**
|
||||
* Create a proxied `XMLHttpRequest` class.
|
||||
* The proxied class establishes spies on certain methods,
|
||||
* allowing us to intercept requests and respond to them.
|
||||
*/
|
||||
function createXMLHttpRequestProxy({ emitter, logger }) {
|
||||
return new Proxy(globalThis.XMLHttpRequest, { construct(target, args, newTarget) {
|
||||
logger.info("constructed new XMLHttpRequest");
|
||||
const originalRequest = Reflect.construct(target, args, newTarget);
|
||||
/**
|
||||
* @note Forward prototype descriptors onto the proxied object.
|
||||
* XMLHttpRequest is implemented in JSDOM in a way that assigns
|
||||
* a bunch of descriptors, like "set responseType()" on the prototype.
|
||||
* With this propagation, we make sure that those descriptors trigger
|
||||
* when the user operates with the proxied request instance.
|
||||
*/
|
||||
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 require_getRawRequest.RequestController(request, {
|
||||
passthrough: () => {
|
||||
this.logger.info("no mocked response received, performing request as-is...");
|
||||
},
|
||||
respondWith: async (response) => {
|
||||
if (require_handleRequest.isResponseError(response)) {
|
||||
this.errorWith(/* @__PURE__ */ new TypeError("Network error"));
|
||||
return;
|
||||
}
|
||||
await this.respondWith(response);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request errored!", { error: reason });
|
||||
if (reason instanceof Error) this.errorWith(reason);
|
||||
}
|
||||
});
|
||||
this.logger.info("awaiting mocked response...");
|
||||
this.logger.info("emitting the \"request\" event for %s listener(s)...", emitter.listenerCount("request"));
|
||||
await require_handleRequest.handleRequest({
|
||||
request,
|
||||
requestId,
|
||||
controller,
|
||||
emitter
|
||||
});
|
||||
};
|
||||
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;
|
||||
} });
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/index.ts
|
||||
var XMLHttpRequestInterceptor = class XMLHttpRequestInterceptor extends require_createRequestId.Interceptor {
|
||||
static {
|
||||
this.interceptorSymbol = Symbol("xhr");
|
||||
}
|
||||
constructor() {
|
||||
super(XMLHttpRequestInterceptor.interceptorSymbol);
|
||||
}
|
||||
checkEnvironment() {
|
||||
return require_hasConfigurableGlobal.hasConfigurableGlobal("XMLHttpRequest");
|
||||
}
|
||||
setup() {
|
||||
const logger = this.logger.extend("setup");
|
||||
logger.info("patching \"XMLHttpRequest\" module...");
|
||||
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
|
||||
(0, outvariant.invariant)(!PureXMLHttpRequest[require_getRawRequest.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, require_getRawRequest.IS_PATCHED_MODULE, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: true
|
||||
});
|
||||
this.subscriptions.push(() => {
|
||||
Object.defineProperty(globalThis.XMLHttpRequest, require_getRawRequest.IS_PATCHED_MODULE, { value: void 0 });
|
||||
globalThis.XMLHttpRequest = PureXMLHttpRequest;
|
||||
logger.info("native \"XMLHttpRequest\" module restored!", globalThis.XMLHttpRequest.name);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'XMLHttpRequestInterceptor', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return XMLHttpRequestInterceptor;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=XMLHttpRequest-BACqefB-.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/XMLHttpRequest-BACqefB-.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/XMLHttpRequest-BACqefB-.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
756
node_modules/@mswjs/interceptors/lib/browser/XMLHttpRequest-BvxZV0WU.mjs
generated
vendored
Normal file
756
node_modules/@mswjs/interceptors/lib/browser/XMLHttpRequest-BvxZV0WU.mjs
generated
vendored
Normal file
@@ -0,0 +1,756 @@
|
||||
import { a as RequestController, n as setRawRequest, r as FetchResponse, s as IS_PATCHED_MODULE } from "./getRawRequest-BTaNLFr0.mjs";
|
||||
import { n as INTERNAL_REQUEST_ID_HEADER_NAME, r as Interceptor, t as createRequestId } from "./createRequestId-DQcIlohW.mjs";
|
||||
import { n as encodeBuffer, r as toArrayBuffer, t as decodeBuffer } from "./bufferUtils-BiiO6HZv.mjs";
|
||||
import { t as hasConfigurableGlobal } from "./hasConfigurableGlobal-npXitu1-.mjs";
|
||||
import { n as isResponseError, t as handleRequest } from "./handleRequest-D7kpTI5U.mjs";
|
||||
import { invariant } from "outvariant";
|
||||
import { isNodeProcess } from "is-node-process";
|
||||
|
||||
//#region src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts
|
||||
/**
|
||||
* Concatenate two `Uint8Array` buffers.
|
||||
*/
|
||||
function concatArrayBuffer(left, right) {
|
||||
const result = new Uint8Array(left.byteLength + right.byteLength);
|
||||
result.set(left, 0);
|
||||
result.set(right, left.byteLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region 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?.target || null;
|
||||
this.currentTarget = 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() {}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts
|
||||
var ProgressEventPolyfill = class extends EventPolyfill {
|
||||
constructor(type, init) {
|
||||
super(type);
|
||||
this.lengthComputable = init?.lengthComputable || false;
|
||||
this.composed = init?.composed || false;
|
||||
this.loaded = init?.loaded || 0;
|
||||
this.total = init?.total || 0;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/createEvent.ts
|
||||
const SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== "undefined";
|
||||
function createEvent(target, type, init) {
|
||||
const progressEvents = [
|
||||
"error",
|
||||
"progress",
|
||||
"loadstart",
|
||||
"loadend",
|
||||
"load",
|
||||
"timeout",
|
||||
"abort"
|
||||
];
|
||||
/**
|
||||
* `ProgressEvent` is not supported in React Native.
|
||||
* @see https://github.com/mswjs/interceptors/issues/40
|
||||
*/
|
||||
const ProgressEventClass = SUPPORTS_PROGRESS_EVENT ? ProgressEvent : ProgressEventPolyfill;
|
||||
return progressEvents.includes(type) ? new ProgressEventClass(type, {
|
||||
lengthComputable: true,
|
||||
loaded: init?.loaded || 0,
|
||||
total: init?.total || 0
|
||||
}) : new EventPolyfill(type, {
|
||||
target,
|
||||
currentTarget: target
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/findPropertySource.ts
|
||||
/**
|
||||
* Returns the source object of the given property on the target object
|
||||
* (the target itself, any parent in its prototype, or null).
|
||||
*/
|
||||
function findPropertySource(target, propertyName) {
|
||||
if (!(propertyName in target)) return null;
|
||||
if (Object.prototype.hasOwnProperty.call(target, propertyName)) return target;
|
||||
const prototype = Reflect.getPrototypeOf(target);
|
||||
return prototype ? findPropertySource(prototype, propertyName) : null;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/createProxy.ts
|
||||
function createProxy(target, options) {
|
||||
return new Proxy(target, optionsToProxyHandler(options));
|
||||
}
|
||||
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?.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) {
|
||||
/**
|
||||
* @note Using `Reflect.get()` here causes "TypeError: Illegal invocation".
|
||||
*/
|
||||
const next = () => target[propertyName];
|
||||
const value = typeof getProperty !== "undefined" ? getProperty.call(target, [propertyName, receiver], next) : next();
|
||||
if (typeof value === "function") return (...args) => {
|
||||
const next$1 = value.bind(target, ...args);
|
||||
if (typeof methodCall !== "undefined") return methodCall.call(target, [propertyName, args], next$1);
|
||||
return next$1();
|
||||
};
|
||||
return value;
|
||||
};
|
||||
return handler;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts
|
||||
function isDomParserSupportedType(type) {
|
||||
return [
|
||||
"application/xhtml+xml",
|
||||
"application/xml",
|
||||
"image/svg+xml",
|
||||
"text/html",
|
||||
"text/xml"
|
||||
].some((supportedType) => {
|
||||
return type.startsWith(supportedType);
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/parseJson.ts
|
||||
/**
|
||||
* Parses a given string into JSON.
|
||||
* Gracefully handles invalid JSON by returning `null`.
|
||||
*/
|
||||
function parseJson(data) {
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
||||
/**
|
||||
* Creates a Fetch API `Response` instance from the given
|
||||
* `XMLHttpRequest` instance and a response body.
|
||||
*/
|
||||
function createResponse(request, body) {
|
||||
return new FetchResponse(FetchResponse.isResponseWithBody(request.status) ? body : null, {
|
||||
url: request.responseURL,
|
||||
status: request.status,
|
||||
statusText: request.statusText,
|
||||
headers: createHeadersFromXMLHttpRequestHeaders(request.getAllResponseHeaders())
|
||||
});
|
||||
}
|
||||
function createHeadersFromXMLHttpRequestHeaders(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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/getBodyByteLength.ts
|
||||
/**
|
||||
* Return a total byte length of the given request/response body.
|
||||
* If the `Content-Length` header is present, it will be used as the byte length.
|
||||
*/
|
||||
async function getBodyByteLength(input) {
|
||||
const explicitContentLength = input.headers.get("content-length");
|
||||
if (explicitContentLength != null && explicitContentLength !== "") return Number(explicitContentLength);
|
||||
return (await input.arrayBuffer()).byteLength;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
|
||||
const kIsRequestHandled = Symbol("kIsRequestHandled");
|
||||
const IS_NODE = isNodeProcess();
|
||||
const kFetchRequest = Symbol("kFetchRequest");
|
||||
/**
|
||||
* An `XMLHttpRequest` instance controller that allows us
|
||||
* to handle any given request instance (e.g. responding to it).
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* @note Proxy callbacks to event listeners because JSDOM has trouble
|
||||
* translating these properties to callbacks. It seemed to be operating
|
||||
* on events exclusively.
|
||||
*/
|
||||
this.request.addEventListener(eventName, nextValue);
|
||||
return invoke();
|
||||
}
|
||||
default: return invoke();
|
||||
}
|
||||
},
|
||||
methodCall: ([methodName, args], invoke) => {
|
||||
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();
|
||||
/**
|
||||
* @note Start request handling on the next tick so that the user
|
||||
* could add event listeners for "loadend" before the interceptor fires it.
|
||||
*/
|
||||
queueMicrotask(() => {
|
||||
(this.onRequest?.call(this, {
|
||||
request: fetchRequest,
|
||||
requestId: this.requestId
|
||||
}) || Promise.resolve()).finally(() => {
|
||||
if (!this[kIsRequestHandled]) {
|
||||
this.logger.info("request callback settled but request has not been handled (readystate %d), performing as-is...", this.request.readyState);
|
||||
/**
|
||||
* @note Set the intercepted request ID on the original request in Node.js
|
||||
* so that if it triggers any other interceptors, they don't attempt
|
||||
* to process it once again.
|
||||
*
|
||||
* For instance, XMLHttpRequest is often implemented via "http.ClientRequest"
|
||||
* and we don't want for both XHR and ClientRequest interceptors to
|
||||
* handle the same request at the same time (e.g. emit the "response" event twice).
|
||||
*/
|
||||
if (IS_NODE) this.request.setRequestHeader(INTERNAL_REQUEST_ID_HEADER_NAME, this.requestId);
|
||||
return invoke();
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: return invoke();
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Proxy the `.upload` property to gather the event listeners/callbacks.
|
||||
*/
|
||||
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 nextEvents = (this.events.get(eventName) || []).concat(listener);
|
||||
this.events.set(eventName, nextEvents);
|
||||
this.logger.info("registered event \"%s\"", eventName, listener);
|
||||
}
|
||||
registerUploadEvent(eventName, listener) {
|
||||
const nextEvents = (this.uploadEvents.get(eventName) || []).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) {
|
||||
/**
|
||||
* @note Since `XMLHttpRequestController` delegates the handling of the responses
|
||||
* to the "load" event listener that doesn't distinguish between the mocked and original
|
||||
* responses, mark the request that had a mocked response with a corresponding symbol.
|
||||
*
|
||||
* Mark this request as having a mocked response immediately since
|
||||
* calculating request/response total body length is asynchronous.
|
||||
*/
|
||||
this[kIsRequestHandled] = true;
|
||||
/**
|
||||
* Dispatch request upload events for requests with a body.
|
||||
* @see https://github.com/mswjs/interceptors/issues/573
|
||||
*/
|
||||
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 allHeaders = Array.from(response.headers.entries()).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() {
|
||||
/**
|
||||
* Throw when trying to read the response body as text when the
|
||||
* "responseType" doesn't expect text. This just respects the spec better.
|
||||
* @see https://xhr.spec.whatwg.org/#the-responsetext-attribute
|
||||
*/
|
||||
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) {
|
||||
/**
|
||||
* @note Mark this request as handled even if it received a mock error.
|
||||
* This prevents the controller from trying to perform this request as-is.
|
||||
*/
|
||||
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("triggering \"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,
|
||||
credentials: this.request.withCredentials ? "include" : "same-origin",
|
||||
body: ["GET", "HEAD"].includes(this.method.toUpperCase()) ? null : resolvedBody
|
||||
});
|
||||
define(fetchRequest, "headers", 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();
|
||||
} }));
|
||||
setRawRequest(fetchRequest, this.request);
|
||||
this.logger.info("converted request to a Fetch API Request!", fetchRequest);
|
||||
return fetchRequest;
|
||||
}
|
||||
};
|
||||
function toAbsoluteUrl(url) {
|
||||
/**
|
||||
* @note XMLHttpRequest interceptor may run in environments
|
||||
* that implement XMLHttpRequest but don't implement "location"
|
||||
* (for example, React Native). If that's the case, return the
|
||||
* input URL as-is (nothing to be relative to).
|
||||
* @see https://github.com/mswjs/msw/issues/1777
|
||||
*/
|
||||
if (typeof location === "undefined") return new URL(url);
|
||||
return new URL(url.toString(), location.href);
|
||||
}
|
||||
function define(target, property, value) {
|
||||
Reflect.defineProperty(target, property, {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
|
||||
/**
|
||||
* Create a proxied `XMLHttpRequest` class.
|
||||
* The proxied class establishes spies on certain methods,
|
||||
* allowing us to intercept requests and respond to them.
|
||||
*/
|
||||
function createXMLHttpRequestProxy({ emitter, logger }) {
|
||||
return new Proxy(globalThis.XMLHttpRequest, { construct(target, args, newTarget) {
|
||||
logger.info("constructed new XMLHttpRequest");
|
||||
const originalRequest = Reflect.construct(target, args, newTarget);
|
||||
/**
|
||||
* @note Forward prototype descriptors onto the proxied object.
|
||||
* XMLHttpRequest is implemented in JSDOM in a way that assigns
|
||||
* a bunch of descriptors, like "set responseType()" on the prototype.
|
||||
* With this propagation, we make sure that those descriptors trigger
|
||||
* when the user operates with the proxied request instance.
|
||||
*/
|
||||
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, {
|
||||
passthrough: () => {
|
||||
this.logger.info("no mocked response received, performing request as-is...");
|
||||
},
|
||||
respondWith: async (response) => {
|
||||
if (isResponseError(response)) {
|
||||
this.errorWith(/* @__PURE__ */ new TypeError("Network error"));
|
||||
return;
|
||||
}
|
||||
await this.respondWith(response);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request errored!", { error: reason });
|
||||
if (reason instanceof Error) this.errorWith(reason);
|
||||
}
|
||||
});
|
||||
this.logger.info("awaiting mocked response...");
|
||||
this.logger.info("emitting the \"request\" event for %s listener(s)...", emitter.listenerCount("request"));
|
||||
await handleRequest({
|
||||
request,
|
||||
requestId,
|
||||
controller,
|
||||
emitter
|
||||
});
|
||||
};
|
||||
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;
|
||||
} });
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/index.ts
|
||||
var XMLHttpRequestInterceptor = class XMLHttpRequestInterceptor extends Interceptor {
|
||||
static {
|
||||
this.interceptorSymbol = Symbol("xhr");
|
||||
}
|
||||
constructor() {
|
||||
super(XMLHttpRequestInterceptor.interceptorSymbol);
|
||||
}
|
||||
checkEnvironment() {
|
||||
return hasConfigurableGlobal("XMLHttpRequest");
|
||||
}
|
||||
setup() {
|
||||
const logger = this.logger.extend("setup");
|
||||
logger.info("patching \"XMLHttpRequest\" module...");
|
||||
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
|
||||
invariant(!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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { XMLHttpRequestInterceptor as t };
|
||||
//# sourceMappingURL=XMLHttpRequest-BvxZV0WU.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/XMLHttpRequest-BvxZV0WU.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/XMLHttpRequest-BvxZV0WU.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
20
node_modules/@mswjs/interceptors/lib/browser/bufferUtils-BiiO6HZv.mjs
generated
vendored
Normal file
20
node_modules/@mswjs/interceptors/lib/browser/bufferUtils-BiiO6HZv.mjs
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
//#region src/utils/bufferUtils.ts
|
||||
const encoder = new TextEncoder();
|
||||
function encodeBuffer(text) {
|
||||
return encoder.encode(text);
|
||||
}
|
||||
function decodeBuffer(buffer, encoding) {
|
||||
return new TextDecoder(encoding).decode(buffer);
|
||||
}
|
||||
/**
|
||||
* Create an `ArrayBuffer` from the given `Uint8Array`.
|
||||
* Takes the byte offset into account to produce the right buffer
|
||||
* in the case when the buffer is bigger than the data view.
|
||||
*/
|
||||
function toArrayBuffer(array) {
|
||||
return array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { encodeBuffer as n, toArrayBuffer as r, decodeBuffer as t };
|
||||
//# sourceMappingURL=bufferUtils-BiiO6HZv.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/bufferUtils-BiiO6HZv.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/bufferUtils-BiiO6HZv.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bufferUtils-BiiO6HZv.mjs","names":[],"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,MAAM,UAAU,IAAI,aAAa;AAEjC,SAAgB,aAAa,MAA0B;AACrD,QAAO,QAAQ,OAAO,KAAK;;AAG7B,SAAgB,aAAa,QAAqB,UAA2B;AAE3E,QADgB,IAAI,YAAY,SAAS,CAC1B,OAAO,OAAO;;;;;;;AAQ/B,SAAgB,cAAc,OAAgC;AAC5D,QAAO,MAAM,OAAO,MAClB,MAAM,YACN,MAAM,aAAa,MAAM,WAC1B"}
|
||||
38
node_modules/@mswjs/interceptors/lib/browser/bufferUtils-Uc0eRItL.cjs
generated
vendored
Normal file
38
node_modules/@mswjs/interceptors/lib/browser/bufferUtils-Uc0eRItL.cjs
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
//#region src/utils/bufferUtils.ts
|
||||
const encoder = new TextEncoder();
|
||||
function encodeBuffer(text) {
|
||||
return encoder.encode(text);
|
||||
}
|
||||
function decodeBuffer(buffer, encoding) {
|
||||
return new TextDecoder(encoding).decode(buffer);
|
||||
}
|
||||
/**
|
||||
* Create an `ArrayBuffer` from the given `Uint8Array`.
|
||||
* Takes the byte offset into account to produce the right buffer
|
||||
* in the case when the buffer is bigger than the data view.
|
||||
*/
|
||||
function toArrayBuffer(array) {
|
||||
return array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'decodeBuffer', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return decodeBuffer;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'encodeBuffer', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return encodeBuffer;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'toArrayBuffer', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return toArrayBuffer;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=bufferUtils-Uc0eRItL.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/bufferUtils-Uc0eRItL.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/bufferUtils-Uc0eRItL.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bufferUtils-Uc0eRItL.cjs","names":[],"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,MAAM,UAAU,IAAI,aAAa;AAEjC,SAAgB,aAAa,MAA0B;AACrD,QAAO,QAAQ,OAAO,KAAK;;AAG7B,SAAgB,aAAa,QAAqB,UAA2B;AAE3E,QADgB,IAAI,YAAY,SAAS,CAC1B,OAAO,OAAO;;;;;;;AAQ/B,SAAgB,cAAc,OAAgC;AAC5D,QAAO,MAAM,OAAO,MAClB,MAAM,YACN,MAAM,aAAa,MAAM,WAC1B"}
|
||||
205
node_modules/@mswjs/interceptors/lib/browser/createRequestId-Cs4oXfa1.cjs
generated
vendored
Normal file
205
node_modules/@mswjs/interceptors/lib/browser/createRequestId-Cs4oXfa1.cjs
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
let _open_draft_logger = require("@open-draft/logger");
|
||||
let strict_event_emitter = require("strict-event-emitter");
|
||||
|
||||
//#region src/Interceptor.ts
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
const INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
|
||||
function getGlobalSymbol(symbol) {
|
||||
return globalThis[symbol] || void 0;
|
||||
}
|
||||
function setGlobalSymbol(symbol, value) {
|
||||
globalThis[symbol] = value;
|
||||
}
|
||||
function deleteGlobalSymbol(symbol) {
|
||||
delete globalThis[symbol];
|
||||
}
|
||||
let InterceptorReadyState = /* @__PURE__ */ function(InterceptorReadyState$1) {
|
||||
InterceptorReadyState$1["INACTIVE"] = "INACTIVE";
|
||||
InterceptorReadyState$1["APPLYING"] = "APPLYING";
|
||||
InterceptorReadyState$1["APPLIED"] = "APPLIED";
|
||||
InterceptorReadyState$1["DISPOSING"] = "DISPOSING";
|
||||
InterceptorReadyState$1["DISPOSED"] = "DISPOSED";
|
||||
return InterceptorReadyState$1;
|
||||
}({});
|
||||
var Interceptor = class {
|
||||
constructor(symbol) {
|
||||
this.symbol = symbol;
|
||||
this.readyState = InterceptorReadyState.INACTIVE;
|
||||
this.emitter = new strict_event_emitter.Emitter();
|
||||
this.subscriptions = [];
|
||||
this.logger = new _open_draft_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 === InterceptorReadyState.APPLIED) {
|
||||
logger.info("intercepted already applied!");
|
||||
return;
|
||||
}
|
||||
if (!this.checkEnvironment()) {
|
||||
logger.info("the interceptor cannot be applied in this environment!");
|
||||
return;
|
||||
}
|
||||
this.readyState = InterceptorReadyState.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 = InterceptorReadyState.APPLIED;
|
||||
return;
|
||||
}
|
||||
logger.info("no running instance found, setting up a new instance...");
|
||||
this.setup();
|
||||
this.setInstance();
|
||||
this.readyState = InterceptorReadyState.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 === InterceptorReadyState.DISPOSING || this.readyState === InterceptorReadyState.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 === InterceptorReadyState.DISPOSED) {
|
||||
logger.info("cannot dispose, already disposed!");
|
||||
return;
|
||||
}
|
||||
logger.info("disposing the interceptor...");
|
||||
this.readyState = InterceptorReadyState.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 = InterceptorReadyState.DISPOSED;
|
||||
}
|
||||
getInstance() {
|
||||
const instance = getGlobalSymbol(this.symbol);
|
||||
this.logger.info("retrieved global instance:", instance?.constructor?.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);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/createRequestId.ts
|
||||
/**
|
||||
* Generate a random ID string to represent a request.
|
||||
* @example
|
||||
* createRequestId()
|
||||
* // "f774b6c9c600f"
|
||||
*/
|
||||
function createRequestId() {
|
||||
return Math.random().toString(16).slice(2);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'INTERNAL_REQUEST_ID_HEADER_NAME', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return INTERNAL_REQUEST_ID_HEADER_NAME;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'Interceptor', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return Interceptor;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'InterceptorReadyState', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return InterceptorReadyState;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'createRequestId', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return createRequestId;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'deleteGlobalSymbol', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return deleteGlobalSymbol;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'getGlobalSymbol', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return getGlobalSymbol;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=createRequestId-Cs4oXfa1.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/createRequestId-Cs4oXfa1.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/createRequestId-Cs4oXfa1.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
170
node_modules/@mswjs/interceptors/lib/browser/createRequestId-DQcIlohW.mjs
generated
vendored
Normal file
170
node_modules/@mswjs/interceptors/lib/browser/createRequestId-DQcIlohW.mjs
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
import { Logger } from "@open-draft/logger";
|
||||
import { Emitter } from "strict-event-emitter";
|
||||
|
||||
//#region src/Interceptor.ts
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
const INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
|
||||
function getGlobalSymbol(symbol) {
|
||||
return globalThis[symbol] || void 0;
|
||||
}
|
||||
function setGlobalSymbol(symbol, value) {
|
||||
globalThis[symbol] = value;
|
||||
}
|
||||
function deleteGlobalSymbol(symbol) {
|
||||
delete globalThis[symbol];
|
||||
}
|
||||
let InterceptorReadyState = /* @__PURE__ */ function(InterceptorReadyState$1) {
|
||||
InterceptorReadyState$1["INACTIVE"] = "INACTIVE";
|
||||
InterceptorReadyState$1["APPLYING"] = "APPLYING";
|
||||
InterceptorReadyState$1["APPLIED"] = "APPLIED";
|
||||
InterceptorReadyState$1["DISPOSING"] = "DISPOSING";
|
||||
InterceptorReadyState$1["DISPOSED"] = "DISPOSED";
|
||||
return InterceptorReadyState$1;
|
||||
}({});
|
||||
var Interceptor = class {
|
||||
constructor(symbol) {
|
||||
this.symbol = symbol;
|
||||
this.readyState = InterceptorReadyState.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 === InterceptorReadyState.APPLIED) {
|
||||
logger.info("intercepted already applied!");
|
||||
return;
|
||||
}
|
||||
if (!this.checkEnvironment()) {
|
||||
logger.info("the interceptor cannot be applied in this environment!");
|
||||
return;
|
||||
}
|
||||
this.readyState = InterceptorReadyState.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 = InterceptorReadyState.APPLIED;
|
||||
return;
|
||||
}
|
||||
logger.info("no running instance found, setting up a new instance...");
|
||||
this.setup();
|
||||
this.setInstance();
|
||||
this.readyState = InterceptorReadyState.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 === InterceptorReadyState.DISPOSING || this.readyState === InterceptorReadyState.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 === InterceptorReadyState.DISPOSED) {
|
||||
logger.info("cannot dispose, already disposed!");
|
||||
return;
|
||||
}
|
||||
logger.info("disposing the interceptor...");
|
||||
this.readyState = InterceptorReadyState.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 = InterceptorReadyState.DISPOSED;
|
||||
}
|
||||
getInstance() {
|
||||
const instance = getGlobalSymbol(this.symbol);
|
||||
this.logger.info("retrieved global instance:", instance?.constructor?.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);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/createRequestId.ts
|
||||
/**
|
||||
* Generate a random ID string to represent a request.
|
||||
* @example
|
||||
* createRequestId()
|
||||
* // "f774b6c9c600f"
|
||||
*/
|
||||
function createRequestId() {
|
||||
return Math.random().toString(16).slice(2);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { deleteGlobalSymbol as a, InterceptorReadyState as i, INTERNAL_REQUEST_ID_HEADER_NAME as n, getGlobalSymbol as o, Interceptor as r, createRequestId as t };
|
||||
//# sourceMappingURL=createRequestId-DQcIlohW.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/createRequestId-DQcIlohW.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/createRequestId-DQcIlohW.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
248
node_modules/@mswjs/interceptors/lib/browser/fetch-DdKEdDOR.mjs
generated
vendored
Normal file
248
node_modules/@mswjs/interceptors/lib/browser/fetch-DdKEdDOR.mjs
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
import { a as RequestController, i as canParseUrl, n as setRawRequest, r as FetchResponse, s as IS_PATCHED_MODULE } from "./getRawRequest-BTaNLFr0.mjs";
|
||||
import { r as Interceptor, t as createRequestId } from "./createRequestId-DQcIlohW.mjs";
|
||||
import { n as emitAsync, t as hasConfigurableGlobal } from "./hasConfigurableGlobal-npXitu1-.mjs";
|
||||
import { n as isResponseError, t as handleRequest } from "./handleRequest-D7kpTI5U.mjs";
|
||||
import { DeferredPromise } from "@open-draft/deferred-promise";
|
||||
import { invariant } from "outvariant";
|
||||
import { until } from "@open-draft/until";
|
||||
|
||||
//#region src/interceptors/fetch/utils/createNetworkError.ts
|
||||
function createNetworkError(cause) {
|
||||
return Object.assign(/* @__PURE__ */ new TypeError("Failed to fetch"), { cause });
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/followRedirect.ts
|
||||
const REQUEST_BODY_HEADERS = [
|
||||
"content-encoding",
|
||||
"content-language",
|
||||
"content-location",
|
||||
"content-type",
|
||||
"content-length"
|
||||
];
|
||||
const kRedirectCount = Symbol("kRedirectCount");
|
||||
/**
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1210
|
||||
*/
|
||||
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");
|
||||
}
|
||||
/**
|
||||
* @note Undici "safely" extracts the request body.
|
||||
* I suspect we cannot dispatch this request again
|
||||
* since its body has been read and the stream is locked.
|
||||
*/
|
||||
requestInit.headers = request.headers;
|
||||
const finalResponse = await fetch(new Request(locationUrl, requestInit));
|
||||
Object.defineProperty(finalResponse, "redirected", {
|
||||
value: true,
|
||||
configurable: true
|
||||
});
|
||||
return finalResponse;
|
||||
}
|
||||
/**
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/util.js#L761
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region 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);
|
||||
} });
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/decompression.ts
|
||||
var PipelineStream = class extends TransformStream {
|
||||
constructor(transformStreams, ...strategies) {
|
||||
super({}, ...strategies);
|
||||
const readable = [super.readable, ...transformStreams].reduce((readable$1, transform) => readable$1.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;
|
||||
return new PipelineStream(codings.reduceRight((transformers, coding) => {
|
||||
if (coding === "gzip" || coding === "x-gzip") return transformers.concat(new DecompressionStream("gzip"));
|
||||
else if (coding === "deflate") return transformers.concat(new DecompressionStream("deflate"));
|
||||
else if (coding === "br") return transformers.concat(new BrotliDecompressionStream());
|
||||
else transformers.length = 0;
|
||||
return 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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/index.ts
|
||||
var FetchInterceptor = class FetchInterceptor extends Interceptor {
|
||||
static {
|
||||
this.symbol = Symbol("fetch");
|
||||
}
|
||||
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();
|
||||
/**
|
||||
* @note Resolve potentially relative request URL
|
||||
* against the present `location`. This is mainly
|
||||
* for native `fetch` in JSDOM.
|
||||
* @see https://github.com/mswjs/msw/issues/1625
|
||||
*/
|
||||
const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !canParseUrl(input) ? new URL(input, location.href) : input;
|
||||
const request = new Request(resolvedInput, init);
|
||||
/**
|
||||
* @note Set the raw request only if a Request instance was provided to fetch.
|
||||
*/
|
||||
if (input instanceof Request) setRawRequest(request, input);
|
||||
const responsePromise = new DeferredPromise();
|
||||
const controller = new RequestController(request, {
|
||||
passthrough: async () => {
|
||||
this.logger.info("request has not been handled, passthrough...");
|
||||
/**
|
||||
* @note Clone the request instance right before performing it.
|
||||
* This preserves any modifications made to the intercepted request
|
||||
* in the "request" listener. This also allows the user to read the
|
||||
* request body in the "response" listener (otherwise "unusable").
|
||||
*/
|
||||
const requestCloneForResponseEvent = request.clone();
|
||||
const { error: responseError, data: originalResponse } = await until(() => pureFetch(request));
|
||||
if (responseError) return responsePromise.reject(responseError);
|
||||
this.logger.info("original fetch performed", originalResponse);
|
||||
if (this.emitter.listenerCount("response") > 0) {
|
||||
this.logger.info("emitting the \"response\" event...");
|
||||
const responseClone = originalResponse.clone();
|
||||
await emitAsync(this.emitter, "response", {
|
||||
response: responseClone,
|
||||
isMockedResponse: false,
|
||||
request: requestCloneForResponseEvent,
|
||||
requestId
|
||||
});
|
||||
}
|
||||
responsePromise.resolve(originalResponse);
|
||||
},
|
||||
respondWith: async (rawResponse) => {
|
||||
if (isResponseError(rawResponse)) {
|
||||
this.logger.info("request has errored!", { response: rawResponse });
|
||||
responsePromise.reject(createNetworkError(rawResponse));
|
||||
return;
|
||||
}
|
||||
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);
|
||||
/**
|
||||
* Undici's handling of following redirect responses.
|
||||
* Treat the "manual" redirect mode as a regular mocked response.
|
||||
* This way, the client can manually follow the redirect it receives.
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1173
|
||||
*/
|
||||
if (FetchResponse.isRedirectResponse(response.status)) {
|
||||
if (request.redirect === "error") {
|
||||
responsePromise.reject(createNetworkError("unexpected redirect"));
|
||||
return;
|
||||
}
|
||||
if (request.redirect === "follow") {
|
||||
followFetchRedirect(request, response).then((response$1) => {
|
||||
responsePromise.resolve(response$1);
|
||||
}, (reason) => {
|
||||
responsePromise.reject(reason);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.emitter.listenerCount("response") > 0) {
|
||||
this.logger.info("emitting the \"response\" event...");
|
||||
await emitAsync(this.emitter, "response", {
|
||||
response: response.clone(),
|
||||
isMockedResponse: true,
|
||||
request,
|
||||
requestId
|
||||
});
|
||||
}
|
||||
responsePromise.resolve(response);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request has been aborted!", { reason });
|
||||
responsePromise.reject(reason);
|
||||
}
|
||||
});
|
||||
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"));
|
||||
await handleRequest({
|
||||
request,
|
||||
requestId,
|
||||
emitter: this.emitter,
|
||||
controller
|
||||
});
|
||||
return responsePromise;
|
||||
};
|
||||
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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { FetchInterceptor as t };
|
||||
//# sourceMappingURL=fetch-DdKEdDOR.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/fetch-DdKEdDOR.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/fetch-DdKEdDOR.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
253
node_modules/@mswjs/interceptors/lib/browser/fetch-U3v3Y4ap.cjs
generated
vendored
Normal file
253
node_modules/@mswjs/interceptors/lib/browser/fetch-U3v3Y4ap.cjs
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
const require_getRawRequest = require('./getRawRequest-zx8rUJL2.cjs');
|
||||
const require_createRequestId = require('./createRequestId-Cs4oXfa1.cjs');
|
||||
const require_hasConfigurableGlobal = require('./hasConfigurableGlobal-BvCTG97d.cjs');
|
||||
const require_handleRequest = require('./handleRequest-CvX2G-Lz.cjs');
|
||||
let _open_draft_deferred_promise = require("@open-draft/deferred-promise");
|
||||
let outvariant = require("outvariant");
|
||||
let _open_draft_until = require("@open-draft/until");
|
||||
|
||||
//#region src/interceptors/fetch/utils/createNetworkError.ts
|
||||
function createNetworkError(cause) {
|
||||
return Object.assign(/* @__PURE__ */ new TypeError("Failed to fetch"), { cause });
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/followRedirect.ts
|
||||
const REQUEST_BODY_HEADERS = [
|
||||
"content-encoding",
|
||||
"content-language",
|
||||
"content-location",
|
||||
"content-type",
|
||||
"content-length"
|
||||
];
|
||||
const kRedirectCount = Symbol("kRedirectCount");
|
||||
/**
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1210
|
||||
*/
|
||||
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");
|
||||
}
|
||||
/**
|
||||
* @note Undici "safely" extracts the request body.
|
||||
* I suspect we cannot dispatch this request again
|
||||
* since its body has been read and the stream is locked.
|
||||
*/
|
||||
requestInit.headers = request.headers;
|
||||
const finalResponse = await fetch(new Request(locationUrl, requestInit));
|
||||
Object.defineProperty(finalResponse, "redirected", {
|
||||
value: true,
|
||||
configurable: true
|
||||
});
|
||||
return finalResponse;
|
||||
}
|
||||
/**
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/util.js#L761
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region 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);
|
||||
} });
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/decompression.ts
|
||||
var PipelineStream = class extends TransformStream {
|
||||
constructor(transformStreams, ...strategies) {
|
||||
super({}, ...strategies);
|
||||
const readable = [super.readable, ...transformStreams].reduce((readable$1, transform) => readable$1.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;
|
||||
return new PipelineStream(codings.reduceRight((transformers, coding) => {
|
||||
if (coding === "gzip" || coding === "x-gzip") return transformers.concat(new DecompressionStream("gzip"));
|
||||
else if (coding === "deflate") return transformers.concat(new DecompressionStream("deflate"));
|
||||
else if (coding === "br") return transformers.concat(new BrotliDecompressionStream());
|
||||
else transformers.length = 0;
|
||||
return 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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/index.ts
|
||||
var FetchInterceptor = class FetchInterceptor extends require_createRequestId.Interceptor {
|
||||
static {
|
||||
this.symbol = Symbol("fetch");
|
||||
}
|
||||
constructor() {
|
||||
super(FetchInterceptor.symbol);
|
||||
}
|
||||
checkEnvironment() {
|
||||
return require_hasConfigurableGlobal.hasConfigurableGlobal("fetch");
|
||||
}
|
||||
async setup() {
|
||||
const pureFetch = globalThis.fetch;
|
||||
(0, outvariant.invariant)(!pureFetch[require_getRawRequest.IS_PATCHED_MODULE], "Failed to patch the \"fetch\" module: already patched.");
|
||||
globalThis.fetch = async (input, init) => {
|
||||
const requestId = require_createRequestId.createRequestId();
|
||||
/**
|
||||
* @note Resolve potentially relative request URL
|
||||
* against the present `location`. This is mainly
|
||||
* for native `fetch` in JSDOM.
|
||||
* @see https://github.com/mswjs/msw/issues/1625
|
||||
*/
|
||||
const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !require_getRawRequest.canParseUrl(input) ? new URL(input, location.href) : input;
|
||||
const request = new Request(resolvedInput, init);
|
||||
/**
|
||||
* @note Set the raw request only if a Request instance was provided to fetch.
|
||||
*/
|
||||
if (input instanceof Request) require_getRawRequest.setRawRequest(request, input);
|
||||
const responsePromise = new _open_draft_deferred_promise.DeferredPromise();
|
||||
const controller = new require_getRawRequest.RequestController(request, {
|
||||
passthrough: async () => {
|
||||
this.logger.info("request has not been handled, passthrough...");
|
||||
/**
|
||||
* @note Clone the request instance right before performing it.
|
||||
* This preserves any modifications made to the intercepted request
|
||||
* in the "request" listener. This also allows the user to read the
|
||||
* request body in the "response" listener (otherwise "unusable").
|
||||
*/
|
||||
const requestCloneForResponseEvent = request.clone();
|
||||
const { error: responseError, data: originalResponse } = await (0, _open_draft_until.until)(() => pureFetch(request));
|
||||
if (responseError) return responsePromise.reject(responseError);
|
||||
this.logger.info("original fetch performed", originalResponse);
|
||||
if (this.emitter.listenerCount("response") > 0) {
|
||||
this.logger.info("emitting the \"response\" event...");
|
||||
const responseClone = originalResponse.clone();
|
||||
await require_hasConfigurableGlobal.emitAsync(this.emitter, "response", {
|
||||
response: responseClone,
|
||||
isMockedResponse: false,
|
||||
request: requestCloneForResponseEvent,
|
||||
requestId
|
||||
});
|
||||
}
|
||||
responsePromise.resolve(originalResponse);
|
||||
},
|
||||
respondWith: async (rawResponse) => {
|
||||
if (require_handleRequest.isResponseError(rawResponse)) {
|
||||
this.logger.info("request has errored!", { response: rawResponse });
|
||||
responsePromise.reject(createNetworkError(rawResponse));
|
||||
return;
|
||||
}
|
||||
this.logger.info("received mocked response!", { rawResponse });
|
||||
const decompressedStream = decompressResponse(rawResponse);
|
||||
const response = decompressedStream === null ? rawResponse : new require_getRawRequest.FetchResponse(decompressedStream, rawResponse);
|
||||
require_getRawRequest.FetchResponse.setUrl(request.url, response);
|
||||
/**
|
||||
* Undici's handling of following redirect responses.
|
||||
* Treat the "manual" redirect mode as a regular mocked response.
|
||||
* This way, the client can manually follow the redirect it receives.
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1173
|
||||
*/
|
||||
if (require_getRawRequest.FetchResponse.isRedirectResponse(response.status)) {
|
||||
if (request.redirect === "error") {
|
||||
responsePromise.reject(createNetworkError("unexpected redirect"));
|
||||
return;
|
||||
}
|
||||
if (request.redirect === "follow") {
|
||||
followFetchRedirect(request, response).then((response$1) => {
|
||||
responsePromise.resolve(response$1);
|
||||
}, (reason) => {
|
||||
responsePromise.reject(reason);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.emitter.listenerCount("response") > 0) {
|
||||
this.logger.info("emitting the \"response\" event...");
|
||||
await require_hasConfigurableGlobal.emitAsync(this.emitter, "response", {
|
||||
response: response.clone(),
|
||||
isMockedResponse: true,
|
||||
request,
|
||||
requestId
|
||||
});
|
||||
}
|
||||
responsePromise.resolve(response);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request has been aborted!", { reason });
|
||||
responsePromise.reject(reason);
|
||||
}
|
||||
});
|
||||
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"));
|
||||
await require_handleRequest.handleRequest({
|
||||
request,
|
||||
requestId,
|
||||
emitter: this.emitter,
|
||||
controller
|
||||
});
|
||||
return responsePromise;
|
||||
};
|
||||
Object.defineProperty(globalThis.fetch, require_getRawRequest.IS_PATCHED_MODULE, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: true
|
||||
});
|
||||
this.subscriptions.push(() => {
|
||||
Object.defineProperty(globalThis.fetch, require_getRawRequest.IS_PATCHED_MODULE, { value: void 0 });
|
||||
globalThis.fetch = pureFetch;
|
||||
this.logger.info("restored native \"globalThis.fetch\"!", globalThis.fetch.name);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'FetchInterceptor', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return FetchInterceptor;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=fetch-U3v3Y4ap.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/fetch-U3v3Y4ap.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/fetch-U3v3Y4ap.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
218
node_modules/@mswjs/interceptors/lib/browser/getRawRequest-BTaNLFr0.mjs
generated
vendored
Normal file
218
node_modules/@mswjs/interceptors/lib/browser/getRawRequest-BTaNLFr0.mjs
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
import { DeferredPromise } from "@open-draft/deferred-promise";
|
||||
import { invariant } from "outvariant";
|
||||
|
||||
//#region src/glossary.ts
|
||||
const IS_PATCHED_MODULE = Symbol("isPatchedModule");
|
||||
|
||||
//#endregion
|
||||
//#region src/InterceptorError.ts
|
||||
var InterceptorError = class InterceptorError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "InterceptorError";
|
||||
Object.setPrototypeOf(this, InterceptorError.prototype);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/RequestController.ts
|
||||
var RequestController = class RequestController {
|
||||
static {
|
||||
this.PENDING = 0;
|
||||
}
|
||||
static {
|
||||
this.PASSTHROUGH = 1;
|
||||
}
|
||||
static {
|
||||
this.RESPONSE = 2;
|
||||
}
|
||||
static {
|
||||
this.ERROR = 3;
|
||||
}
|
||||
constructor(request, source) {
|
||||
this.request = request;
|
||||
this.source = source;
|
||||
this.readyState = RequestController.PENDING;
|
||||
this.handled = new DeferredPromise();
|
||||
}
|
||||
get #handled() {
|
||||
return this.handled;
|
||||
}
|
||||
/**
|
||||
* Perform this request as-is.
|
||||
*/
|
||||
async passthrough() {
|
||||
invariant.as(InterceptorError, this.readyState === RequestController.PENDING, "Failed to passthrough the \"%s %s\" request: the request has already been handled", this.request.method, this.request.url);
|
||||
this.readyState = RequestController.PASSTHROUGH;
|
||||
await this.source.passthrough();
|
||||
this.#handled.resolve();
|
||||
}
|
||||
/**
|
||||
* 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.readyState === RequestController.PENDING, "Failed to respond to the \"%s %s\" request with \"%d %s\": the request has already been handled (%d)", this.request.method, this.request.url, response.status, response.statusText || "OK", this.readyState);
|
||||
this.readyState = RequestController.RESPONSE;
|
||||
this.#handled.resolve();
|
||||
/**
|
||||
* @note Although `source.respondWith()` is potentially asynchronous,
|
||||
* do NOT await it for backward-compatibility. Awaiting it will short-circuit
|
||||
* the request listener invocation as soon as a listener responds to a request.
|
||||
* Ideally, that's what we want, but that's not what we promise the user.
|
||||
*/
|
||||
this.source.respondWith(response);
|
||||
}
|
||||
/**
|
||||
* Error this request with the given reason.
|
||||
*
|
||||
* @example
|
||||
* controller.errorWith()
|
||||
* controller.errorWith(new Error('Oops!'))
|
||||
* controller.errorWith({ message: 'Oops!'})
|
||||
*/
|
||||
errorWith(reason) {
|
||||
invariant.as(InterceptorError, this.readyState === RequestController.PENDING, "Failed to error the \"%s %s\" request with \"%s\": the request has already been handled (%d)", this.request.method, this.request.url, reason?.toString(), this.readyState);
|
||||
this.readyState = RequestController.ERROR;
|
||||
this.source.errorWith(reason);
|
||||
this.#handled.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/canParseUrl.ts
|
||||
/**
|
||||
* Returns a boolean indicating whether the given URL string
|
||||
* can be parsed into a `URL` instance.
|
||||
* A substitute for `URL.canParse()` for Node.js 18.
|
||||
*/
|
||||
function canParseUrl(url) {
|
||||
try {
|
||||
new URL(url);
|
||||
return true;
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/getValueBySymbol.ts
|
||||
/**
|
||||
* Returns the value behind the symbol with the given name.
|
||||
*/
|
||||
function getValueBySymbol(symbolName, source) {
|
||||
const symbol = Object.getOwnPropertySymbols(source).find((symbol$1) => {
|
||||
return symbol$1.description === symbolName;
|
||||
});
|
||||
if (symbol) return Reflect.get(source, symbol);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/fetchUtils.ts
|
||||
var FetchResponse = class FetchResponse extends Response {
|
||||
static {
|
||||
this.STATUS_CODES_WITHOUT_BODY = [
|
||||
101,
|
||||
103,
|
||||
204,
|
||||
205,
|
||||
304
|
||||
];
|
||||
}
|
||||
static {
|
||||
this.STATUS_CODES_WITH_REDIRECT = [
|
||||
301,
|
||||
302,
|
||||
303,
|
||||
307,
|
||||
308
|
||||
];
|
||||
}
|
||||
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 || url === "about:" || !canParseUrl(url)) return;
|
||||
const state = getValueBySymbol("state", response);
|
||||
if (state) state.urlList.push(new URL(url));
|
||||
else 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 = {}) {
|
||||
const status = init.status ?? 200;
|
||||
const safeStatus = FetchResponse.isConfigurableStatusCode(status) ? status : 200;
|
||||
const finalBody = FetchResponse.isResponseWithBody(status) ? body : null;
|
||||
super(finalBody, {
|
||||
status: safeStatus,
|
||||
statusText: init.statusText,
|
||||
headers: init.headers
|
||||
});
|
||||
if (status !== safeStatus) {
|
||||
/**
|
||||
* @note Undici keeps an internal "Symbol(state)" that holds
|
||||
* the actual value of response status. Update that in Node.js.
|
||||
*/
|
||||
const state = getValueBySymbol("state", this);
|
||||
if (state) state.status = status;
|
||||
else Object.defineProperty(this, "status", {
|
||||
value: status,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
FetchResponse.setUrl(init.url, this);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/getRawRequest.ts
|
||||
const kRawRequest = Symbol("kRawRequest");
|
||||
/**
|
||||
* Returns a raw request instance associated with this request.
|
||||
*
|
||||
* @example
|
||||
* interceptor.on('request', ({ request }) => {
|
||||
* const rawRequest = getRawRequest(request)
|
||||
*
|
||||
* if (rawRequest instanceof http.ClientRequest) {
|
||||
* console.log(rawRequest.rawHeaders)
|
||||
* }
|
||||
* })
|
||||
*/
|
||||
function getRawRequest(request) {
|
||||
return Reflect.get(request, kRawRequest);
|
||||
}
|
||||
function setRawRequest(request, rawRequest) {
|
||||
Reflect.set(request, kRawRequest, rawRequest);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { RequestController as a, canParseUrl as i, setRawRequest as n, InterceptorError as o, FetchResponse as r, IS_PATCHED_MODULE as s, getRawRequest as t };
|
||||
//# sourceMappingURL=getRawRequest-BTaNLFr0.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/getRawRequest-BTaNLFr0.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/getRawRequest-BTaNLFr0.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
259
node_modules/@mswjs/interceptors/lib/browser/getRawRequest-zx8rUJL2.cjs
generated
vendored
Normal file
259
node_modules/@mswjs/interceptors/lib/browser/getRawRequest-zx8rUJL2.cjs
generated
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
let _open_draft_deferred_promise = require("@open-draft/deferred-promise");
|
||||
let outvariant = require("outvariant");
|
||||
|
||||
//#region src/glossary.ts
|
||||
const IS_PATCHED_MODULE = Symbol("isPatchedModule");
|
||||
|
||||
//#endregion
|
||||
//#region src/InterceptorError.ts
|
||||
var InterceptorError = class InterceptorError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "InterceptorError";
|
||||
Object.setPrototypeOf(this, InterceptorError.prototype);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/RequestController.ts
|
||||
var RequestController = class RequestController {
|
||||
static {
|
||||
this.PENDING = 0;
|
||||
}
|
||||
static {
|
||||
this.PASSTHROUGH = 1;
|
||||
}
|
||||
static {
|
||||
this.RESPONSE = 2;
|
||||
}
|
||||
static {
|
||||
this.ERROR = 3;
|
||||
}
|
||||
constructor(request, source) {
|
||||
this.request = request;
|
||||
this.source = source;
|
||||
this.readyState = RequestController.PENDING;
|
||||
this.handled = new _open_draft_deferred_promise.DeferredPromise();
|
||||
}
|
||||
get #handled() {
|
||||
return this.handled;
|
||||
}
|
||||
/**
|
||||
* Perform this request as-is.
|
||||
*/
|
||||
async passthrough() {
|
||||
outvariant.invariant.as(InterceptorError, this.readyState === RequestController.PENDING, "Failed to passthrough the \"%s %s\" request: the request has already been handled", this.request.method, this.request.url);
|
||||
this.readyState = RequestController.PASSTHROUGH;
|
||||
await this.source.passthrough();
|
||||
this.#handled.resolve();
|
||||
}
|
||||
/**
|
||||
* 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.readyState === RequestController.PENDING, "Failed to respond to the \"%s %s\" request with \"%d %s\": the request has already been handled (%d)", this.request.method, this.request.url, response.status, response.statusText || "OK", this.readyState);
|
||||
this.readyState = RequestController.RESPONSE;
|
||||
this.#handled.resolve();
|
||||
/**
|
||||
* @note Although `source.respondWith()` is potentially asynchronous,
|
||||
* do NOT await it for backward-compatibility. Awaiting it will short-circuit
|
||||
* the request listener invocation as soon as a listener responds to a request.
|
||||
* Ideally, that's what we want, but that's not what we promise the user.
|
||||
*/
|
||||
this.source.respondWith(response);
|
||||
}
|
||||
/**
|
||||
* Error this request with the given reason.
|
||||
*
|
||||
* @example
|
||||
* controller.errorWith()
|
||||
* controller.errorWith(new Error('Oops!'))
|
||||
* controller.errorWith({ message: 'Oops!'})
|
||||
*/
|
||||
errorWith(reason) {
|
||||
outvariant.invariant.as(InterceptorError, this.readyState === RequestController.PENDING, "Failed to error the \"%s %s\" request with \"%s\": the request has already been handled (%d)", this.request.method, this.request.url, reason?.toString(), this.readyState);
|
||||
this.readyState = RequestController.ERROR;
|
||||
this.source.errorWith(reason);
|
||||
this.#handled.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/canParseUrl.ts
|
||||
/**
|
||||
* Returns a boolean indicating whether the given URL string
|
||||
* can be parsed into a `URL` instance.
|
||||
* A substitute for `URL.canParse()` for Node.js 18.
|
||||
*/
|
||||
function canParseUrl(url) {
|
||||
try {
|
||||
new URL(url);
|
||||
return true;
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/getValueBySymbol.ts
|
||||
/**
|
||||
* Returns the value behind the symbol with the given name.
|
||||
*/
|
||||
function getValueBySymbol(symbolName, source) {
|
||||
const symbol = Object.getOwnPropertySymbols(source).find((symbol$1) => {
|
||||
return symbol$1.description === symbolName;
|
||||
});
|
||||
if (symbol) return Reflect.get(source, symbol);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/fetchUtils.ts
|
||||
var FetchResponse = class FetchResponse extends Response {
|
||||
static {
|
||||
this.STATUS_CODES_WITHOUT_BODY = [
|
||||
101,
|
||||
103,
|
||||
204,
|
||||
205,
|
||||
304
|
||||
];
|
||||
}
|
||||
static {
|
||||
this.STATUS_CODES_WITH_REDIRECT = [
|
||||
301,
|
||||
302,
|
||||
303,
|
||||
307,
|
||||
308
|
||||
];
|
||||
}
|
||||
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 || url === "about:" || !canParseUrl(url)) return;
|
||||
const state = getValueBySymbol("state", response);
|
||||
if (state) state.urlList.push(new URL(url));
|
||||
else 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 = {}) {
|
||||
const status = init.status ?? 200;
|
||||
const safeStatus = FetchResponse.isConfigurableStatusCode(status) ? status : 200;
|
||||
const finalBody = FetchResponse.isResponseWithBody(status) ? body : null;
|
||||
super(finalBody, {
|
||||
status: safeStatus,
|
||||
statusText: init.statusText,
|
||||
headers: init.headers
|
||||
});
|
||||
if (status !== safeStatus) {
|
||||
/**
|
||||
* @note Undici keeps an internal "Symbol(state)" that holds
|
||||
* the actual value of response status. Update that in Node.js.
|
||||
*/
|
||||
const state = getValueBySymbol("state", this);
|
||||
if (state) state.status = status;
|
||||
else Object.defineProperty(this, "status", {
|
||||
value: status,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
FetchResponse.setUrl(init.url, this);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/getRawRequest.ts
|
||||
const kRawRequest = Symbol("kRawRequest");
|
||||
/**
|
||||
* Returns a raw request instance associated with this request.
|
||||
*
|
||||
* @example
|
||||
* interceptor.on('request', ({ request }) => {
|
||||
* const rawRequest = getRawRequest(request)
|
||||
*
|
||||
* if (rawRequest instanceof http.ClientRequest) {
|
||||
* console.log(rawRequest.rawHeaders)
|
||||
* }
|
||||
* })
|
||||
*/
|
||||
function getRawRequest(request) {
|
||||
return Reflect.get(request, kRawRequest);
|
||||
}
|
||||
function setRawRequest(request, rawRequest) {
|
||||
Reflect.set(request, kRawRequest, rawRequest);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'FetchResponse', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return FetchResponse;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'IS_PATCHED_MODULE', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return IS_PATCHED_MODULE;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'InterceptorError', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return InterceptorError;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'RequestController', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return RequestController;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'canParseUrl', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return canParseUrl;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'getRawRequest', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return getRawRequest;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'setRawRequest', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return setRawRequest;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=getRawRequest-zx8rUJL2.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/getRawRequest-zx8rUJL2.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/getRawRequest-zx8rUJL2.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
70
node_modules/@mswjs/interceptors/lib/browser/glossary-BdLS4k1H.d.cts
generated
vendored
Normal file
70
node_modules/@mswjs/interceptors/lib/browser/glossary-BdLS4k1H.d.cts
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
//#region src/RequestController.d.ts
|
||||
interface RequestControllerSource {
|
||||
passthrough(): void;
|
||||
respondWith(response: Response): void;
|
||||
errorWith(reason?: unknown): void;
|
||||
}
|
||||
declare class RequestController {
|
||||
#private;
|
||||
protected readonly request: Request;
|
||||
protected readonly source: RequestControllerSource;
|
||||
static PENDING: 0;
|
||||
static PASSTHROUGH: 1;
|
||||
static RESPONSE: 2;
|
||||
static ERROR: 3;
|
||||
readyState: number;
|
||||
/**
|
||||
* A Promise that resolves when this controller handles a request.
|
||||
* See `controller.readyState` for more information on the handling result.
|
||||
*/
|
||||
handled: Promise<void>;
|
||||
constructor(request: Request, source: RequestControllerSource);
|
||||
/**
|
||||
* Perform this request as-is.
|
||||
*/
|
||||
passthrough(): Promise<void>;
|
||||
/**
|
||||
* 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 reason.
|
||||
*
|
||||
* @example
|
||||
* controller.errorWith()
|
||||
* controller.errorWith(new Error('Oops!'))
|
||||
* controller.errorWith({ message: 'Oops!'})
|
||||
*/
|
||||
errorWith(reason?: unknown): void;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/glossary.d.ts
|
||||
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;
|
||||
}];
|
||||
};
|
||||
//#endregion
|
||||
export { RequestControllerSource as a, RequestController as i, IS_PATCHED_MODULE as n, RequestCredentials as r, HttpRequestEventMap as t };
|
||||
//# sourceMappingURL=glossary-BdLS4k1H.d.cts.map
|
||||
70
node_modules/@mswjs/interceptors/lib/browser/glossary-DYwOrogs.d.mts
generated
vendored
Normal file
70
node_modules/@mswjs/interceptors/lib/browser/glossary-DYwOrogs.d.mts
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
//#region src/RequestController.d.ts
|
||||
interface RequestControllerSource {
|
||||
passthrough(): void;
|
||||
respondWith(response: Response): void;
|
||||
errorWith(reason?: unknown): void;
|
||||
}
|
||||
declare class RequestController {
|
||||
#private;
|
||||
protected readonly request: Request;
|
||||
protected readonly source: RequestControllerSource;
|
||||
static PENDING: 0;
|
||||
static PASSTHROUGH: 1;
|
||||
static RESPONSE: 2;
|
||||
static ERROR: 3;
|
||||
readyState: number;
|
||||
/**
|
||||
* A Promise that resolves when this controller handles a request.
|
||||
* See `controller.readyState` for more information on the handling result.
|
||||
*/
|
||||
handled: Promise<void>;
|
||||
constructor(request: Request, source: RequestControllerSource);
|
||||
/**
|
||||
* Perform this request as-is.
|
||||
*/
|
||||
passthrough(): Promise<void>;
|
||||
/**
|
||||
* 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 reason.
|
||||
*
|
||||
* @example
|
||||
* controller.errorWith()
|
||||
* controller.errorWith(new Error('Oops!'))
|
||||
* controller.errorWith({ message: 'Oops!'})
|
||||
*/
|
||||
errorWith(reason?: unknown): void;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/glossary.d.ts
|
||||
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;
|
||||
}];
|
||||
};
|
||||
//#endregion
|
||||
export { RequestControllerSource as a, RequestController as i, IS_PATCHED_MODULE as n, RequestCredentials as r, HttpRequestEventMap as t };
|
||||
//# sourceMappingURL=glossary-DYwOrogs.d.mts.map
|
||||
189
node_modules/@mswjs/interceptors/lib/browser/handleRequest-CvX2G-Lz.cjs
generated
vendored
Normal file
189
node_modules/@mswjs/interceptors/lib/browser/handleRequest-CvX2G-Lz.cjs
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
const require_getRawRequest = require('./getRawRequest-zx8rUJL2.cjs');
|
||||
const require_hasConfigurableGlobal = require('./hasConfigurableGlobal-BvCTG97d.cjs');
|
||||
let _open_draft_deferred_promise = require("@open-draft/deferred-promise");
|
||||
let _open_draft_until = require("@open-draft/until");
|
||||
|
||||
//#region src/utils/isObject.ts
|
||||
/**
|
||||
* Determines if a given value is an instance of object.
|
||||
*/
|
||||
function isObject(value, loose = false) {
|
||||
return loose ? Object.prototype.toString.call(value).startsWith("[object ") : Object.prototype.toString.call(value) === "[object Object]";
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/isPropertyAccessible.ts
|
||||
/**
|
||||
* A function that validates if property access is possible on an object
|
||||
* without throwing. It returns `true` if the property access is possible
|
||||
* and `false` otherwise.
|
||||
*
|
||||
* Environments like miniflare will throw on property access on certain objects
|
||||
* like Request and Response, for unimplemented properties.
|
||||
*/
|
||||
function isPropertyAccessible(obj, key) {
|
||||
try {
|
||||
obj[key];
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/responseUtils.ts
|
||||
/**
|
||||
* Creates a generic 500 Unhandled Exception response.
|
||||
*/
|
||||
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" }
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Check if the given response is a `Response.error()`.
|
||||
*
|
||||
* @note Some environments, like Miniflare (Cloudflare) do not
|
||||
* implement the "Response.type" property and throw on its access.
|
||||
* Safely check if we can access "type" on "Response" before continuing.
|
||||
* @see https://github.com/mswjs/msw/issues/1834
|
||||
*/
|
||||
function isResponseError(response) {
|
||||
return response != null && response instanceof Response && isPropertyAccessible(response, "type") && response.type === "error";
|
||||
}
|
||||
/**
|
||||
* Check if the given value is a `Response` or a Response-like object.
|
||||
* This is different from `value instanceof Response` because it supports
|
||||
* custom `Response` constructors, like the one when using Undici directly.
|
||||
*/
|
||||
function isResponseLike(value) {
|
||||
return isObject(value, true) && isPropertyAccessible(value, "status") && isPropertyAccessible(value, "statusText") && isPropertyAccessible(value, "bodyUsed");
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region 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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/handleRequest.ts
|
||||
async function handleRequest(options) {
|
||||
const handleResponse = async (response) => {
|
||||
if (response instanceof Error) {
|
||||
await options.controller.errorWith(response);
|
||||
return true;
|
||||
}
|
||||
if (isResponseError(response)) {
|
||||
await options.controller.respondWith(response);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Handle normal responses or response-like objects.
|
||||
* @note This must come before the arbitrary object check
|
||||
* since Response instances are, in fact, objects.
|
||||
*/
|
||||
if (isResponseLike(response)) {
|
||||
await options.controller.respondWith(response);
|
||||
return true;
|
||||
}
|
||||
if (isObject(response)) {
|
||||
await options.controller.errorWith(response);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const handleResponseError = async (error) => {
|
||||
if (error instanceof require_getRawRequest.InterceptorError) throw result.error;
|
||||
if (isNodeLikeError(error)) {
|
||||
await options.controller.errorWith(error);
|
||||
return true;
|
||||
}
|
||||
if (error instanceof Response) return await handleResponse(error);
|
||||
return false;
|
||||
};
|
||||
const requestAbortPromise = new _open_draft_deferred_promise.DeferredPromise();
|
||||
/**
|
||||
* @note `signal` is not always defined in React Native.
|
||||
*/
|
||||
if (options.request.signal) {
|
||||
if (options.request.signal.aborted) {
|
||||
await options.controller.errorWith(options.request.signal.reason);
|
||||
return;
|
||||
}
|
||||
options.request.signal.addEventListener("abort", () => {
|
||||
requestAbortPromise.reject(options.request.signal.reason);
|
||||
}, { once: true });
|
||||
}
|
||||
const result = await (0, _open_draft_until.until)(async () => {
|
||||
const requestListenersPromise = require_hasConfigurableGlobal.emitAsync(options.emitter, "request", {
|
||||
requestId: options.requestId,
|
||||
request: options.request,
|
||||
controller: options.controller
|
||||
});
|
||||
await Promise.race([
|
||||
requestAbortPromise,
|
||||
requestListenersPromise,
|
||||
options.controller.handled
|
||||
]);
|
||||
});
|
||||
if (requestAbortPromise.state === "rejected") {
|
||||
await options.controller.errorWith(requestAbortPromise.rejectionReason);
|
||||
return;
|
||||
}
|
||||
if (result.error) {
|
||||
if (await handleResponseError(result.error)) return;
|
||||
if (options.emitter.listenerCount("unhandledException") > 0) {
|
||||
const unhandledExceptionController = new require_getRawRequest.RequestController(options.request, {
|
||||
passthrough() {},
|
||||
async respondWith(response) {
|
||||
await handleResponse(response);
|
||||
},
|
||||
async errorWith(reason) {
|
||||
/**
|
||||
* @note Handle the result of the unhandled controller
|
||||
* in the same way as the original request controller.
|
||||
* The exception here is that thrown errors within the
|
||||
* "unhandledException" event do NOT result in another
|
||||
* emit of the same event. They are forwarded as-is.
|
||||
*/
|
||||
await options.controller.errorWith(reason);
|
||||
}
|
||||
});
|
||||
await require_hasConfigurableGlobal.emitAsync(options.emitter, "unhandledException", {
|
||||
error: result.error,
|
||||
request: options.request,
|
||||
requestId: options.requestId,
|
||||
controller: unhandledExceptionController
|
||||
});
|
||||
if (unhandledExceptionController.readyState !== require_getRawRequest.RequestController.PENDING) return;
|
||||
}
|
||||
await options.controller.respondWith(createServerErrorResponse(result.error));
|
||||
return;
|
||||
}
|
||||
if (options.controller.readyState === require_getRawRequest.RequestController.PENDING) return await options.controller.passthrough();
|
||||
return options.controller.handled;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'handleRequest', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return handleRequest;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'isResponseError', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return isResponseError;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=handleRequest-CvX2G-Lz.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/handleRequest-CvX2G-Lz.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/handleRequest-CvX2G-Lz.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
178
node_modules/@mswjs/interceptors/lib/browser/handleRequest-D7kpTI5U.mjs
generated
vendored
Normal file
178
node_modules/@mswjs/interceptors/lib/browser/handleRequest-D7kpTI5U.mjs
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
import { a as RequestController, o as InterceptorError } from "./getRawRequest-BTaNLFr0.mjs";
|
||||
import { n as emitAsync } from "./hasConfigurableGlobal-npXitu1-.mjs";
|
||||
import { DeferredPromise } from "@open-draft/deferred-promise";
|
||||
import { until } from "@open-draft/until";
|
||||
|
||||
//#region src/utils/isObject.ts
|
||||
/**
|
||||
* Determines if a given value is an instance of object.
|
||||
*/
|
||||
function isObject(value, loose = false) {
|
||||
return loose ? Object.prototype.toString.call(value).startsWith("[object ") : Object.prototype.toString.call(value) === "[object Object]";
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/isPropertyAccessible.ts
|
||||
/**
|
||||
* A function that validates if property access is possible on an object
|
||||
* without throwing. It returns `true` if the property access is possible
|
||||
* and `false` otherwise.
|
||||
*
|
||||
* Environments like miniflare will throw on property access on certain objects
|
||||
* like Request and Response, for unimplemented properties.
|
||||
*/
|
||||
function isPropertyAccessible(obj, key) {
|
||||
try {
|
||||
obj[key];
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/responseUtils.ts
|
||||
/**
|
||||
* Creates a generic 500 Unhandled Exception response.
|
||||
*/
|
||||
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" }
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Check if the given response is a `Response.error()`.
|
||||
*
|
||||
* @note Some environments, like Miniflare (Cloudflare) do not
|
||||
* implement the "Response.type" property and throw on its access.
|
||||
* Safely check if we can access "type" on "Response" before continuing.
|
||||
* @see https://github.com/mswjs/msw/issues/1834
|
||||
*/
|
||||
function isResponseError(response) {
|
||||
return response != null && response instanceof Response && isPropertyAccessible(response, "type") && response.type === "error";
|
||||
}
|
||||
/**
|
||||
* Check if the given value is a `Response` or a Response-like object.
|
||||
* This is different from `value instanceof Response` because it supports
|
||||
* custom `Response` constructors, like the one when using Undici directly.
|
||||
*/
|
||||
function isResponseLike(value) {
|
||||
return isObject(value, true) && isPropertyAccessible(value, "status") && isPropertyAccessible(value, "statusText") && isPropertyAccessible(value, "bodyUsed");
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region 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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/handleRequest.ts
|
||||
async function handleRequest(options) {
|
||||
const handleResponse = async (response) => {
|
||||
if (response instanceof Error) {
|
||||
await options.controller.errorWith(response);
|
||||
return true;
|
||||
}
|
||||
if (isResponseError(response)) {
|
||||
await options.controller.respondWith(response);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Handle normal responses or response-like objects.
|
||||
* @note This must come before the arbitrary object check
|
||||
* since Response instances are, in fact, objects.
|
||||
*/
|
||||
if (isResponseLike(response)) {
|
||||
await options.controller.respondWith(response);
|
||||
return true;
|
||||
}
|
||||
if (isObject(response)) {
|
||||
await options.controller.errorWith(response);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const handleResponseError = async (error) => {
|
||||
if (error instanceof InterceptorError) throw result.error;
|
||||
if (isNodeLikeError(error)) {
|
||||
await options.controller.errorWith(error);
|
||||
return true;
|
||||
}
|
||||
if (error instanceof Response) return await handleResponse(error);
|
||||
return false;
|
||||
};
|
||||
const requestAbortPromise = new DeferredPromise();
|
||||
/**
|
||||
* @note `signal` is not always defined in React Native.
|
||||
*/
|
||||
if (options.request.signal) {
|
||||
if (options.request.signal.aborted) {
|
||||
await options.controller.errorWith(options.request.signal.reason);
|
||||
return;
|
||||
}
|
||||
options.request.signal.addEventListener("abort", () => {
|
||||
requestAbortPromise.reject(options.request.signal.reason);
|
||||
}, { once: true });
|
||||
}
|
||||
const result = await until(async () => {
|
||||
const requestListenersPromise = emitAsync(options.emitter, "request", {
|
||||
requestId: options.requestId,
|
||||
request: options.request,
|
||||
controller: options.controller
|
||||
});
|
||||
await Promise.race([
|
||||
requestAbortPromise,
|
||||
requestListenersPromise,
|
||||
options.controller.handled
|
||||
]);
|
||||
});
|
||||
if (requestAbortPromise.state === "rejected") {
|
||||
await options.controller.errorWith(requestAbortPromise.rejectionReason);
|
||||
return;
|
||||
}
|
||||
if (result.error) {
|
||||
if (await handleResponseError(result.error)) return;
|
||||
if (options.emitter.listenerCount("unhandledException") > 0) {
|
||||
const unhandledExceptionController = new RequestController(options.request, {
|
||||
passthrough() {},
|
||||
async respondWith(response) {
|
||||
await handleResponse(response);
|
||||
},
|
||||
async errorWith(reason) {
|
||||
/**
|
||||
* @note Handle the result of the unhandled controller
|
||||
* in the same way as the original request controller.
|
||||
* The exception here is that thrown errors within the
|
||||
* "unhandledException" event do NOT result in another
|
||||
* emit of the same event. They are forwarded as-is.
|
||||
*/
|
||||
await options.controller.errorWith(reason);
|
||||
}
|
||||
});
|
||||
await emitAsync(options.emitter, "unhandledException", {
|
||||
error: result.error,
|
||||
request: options.request,
|
||||
requestId: options.requestId,
|
||||
controller: unhandledExceptionController
|
||||
});
|
||||
if (unhandledExceptionController.readyState !== RequestController.PENDING) return;
|
||||
}
|
||||
await options.controller.respondWith(createServerErrorResponse(result.error));
|
||||
return;
|
||||
}
|
||||
if (options.controller.readyState === RequestController.PENDING) return await options.controller.passthrough();
|
||||
return options.controller.handled;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { isResponseError as n, handleRequest as t };
|
||||
//# sourceMappingURL=handleRequest-D7kpTI5U.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/handleRequest-D7kpTI5U.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/handleRequest-D7kpTI5U.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
45
node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs
generated
vendored
Normal file
45
node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
//#region src/utils/emitAsync.ts
|
||||
/**
|
||||
* Emits an event on the given emitter but executes
|
||||
* the listeners sequentially. This accounts for asynchronous
|
||||
* listeners (e.g. those having "sleep" and handling the request).
|
||||
*/
|
||||
async function emitAsync(emitter, eventName, ...data) {
|
||||
const listeners = emitter.listeners(eventName);
|
||||
if (listeners.length === 0) return;
|
||||
for (const listener of listeners) await listener.apply(emitter, data);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/hasConfigurableGlobal.ts
|
||||
/**
|
||||
* Returns a boolean indicating whether the given global property
|
||||
* is defined and is configurable.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'emitAsync', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return emitAsync;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'hasConfigurableGlobal', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return hasConfigurableGlobal;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=hasConfigurableGlobal-BvCTG97d.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"hasConfigurableGlobal-BvCTG97d.cjs","names":[],"sources":["../../src/utils/emitAsync.ts","../../src/utils/hasConfigurableGlobal.ts"],"sourcesContent":["import { Emitter, EventMap } from 'strict-event-emitter'\n\n/**\n * Emits an event on the given emitter but executes\n * the listeners sequentially. This accounts for asynchronous\n * listeners (e.g. those having \"sleep\" and handling the request).\n */\nexport async function emitAsync<\n Events extends EventMap,\n EventName extends keyof Events\n>(\n emitter: Emitter<Events>,\n eventName: EventName,\n ...data: Events[EventName]\n): Promise<void> {\n const listeners = emitter.listeners(eventName)\n\n if (listeners.length === 0) {\n return\n }\n\n for (const listener of listeners) {\n await listener.apply(emitter, data)\n }\n}\n","/**\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":";;;;;;;AAOA,eAAsB,UAIpB,SACA,WACA,GAAG,MACY;CACf,MAAM,YAAY,QAAQ,UAAU,UAAU;AAE9C,KAAI,UAAU,WAAW,EACvB;AAGF,MAAK,MAAM,YAAY,UACrB,OAAM,SAAS,MAAM,SAAS,KAAK;;;;;;;;;AClBvC,SAAgB,sBAAsB,cAA+B;CACnE,MAAM,aAAa,OAAO,yBAAyB,YAAY,aAAa;AAG5E,KAAI,OAAO,eAAe,YACxB,QAAO;AAIT,KACE,OAAO,WAAW,QAAQ,cAC1B,OAAO,WAAW,KAAK,KAAK,YAE5B,QAAO;AAIT,KAAI,OAAO,WAAW,QAAQ,eAAe,WAAW,SAAS,KAC/D,QAAO;AAGT,KAAI,OAAO,WAAW,QAAQ,eAAe,CAAC,WAAW,cAAc;AACrE,UAAQ,MACN,mDAAmD,aAAa,oKACjE;AACD,SAAO;;AAGT,QAAO"}
|
||||
33
node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-npXitu1-.mjs
generated
vendored
Normal file
33
node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-npXitu1-.mjs
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
//#region src/utils/emitAsync.ts
|
||||
/**
|
||||
* Emits an event on the given emitter but executes
|
||||
* the listeners sequentially. This accounts for asynchronous
|
||||
* listeners (e.g. those having "sleep" and handling the request).
|
||||
*/
|
||||
async function emitAsync(emitter, eventName, ...data) {
|
||||
const listeners = emitter.listeners(eventName);
|
||||
if (listeners.length === 0) return;
|
||||
for (const listener of listeners) await listener.apply(emitter, data);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/hasConfigurableGlobal.ts
|
||||
/**
|
||||
* Returns a boolean indicating whether the given global property
|
||||
* is defined and is configurable.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { emitAsync as n, hasConfigurableGlobal as t };
|
||||
//# sourceMappingURL=hasConfigurableGlobal-npXitu1-.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-npXitu1-.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-npXitu1-.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"hasConfigurableGlobal-npXitu1-.mjs","names":[],"sources":["../../src/utils/emitAsync.ts","../../src/utils/hasConfigurableGlobal.ts"],"sourcesContent":["import { Emitter, EventMap } from 'strict-event-emitter'\n\n/**\n * Emits an event on the given emitter but executes\n * the listeners sequentially. This accounts for asynchronous\n * listeners (e.g. those having \"sleep\" and handling the request).\n */\nexport async function emitAsync<\n Events extends EventMap,\n EventName extends keyof Events\n>(\n emitter: Emitter<Events>,\n eventName: EventName,\n ...data: Events[EventName]\n): Promise<void> {\n const listeners = emitter.listeners(eventName)\n\n if (listeners.length === 0) {\n return\n }\n\n for (const listener of listeners) {\n await listener.apply(emitter, data)\n }\n}\n","/**\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":";;;;;;AAOA,eAAsB,UAIpB,SACA,WACA,GAAG,MACY;CACf,MAAM,YAAY,QAAQ,UAAU,UAAU;AAE9C,KAAI,UAAU,WAAW,EACvB;AAGF,MAAK,MAAM,YAAY,UACrB,OAAM,SAAS,MAAM,SAAS,KAAK;;;;;;;;;AClBvC,SAAgB,sBAAsB,cAA+B;CACnE,MAAM,aAAa,OAAO,yBAAyB,YAAY,aAAa;AAG5E,KAAI,OAAO,eAAe,YACxB,QAAO;AAIT,KACE,OAAO,WAAW,QAAQ,cAC1B,OAAO,WAAW,KAAK,KAAK,YAE5B,QAAO;AAIT,KAAI,OAAO,WAAW,QAAQ,eAAe,WAAW,SAAS,KAC/D,QAAO;AAGT,KAAI,OAAO,WAAW,QAAQ,eAAe,CAAC,WAAW,cAAc;AACrE,UAAQ,MACN,mDAAmD,aAAa,oKACjE;AACD,SAAO;;AAGT,QAAO"}
|
||||
70
node_modules/@mswjs/interceptors/lib/browser/index.cjs
generated
vendored
Normal file
70
node_modules/@mswjs/interceptors/lib/browser/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
const require_getRawRequest = require('./getRawRequest-zx8rUJL2.cjs');
|
||||
const require_createRequestId = require('./createRequestId-Cs4oXfa1.cjs');
|
||||
const require_bufferUtils = require('./bufferUtils-Uc0eRItL.cjs');
|
||||
const require_resolveWebSocketUrl = require('./resolveWebSocketUrl-6K6EgqsA.cjs');
|
||||
|
||||
//#region src/BatchInterceptor.ts
|
||||
/**
|
||||
* A batch interceptor that exposes a single interface
|
||||
* to apply and operate with multiple interceptors at once.
|
||||
*/
|
||||
var BatchInterceptor = class BatchInterceptor extends require_createRequestId.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;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/getCleanUrl.ts
|
||||
/**
|
||||
* Removes query parameters and hashes from a given URL.
|
||||
*/
|
||||
function getCleanUrl(url, isAbsolute = true) {
|
||||
return [isAbsolute && url.origin, url.pathname].filter(Boolean).join("");
|
||||
}
|
||||
|
||||
//#endregion
|
||||
exports.BatchInterceptor = BatchInterceptor;
|
||||
exports.FetchResponse = require_getRawRequest.FetchResponse;
|
||||
exports.INTERNAL_REQUEST_ID_HEADER_NAME = require_createRequestId.INTERNAL_REQUEST_ID_HEADER_NAME;
|
||||
exports.IS_PATCHED_MODULE = require_getRawRequest.IS_PATCHED_MODULE;
|
||||
exports.Interceptor = require_createRequestId.Interceptor;
|
||||
exports.InterceptorReadyState = require_createRequestId.InterceptorReadyState;
|
||||
exports.RequestController = require_getRawRequest.RequestController;
|
||||
exports.createRequestId = require_createRequestId.createRequestId;
|
||||
exports.decodeBuffer = require_bufferUtils.decodeBuffer;
|
||||
exports.deleteGlobalSymbol = require_createRequestId.deleteGlobalSymbol;
|
||||
exports.encodeBuffer = require_bufferUtils.encodeBuffer;
|
||||
exports.getCleanUrl = getCleanUrl;
|
||||
exports.getGlobalSymbol = require_createRequestId.getGlobalSymbol;
|
||||
exports.getRawRequest = require_getRawRequest.getRawRequest;
|
||||
exports.resolveWebSocketUrl = require_resolveWebSocketUrl.resolveWebSocketUrl;
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/index.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/index.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.cjs","names":["Interceptor"],"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":";;;;;;;;;;AAsBA,IAAa,mBAAb,MAAa,yBAGHA,oCAAoB;CAK5B,YAAY,SAAmD;AAC7D,mBAAiB,SAAS,OAAO,QAAQ,KAAK;AAC9C,QAAM,iBAAiB,OAAO;AAC9B,OAAK,eAAe,QAAQ;;CAG9B,AAAU,QAAQ;EAChB,MAAM,SAAS,KAAK,OAAO,OAAO,QAAQ;AAE1C,SAAO,KAAK,mCAAmC,KAAK,aAAa,OAAO;AAExE,OAAK,MAAM,eAAe,KAAK,cAAc;AAC3C,UAAO,KAAK,kCAAgC,YAAY,YAAY,KAAK;AACzE,eAAY,OAAO;AAEnB,UAAO,KAAK,0CAA0C;AACtD,QAAK,cAAc,WAAW,YAAY,SAAS,CAAC;;;CAIxD,AAAO,GACL,OACA,UACM;AAGN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,GAAG,OAAO,SAAS;AAGjC,SAAO;;CAGT,AAAO,KACL,OACA,UACM;AACN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,KAAK,OAAO,SAAS;AAGnC,SAAO;;CAGT,AAAO,IACL,OACA,UACM;AACN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,IAAI,OAAO,SAAS;AAGlC,SAAO;;CAGT,AAAO,mBACL,OACM;AACN,OAAK,MAAM,gBAAgB,KAAK,aAC9B,cAAa,mBAAmB,MAAM;AAGxC,SAAO;;;;;;;;;ACzFX,SAAgB,YAAY,KAAU,aAAsB,MAAc;AACxE,QAAO,CAAC,cAAc,IAAI,QAAQ,IAAI,SAAS,CAAC,OAAO,QAAQ,CAAC,KAAK,GAAG"}
|
||||
96
node_modules/@mswjs/interceptors/lib/browser/index.d.cts
generated
vendored
Normal file
96
node_modules/@mswjs/interceptors/lib/browser/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
import { a as RequestControllerSource, i as RequestController, n as IS_PATCHED_MODULE, r as RequestCredentials, t as HttpRequestEventMap } from "./glossary-BdLS4k1H.cjs";
|
||||
import { a as InterceptorReadyState, c as getGlobalSymbol, i as InterceptorEventMap, n as INTERNAL_REQUEST_ID_HEADER_NAME, o as InterceptorSubscription, r as Interceptor, s as deleteGlobalSymbol, t as ExtractEventNames } from "./Interceptor-Deczogc8.cjs";
|
||||
import { EventMap, Listener } from "strict-event-emitter";
|
||||
|
||||
//#region src/BatchInterceptor.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/createRequestId.d.ts
|
||||
/**
|
||||
* Generate a random ID string to represent a request.
|
||||
* @example
|
||||
* createRequestId()
|
||||
* // "f774b6c9c600f"
|
||||
*/
|
||||
declare function createRequestId(): string;
|
||||
//#endregion
|
||||
//#region src/utils/getCleanUrl.d.ts
|
||||
/**
|
||||
* Removes query parameters and hashes from a given URL.
|
||||
*/
|
||||
declare function getCleanUrl(url: URL, isAbsolute?: boolean): string;
|
||||
//#endregion
|
||||
//#region src/utils/bufferUtils.d.ts
|
||||
declare function encodeBuffer(text: string): Uint8Array;
|
||||
declare function decodeBuffer(buffer: ArrayBuffer, encoding?: string): string;
|
||||
//#endregion
|
||||
//#region src/utils/fetchUtils.d.ts
|
||||
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);
|
||||
}
|
||||
//#endregion
|
||||
//#region src/getRawRequest.d.ts
|
||||
/**
|
||||
* Returns a raw request instance associated with this request.
|
||||
*
|
||||
* @example
|
||||
* interceptor.on('request', ({ request }) => {
|
||||
* const rawRequest = getRawRequest(request)
|
||||
*
|
||||
* if (rawRequest instanceof http.ClientRequest) {
|
||||
* console.log(rawRequest.rawHeaders)
|
||||
* }
|
||||
* })
|
||||
*/
|
||||
declare function getRawRequest(request: Request): unknown | undefined;
|
||||
//#endregion
|
||||
//#region src/utils/resolveWebSocketUrl.d.ts
|
||||
/**
|
||||
* Resolve potentially relative WebSocket URLs the same way
|
||||
* the browser does (replace the protocol, use the origin, etc).
|
||||
*
|
||||
* @see https://websockets.spec.whatwg.org//#dom-websocket-websocket
|
||||
*/
|
||||
declare function resolveWebSocketUrl(url: string | URL): string;
|
||||
//#endregion
|
||||
export { BatchInterceptor, BatchInterceptorOptions, ExtractEventMapType, ExtractEventNames, FetchResponse, HttpRequestEventMap, INTERNAL_REQUEST_ID_HEADER_NAME, IS_PATCHED_MODULE, Interceptor, InterceptorEventMap, InterceptorReadyState, InterceptorSubscription, RequestController, type RequestControllerSource, RequestCredentials, createRequestId, decodeBuffer, deleteGlobalSymbol, encodeBuffer, getCleanUrl, getGlobalSymbol, getRawRequest, resolveWebSocketUrl };
|
||||
//# sourceMappingURL=index.d.cts.map
|
||||
96
node_modules/@mswjs/interceptors/lib/browser/index.d.mts
generated
vendored
Normal file
96
node_modules/@mswjs/interceptors/lib/browser/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
import { a as RequestControllerSource, i as RequestController, n as IS_PATCHED_MODULE, r as RequestCredentials, t as HttpRequestEventMap } from "./glossary-DYwOrogs.mjs";
|
||||
import { a as InterceptorReadyState, c as getGlobalSymbol, i as InterceptorEventMap, n as INTERNAL_REQUEST_ID_HEADER_NAME, o as InterceptorSubscription, r as Interceptor, s as deleteGlobalSymbol, t as ExtractEventNames } from "./Interceptor-gqKgs-aF.mjs";
|
||||
import { EventMap, Listener } from "strict-event-emitter";
|
||||
|
||||
//#region src/BatchInterceptor.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/createRequestId.d.ts
|
||||
/**
|
||||
* Generate a random ID string to represent a request.
|
||||
* @example
|
||||
* createRequestId()
|
||||
* // "f774b6c9c600f"
|
||||
*/
|
||||
declare function createRequestId(): string;
|
||||
//#endregion
|
||||
//#region src/utils/getCleanUrl.d.ts
|
||||
/**
|
||||
* Removes query parameters and hashes from a given URL.
|
||||
*/
|
||||
declare function getCleanUrl(url: URL, isAbsolute?: boolean): string;
|
||||
//#endregion
|
||||
//#region src/utils/bufferUtils.d.ts
|
||||
declare function encodeBuffer(text: string): Uint8Array;
|
||||
declare function decodeBuffer(buffer: ArrayBuffer, encoding?: string): string;
|
||||
//#endregion
|
||||
//#region src/utils/fetchUtils.d.ts
|
||||
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);
|
||||
}
|
||||
//#endregion
|
||||
//#region src/getRawRequest.d.ts
|
||||
/**
|
||||
* Returns a raw request instance associated with this request.
|
||||
*
|
||||
* @example
|
||||
* interceptor.on('request', ({ request }) => {
|
||||
* const rawRequest = getRawRequest(request)
|
||||
*
|
||||
* if (rawRequest instanceof http.ClientRequest) {
|
||||
* console.log(rawRequest.rawHeaders)
|
||||
* }
|
||||
* })
|
||||
*/
|
||||
declare function getRawRequest(request: Request): unknown | undefined;
|
||||
//#endregion
|
||||
//#region src/utils/resolveWebSocketUrl.d.ts
|
||||
/**
|
||||
* Resolve potentially relative WebSocket URLs the same way
|
||||
* the browser does (replace the protocol, use the origin, etc).
|
||||
*
|
||||
* @see https://websockets.spec.whatwg.org//#dom-websocket-websocket
|
||||
*/
|
||||
declare function resolveWebSocketUrl(url: string | URL): string;
|
||||
//#endregion
|
||||
export { BatchInterceptor, BatchInterceptorOptions, ExtractEventMapType, ExtractEventNames, FetchResponse, HttpRequestEventMap, INTERNAL_REQUEST_ID_HEADER_NAME, IS_PATCHED_MODULE, Interceptor, InterceptorEventMap, InterceptorReadyState, InterceptorSubscription, RequestController, type RequestControllerSource, RequestCredentials, createRequestId, decodeBuffer, deleteGlobalSymbol, encodeBuffer, getCleanUrl, getGlobalSymbol, getRawRequest, resolveWebSocketUrl };
|
||||
//# sourceMappingURL=index.d.mts.map
|
||||
56
node_modules/@mswjs/interceptors/lib/browser/index.mjs
generated
vendored
Normal file
56
node_modules/@mswjs/interceptors/lib/browser/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
import { a as RequestController, r as FetchResponse, s as IS_PATCHED_MODULE, t as getRawRequest } from "./getRawRequest-BTaNLFr0.mjs";
|
||||
import { a as deleteGlobalSymbol, i as InterceptorReadyState, n as INTERNAL_REQUEST_ID_HEADER_NAME, o as getGlobalSymbol, r as Interceptor, t as createRequestId } from "./createRequestId-DQcIlohW.mjs";
|
||||
import { n as encodeBuffer, t as decodeBuffer } from "./bufferUtils-BiiO6HZv.mjs";
|
||||
import { t as resolveWebSocketUrl } from "./resolveWebSocketUrl-C83-x9iE.mjs";
|
||||
|
||||
//#region src/BatchInterceptor.ts
|
||||
/**
|
||||
* A batch interceptor that exposes a single interface
|
||||
* to apply and operate with multiple interceptors at once.
|
||||
*/
|
||||
var BatchInterceptor = class BatchInterceptor 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;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/getCleanUrl.ts
|
||||
/**
|
||||
* Removes query parameters and hashes from a given URL.
|
||||
*/
|
||||
function getCleanUrl(url, isAbsolute = true) {
|
||||
return [isAbsolute && url.origin, url.pathname].filter(Boolean).join("");
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { BatchInterceptor, FetchResponse, INTERNAL_REQUEST_ID_HEADER_NAME, IS_PATCHED_MODULE, Interceptor, InterceptorReadyState, RequestController, createRequestId, decodeBuffer, deleteGlobalSymbol, encodeBuffer, getCleanUrl, getGlobalSymbol, getRawRequest, resolveWebSocketUrl };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/index.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/index.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","names":[],"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":";;;;;;;;;;AAsBA,IAAa,mBAAb,MAAa,yBAGH,YAAoB;CAK5B,YAAY,SAAmD;AAC7D,mBAAiB,SAAS,OAAO,QAAQ,KAAK;AAC9C,QAAM,iBAAiB,OAAO;AAC9B,OAAK,eAAe,QAAQ;;CAG9B,AAAU,QAAQ;EAChB,MAAM,SAAS,KAAK,OAAO,OAAO,QAAQ;AAE1C,SAAO,KAAK,mCAAmC,KAAK,aAAa,OAAO;AAExE,OAAK,MAAM,eAAe,KAAK,cAAc;AAC3C,UAAO,KAAK,kCAAgC,YAAY,YAAY,KAAK;AACzE,eAAY,OAAO;AAEnB,UAAO,KAAK,0CAA0C;AACtD,QAAK,cAAc,WAAW,YAAY,SAAS,CAAC;;;CAIxD,AAAO,GACL,OACA,UACM;AAGN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,GAAG,OAAO,SAAS;AAGjC,SAAO;;CAGT,AAAO,KACL,OACA,UACM;AACN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,KAAK,OAAO,SAAS;AAGnC,SAAO;;CAGT,AAAO,IACL,OACA,UACM;AACN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,IAAI,OAAO,SAAS;AAGlC,SAAO;;CAGT,AAAO,mBACL,OACM;AACN,OAAK,MAAM,gBAAgB,KAAK,aAC9B,cAAa,mBAAmB,MAAM;AAGxC,SAAO;;;;;;;;;ACzFX,SAAgB,YAAY,KAAU,aAAsB,MAAc;AACxE,QAAO,CAAC,cAAc,IAAI,QAAQ,IAAI,SAAS,CAAC,OAAO,QAAQ,CAAC,KAAK,GAAG"}
|
||||
622
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.cjs
generated
vendored
Normal file
622
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,622 @@
|
||||
const require_createRequestId = require('../../createRequestId-Cs4oXfa1.cjs');
|
||||
const require_resolveWebSocketUrl = require('../../resolveWebSocketUrl-6K6EgqsA.cjs');
|
||||
const require_hasConfigurableGlobal = require('../../hasConfigurableGlobal-BvCTG97d.cjs');
|
||||
let _open_draft_deferred_promise = require("@open-draft/deferred-promise");
|
||||
let outvariant = require("outvariant");
|
||||
|
||||
//#region 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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/utils/events.ts
|
||||
const kCancelable = Symbol("kCancelable");
|
||||
const kDefaultPrevented = Symbol("kDefaultPrevented");
|
||||
/**
|
||||
* A `MessageEvent` superset that supports event cancellation
|
||||
* in Node.js. It's rather non-intrusive so it can be safely
|
||||
* used in the browser as well.
|
||||
*
|
||||
* @see https://github.com/nodejs/node/issues/51767
|
||||
*/
|
||||
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;
|
||||
}
|
||||
};
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketClientConnection.ts
|
||||
const kEmitter$1 = Symbol("kEmitter");
|
||||
const kBoundListener$1 = Symbol("kBoundListener");
|
||||
var WebSocketClientConnectionProtocol = class {};
|
||||
/**
|
||||
* The WebSocket client instance represents an incoming
|
||||
* client connection. The user can control the connection,
|
||||
* send and receive events.
|
||||
*/
|
||||
var WebSocketClientConnection = class {
|
||||
constructor(socket, transport) {
|
||||
this.socket = socket;
|
||||
this.transport = transport;
|
||||
this.id = require_createRequestId.createRequestId();
|
||||
this.url = new URL(socket.url);
|
||||
this[kEmitter$1] = 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$1].dispatchEvent(message);
|
||||
if (message.defaultPrevented) event.preventDefault();
|
||||
});
|
||||
/**
|
||||
* Emit the "close" event on the "client" connection
|
||||
* whenever the underlying transport is closed.
|
||||
* @note "client.close()" does NOT dispatch the "close"
|
||||
* event on the WebSocket because it uses non-configurable
|
||||
* close status code. Thus, we listen to the transport
|
||||
* instead of the WebSocket's "close" event.
|
||||
*/
|
||||
this.transport.addEventListener("close", (event) => {
|
||||
this[kEmitter$1].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$1)) {
|
||||
const boundListener = listener.bind(this.socket);
|
||||
Object.defineProperty(listener, kBoundListener$1, {
|
||||
value: boundListener,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
});
|
||||
}
|
||||
this[kEmitter$1].addEventListener(type, Reflect.get(listener, kBoundListener$1), options);
|
||||
}
|
||||
/**
|
||||
* Removes the listener for the given event.
|
||||
*/
|
||||
removeEventListener(event, listener, options) {
|
||||
this[kEmitter$1].removeEventListener(event, Reflect.get(listener, kBoundListener$1), 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);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketOverride.ts
|
||||
const WEBSOCKET_CLOSE_CODE_RANGE_ERROR = "InvalidAccessError: close code out of user configurable range";
|
||||
const kPassthroughPromise = Symbol("kPassthroughPromise");
|
||||
const kOnSend = Symbol("kOnSend");
|
||||
const kClose = Symbol("kClose");
|
||||
var WebSocketOverride = class extends EventTarget {
|
||||
static {
|
||||
this.CONNECTING = 0;
|
||||
}
|
||||
static {
|
||||
this.OPEN = 1;
|
||||
}
|
||||
static {
|
||||
this.CLOSING = 2;
|
||||
}
|
||||
static {
|
||||
this.CLOSED = 3;
|
||||
}
|
||||
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 = require_resolveWebSocketUrl.resolveWebSocketUrl(url);
|
||||
this.protocol = "";
|
||||
this.extensions = "";
|
||||
this.binaryType = "blob";
|
||||
this.readyState = this.CONNECTING;
|
||||
this.bufferedAmount = 0;
|
||||
this[kPassthroughPromise] = new _open_draft_deferred_promise.DeferredPromise();
|
||||
queueMicrotask(async () => {
|
||||
if (await this[kPassthroughPromise]) return;
|
||||
this.protocol = typeof protocols === "string" ? protocols : Array.isArray(protocols) && protocols.length > 0 ? protocols[0] : "";
|
||||
/**
|
||||
* @note Check that nothing has prevented this connection
|
||||
* (e.g. called `client.close()` in the connection listener).
|
||||
* If the connection has been prevented, never dispatch the open event,.
|
||||
*/
|
||||
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(() => {
|
||||
this.bufferedAmount = 0;
|
||||
/**
|
||||
* @note Notify the parent about outgoing data.
|
||||
* This notifies the transport and the connection
|
||||
* listens to the outgoing data to emit the "message" event.
|
||||
*/
|
||||
this[kOnSend]?.(data);
|
||||
});
|
||||
}
|
||||
close(code = 1e3, reason) {
|
||||
(0, outvariant.invariant)(code, WEBSOCKET_CLOSE_CODE_RANGE_ERROR);
|
||||
(0, outvariant.invariant)(code === 1e3 || code >= 3e3 && code <= 4999, WEBSOCKET_CLOSE_CODE_RANGE_ERROR);
|
||||
this[kClose](code, reason);
|
||||
}
|
||||
[kClose](code = 1e3, reason, wasClean = true) {
|
||||
/**
|
||||
* @note Move this check here so that even internal closures,
|
||||
* like those triggered by the `server` connection, are not
|
||||
* performed twice.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
function getDataSize(data) {
|
||||
if (typeof data === "string") return data.length;
|
||||
if (data instanceof Blob) return data.size;
|
||||
return data.byteLength;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketServerConnection.ts
|
||||
const kEmitter = Symbol("kEmitter");
|
||||
const kBoundListener = Symbol("kBoundListener");
|
||||
const kSend = Symbol("kSend");
|
||||
var WebSocketServerConnectionProtocol = class {};
|
||||
/**
|
||||
* 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()`.
|
||||
*/
|
||||
var WebSocketServerConnection = class {
|
||||
constructor(client, transport, createConnection) {
|
||||
this.client = client;
|
||||
this.transport = transport;
|
||||
this.createConnection = createConnection;
|
||||
this[kEmitter] = 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)
|
||||
/**
|
||||
* @note Use the internal send mechanism so consumers can tell
|
||||
* apart direct user calls to `server.send()` and internal calls.
|
||||
* E.g. MSW has to ignore this internal call to log out messages correctly.
|
||||
*/
|
||||
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() {
|
||||
(0, outvariant.invariant)(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() {
|
||||
(0, outvariant.invariant)(!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[kEmitter].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[kEmitter].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, kBoundListener)) {
|
||||
const boundListener = listener.bind(this.client);
|
||||
Object.defineProperty(listener, kBoundListener, {
|
||||
value: boundListener,
|
||||
enumerable: false
|
||||
});
|
||||
}
|
||||
this[kEmitter].addEventListener(event, Reflect.get(listener, kBoundListener), options);
|
||||
}
|
||||
/**
|
||||
* Remove the listener for the given event.
|
||||
*/
|
||||
removeEventListener(event, listener, options) {
|
||||
this[kEmitter].removeEventListener(event, Reflect.get(listener, kBoundListener), 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);
|
||||
}
|
||||
[kSend](data) {
|
||||
const { realWebSocket } = this;
|
||||
(0, outvariant.invariant)(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;
|
||||
(0, outvariant.invariant)(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[kEmitter].dispatchEvent(bindEvent(this.realWebSocket, new CancelableCloseEvent("close", {
|
||||
code: 1e3,
|
||||
cancelable: true
|
||||
})));
|
||||
});
|
||||
}
|
||||
handleIncomingMessage(event) {
|
||||
const messageEvent = bindEvent(event.target, new CancelableMessageEvent("message", {
|
||||
data: event.data,
|
||||
origin: event.origin,
|
||||
cancelable: true
|
||||
}));
|
||||
/**
|
||||
* @note Emit "message" event on the server connection
|
||||
* instance to let the interceptor know about these
|
||||
* incoming events from the original server. In that listener,
|
||||
* the interceptor can modify or skip the event forwarding
|
||||
* to the mock WebSocket instance.
|
||||
*/
|
||||
this[kEmitter].dispatchEvent(messageEvent);
|
||||
/**
|
||||
* @note Forward the incoming server events to the client.
|
||||
* Preventing the default on the message event stops this.
|
||||
*/
|
||||
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,
|
||||
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[kEmitter].dispatchEvent(closeEvent);
|
||||
if (!closeEvent.defaultPrevented) this.client[kClose](event.code, event.reason);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketClassTransport.ts
|
||||
/**
|
||||
* Abstraction over the given mock `WebSocket` instance that allows
|
||||
* for controlling that instance (e.g. sending and receiving messages).
|
||||
*/
|
||||
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)));
|
||||
});
|
||||
/**
|
||||
* Emit the "outgoing" event on the transport
|
||||
* whenever the WebSocket client sends data ("ws.send()").
|
||||
*/
|
||||
this.socket[kOnSend] = (data) => {
|
||||
this.dispatchEvent(bindEvent(this.socket, 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) {
|
||||
/**
|
||||
* @note Call the internal close method directly
|
||||
* to allow closing the connection with the status codes
|
||||
* that are non-configurable by the user (> 1000 <= 1015).
|
||||
*/
|
||||
this.socket[kClose](code, reason);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/index.ts
|
||||
/**
|
||||
* Intercept the outgoing WebSocket connections created using
|
||||
* the global `WebSocket` class.
|
||||
*/
|
||||
var WebSocketInterceptor = class WebSocketInterceptor extends require_createRequestId.Interceptor {
|
||||
static {
|
||||
this.symbol = Symbol("websocket");
|
||||
}
|
||||
constructor() {
|
||||
super(WebSocketInterceptor.symbol);
|
||||
}
|
||||
checkEnvironment() {
|
||||
return require_hasConfigurableGlobal.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(async () => {
|
||||
try {
|
||||
const server = new WebSocketServerConnection(socket, transport, createConnection);
|
||||
const hasConnectionListeners = this.emitter.listenerCount("connection") > 0;
|
||||
await require_hasConfigurableGlobal.emitAsync(this.emitter, "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) {
|
||||
/**
|
||||
* @note Translate unhandled exceptions during the connection
|
||||
* handling (i.e. interceptor exceptions) as WebSocket connection
|
||||
* closures with error. This prevents from the exceptions occurring
|
||||
* in `queueMicrotask` from being process-wide and uncatchable.
|
||||
*/
|
||||
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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
exports.CancelableCloseEvent = CancelableCloseEvent;
|
||||
exports.CancelableMessageEvent = CancelableMessageEvent;
|
||||
exports.CloseEvent = CloseEvent;
|
||||
exports.WebSocketClientConnection = WebSocketClientConnection;
|
||||
exports.WebSocketClientConnectionProtocol = WebSocketClientConnectionProtocol;
|
||||
exports.WebSocketInterceptor = WebSocketInterceptor;
|
||||
exports.WebSocketServerConnection = WebSocketServerConnection;
|
||||
exports.WebSocketServerConnectionProtocol = WebSocketServerConnectionProtocol;
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
277
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.d.cts
generated
vendored
Normal file
277
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
import { r as Interceptor } from "../../Interceptor-Deczogc8.cjs";
|
||||
|
||||
//#region src/interceptors/WebSocket/utils/events.d.ts
|
||||
declare const kCancelable: unique symbol;
|
||||
declare const kDefaultPrevented: unique symbol;
|
||||
/**
|
||||
* A `MessageEvent` superset that supports event cancellation
|
||||
* in Node.js. It's rather non-intrusive so it can be safely
|
||||
* used in the browser as well.
|
||||
*
|
||||
* @see https://github.com/nodejs/node/issues/51767
|
||||
*/
|
||||
declare class CancelableMessageEvent<T = any> extends MessageEvent<T> {
|
||||
[kCancelable]: boolean;
|
||||
[kDefaultPrevented]: boolean;
|
||||
constructor(type: string, init: MessageEventInit<T>);
|
||||
get cancelable(): boolean;
|
||||
set cancelable(nextCancelable: boolean);
|
||||
get defaultPrevented(): boolean;
|
||||
set defaultPrevented(nextDefaultPrevented: boolean);
|
||||
preventDefault(): void;
|
||||
}
|
||||
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);
|
||||
}
|
||||
declare class CancelableCloseEvent extends CloseEvent {
|
||||
[kCancelable]: boolean;
|
||||
[kDefaultPrevented]: boolean;
|
||||
constructor(type: string, init?: CloseEventInit);
|
||||
get cancelable(): boolean;
|
||||
set cancelable(nextCancelable: boolean);
|
||||
get defaultPrevented(): boolean;
|
||||
set defaultPrevented(nextDefaultPrevented: boolean);
|
||||
preventDefault(): void;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketTransport.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketOverride.d.ts
|
||||
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: WebSocket['readyState'];
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketClientConnection.d.ts
|
||||
declare const kEmitter$1: unique symbol;
|
||||
interface WebSocketClientEventMap {
|
||||
message: MessageEvent<WebSocketData>;
|
||||
close: CloseEvent;
|
||||
}
|
||||
declare abstract class WebSocketClientConnectionProtocol {
|
||||
abstract id: string;
|
||||
abstract url: URL;
|
||||
abstract send(data: WebSocketData): void;
|
||||
abstract close(code?: number, reason?: string): void;
|
||||
abstract addEventListener<EventType extends keyof WebSocketClientEventMap>(type: EventType, listener: WebSocketEventListener<WebSocketClientEventMap[EventType]>, options?: AddEventListenerOptions | boolean): void;
|
||||
abstract removeEventListener<EventType extends keyof WebSocketClientEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketClientEventMap[EventType]>, options?: EventListenerOptions | boolean): 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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketClassTransport.d.ts
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketServerConnection.d.ts
|
||||
declare const kEmitter: unique symbol;
|
||||
declare const kSend: unique symbol;
|
||||
interface WebSocketServerEventMap {
|
||||
open: Event;
|
||||
message: MessageEvent<WebSocketData>;
|
||||
error: Event;
|
||||
close: CloseEvent;
|
||||
}
|
||||
declare abstract class WebSocketServerConnectionProtocol {
|
||||
abstract connect(): void;
|
||||
abstract send(data: WebSocketData): void;
|
||||
abstract close(): void;
|
||||
abstract addEventListener<EventType extends keyof WebSocketServerEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketServerEventMap[EventType]>, options?: AddEventListenerOptions | boolean): void;
|
||||
abstract removeEventListener<EventType extends keyof WebSocketServerEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketServerEventMap[EventType]>, options?: EventListenerOptions | boolean): void;
|
||||
}
|
||||
/**
|
||||
* 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 implements WebSocketServerConnectionProtocol {
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/index.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
export { CancelableCloseEvent, CancelableMessageEvent, CloseEvent, WebSocketClientConnection, WebSocketClientConnectionProtocol, WebSocketClientEventMap, WebSocketConnectionData, type WebSocketData, WebSocketEventMap$1 as WebSocketEventMap, WebSocketInterceptor, WebSocketServerConnection, WebSocketServerConnectionProtocol, WebSocketServerEventMap, type WebSocketTransport };
|
||||
//# sourceMappingURL=index.d.cts.map
|
||||
277
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.d.mts
generated
vendored
Normal file
277
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
import { r as Interceptor } from "../../Interceptor-gqKgs-aF.mjs";
|
||||
|
||||
//#region src/interceptors/WebSocket/utils/events.d.ts
|
||||
declare const kCancelable: unique symbol;
|
||||
declare const kDefaultPrevented: unique symbol;
|
||||
/**
|
||||
* A `MessageEvent` superset that supports event cancellation
|
||||
* in Node.js. It's rather non-intrusive so it can be safely
|
||||
* used in the browser as well.
|
||||
*
|
||||
* @see https://github.com/nodejs/node/issues/51767
|
||||
*/
|
||||
declare class CancelableMessageEvent<T = any> extends MessageEvent<T> {
|
||||
[kCancelable]: boolean;
|
||||
[kDefaultPrevented]: boolean;
|
||||
constructor(type: string, init: MessageEventInit<T>);
|
||||
get cancelable(): boolean;
|
||||
set cancelable(nextCancelable: boolean);
|
||||
get defaultPrevented(): boolean;
|
||||
set defaultPrevented(nextDefaultPrevented: boolean);
|
||||
preventDefault(): void;
|
||||
}
|
||||
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);
|
||||
}
|
||||
declare class CancelableCloseEvent extends CloseEvent {
|
||||
[kCancelable]: boolean;
|
||||
[kDefaultPrevented]: boolean;
|
||||
constructor(type: string, init?: CloseEventInit);
|
||||
get cancelable(): boolean;
|
||||
set cancelable(nextCancelable: boolean);
|
||||
get defaultPrevented(): boolean;
|
||||
set defaultPrevented(nextDefaultPrevented: boolean);
|
||||
preventDefault(): void;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketTransport.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketOverride.d.ts
|
||||
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: WebSocket['readyState'];
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketClientConnection.d.ts
|
||||
declare const kEmitter$1: unique symbol;
|
||||
interface WebSocketClientEventMap {
|
||||
message: MessageEvent<WebSocketData>;
|
||||
close: CloseEvent;
|
||||
}
|
||||
declare abstract class WebSocketClientConnectionProtocol {
|
||||
abstract id: string;
|
||||
abstract url: URL;
|
||||
abstract send(data: WebSocketData): void;
|
||||
abstract close(code?: number, reason?: string): void;
|
||||
abstract addEventListener<EventType extends keyof WebSocketClientEventMap>(type: EventType, listener: WebSocketEventListener<WebSocketClientEventMap[EventType]>, options?: AddEventListenerOptions | boolean): void;
|
||||
abstract removeEventListener<EventType extends keyof WebSocketClientEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketClientEventMap[EventType]>, options?: EventListenerOptions | boolean): 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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketClassTransport.d.ts
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketServerConnection.d.ts
|
||||
declare const kEmitter: unique symbol;
|
||||
declare const kSend: unique symbol;
|
||||
interface WebSocketServerEventMap {
|
||||
open: Event;
|
||||
message: MessageEvent<WebSocketData>;
|
||||
error: Event;
|
||||
close: CloseEvent;
|
||||
}
|
||||
declare abstract class WebSocketServerConnectionProtocol {
|
||||
abstract connect(): void;
|
||||
abstract send(data: WebSocketData): void;
|
||||
abstract close(): void;
|
||||
abstract addEventListener<EventType extends keyof WebSocketServerEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketServerEventMap[EventType]>, options?: AddEventListenerOptions | boolean): void;
|
||||
abstract removeEventListener<EventType extends keyof WebSocketServerEventMap>(event: EventType, listener: WebSocketEventListener<WebSocketServerEventMap[EventType]>, options?: EventListenerOptions | boolean): void;
|
||||
}
|
||||
/**
|
||||
* 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 implements WebSocketServerConnectionProtocol {
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/index.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
export { CancelableCloseEvent, CancelableMessageEvent, CloseEvent, WebSocketClientConnection, WebSocketClientConnectionProtocol, WebSocketClientEventMap, WebSocketConnectionData, type WebSocketData, WebSocketEventMap$1 as WebSocketEventMap, WebSocketInterceptor, WebSocketServerConnection, WebSocketServerConnectionProtocol, WebSocketServerEventMap, type WebSocketTransport };
|
||||
//# sourceMappingURL=index.d.mts.map
|
||||
615
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.mjs
generated
vendored
Normal file
615
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,615 @@
|
||||
import { r as Interceptor, t as createRequestId } from "../../createRequestId-DQcIlohW.mjs";
|
||||
import { t as resolveWebSocketUrl } from "../../resolveWebSocketUrl-C83-x9iE.mjs";
|
||||
import { n as emitAsync, t as hasConfigurableGlobal } from "../../hasConfigurableGlobal-npXitu1-.mjs";
|
||||
import { DeferredPromise } from "@open-draft/deferred-promise";
|
||||
import { invariant } from "outvariant";
|
||||
|
||||
//#region 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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/utils/events.ts
|
||||
const kCancelable = Symbol("kCancelable");
|
||||
const kDefaultPrevented = Symbol("kDefaultPrevented");
|
||||
/**
|
||||
* A `MessageEvent` superset that supports event cancellation
|
||||
* in Node.js. It's rather non-intrusive so it can be safely
|
||||
* used in the browser as well.
|
||||
*
|
||||
* @see https://github.com/nodejs/node/issues/51767
|
||||
*/
|
||||
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;
|
||||
}
|
||||
};
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketClientConnection.ts
|
||||
const kEmitter$1 = Symbol("kEmitter");
|
||||
const kBoundListener$1 = Symbol("kBoundListener");
|
||||
var WebSocketClientConnectionProtocol = class {};
|
||||
/**
|
||||
* The WebSocket client instance represents an incoming
|
||||
* client connection. The user can control the connection,
|
||||
* send and receive events.
|
||||
*/
|
||||
var WebSocketClientConnection = class {
|
||||
constructor(socket, transport) {
|
||||
this.socket = socket;
|
||||
this.transport = transport;
|
||||
this.id = createRequestId();
|
||||
this.url = new URL(socket.url);
|
||||
this[kEmitter$1] = 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$1].dispatchEvent(message);
|
||||
if (message.defaultPrevented) event.preventDefault();
|
||||
});
|
||||
/**
|
||||
* Emit the "close" event on the "client" connection
|
||||
* whenever the underlying transport is closed.
|
||||
* @note "client.close()" does NOT dispatch the "close"
|
||||
* event on the WebSocket because it uses non-configurable
|
||||
* close status code. Thus, we listen to the transport
|
||||
* instead of the WebSocket's "close" event.
|
||||
*/
|
||||
this.transport.addEventListener("close", (event) => {
|
||||
this[kEmitter$1].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$1)) {
|
||||
const boundListener = listener.bind(this.socket);
|
||||
Object.defineProperty(listener, kBoundListener$1, {
|
||||
value: boundListener,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
});
|
||||
}
|
||||
this[kEmitter$1].addEventListener(type, Reflect.get(listener, kBoundListener$1), options);
|
||||
}
|
||||
/**
|
||||
* Removes the listener for the given event.
|
||||
*/
|
||||
removeEventListener(event, listener, options) {
|
||||
this[kEmitter$1].removeEventListener(event, Reflect.get(listener, kBoundListener$1), 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);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketOverride.ts
|
||||
const WEBSOCKET_CLOSE_CODE_RANGE_ERROR = "InvalidAccessError: close code out of user configurable range";
|
||||
const kPassthroughPromise = Symbol("kPassthroughPromise");
|
||||
const kOnSend = Symbol("kOnSend");
|
||||
const kClose = Symbol("kClose");
|
||||
var WebSocketOverride = class extends EventTarget {
|
||||
static {
|
||||
this.CONNECTING = 0;
|
||||
}
|
||||
static {
|
||||
this.OPEN = 1;
|
||||
}
|
||||
static {
|
||||
this.CLOSING = 2;
|
||||
}
|
||||
static {
|
||||
this.CLOSED = 3;
|
||||
}
|
||||
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 = resolveWebSocketUrl(url);
|
||||
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] : "";
|
||||
/**
|
||||
* @note Check that nothing has prevented this connection
|
||||
* (e.g. called `client.close()` in the connection listener).
|
||||
* If the connection has been prevented, never dispatch the open event,.
|
||||
*/
|
||||
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(() => {
|
||||
this.bufferedAmount = 0;
|
||||
/**
|
||||
* @note Notify the parent about outgoing data.
|
||||
* This notifies the transport and the connection
|
||||
* listens to the outgoing data to emit the "message" event.
|
||||
*/
|
||||
this[kOnSend]?.(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);
|
||||
}
|
||||
[kClose](code = 1e3, reason, wasClean = true) {
|
||||
/**
|
||||
* @note Move this check here so that even internal closures,
|
||||
* like those triggered by the `server` connection, are not
|
||||
* performed twice.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
function getDataSize(data) {
|
||||
if (typeof data === "string") return data.length;
|
||||
if (data instanceof Blob) return data.size;
|
||||
return data.byteLength;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketServerConnection.ts
|
||||
const kEmitter = Symbol("kEmitter");
|
||||
const kBoundListener = Symbol("kBoundListener");
|
||||
const kSend = Symbol("kSend");
|
||||
var WebSocketServerConnectionProtocol = class {};
|
||||
/**
|
||||
* 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()`.
|
||||
*/
|
||||
var WebSocketServerConnection = class {
|
||||
constructor(client, transport, createConnection) {
|
||||
this.client = client;
|
||||
this.transport = transport;
|
||||
this.createConnection = createConnection;
|
||||
this[kEmitter] = 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)
|
||||
/**
|
||||
* @note Use the internal send mechanism so consumers can tell
|
||||
* apart direct user calls to `server.send()` and internal calls.
|
||||
* E.g. MSW has to ignore this internal call to log out messages correctly.
|
||||
*/
|
||||
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() {
|
||||
invariant(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() {
|
||||
invariant(!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[kEmitter].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[kEmitter].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, kBoundListener)) {
|
||||
const boundListener = listener.bind(this.client);
|
||||
Object.defineProperty(listener, kBoundListener, {
|
||||
value: boundListener,
|
||||
enumerable: false
|
||||
});
|
||||
}
|
||||
this[kEmitter].addEventListener(event, Reflect.get(listener, kBoundListener), options);
|
||||
}
|
||||
/**
|
||||
* Remove the listener for the given event.
|
||||
*/
|
||||
removeEventListener(event, listener, options) {
|
||||
this[kEmitter].removeEventListener(event, Reflect.get(listener, kBoundListener), 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);
|
||||
}
|
||||
[kSend](data) {
|
||||
const { realWebSocket } = this;
|
||||
invariant(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;
|
||||
invariant(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[kEmitter].dispatchEvent(bindEvent(this.realWebSocket, new CancelableCloseEvent("close", {
|
||||
code: 1e3,
|
||||
cancelable: true
|
||||
})));
|
||||
});
|
||||
}
|
||||
handleIncomingMessage(event) {
|
||||
const messageEvent = bindEvent(event.target, new CancelableMessageEvent("message", {
|
||||
data: event.data,
|
||||
origin: event.origin,
|
||||
cancelable: true
|
||||
}));
|
||||
/**
|
||||
* @note Emit "message" event on the server connection
|
||||
* instance to let the interceptor know about these
|
||||
* incoming events from the original server. In that listener,
|
||||
* the interceptor can modify or skip the event forwarding
|
||||
* to the mock WebSocket instance.
|
||||
*/
|
||||
this[kEmitter].dispatchEvent(messageEvent);
|
||||
/**
|
||||
* @note Forward the incoming server events to the client.
|
||||
* Preventing the default on the message event stops this.
|
||||
*/
|
||||
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,
|
||||
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[kEmitter].dispatchEvent(closeEvent);
|
||||
if (!closeEvent.defaultPrevented) this.client[kClose](event.code, event.reason);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/WebSocketClassTransport.ts
|
||||
/**
|
||||
* Abstraction over the given mock `WebSocket` instance that allows
|
||||
* for controlling that instance (e.g. sending and receiving messages).
|
||||
*/
|
||||
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)));
|
||||
});
|
||||
/**
|
||||
* Emit the "outgoing" event on the transport
|
||||
* whenever the WebSocket client sends data ("ws.send()").
|
||||
*/
|
||||
this.socket[kOnSend] = (data) => {
|
||||
this.dispatchEvent(bindEvent(this.socket, 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) {
|
||||
/**
|
||||
* @note Call the internal close method directly
|
||||
* to allow closing the connection with the status codes
|
||||
* that are non-configurable by the user (> 1000 <= 1015).
|
||||
*/
|
||||
this.socket[kClose](code, reason);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/WebSocket/index.ts
|
||||
/**
|
||||
* Intercept the outgoing WebSocket connections created using
|
||||
* the global `WebSocket` class.
|
||||
*/
|
||||
var WebSocketInterceptor = class WebSocketInterceptor extends Interceptor {
|
||||
static {
|
||||
this.symbol = Symbol("websocket");
|
||||
}
|
||||
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(async () => {
|
||||
try {
|
||||
const server = new WebSocketServerConnection(socket, transport, createConnection);
|
||||
const hasConnectionListeners = this.emitter.listenerCount("connection") > 0;
|
||||
await emitAsync(this.emitter, "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) {
|
||||
/**
|
||||
* @note Translate unhandled exceptions during the connection
|
||||
* handling (i.e. interceptor exceptions) as WebSocket connection
|
||||
* closures with error. This prevents from the exceptions occurring
|
||||
* in `queueMicrotask` from being process-wide and uncatchable.
|
||||
*/
|
||||
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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { CancelableCloseEvent, CancelableMessageEvent, CloseEvent, WebSocketClientConnection, WebSocketClientConnectionProtocol, WebSocketInterceptor, WebSocketServerConnection, WebSocketServerConnectionProtocol };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
7
node_modules/@mswjs/interceptors/lib/browser/interceptors/XMLHttpRequest/index.cjs
generated
vendored
Normal file
7
node_modules/@mswjs/interceptors/lib/browser/interceptors/XMLHttpRequest/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
require('../../getRawRequest-zx8rUJL2.cjs');
|
||||
require('../../createRequestId-Cs4oXfa1.cjs');
|
||||
require('../../bufferUtils-Uc0eRItL.cjs');
|
||||
require('../../handleRequest-CvX2G-Lz.cjs');
|
||||
const require_XMLHttpRequest = require('../../XMLHttpRequest-BACqefB-.cjs');
|
||||
|
||||
exports.XMLHttpRequestInterceptor = require_XMLHttpRequest.XMLHttpRequestInterceptor;
|
||||
15
node_modules/@mswjs/interceptors/lib/browser/interceptors/XMLHttpRequest/index.d.cts
generated
vendored
Normal file
15
node_modules/@mswjs/interceptors/lib/browser/interceptors/XMLHttpRequest/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { t as HttpRequestEventMap } from "../../glossary-BdLS4k1H.cjs";
|
||||
import { r as Interceptor } from "../../Interceptor-Deczogc8.cjs";
|
||||
import { Emitter } from "strict-event-emitter";
|
||||
|
||||
//#region src/interceptors/XMLHttpRequest/index.d.ts
|
||||
type XMLHttpRequestEmitter = Emitter<HttpRequestEventMap>;
|
||||
declare class XMLHttpRequestInterceptor extends Interceptor<HttpRequestEventMap> {
|
||||
static interceptorSymbol: symbol;
|
||||
constructor();
|
||||
protected checkEnvironment(): boolean;
|
||||
protected setup(): void;
|
||||
}
|
||||
//#endregion
|
||||
export { XMLHttpRequestEmitter, XMLHttpRequestInterceptor };
|
||||
//# sourceMappingURL=index.d.cts.map
|
||||
15
node_modules/@mswjs/interceptors/lib/browser/interceptors/XMLHttpRequest/index.d.mts
generated
vendored
Normal file
15
node_modules/@mswjs/interceptors/lib/browser/interceptors/XMLHttpRequest/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { t as HttpRequestEventMap } from "../../glossary-DYwOrogs.mjs";
|
||||
import { r as Interceptor } from "../../Interceptor-gqKgs-aF.mjs";
|
||||
import { Emitter } from "strict-event-emitter";
|
||||
|
||||
//#region src/interceptors/XMLHttpRequest/index.d.ts
|
||||
type XMLHttpRequestEmitter = Emitter<HttpRequestEventMap>;
|
||||
declare class XMLHttpRequestInterceptor extends Interceptor<HttpRequestEventMap> {
|
||||
static interceptorSymbol: symbol;
|
||||
constructor();
|
||||
protected checkEnvironment(): boolean;
|
||||
protected setup(): void;
|
||||
}
|
||||
//#endregion
|
||||
export { XMLHttpRequestEmitter, XMLHttpRequestInterceptor };
|
||||
//# sourceMappingURL=index.d.mts.map
|
||||
7
node_modules/@mswjs/interceptors/lib/browser/interceptors/XMLHttpRequest/index.mjs
generated
vendored
Normal file
7
node_modules/@mswjs/interceptors/lib/browser/interceptors/XMLHttpRequest/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import "../../getRawRequest-BTaNLFr0.mjs";
|
||||
import "../../createRequestId-DQcIlohW.mjs";
|
||||
import "../../bufferUtils-BiiO6HZv.mjs";
|
||||
import "../../handleRequest-D7kpTI5U.mjs";
|
||||
import { t as XMLHttpRequestInterceptor } from "../../XMLHttpRequest-BvxZV0WU.mjs";
|
||||
|
||||
export { XMLHttpRequestInterceptor };
|
||||
6
node_modules/@mswjs/interceptors/lib/browser/interceptors/fetch/index.cjs
generated
vendored
Normal file
6
node_modules/@mswjs/interceptors/lib/browser/interceptors/fetch/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
require('../../getRawRequest-zx8rUJL2.cjs');
|
||||
require('../../createRequestId-Cs4oXfa1.cjs');
|
||||
require('../../handleRequest-CvX2G-Lz.cjs');
|
||||
const require_fetch = require('../../fetch-U3v3Y4ap.cjs');
|
||||
|
||||
exports.FetchInterceptor = require_fetch.FetchInterceptor;
|
||||
13
node_modules/@mswjs/interceptors/lib/browser/interceptors/fetch/index.d.cts
generated
vendored
Normal file
13
node_modules/@mswjs/interceptors/lib/browser/interceptors/fetch/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { t as HttpRequestEventMap } from "../../glossary-BdLS4k1H.cjs";
|
||||
import { r as Interceptor } from "../../Interceptor-Deczogc8.cjs";
|
||||
|
||||
//#region src/interceptors/fetch/index.d.ts
|
||||
declare class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
|
||||
static symbol: symbol;
|
||||
constructor();
|
||||
protected checkEnvironment(): boolean;
|
||||
protected setup(): Promise<void>;
|
||||
}
|
||||
//#endregion
|
||||
export { FetchInterceptor };
|
||||
//# sourceMappingURL=index.d.cts.map
|
||||
13
node_modules/@mswjs/interceptors/lib/browser/interceptors/fetch/index.d.mts
generated
vendored
Normal file
13
node_modules/@mswjs/interceptors/lib/browser/interceptors/fetch/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { t as HttpRequestEventMap } from "../../glossary-DYwOrogs.mjs";
|
||||
import { r as Interceptor } from "../../Interceptor-gqKgs-aF.mjs";
|
||||
|
||||
//#region src/interceptors/fetch/index.d.ts
|
||||
declare class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
|
||||
static symbol: symbol;
|
||||
constructor();
|
||||
protected checkEnvironment(): boolean;
|
||||
protected setup(): Promise<void>;
|
||||
}
|
||||
//#endregion
|
||||
export { FetchInterceptor };
|
||||
//# sourceMappingURL=index.d.mts.map
|
||||
6
node_modules/@mswjs/interceptors/lib/browser/interceptors/fetch/index.mjs
generated
vendored
Normal file
6
node_modules/@mswjs/interceptors/lib/browser/interceptors/fetch/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import "../../getRawRequest-BTaNLFr0.mjs";
|
||||
import "../../createRequestId-DQcIlohW.mjs";
|
||||
import "../../handleRequest-D7kpTI5U.mjs";
|
||||
import { t as FetchInterceptor } from "../../fetch-DdKEdDOR.mjs";
|
||||
|
||||
export { FetchInterceptor };
|
||||
17
node_modules/@mswjs/interceptors/lib/browser/presets/browser.cjs
generated
vendored
Normal file
17
node_modules/@mswjs/interceptors/lib/browser/presets/browser.cjs
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
require('../getRawRequest-zx8rUJL2.cjs');
|
||||
require('../createRequestId-Cs4oXfa1.cjs');
|
||||
require('../bufferUtils-Uc0eRItL.cjs');
|
||||
require('../handleRequest-CvX2G-Lz.cjs');
|
||||
const require_fetch = require('../fetch-U3v3Y4ap.cjs');
|
||||
const require_XMLHttpRequest = require('../XMLHttpRequest-BACqefB-.cjs');
|
||||
|
||||
//#region src/presets/browser.ts
|
||||
/**
|
||||
* The default preset provisions the interception of requests
|
||||
* regardless of their type (fetch/XMLHttpRequest).
|
||||
*/
|
||||
var browser_default = [new require_fetch.FetchInterceptor(), new require_XMLHttpRequest.XMLHttpRequestInterceptor()];
|
||||
|
||||
//#endregion
|
||||
module.exports = browser_default;
|
||||
//# sourceMappingURL=browser.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/presets/browser.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/presets/browser.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"browser.cjs","names":["FetchInterceptor","XMLHttpRequestInterceptor"],"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,sBAAe,CACb,IAAIA,gCAAkB,EACtB,IAAIC,kDAA2B,CAChC"}
|
||||
12
node_modules/@mswjs/interceptors/lib/browser/presets/browser.d.cts
generated
vendored
Normal file
12
node_modules/@mswjs/interceptors/lib/browser/presets/browser.d.cts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { XMLHttpRequestInterceptor } from "../interceptors/XMLHttpRequest/index.cjs";
|
||||
import { FetchInterceptor } from "../interceptors/fetch/index.cjs";
|
||||
|
||||
//#region src/presets/browser.d.ts
|
||||
|
||||
/**
|
||||
* The default preset provisions the interception of requests
|
||||
* regardless of their type (fetch/XMLHttpRequest).
|
||||
*/
|
||||
declare const _default: readonly [FetchInterceptor, XMLHttpRequestInterceptor];
|
||||
export = _default;
|
||||
//# sourceMappingURL=browser.d.cts.map
|
||||
14
node_modules/@mswjs/interceptors/lib/browser/presets/browser.d.mts
generated
vendored
Normal file
14
node_modules/@mswjs/interceptors/lib/browser/presets/browser.d.mts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import "../Interceptor-gqKgs-aF.mjs";
|
||||
import { XMLHttpRequestInterceptor } from "../interceptors/XMLHttpRequest/index.mjs";
|
||||
import { FetchInterceptor } from "../interceptors/fetch/index.mjs";
|
||||
|
||||
//#region src/presets/browser.d.ts
|
||||
|
||||
/**
|
||||
* The default preset provisions the interception of requests
|
||||
* regardless of their type (fetch/XMLHttpRequest).
|
||||
*/
|
||||
declare const _default: readonly [FetchInterceptor, XMLHttpRequestInterceptor];
|
||||
//#endregion
|
||||
export { _default as default };
|
||||
//# sourceMappingURL=browser.d.mts.map
|
||||
17
node_modules/@mswjs/interceptors/lib/browser/presets/browser.mjs
generated
vendored
Normal file
17
node_modules/@mswjs/interceptors/lib/browser/presets/browser.mjs
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import "../getRawRequest-BTaNLFr0.mjs";
|
||||
import "../createRequestId-DQcIlohW.mjs";
|
||||
import "../bufferUtils-BiiO6HZv.mjs";
|
||||
import "../handleRequest-D7kpTI5U.mjs";
|
||||
import { t as FetchInterceptor } from "../fetch-DdKEdDOR.mjs";
|
||||
import { t as XMLHttpRequestInterceptor } from "../XMLHttpRequest-BvxZV0WU.mjs";
|
||||
|
||||
//#region src/presets/browser.ts
|
||||
/**
|
||||
* The default preset provisions the interception of requests
|
||||
* regardless of their type (fetch/XMLHttpRequest).
|
||||
*/
|
||||
var browser_default = [new FetchInterceptor(), new XMLHttpRequestInterceptor()];
|
||||
|
||||
//#endregion
|
||||
export { browser_default as default };
|
||||
//# sourceMappingURL=browser.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/presets/browser.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/presets/browser.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"browser.mjs","names":[],"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,sBAAe,CACb,IAAI,kBAAkB,EACtB,IAAI,2BAA2B,CAChC"}
|
||||
31
node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-6K6EgqsA.cjs
generated
vendored
Normal file
31
node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-6K6EgqsA.cjs
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
//#region src/utils/resolveWebSocketUrl.ts
|
||||
/**
|
||||
* Resolve potentially relative WebSocket URLs the same way
|
||||
* the browser does (replace the protocol, use the origin, etc).
|
||||
*
|
||||
* @see https://websockets.spec.whatwg.org//#dom-websocket-websocket
|
||||
*/
|
||||
function resolveWebSocketUrl(url) {
|
||||
if (typeof url === "string") return resolveWebSocketUrl(new URL(url, typeof location !== "undefined" ? location.href : void 0));
|
||||
if (url.protocol === "http:") url.protocol = "ws:";
|
||||
else if (url.protocol === "https:") url.protocol = "wss:";
|
||||
if (url.protocol !== "ws:" && url.protocol !== "wss:")
|
||||
/**
|
||||
* @note These errors are modeled after the browser errors.
|
||||
* The exact error messages aren't provided in the specification.
|
||||
* Node.js uses more obscure error messages that I don't wish to replicate.
|
||||
*/
|
||||
throw new SyntaxError(`Failed to construct 'WebSocket': The URL's scheme must be either 'http', 'https', 'ws', or 'wss'. '${url.protocol}' is not allowed.`);
|
||||
if (url.hash !== "") throw new SyntaxError(`Failed to construct 'WebSocket': The URL contains a fragment identifier ('${url.hash}'). Fragment identifiers are not allowed in WebSocket URLs.`);
|
||||
return url.href;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'resolveWebSocketUrl', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return resolveWebSocketUrl;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=resolveWebSocketUrl-6K6EgqsA.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-6K6EgqsA.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-6K6EgqsA.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resolveWebSocketUrl-6K6EgqsA.cjs","names":[],"sources":["../../src/utils/resolveWebSocketUrl.ts"],"sourcesContent":["/**\n * Resolve potentially relative WebSocket URLs the same way\n * the browser does (replace the protocol, use the origin, etc).\n *\n * @see https://websockets.spec.whatwg.org//#dom-websocket-websocket\n */\nexport function resolveWebSocketUrl(url: string | URL): string {\n if (typeof url === 'string') {\n /**\n * @note Cast the string to a URL first so the parsing errors\n * are thrown as a part of the WebSocket constructor, not consumers.\n */\n const urlRecord = new URL(\n url,\n typeof location !== 'undefined' ? location.href : undefined\n )\n\n return resolveWebSocketUrl(urlRecord)\n }\n\n if (url.protocol === 'http:') {\n url.protocol = 'ws:'\n } else if (url.protocol === 'https:') {\n url.protocol = 'wss:'\n }\n\n if (url.protocol !== 'ws:' && url.protocol !== 'wss:') {\n /**\n * @note These errors are modeled after the browser errors.\n * The exact error messages aren't provided in the specification.\n * Node.js uses more obscure error messages that I don't wish to replicate.\n */\n throw new SyntaxError(\n `Failed to construct 'WebSocket': The URL's scheme must be either 'http', 'https', 'ws', or 'wss'. '${url.protocol}' is not allowed.`\n )\n }\n\n if (url.hash !== '') {\n throw new SyntaxError(\n `Failed to construct 'WebSocket': The URL contains a fragment identifier ('${url.hash}'). Fragment identifiers are not allowed in WebSocket URLs.`\n )\n }\n\n return url.href\n}\n"],"mappings":";;;;;;;;AAMA,SAAgB,oBAAoB,KAA2B;AAC7D,KAAI,OAAO,QAAQ,SAUjB,QAAO,oBALW,IAAI,IACpB,KACA,OAAO,aAAa,cAAc,SAAS,OAAO,OACnD,CAEoC;AAGvC,KAAI,IAAI,aAAa,QACnB,KAAI,WAAW;UACN,IAAI,aAAa,SAC1B,KAAI,WAAW;AAGjB,KAAI,IAAI,aAAa,SAAS,IAAI,aAAa;;;;;;AAM7C,OAAM,IAAI,YACR,sGAAsG,IAAI,SAAS,mBACpH;AAGH,KAAI,IAAI,SAAS,GACf,OAAM,IAAI,YACR,6EAA6E,IAAI,KAAK,6DACvF;AAGH,QAAO,IAAI"}
|
||||
25
node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-C83-x9iE.mjs
generated
vendored
Normal file
25
node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-C83-x9iE.mjs
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
//#region src/utils/resolveWebSocketUrl.ts
|
||||
/**
|
||||
* Resolve potentially relative WebSocket URLs the same way
|
||||
* the browser does (replace the protocol, use the origin, etc).
|
||||
*
|
||||
* @see https://websockets.spec.whatwg.org//#dom-websocket-websocket
|
||||
*/
|
||||
function resolveWebSocketUrl(url) {
|
||||
if (typeof url === "string") return resolveWebSocketUrl(new URL(url, typeof location !== "undefined" ? location.href : void 0));
|
||||
if (url.protocol === "http:") url.protocol = "ws:";
|
||||
else if (url.protocol === "https:") url.protocol = "wss:";
|
||||
if (url.protocol !== "ws:" && url.protocol !== "wss:")
|
||||
/**
|
||||
* @note These errors are modeled after the browser errors.
|
||||
* The exact error messages aren't provided in the specification.
|
||||
* Node.js uses more obscure error messages that I don't wish to replicate.
|
||||
*/
|
||||
throw new SyntaxError(`Failed to construct 'WebSocket': The URL's scheme must be either 'http', 'https', 'ws', or 'wss'. '${url.protocol}' is not allowed.`);
|
||||
if (url.hash !== "") throw new SyntaxError(`Failed to construct 'WebSocket': The URL contains a fragment identifier ('${url.hash}'). Fragment identifiers are not allowed in WebSocket URLs.`);
|
||||
return url.href;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { resolveWebSocketUrl as t };
|
||||
//# sourceMappingURL=resolveWebSocketUrl-C83-x9iE.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-C83-x9iE.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-C83-x9iE.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resolveWebSocketUrl-C83-x9iE.mjs","names":[],"sources":["../../src/utils/resolveWebSocketUrl.ts"],"sourcesContent":["/**\n * Resolve potentially relative WebSocket URLs the same way\n * the browser does (replace the protocol, use the origin, etc).\n *\n * @see https://websockets.spec.whatwg.org//#dom-websocket-websocket\n */\nexport function resolveWebSocketUrl(url: string | URL): string {\n if (typeof url === 'string') {\n /**\n * @note Cast the string to a URL first so the parsing errors\n * are thrown as a part of the WebSocket constructor, not consumers.\n */\n const urlRecord = new URL(\n url,\n typeof location !== 'undefined' ? location.href : undefined\n )\n\n return resolveWebSocketUrl(urlRecord)\n }\n\n if (url.protocol === 'http:') {\n url.protocol = 'ws:'\n } else if (url.protocol === 'https:') {\n url.protocol = 'wss:'\n }\n\n if (url.protocol !== 'ws:' && url.protocol !== 'wss:') {\n /**\n * @note These errors are modeled after the browser errors.\n * The exact error messages aren't provided in the specification.\n * Node.js uses more obscure error messages that I don't wish to replicate.\n */\n throw new SyntaxError(\n `Failed to construct 'WebSocket': The URL's scheme must be either 'http', 'https', 'ws', or 'wss'. '${url.protocol}' is not allowed.`\n )\n }\n\n if (url.hash !== '') {\n throw new SyntaxError(\n `Failed to construct 'WebSocket': The URL contains a fragment identifier ('${url.hash}'). Fragment identifiers are not allowed in WebSocket URLs.`\n )\n }\n\n return url.href\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,oBAAoB,KAA2B;AAC7D,KAAI,OAAO,QAAQ,SAUjB,QAAO,oBALW,IAAI,IACpB,KACA,OAAO,aAAa,cAAc,SAAS,OAAO,OACnD,CAEoC;AAGvC,KAAI,IAAI,aAAa,QACnB,KAAI,WAAW;UACN,IAAI,aAAa,SAC1B,KAAI,WAAW;AAGjB,KAAI,IAAI,aAAa,SAAS,IAAI,aAAa;;;;;;AAM7C,OAAM,IAAI,YACR,sGAAsG,IAAI,SAAS,mBACpH;AAGH,KAAI,IAAI,SAAS,GACf,OAAM,IAAI,YACR,6EAA6E,IAAI,KAAK,6DACvF;AAGH,QAAO,IAAI"}
|
||||
49
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-3LnAnLTx.cjs
generated
vendored
Normal file
49
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-3LnAnLTx.cjs
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
const require_fetchUtils = require('./fetchUtils-BaY5iWXw.cjs');
|
||||
|
||||
//#region src/BatchInterceptor.ts
|
||||
/**
|
||||
* A batch interceptor that exposes a single interface
|
||||
* to apply and operate with multiple interceptors at once.
|
||||
*/
|
||||
var BatchInterceptor = class BatchInterceptor extends require_fetchUtils.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;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'BatchInterceptor', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return BatchInterceptor;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=BatchInterceptor-3LnAnLTx.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-3LnAnLTx.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-3LnAnLTx.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"BatchInterceptor-3LnAnLTx.cjs","names":["Interceptor"],"sources":["../../src/BatchInterceptor.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"],"mappings":";;;;;;;AAsBA,IAAa,mBAAb,MAAa,yBAGHA,+BAAoB;CAK5B,YAAY,SAAmD;AAC7D,mBAAiB,SAAS,OAAO,QAAQ,KAAK;AAC9C,QAAM,iBAAiB,OAAO;AAC9B,OAAK,eAAe,QAAQ;;CAG9B,AAAU,QAAQ;EAChB,MAAM,SAAS,KAAK,OAAO,OAAO,QAAQ;AAE1C,SAAO,KAAK,mCAAmC,KAAK,aAAa,OAAO;AAExE,OAAK,MAAM,eAAe,KAAK,cAAc;AAC3C,UAAO,KAAK,kCAAgC,YAAY,YAAY,KAAK;AACzE,eAAY,OAAO;AAEnB,UAAO,KAAK,0CAA0C;AACtD,QAAK,cAAc,WAAW,YAAY,SAAS,CAAC;;;CAIxD,AAAO,GACL,OACA,UACM;AAGN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,GAAG,OAAO,SAAS;AAGjC,SAAO;;CAGT,AAAO,KACL,OACA,UACM;AACN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,KAAK,OAAO,SAAS;AAGnC,SAAO;;CAGT,AAAO,IACL,OACA,UACM;AACN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,IAAI,OAAO,SAAS;AAGlC,SAAO;;CAGT,AAAO,mBACL,OACM;AACN,OAAK,MAAM,gBAAgB,KAAK,aAC9B,cAAa,mBAAmB,MAAM;AAGxC,SAAO"}
|
||||
26
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-D7mXzHcQ.d.mts
generated
vendored
Normal file
26
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-D7mXzHcQ.d.mts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import { r as Interceptor, t as ExtractEventNames } from "./Interceptor-DEazpLJd.mjs";
|
||||
import { EventMap, Listener } from "strict-event-emitter";
|
||||
|
||||
//#region src/BatchInterceptor.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
export { BatchInterceptorOptions as n, ExtractEventMapType as r, BatchInterceptor as t };
|
||||
//# sourceMappingURL=BatchInterceptor-D7mXzHcQ.d.mts.map
|
||||
44
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-DFaBPilf.mjs
generated
vendored
Normal file
44
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-DFaBPilf.mjs
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import { s as Interceptor } from "./fetchUtils-CoU35g3M.mjs";
|
||||
|
||||
//#region src/BatchInterceptor.ts
|
||||
/**
|
||||
* A batch interceptor that exposes a single interface
|
||||
* to apply and operate with multiple interceptors at once.
|
||||
*/
|
||||
var BatchInterceptor = class BatchInterceptor 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;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { BatchInterceptor as t };
|
||||
//# sourceMappingURL=BatchInterceptor-DFaBPilf.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-DFaBPilf.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-DFaBPilf.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"BatchInterceptor-DFaBPilf.mjs","names":[],"sources":["../../src/BatchInterceptor.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"],"mappings":";;;;;;;AAsBA,IAAa,mBAAb,MAAa,yBAGH,YAAoB;CAK5B,YAAY,SAAmD;AAC7D,mBAAiB,SAAS,OAAO,QAAQ,KAAK;AAC9C,QAAM,iBAAiB,OAAO;AAC9B,OAAK,eAAe,QAAQ;;CAG9B,AAAU,QAAQ;EAChB,MAAM,SAAS,KAAK,OAAO,OAAO,QAAQ;AAE1C,SAAO,KAAK,mCAAmC,KAAK,aAAa,OAAO;AAExE,OAAK,MAAM,eAAe,KAAK,cAAc;AAC3C,UAAO,KAAK,kCAAgC,YAAY,YAAY,KAAK;AACzE,eAAY,OAAO;AAEnB,UAAO,KAAK,0CAA0C;AACtD,QAAK,cAAc,WAAW,YAAY,SAAS,CAAC;;;CAIxD,AAAO,GACL,OACA,UACM;AAGN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,GAAG,OAAO,SAAS;AAGjC,SAAO;;CAGT,AAAO,KACL,OACA,UACM;AACN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,KAAK,OAAO,SAAS;AAGnC,SAAO;;CAGT,AAAO,IACL,OACA,UACM;AACN,OAAK,MAAM,eAAe,KAAK,aAC7B,aAAY,IAAI,OAAO,SAAS;AAGlC,SAAO;;CAGT,AAAO,mBACL,OACM;AACN,OAAK,MAAM,gBAAgB,KAAK,aAC9B,cAAa,mBAAmB,MAAM;AAGxC,SAAO"}
|
||||
26
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-D_YqR8qU.d.cts
generated
vendored
Normal file
26
node_modules/@mswjs/interceptors/lib/node/BatchInterceptor-D_YqR8qU.d.cts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import { r as Interceptor, t as ExtractEventNames } from "./Interceptor-DJ2akVWI.cjs";
|
||||
import { EventMap, Listener } from "strict-event-emitter";
|
||||
|
||||
//#region src/BatchInterceptor.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
export { BatchInterceptorOptions as n, ExtractEventMapType as r, BatchInterceptor as t };
|
||||
//# sourceMappingURL=BatchInterceptor-D_YqR8qU.d.cts.map
|
||||
1043
node_modules/@mswjs/interceptors/lib/node/ClientRequest-2rDe54Ui.cjs
generated
vendored
Normal file
1043
node_modules/@mswjs/interceptors/lib/node/ClientRequest-2rDe54Ui.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@mswjs/interceptors/lib/node/ClientRequest-2rDe54Ui.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/ClientRequest-2rDe54Ui.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1034
node_modules/@mswjs/interceptors/lib/node/ClientRequest-Ca8Qykuv.mjs
generated
vendored
Normal file
1034
node_modules/@mswjs/interceptors/lib/node/ClientRequest-Ca8Qykuv.mjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@mswjs/interceptors/lib/node/ClientRequest-Ca8Qykuv.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/ClientRequest-Ca8Qykuv.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
133
node_modules/@mswjs/interceptors/lib/node/Interceptor-DEazpLJd.d.mts
generated
vendored
Normal file
133
node_modules/@mswjs/interceptors/lib/node/Interceptor-DEazpLJd.d.mts
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
import { Logger } from "@open-draft/logger";
|
||||
import { Emitter, Listener } from "strict-event-emitter";
|
||||
|
||||
//#region src/RequestController.d.ts
|
||||
interface RequestControllerSource {
|
||||
passthrough(): void;
|
||||
respondWith(response: Response): void;
|
||||
errorWith(reason?: unknown): void;
|
||||
}
|
||||
declare class RequestController {
|
||||
#private;
|
||||
protected readonly request: Request;
|
||||
protected readonly source: RequestControllerSource;
|
||||
static PENDING: 0;
|
||||
static PASSTHROUGH: 1;
|
||||
static RESPONSE: 2;
|
||||
static ERROR: 3;
|
||||
readyState: number;
|
||||
/**
|
||||
* A Promise that resolves when this controller handles a request.
|
||||
* See `controller.readyState` for more information on the handling result.
|
||||
*/
|
||||
handled: Promise<void>;
|
||||
constructor(request: Request, source: RequestControllerSource);
|
||||
/**
|
||||
* Perform this request as-is.
|
||||
*/
|
||||
passthrough(): Promise<void>;
|
||||
/**
|
||||
* 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 reason.
|
||||
*
|
||||
* @example
|
||||
* controller.errorWith()
|
||||
* controller.errorWith(new Error('Oops!'))
|
||||
* controller.errorWith({ message: 'Oops!'})
|
||||
*/
|
||||
errorWith(reason?: unknown): void;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/glossary.d.ts
|
||||
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;
|
||||
}];
|
||||
};
|
||||
//#endregion
|
||||
//#region src/Interceptor.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
export { InterceptorReadyState as a, getGlobalSymbol as c, RequestCredentials as d, RequestController as f, InterceptorEventMap as i, HttpRequestEventMap as l, INTERNAL_REQUEST_ID_HEADER_NAME as n, InterceptorSubscription as o, RequestControllerSource as p, Interceptor as r, deleteGlobalSymbol as s, ExtractEventNames as t, IS_PATCHED_MODULE as u };
|
||||
//# sourceMappingURL=Interceptor-DEazpLJd.d.mts.map
|
||||
133
node_modules/@mswjs/interceptors/lib/node/Interceptor-DJ2akVWI.d.cts
generated
vendored
Normal file
133
node_modules/@mswjs/interceptors/lib/node/Interceptor-DJ2akVWI.d.cts
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
import { Logger } from "@open-draft/logger";
|
||||
import { Emitter, Listener } from "strict-event-emitter";
|
||||
|
||||
//#region src/RequestController.d.ts
|
||||
interface RequestControllerSource {
|
||||
passthrough(): void;
|
||||
respondWith(response: Response): void;
|
||||
errorWith(reason?: unknown): void;
|
||||
}
|
||||
declare class RequestController {
|
||||
#private;
|
||||
protected readonly request: Request;
|
||||
protected readonly source: RequestControllerSource;
|
||||
static PENDING: 0;
|
||||
static PASSTHROUGH: 1;
|
||||
static RESPONSE: 2;
|
||||
static ERROR: 3;
|
||||
readyState: number;
|
||||
/**
|
||||
* A Promise that resolves when this controller handles a request.
|
||||
* See `controller.readyState` for more information on the handling result.
|
||||
*/
|
||||
handled: Promise<void>;
|
||||
constructor(request: Request, source: RequestControllerSource);
|
||||
/**
|
||||
* Perform this request as-is.
|
||||
*/
|
||||
passthrough(): Promise<void>;
|
||||
/**
|
||||
* 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 reason.
|
||||
*
|
||||
* @example
|
||||
* controller.errorWith()
|
||||
* controller.errorWith(new Error('Oops!'))
|
||||
* controller.errorWith({ message: 'Oops!'})
|
||||
*/
|
||||
errorWith(reason?: unknown): void;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/glossary.d.ts
|
||||
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;
|
||||
}];
|
||||
};
|
||||
//#endregion
|
||||
//#region src/Interceptor.d.ts
|
||||
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;
|
||||
}
|
||||
//#endregion
|
||||
export { InterceptorReadyState as a, getGlobalSymbol as c, RequestCredentials as d, RequestController as f, InterceptorEventMap as i, HttpRequestEventMap as l, INTERNAL_REQUEST_ID_HEADER_NAME as n, InterceptorSubscription as o, RequestControllerSource as p, Interceptor as r, deleteGlobalSymbol as s, ExtractEventNames as t, IS_PATCHED_MODULE as u };
|
||||
//# sourceMappingURL=Interceptor-DJ2akVWI.d.cts.map
|
||||
154
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.cjs
generated
vendored
Normal file
154
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.cjs
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
const require_fetchUtils = require('./fetchUtils-BaY5iWXw.cjs');
|
||||
const require_BatchInterceptor = require('./BatchInterceptor-3LnAnLTx.cjs');
|
||||
require('./bufferUtils-DiCTqG-7.cjs');
|
||||
const require_ClientRequest = require('./ClientRequest-2rDe54Ui.cjs');
|
||||
const require_handleRequest = require('./handleRequest-Bb7Y-XLw.cjs');
|
||||
require('./node-dKdAf3tC.cjs');
|
||||
const require_XMLHttpRequest = require('./XMLHttpRequest-B7kJdYYI.cjs');
|
||||
const require_fetch = require('./fetch-BmXpK10r.cjs');
|
||||
|
||||
//#region src/RemoteHttpInterceptor.ts
|
||||
var RemoteHttpInterceptor = class extends require_BatchInterceptor.BatchInterceptor {
|
||||
constructor() {
|
||||
super({
|
||||
name: "remote-interceptor",
|
||||
interceptors: [
|
||||
new require_ClientRequest.ClientRequestInterceptor(),
|
||||
new require_XMLHttpRequest.XMLHttpRequestInterceptor(),
|
||||
new require_fetch.FetchInterceptor()
|
||||
]
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
super.setup();
|
||||
let handleParentMessage;
|
||||
this.on("request", async ({ request, requestId, controller }) => {
|
||||
const serializedRequest = JSON.stringify({
|
||||
id: requestId,
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
headers: Array.from(request.headers.entries()),
|
||||
credentials: request.credentials,
|
||||
body: ["GET", "HEAD"].includes(request.method) ? null : await request.text()
|
||||
});
|
||||
this.logger.info("sent serialized request to the child:", serializedRequest);
|
||||
process.send?.(`request:${serializedRequest}`);
|
||||
const responsePromise = new Promise((resolve) => {
|
||||
handleParentMessage = (message) => {
|
||||
if (typeof message !== "string") return resolve();
|
||||
if (message.startsWith(`response:${requestId}`)) {
|
||||
const [, serializedResponse] = message.match(/^response:.+?:(.+)$/) || [];
|
||||
if (!serializedResponse) return resolve();
|
||||
const responseInit = JSON.parse(serializedResponse);
|
||||
const mockedResponse = new require_fetchUtils.FetchResponse(responseInit.body, {
|
||||
url: request.url,
|
||||
status: responseInit.status,
|
||||
statusText: responseInit.statusText,
|
||||
headers: responseInit.headers
|
||||
});
|
||||
/**
|
||||
* @todo Support "errorWith" as well.
|
||||
* This response handling from the child is incomplete.
|
||||
*/
|
||||
controller.respondWith(mockedResponse);
|
||||
return resolve();
|
||||
}
|
||||
};
|
||||
});
|
||||
this.logger.info("add \"message\" listener to the parent process", handleParentMessage);
|
||||
process.addListener("message", handleParentMessage);
|
||||
return responsePromise;
|
||||
});
|
||||
this.subscriptions.push(() => {
|
||||
process.removeListener("message", handleParentMessage);
|
||||
});
|
||||
}
|
||||
};
|
||||
function requestReviver(key, value) {
|
||||
switch (key) {
|
||||
case "url": return new URL(value);
|
||||
case "headers": return new Headers(value);
|
||||
default: return value;
|
||||
}
|
||||
}
|
||||
var RemoteHttpResolver = class RemoteHttpResolver extends require_fetchUtils.Interceptor {
|
||||
static {
|
||||
this.symbol = Symbol("remote-resolver");
|
||||
}
|
||||
constructor(options) {
|
||||
super(RemoteHttpResolver.symbol);
|
||||
this.process = options.process;
|
||||
}
|
||||
setup() {
|
||||
const logger = this.logger.extend("setup");
|
||||
const handleChildMessage = async (message) => {
|
||||
logger.info("received message from child!", message);
|
||||
if (typeof message !== "string" || !message.startsWith("request:")) {
|
||||
logger.info("unknown message, ignoring...");
|
||||
return;
|
||||
}
|
||||
const [, serializedRequest] = message.match(/^request:(.+)$/) || [];
|
||||
if (!serializedRequest) return;
|
||||
const requestJson = JSON.parse(serializedRequest, requestReviver);
|
||||
logger.info("parsed intercepted request", requestJson);
|
||||
const request = new Request(requestJson.url, {
|
||||
method: requestJson.method,
|
||||
headers: new Headers(requestJson.headers),
|
||||
credentials: requestJson.credentials,
|
||||
body: requestJson.body
|
||||
});
|
||||
const controller = new require_fetchUtils.RequestController(request, {
|
||||
passthrough: () => {},
|
||||
respondWith: async (response) => {
|
||||
if (require_handleRequest.isResponseError(response)) {
|
||||
this.logger.info("received a network error!", { response });
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
this.logger.info("received mocked response!", { response });
|
||||
const responseClone = response.clone();
|
||||
const responseText = await responseClone.text();
|
||||
const serializedResponse = JSON.stringify({
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: Array.from(response.headers.entries()),
|
||||
body: responseText
|
||||
});
|
||||
this.process.send(`response:${requestJson.id}:${serializedResponse}`, (error) => {
|
||||
if (error) return;
|
||||
this.emitter.emit("response", {
|
||||
request,
|
||||
requestId: requestJson.id,
|
||||
response: responseClone,
|
||||
isMockedResponse: true
|
||||
});
|
||||
});
|
||||
logger.info("sent serialized mocked response to the parent:", serializedResponse);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request has errored!", { error: reason });
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
});
|
||||
await require_handleRequest.handleRequest({
|
||||
request,
|
||||
requestId: requestJson.id,
|
||||
controller,
|
||||
emitter: this.emitter
|
||||
});
|
||||
};
|
||||
this.subscriptions.push(() => {
|
||||
this.process.removeListener("message", handleChildMessage);
|
||||
logger.info("removed the \"message\" listener from the child process!");
|
||||
});
|
||||
logger.info("adding a \"message\" listener to the child process");
|
||||
this.process.addListener("message", handleChildMessage);
|
||||
this.process.once("error", () => this.dispose());
|
||||
this.process.once("exit", () => this.dispose());
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
exports.RemoteHttpInterceptor = RemoteHttpInterceptor;
|
||||
exports.RemoteHttpResolver = RemoteHttpResolver;
|
||||
exports.requestReviver = requestReviver;
|
||||
//# sourceMappingURL=RemoteHttpInterceptor.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
39
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.d.cts
generated
vendored
Normal file
39
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.d.cts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { l as HttpRequestEventMap, r as Interceptor } from "./Interceptor-DJ2akVWI.cjs";
|
||||
import { t as BatchInterceptor } from "./BatchInterceptor-D_YqR8qU.cjs";
|
||||
import { t as ClientRequestInterceptor } from "./index-BMbJ8FXL.cjs";
|
||||
import { XMLHttpRequestInterceptor } from "./interceptors/XMLHttpRequest/index.cjs";
|
||||
import { FetchInterceptor } from "./interceptors/fetch/index.cjs";
|
||||
import { ChildProcess } from "child_process";
|
||||
|
||||
//#region src/RemoteHttpInterceptor.d.ts
|
||||
interface SerializedRequest {
|
||||
id: string;
|
||||
url: string;
|
||||
method: string;
|
||||
headers: Array<[string, string]>;
|
||||
credentials: RequestCredentials;
|
||||
body: string;
|
||||
}
|
||||
interface SerializedResponse {
|
||||
status: number;
|
||||
statusText: string;
|
||||
headers: Array<[string, string]>;
|
||||
body: string;
|
||||
}
|
||||
declare class RemoteHttpInterceptor extends BatchInterceptor<[ClientRequestInterceptor, XMLHttpRequestInterceptor, FetchInterceptor]> {
|
||||
constructor();
|
||||
protected setup(): void;
|
||||
}
|
||||
declare function requestReviver(key: string, value: any): any;
|
||||
interface RemoveResolverOptions {
|
||||
process: ChildProcess;
|
||||
}
|
||||
declare class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {
|
||||
static symbol: symbol;
|
||||
private process;
|
||||
constructor(options: RemoveResolverOptions);
|
||||
protected setup(): void;
|
||||
}
|
||||
//#endregion
|
||||
export { RemoteHttpInterceptor, RemoteHttpResolver, RemoveResolverOptions, SerializedRequest, SerializedResponse, requestReviver };
|
||||
//# sourceMappingURL=RemoteHttpInterceptor.d.cts.map
|
||||
39
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.d.mts
generated
vendored
Normal file
39
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.d.mts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { l as HttpRequestEventMap, r as Interceptor } from "./Interceptor-DEazpLJd.mjs";
|
||||
import { t as BatchInterceptor } from "./BatchInterceptor-D7mXzHcQ.mjs";
|
||||
import { t as ClientRequestInterceptor } from "./index-C0YAQ36w.mjs";
|
||||
import { XMLHttpRequestInterceptor } from "./interceptors/XMLHttpRequest/index.mjs";
|
||||
import { FetchInterceptor } from "./interceptors/fetch/index.mjs";
|
||||
import { ChildProcess } from "child_process";
|
||||
|
||||
//#region src/RemoteHttpInterceptor.d.ts
|
||||
interface SerializedRequest {
|
||||
id: string;
|
||||
url: string;
|
||||
method: string;
|
||||
headers: Array<[string, string]>;
|
||||
credentials: RequestCredentials;
|
||||
body: string;
|
||||
}
|
||||
interface SerializedResponse {
|
||||
status: number;
|
||||
statusText: string;
|
||||
headers: Array<[string, string]>;
|
||||
body: string;
|
||||
}
|
||||
declare class RemoteHttpInterceptor extends BatchInterceptor<[ClientRequestInterceptor, XMLHttpRequestInterceptor, FetchInterceptor]> {
|
||||
constructor();
|
||||
protected setup(): void;
|
||||
}
|
||||
declare function requestReviver(key: string, value: any): any;
|
||||
interface RemoveResolverOptions {
|
||||
process: ChildProcess;
|
||||
}
|
||||
declare class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {
|
||||
static symbol: symbol;
|
||||
private process;
|
||||
constructor(options: RemoveResolverOptions);
|
||||
protected setup(): void;
|
||||
}
|
||||
//#endregion
|
||||
export { RemoteHttpInterceptor, RemoteHttpResolver, RemoveResolverOptions, SerializedRequest, SerializedResponse, requestReviver };
|
||||
//# sourceMappingURL=RemoteHttpInterceptor.d.mts.map
|
||||
152
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.mjs
generated
vendored
Normal file
152
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.mjs
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
import { i as RequestController, s as Interceptor, t as FetchResponse } from "./fetchUtils-CoU35g3M.mjs";
|
||||
import { t as BatchInterceptor } from "./BatchInterceptor-DFaBPilf.mjs";
|
||||
import "./bufferUtils-_8XfKIfX.mjs";
|
||||
import { t as ClientRequestInterceptor } from "./ClientRequest-Ca8Qykuv.mjs";
|
||||
import { n as isResponseError, t as handleRequest } from "./handleRequest-Y97UwBbF.mjs";
|
||||
import "./node-DwCc6iuP.mjs";
|
||||
import { t as XMLHttpRequestInterceptor } from "./XMLHttpRequest-C8dIZpds.mjs";
|
||||
import { t as FetchInterceptor } from "./fetch-G1DVwDKG.mjs";
|
||||
|
||||
//#region src/RemoteHttpInterceptor.ts
|
||||
var RemoteHttpInterceptor = class extends BatchInterceptor {
|
||||
constructor() {
|
||||
super({
|
||||
name: "remote-interceptor",
|
||||
interceptors: [
|
||||
new ClientRequestInterceptor(),
|
||||
new XMLHttpRequestInterceptor(),
|
||||
new FetchInterceptor()
|
||||
]
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
super.setup();
|
||||
let handleParentMessage;
|
||||
this.on("request", async ({ request, requestId, controller }) => {
|
||||
const serializedRequest = JSON.stringify({
|
||||
id: requestId,
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
headers: Array.from(request.headers.entries()),
|
||||
credentials: request.credentials,
|
||||
body: ["GET", "HEAD"].includes(request.method) ? null : await request.text()
|
||||
});
|
||||
this.logger.info("sent serialized request to the child:", serializedRequest);
|
||||
process.send?.(`request:${serializedRequest}`);
|
||||
const responsePromise = new Promise((resolve) => {
|
||||
handleParentMessage = (message) => {
|
||||
if (typeof message !== "string") return resolve();
|
||||
if (message.startsWith(`response:${requestId}`)) {
|
||||
const [, serializedResponse] = message.match(/^response:.+?:(.+)$/) || [];
|
||||
if (!serializedResponse) return resolve();
|
||||
const responseInit = JSON.parse(serializedResponse);
|
||||
const mockedResponse = new FetchResponse(responseInit.body, {
|
||||
url: request.url,
|
||||
status: responseInit.status,
|
||||
statusText: responseInit.statusText,
|
||||
headers: responseInit.headers
|
||||
});
|
||||
/**
|
||||
* @todo Support "errorWith" as well.
|
||||
* This response handling from the child is incomplete.
|
||||
*/
|
||||
controller.respondWith(mockedResponse);
|
||||
return resolve();
|
||||
}
|
||||
};
|
||||
});
|
||||
this.logger.info("add \"message\" listener to the parent process", handleParentMessage);
|
||||
process.addListener("message", handleParentMessage);
|
||||
return responsePromise;
|
||||
});
|
||||
this.subscriptions.push(() => {
|
||||
process.removeListener("message", handleParentMessage);
|
||||
});
|
||||
}
|
||||
};
|
||||
function requestReviver(key, value) {
|
||||
switch (key) {
|
||||
case "url": return new URL(value);
|
||||
case "headers": return new Headers(value);
|
||||
default: return value;
|
||||
}
|
||||
}
|
||||
var RemoteHttpResolver = class RemoteHttpResolver extends Interceptor {
|
||||
static {
|
||||
this.symbol = Symbol("remote-resolver");
|
||||
}
|
||||
constructor(options) {
|
||||
super(RemoteHttpResolver.symbol);
|
||||
this.process = options.process;
|
||||
}
|
||||
setup() {
|
||||
const logger = this.logger.extend("setup");
|
||||
const handleChildMessage = async (message) => {
|
||||
logger.info("received message from child!", message);
|
||||
if (typeof message !== "string" || !message.startsWith("request:")) {
|
||||
logger.info("unknown message, ignoring...");
|
||||
return;
|
||||
}
|
||||
const [, serializedRequest] = message.match(/^request:(.+)$/) || [];
|
||||
if (!serializedRequest) return;
|
||||
const requestJson = JSON.parse(serializedRequest, requestReviver);
|
||||
logger.info("parsed intercepted request", requestJson);
|
||||
const request = new Request(requestJson.url, {
|
||||
method: requestJson.method,
|
||||
headers: new Headers(requestJson.headers),
|
||||
credentials: requestJson.credentials,
|
||||
body: requestJson.body
|
||||
});
|
||||
const controller = new RequestController(request, {
|
||||
passthrough: () => {},
|
||||
respondWith: async (response) => {
|
||||
if (isResponseError(response)) {
|
||||
this.logger.info("received a network error!", { response });
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
this.logger.info("received mocked response!", { response });
|
||||
const responseClone = response.clone();
|
||||
const responseText = await responseClone.text();
|
||||
const serializedResponse = JSON.stringify({
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: Array.from(response.headers.entries()),
|
||||
body: responseText
|
||||
});
|
||||
this.process.send(`response:${requestJson.id}:${serializedResponse}`, (error) => {
|
||||
if (error) return;
|
||||
this.emitter.emit("response", {
|
||||
request,
|
||||
requestId: requestJson.id,
|
||||
response: responseClone,
|
||||
isMockedResponse: true
|
||||
});
|
||||
});
|
||||
logger.info("sent serialized mocked response to the parent:", serializedResponse);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request has errored!", { error: reason });
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
});
|
||||
await handleRequest({
|
||||
request,
|
||||
requestId: requestJson.id,
|
||||
controller,
|
||||
emitter: this.emitter
|
||||
});
|
||||
};
|
||||
this.subscriptions.push(() => {
|
||||
this.process.removeListener("message", handleChildMessage);
|
||||
logger.info("removed the \"message\" listener from the child process!");
|
||||
});
|
||||
logger.info("adding a \"message\" listener to the child process");
|
||||
this.process.addListener("message", handleChildMessage);
|
||||
this.process.once("error", () => this.dispose());
|
||||
this.process.once("exit", () => this.dispose());
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { RemoteHttpInterceptor, RemoteHttpResolver, requestReviver };
|
||||
//# sourceMappingURL=RemoteHttpInterceptor.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/RemoteHttpInterceptor.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
763
node_modules/@mswjs/interceptors/lib/node/XMLHttpRequest-B7kJdYYI.cjs
generated
vendored
Normal file
763
node_modules/@mswjs/interceptors/lib/node/XMLHttpRequest-B7kJdYYI.cjs
generated
vendored
Normal file
@@ -0,0 +1,763 @@
|
||||
const require_chunk = require('./chunk-CbDLau6x.cjs');
|
||||
const require_glossary = require('./glossary-BLKRyLBd.cjs');
|
||||
const require_fetchUtils = require('./fetchUtils-BaY5iWXw.cjs');
|
||||
const require_bufferUtils = require('./bufferUtils-DiCTqG-7.cjs');
|
||||
const require_getRawRequest = require('./getRawRequest-BavnMWh_.cjs');
|
||||
const require_handleRequest = require('./handleRequest-Bb7Y-XLw.cjs');
|
||||
const require_hasConfigurableGlobal = require('./hasConfigurableGlobal-C97fWuaA.cjs');
|
||||
let outvariant = require("outvariant");
|
||||
let is_node_process = require("is-node-process");
|
||||
|
||||
//#region src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts
|
||||
/**
|
||||
* Concatenate two `Uint8Array` buffers.
|
||||
*/
|
||||
function concatArrayBuffer(left, right) {
|
||||
const result = new Uint8Array(left.byteLength + right.byteLength);
|
||||
result.set(left, 0);
|
||||
result.set(right, left.byteLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region 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?.target || null;
|
||||
this.currentTarget = 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() {}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts
|
||||
var ProgressEventPolyfill = class extends EventPolyfill {
|
||||
constructor(type, init) {
|
||||
super(type);
|
||||
this.lengthComputable = init?.lengthComputable || false;
|
||||
this.composed = init?.composed || false;
|
||||
this.loaded = init?.loaded || 0;
|
||||
this.total = init?.total || 0;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/createEvent.ts
|
||||
const SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== "undefined";
|
||||
function createEvent(target, type, init) {
|
||||
const progressEvents = [
|
||||
"error",
|
||||
"progress",
|
||||
"loadstart",
|
||||
"loadend",
|
||||
"load",
|
||||
"timeout",
|
||||
"abort"
|
||||
];
|
||||
/**
|
||||
* `ProgressEvent` is not supported in React Native.
|
||||
* @see https://github.com/mswjs/interceptors/issues/40
|
||||
*/
|
||||
const ProgressEventClass = SUPPORTS_PROGRESS_EVENT ? ProgressEvent : ProgressEventPolyfill;
|
||||
return progressEvents.includes(type) ? new ProgressEventClass(type, {
|
||||
lengthComputable: true,
|
||||
loaded: init?.loaded || 0,
|
||||
total: init?.total || 0
|
||||
}) : new EventPolyfill(type, {
|
||||
target,
|
||||
currentTarget: target
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/findPropertySource.ts
|
||||
/**
|
||||
* Returns the source object of the given property on the target object
|
||||
* (the target itself, any parent in its prototype, or null).
|
||||
*/
|
||||
function findPropertySource(target, propertyName) {
|
||||
if (!(propertyName in target)) return null;
|
||||
if (Object.prototype.hasOwnProperty.call(target, propertyName)) return target;
|
||||
const prototype = Reflect.getPrototypeOf(target);
|
||||
return prototype ? findPropertySource(prototype, propertyName) : null;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/createProxy.ts
|
||||
function createProxy(target, options) {
|
||||
return new Proxy(target, optionsToProxyHandler(options));
|
||||
}
|
||||
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?.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) {
|
||||
/**
|
||||
* @note Using `Reflect.get()` here causes "TypeError: Illegal invocation".
|
||||
*/
|
||||
const next = () => target[propertyName];
|
||||
const value = typeof getProperty !== "undefined" ? getProperty.call(target, [propertyName, receiver], next) : next();
|
||||
if (typeof value === "function") return (...args) => {
|
||||
const next$1 = value.bind(target, ...args);
|
||||
if (typeof methodCall !== "undefined") return methodCall.call(target, [propertyName, args], next$1);
|
||||
return next$1();
|
||||
};
|
||||
return value;
|
||||
};
|
||||
return handler;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts
|
||||
function isDomParserSupportedType(type) {
|
||||
return [
|
||||
"application/xhtml+xml",
|
||||
"application/xml",
|
||||
"image/svg+xml",
|
||||
"text/html",
|
||||
"text/xml"
|
||||
].some((supportedType) => {
|
||||
return type.startsWith(supportedType);
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/parseJson.ts
|
||||
/**
|
||||
* Parses a given string into JSON.
|
||||
* Gracefully handles invalid JSON by returning `null`.
|
||||
*/
|
||||
function parseJson(data) {
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
||||
/**
|
||||
* Creates a Fetch API `Response` instance from the given
|
||||
* `XMLHttpRequest` instance and a response body.
|
||||
*/
|
||||
function createResponse(request, body) {
|
||||
return new require_fetchUtils.FetchResponse(require_fetchUtils.FetchResponse.isResponseWithBody(request.status) ? body : null, {
|
||||
url: request.responseURL,
|
||||
status: request.status,
|
||||
statusText: request.statusText,
|
||||
headers: createHeadersFromXMLHttpRequestHeaders(request.getAllResponseHeaders())
|
||||
});
|
||||
}
|
||||
function createHeadersFromXMLHttpRequestHeaders(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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/getBodyByteLength.ts
|
||||
/**
|
||||
* Return a total byte length of the given request/response body.
|
||||
* If the `Content-Length` header is present, it will be used as the byte length.
|
||||
*/
|
||||
async function getBodyByteLength(input) {
|
||||
const explicitContentLength = input.headers.get("content-length");
|
||||
if (explicitContentLength != null && explicitContentLength !== "") return Number(explicitContentLength);
|
||||
return (await input.arrayBuffer()).byteLength;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
|
||||
const kIsRequestHandled = Symbol("kIsRequestHandled");
|
||||
const IS_NODE = (0, is_node_process.isNodeProcess)();
|
||||
const kFetchRequest = Symbol("kFetchRequest");
|
||||
/**
|
||||
* An `XMLHttpRequest` instance controller that allows us
|
||||
* to handle any given request instance (e.g. responding to it).
|
||||
*/
|
||||
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 = require_fetchUtils.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);
|
||||
/**
|
||||
* @note Proxy callbacks to event listeners because JSDOM has trouble
|
||||
* translating these properties to callbacks. It seemed to be operating
|
||||
* on events exclusively.
|
||||
*/
|
||||
this.request.addEventListener(eventName, nextValue);
|
||||
return invoke();
|
||||
}
|
||||
default: return invoke();
|
||||
}
|
||||
},
|
||||
methodCall: ([methodName, args], invoke) => {
|
||||
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" ? require_bufferUtils.encodeBuffer(body) : body;
|
||||
const fetchRequest = this.toFetchApiRequest(requestBody);
|
||||
this[kFetchRequest] = fetchRequest.clone();
|
||||
/**
|
||||
* @note Start request handling on the next tick so that the user
|
||||
* could add event listeners for "loadend" before the interceptor fires it.
|
||||
*/
|
||||
queueMicrotask(() => {
|
||||
(this.onRequest?.call(this, {
|
||||
request: fetchRequest,
|
||||
requestId: this.requestId
|
||||
}) || Promise.resolve()).finally(() => {
|
||||
if (!this[kIsRequestHandled]) {
|
||||
this.logger.info("request callback settled but request has not been handled (readystate %d), performing as-is...", this.request.readyState);
|
||||
/**
|
||||
* @note Set the intercepted request ID on the original request in Node.js
|
||||
* so that if it triggers any other interceptors, they don't attempt
|
||||
* to process it once again.
|
||||
*
|
||||
* For instance, XMLHttpRequest is often implemented via "http.ClientRequest"
|
||||
* and we don't want for both XHR and ClientRequest interceptors to
|
||||
* handle the same request at the same time (e.g. emit the "response" event twice).
|
||||
*/
|
||||
if (IS_NODE) this.request.setRequestHeader(require_fetchUtils.INTERNAL_REQUEST_ID_HEADER_NAME, this.requestId);
|
||||
return invoke();
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: return invoke();
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Proxy the `.upload` property to gather the event listeners/callbacks.
|
||||
*/
|
||||
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 nextEvents = (this.events.get(eventName) || []).concat(listener);
|
||||
this.events.set(eventName, nextEvents);
|
||||
this.logger.info("registered event \"%s\"", eventName, listener);
|
||||
}
|
||||
registerUploadEvent(eventName, listener) {
|
||||
const nextEvents = (this.uploadEvents.get(eventName) || []).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) {
|
||||
/**
|
||||
* @note Since `XMLHttpRequestController` delegates the handling of the responses
|
||||
* to the "load" event listener that doesn't distinguish between the mocked and original
|
||||
* responses, mark the request that had a mocked response with a corresponding symbol.
|
||||
*
|
||||
* Mark this request as having a mocked response immediately since
|
||||
* calculating request/response total body length is asynchronous.
|
||||
*/
|
||||
this[kIsRequestHandled] = true;
|
||||
/**
|
||||
* Dispatch request upload events for requests with a body.
|
||||
* @see https://github.com/mswjs/interceptors/issues/573
|
||||
*/
|
||||
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 allHeaders = Array.from(response.headers.entries()).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 require_bufferUtils.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 = require_bufferUtils.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() {
|
||||
/**
|
||||
* Throw when trying to read the response body as text when the
|
||||
* "responseType" doesn't expect text. This just respects the spec better.
|
||||
* @see https://xhr.spec.whatwg.org/#the-responsetext-attribute
|
||||
*/
|
||||
(0, outvariant.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() {
|
||||
(0, outvariant.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) {
|
||||
/**
|
||||
* @note Mark this request as handled even if it received a mock error.
|
||||
* This prevents the controller from trying to perform this request as-is.
|
||||
*/
|
||||
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("triggering \"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,
|
||||
credentials: this.request.withCredentials ? "include" : "same-origin",
|
||||
body: ["GET", "HEAD"].includes(this.method.toUpperCase()) ? null : resolvedBody
|
||||
});
|
||||
define(fetchRequest, "headers", 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();
|
||||
} }));
|
||||
require_getRawRequest.setRawRequest(fetchRequest, this.request);
|
||||
this.logger.info("converted request to a Fetch API Request!", fetchRequest);
|
||||
return fetchRequest;
|
||||
}
|
||||
};
|
||||
function toAbsoluteUrl(url) {
|
||||
/**
|
||||
* @note XMLHttpRequest interceptor may run in environments
|
||||
* that implement XMLHttpRequest but don't implement "location"
|
||||
* (for example, React Native). If that's the case, return the
|
||||
* input URL as-is (nothing to be relative to).
|
||||
* @see https://github.com/mswjs/msw/issues/1777
|
||||
*/
|
||||
if (typeof location === "undefined") return new URL(url);
|
||||
return new URL(url.toString(), location.href);
|
||||
}
|
||||
function define(target, property, value) {
|
||||
Reflect.defineProperty(target, property, {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
|
||||
/**
|
||||
* Create a proxied `XMLHttpRequest` class.
|
||||
* The proxied class establishes spies on certain methods,
|
||||
* allowing us to intercept requests and respond to them.
|
||||
*/
|
||||
function createXMLHttpRequestProxy({ emitter, logger }) {
|
||||
return new Proxy(globalThis.XMLHttpRequest, { construct(target, args, newTarget) {
|
||||
logger.info("constructed new XMLHttpRequest");
|
||||
const originalRequest = Reflect.construct(target, args, newTarget);
|
||||
/**
|
||||
* @note Forward prototype descriptors onto the proxied object.
|
||||
* XMLHttpRequest is implemented in JSDOM in a way that assigns
|
||||
* a bunch of descriptors, like "set responseType()" on the prototype.
|
||||
* With this propagation, we make sure that those descriptors trigger
|
||||
* when the user operates with the proxied request instance.
|
||||
*/
|
||||
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 require_fetchUtils.RequestController(request, {
|
||||
passthrough: () => {
|
||||
this.logger.info("no mocked response received, performing request as-is...");
|
||||
},
|
||||
respondWith: async (response) => {
|
||||
if (require_handleRequest.isResponseError(response)) {
|
||||
this.errorWith(/* @__PURE__ */ new TypeError("Network error"));
|
||||
return;
|
||||
}
|
||||
await this.respondWith(response);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request errored!", { error: reason });
|
||||
if (reason instanceof Error) this.errorWith(reason);
|
||||
}
|
||||
});
|
||||
this.logger.info("awaiting mocked response...");
|
||||
this.logger.info("emitting the \"request\" event for %s listener(s)...", emitter.listenerCount("request"));
|
||||
await require_handleRequest.handleRequest({
|
||||
request,
|
||||
requestId,
|
||||
controller,
|
||||
emitter
|
||||
});
|
||||
};
|
||||
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;
|
||||
} });
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/index.ts
|
||||
var XMLHttpRequestInterceptor = class XMLHttpRequestInterceptor extends require_fetchUtils.Interceptor {
|
||||
static {
|
||||
this.interceptorSymbol = Symbol("xhr");
|
||||
}
|
||||
constructor() {
|
||||
super(XMLHttpRequestInterceptor.interceptorSymbol);
|
||||
}
|
||||
checkEnvironment() {
|
||||
return require_hasConfigurableGlobal.hasConfigurableGlobal("XMLHttpRequest");
|
||||
}
|
||||
setup() {
|
||||
const logger = this.logger.extend("setup");
|
||||
logger.info("patching \"XMLHttpRequest\" module...");
|
||||
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
|
||||
(0, outvariant.invariant)(!PureXMLHttpRequest[require_glossary.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, require_glossary.IS_PATCHED_MODULE, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: true
|
||||
});
|
||||
this.subscriptions.push(() => {
|
||||
Object.defineProperty(globalThis.XMLHttpRequest, require_glossary.IS_PATCHED_MODULE, { value: void 0 });
|
||||
globalThis.XMLHttpRequest = PureXMLHttpRequest;
|
||||
logger.info("native \"XMLHttpRequest\" module restored!", globalThis.XMLHttpRequest.name);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'XMLHttpRequestInterceptor', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return XMLHttpRequestInterceptor;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=XMLHttpRequest-B7kJdYYI.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/XMLHttpRequest-B7kJdYYI.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/XMLHttpRequest-B7kJdYYI.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
757
node_modules/@mswjs/interceptors/lib/node/XMLHttpRequest-C8dIZpds.mjs
generated
vendored
Normal file
757
node_modules/@mswjs/interceptors/lib/node/XMLHttpRequest-C8dIZpds.mjs
generated
vendored
Normal file
@@ -0,0 +1,757 @@
|
||||
import { t as IS_PATCHED_MODULE } from "./glossary-glQBRnVD.mjs";
|
||||
import { i as RequestController, o as INTERNAL_REQUEST_ID_HEADER_NAME, r as createRequestId, s as Interceptor, t as FetchResponse } from "./fetchUtils-CoU35g3M.mjs";
|
||||
import { n as encodeBuffer, r as toArrayBuffer, t as decodeBuffer } from "./bufferUtils-_8XfKIfX.mjs";
|
||||
import { n as setRawRequest } from "./getRawRequest-DnwmXyOW.mjs";
|
||||
import { n as isResponseError, t as handleRequest } from "./handleRequest-Y97UwBbF.mjs";
|
||||
import { t as hasConfigurableGlobal } from "./hasConfigurableGlobal-DBJA0vjm.mjs";
|
||||
import { invariant } from "outvariant";
|
||||
import { isNodeProcess } from "is-node-process";
|
||||
|
||||
//#region src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts
|
||||
/**
|
||||
* Concatenate two `Uint8Array` buffers.
|
||||
*/
|
||||
function concatArrayBuffer(left, right) {
|
||||
const result = new Uint8Array(left.byteLength + right.byteLength);
|
||||
result.set(left, 0);
|
||||
result.set(right, left.byteLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region 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?.target || null;
|
||||
this.currentTarget = 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() {}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts
|
||||
var ProgressEventPolyfill = class extends EventPolyfill {
|
||||
constructor(type, init) {
|
||||
super(type);
|
||||
this.lengthComputable = init?.lengthComputable || false;
|
||||
this.composed = init?.composed || false;
|
||||
this.loaded = init?.loaded || 0;
|
||||
this.total = init?.total || 0;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/createEvent.ts
|
||||
const SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== "undefined";
|
||||
function createEvent(target, type, init) {
|
||||
const progressEvents = [
|
||||
"error",
|
||||
"progress",
|
||||
"loadstart",
|
||||
"loadend",
|
||||
"load",
|
||||
"timeout",
|
||||
"abort"
|
||||
];
|
||||
/**
|
||||
* `ProgressEvent` is not supported in React Native.
|
||||
* @see https://github.com/mswjs/interceptors/issues/40
|
||||
*/
|
||||
const ProgressEventClass = SUPPORTS_PROGRESS_EVENT ? ProgressEvent : ProgressEventPolyfill;
|
||||
return progressEvents.includes(type) ? new ProgressEventClass(type, {
|
||||
lengthComputable: true,
|
||||
loaded: init?.loaded || 0,
|
||||
total: init?.total || 0
|
||||
}) : new EventPolyfill(type, {
|
||||
target,
|
||||
currentTarget: target
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/findPropertySource.ts
|
||||
/**
|
||||
* Returns the source object of the given property on the target object
|
||||
* (the target itself, any parent in its prototype, or null).
|
||||
*/
|
||||
function findPropertySource(target, propertyName) {
|
||||
if (!(propertyName in target)) return null;
|
||||
if (Object.prototype.hasOwnProperty.call(target, propertyName)) return target;
|
||||
const prototype = Reflect.getPrototypeOf(target);
|
||||
return prototype ? findPropertySource(prototype, propertyName) : null;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/createProxy.ts
|
||||
function createProxy(target, options) {
|
||||
return new Proxy(target, optionsToProxyHandler(options));
|
||||
}
|
||||
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?.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) {
|
||||
/**
|
||||
* @note Using `Reflect.get()` here causes "TypeError: Illegal invocation".
|
||||
*/
|
||||
const next = () => target[propertyName];
|
||||
const value = typeof getProperty !== "undefined" ? getProperty.call(target, [propertyName, receiver], next) : next();
|
||||
if (typeof value === "function") return (...args) => {
|
||||
const next$1 = value.bind(target, ...args);
|
||||
if (typeof methodCall !== "undefined") return methodCall.call(target, [propertyName, args], next$1);
|
||||
return next$1();
|
||||
};
|
||||
return value;
|
||||
};
|
||||
return handler;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts
|
||||
function isDomParserSupportedType(type) {
|
||||
return [
|
||||
"application/xhtml+xml",
|
||||
"application/xml",
|
||||
"image/svg+xml",
|
||||
"text/html",
|
||||
"text/xml"
|
||||
].some((supportedType) => {
|
||||
return type.startsWith(supportedType);
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/parseJson.ts
|
||||
/**
|
||||
* Parses a given string into JSON.
|
||||
* Gracefully handles invalid JSON by returning `null`.
|
||||
*/
|
||||
function parseJson(data) {
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/createResponse.ts
|
||||
/**
|
||||
* Creates a Fetch API `Response` instance from the given
|
||||
* `XMLHttpRequest` instance and a response body.
|
||||
*/
|
||||
function createResponse(request, body) {
|
||||
return new FetchResponse(FetchResponse.isResponseWithBody(request.status) ? body : null, {
|
||||
url: request.responseURL,
|
||||
status: request.status,
|
||||
statusText: request.statusText,
|
||||
headers: createHeadersFromXMLHttpRequestHeaders(request.getAllResponseHeaders())
|
||||
});
|
||||
}
|
||||
function createHeadersFromXMLHttpRequestHeaders(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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/utils/getBodyByteLength.ts
|
||||
/**
|
||||
* Return a total byte length of the given request/response body.
|
||||
* If the `Content-Length` header is present, it will be used as the byte length.
|
||||
*/
|
||||
async function getBodyByteLength(input) {
|
||||
const explicitContentLength = input.headers.get("content-length");
|
||||
if (explicitContentLength != null && explicitContentLength !== "") return Number(explicitContentLength);
|
||||
return (await input.arrayBuffer()).byteLength;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts
|
||||
const kIsRequestHandled = Symbol("kIsRequestHandled");
|
||||
const IS_NODE = isNodeProcess();
|
||||
const kFetchRequest = Symbol("kFetchRequest");
|
||||
/**
|
||||
* An `XMLHttpRequest` instance controller that allows us
|
||||
* to handle any given request instance (e.g. responding to it).
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* @note Proxy callbacks to event listeners because JSDOM has trouble
|
||||
* translating these properties to callbacks. It seemed to be operating
|
||||
* on events exclusively.
|
||||
*/
|
||||
this.request.addEventListener(eventName, nextValue);
|
||||
return invoke();
|
||||
}
|
||||
default: return invoke();
|
||||
}
|
||||
},
|
||||
methodCall: ([methodName, args], invoke) => {
|
||||
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();
|
||||
/**
|
||||
* @note Start request handling on the next tick so that the user
|
||||
* could add event listeners for "loadend" before the interceptor fires it.
|
||||
*/
|
||||
queueMicrotask(() => {
|
||||
(this.onRequest?.call(this, {
|
||||
request: fetchRequest,
|
||||
requestId: this.requestId
|
||||
}) || Promise.resolve()).finally(() => {
|
||||
if (!this[kIsRequestHandled]) {
|
||||
this.logger.info("request callback settled but request has not been handled (readystate %d), performing as-is...", this.request.readyState);
|
||||
/**
|
||||
* @note Set the intercepted request ID on the original request in Node.js
|
||||
* so that if it triggers any other interceptors, they don't attempt
|
||||
* to process it once again.
|
||||
*
|
||||
* For instance, XMLHttpRequest is often implemented via "http.ClientRequest"
|
||||
* and we don't want for both XHR and ClientRequest interceptors to
|
||||
* handle the same request at the same time (e.g. emit the "response" event twice).
|
||||
*/
|
||||
if (IS_NODE) this.request.setRequestHeader(INTERNAL_REQUEST_ID_HEADER_NAME, this.requestId);
|
||||
return invoke();
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: return invoke();
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Proxy the `.upload` property to gather the event listeners/callbacks.
|
||||
*/
|
||||
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 nextEvents = (this.events.get(eventName) || []).concat(listener);
|
||||
this.events.set(eventName, nextEvents);
|
||||
this.logger.info("registered event \"%s\"", eventName, listener);
|
||||
}
|
||||
registerUploadEvent(eventName, listener) {
|
||||
const nextEvents = (this.uploadEvents.get(eventName) || []).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) {
|
||||
/**
|
||||
* @note Since `XMLHttpRequestController` delegates the handling of the responses
|
||||
* to the "load" event listener that doesn't distinguish between the mocked and original
|
||||
* responses, mark the request that had a mocked response with a corresponding symbol.
|
||||
*
|
||||
* Mark this request as having a mocked response immediately since
|
||||
* calculating request/response total body length is asynchronous.
|
||||
*/
|
||||
this[kIsRequestHandled] = true;
|
||||
/**
|
||||
* Dispatch request upload events for requests with a body.
|
||||
* @see https://github.com/mswjs/interceptors/issues/573
|
||||
*/
|
||||
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 allHeaders = Array.from(response.headers.entries()).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() {
|
||||
/**
|
||||
* Throw when trying to read the response body as text when the
|
||||
* "responseType" doesn't expect text. This just respects the spec better.
|
||||
* @see https://xhr.spec.whatwg.org/#the-responsetext-attribute
|
||||
*/
|
||||
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) {
|
||||
/**
|
||||
* @note Mark this request as handled even if it received a mock error.
|
||||
* This prevents the controller from trying to perform this request as-is.
|
||||
*/
|
||||
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("triggering \"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,
|
||||
credentials: this.request.withCredentials ? "include" : "same-origin",
|
||||
body: ["GET", "HEAD"].includes(this.method.toUpperCase()) ? null : resolvedBody
|
||||
});
|
||||
define(fetchRequest, "headers", 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();
|
||||
} }));
|
||||
setRawRequest(fetchRequest, this.request);
|
||||
this.logger.info("converted request to a Fetch API Request!", fetchRequest);
|
||||
return fetchRequest;
|
||||
}
|
||||
};
|
||||
function toAbsoluteUrl(url) {
|
||||
/**
|
||||
* @note XMLHttpRequest interceptor may run in environments
|
||||
* that implement XMLHttpRequest but don't implement "location"
|
||||
* (for example, React Native). If that's the case, return the
|
||||
* input URL as-is (nothing to be relative to).
|
||||
* @see https://github.com/mswjs/msw/issues/1777
|
||||
*/
|
||||
if (typeof location === "undefined") return new URL(url);
|
||||
return new URL(url.toString(), location.href);
|
||||
}
|
||||
function define(target, property, value) {
|
||||
Reflect.defineProperty(target, property, {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts
|
||||
/**
|
||||
* Create a proxied `XMLHttpRequest` class.
|
||||
* The proxied class establishes spies on certain methods,
|
||||
* allowing us to intercept requests and respond to them.
|
||||
*/
|
||||
function createXMLHttpRequestProxy({ emitter, logger }) {
|
||||
return new Proxy(globalThis.XMLHttpRequest, { construct(target, args, newTarget) {
|
||||
logger.info("constructed new XMLHttpRequest");
|
||||
const originalRequest = Reflect.construct(target, args, newTarget);
|
||||
/**
|
||||
* @note Forward prototype descriptors onto the proxied object.
|
||||
* XMLHttpRequest is implemented in JSDOM in a way that assigns
|
||||
* a bunch of descriptors, like "set responseType()" on the prototype.
|
||||
* With this propagation, we make sure that those descriptors trigger
|
||||
* when the user operates with the proxied request instance.
|
||||
*/
|
||||
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, {
|
||||
passthrough: () => {
|
||||
this.logger.info("no mocked response received, performing request as-is...");
|
||||
},
|
||||
respondWith: async (response) => {
|
||||
if (isResponseError(response)) {
|
||||
this.errorWith(/* @__PURE__ */ new TypeError("Network error"));
|
||||
return;
|
||||
}
|
||||
await this.respondWith(response);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request errored!", { error: reason });
|
||||
if (reason instanceof Error) this.errorWith(reason);
|
||||
}
|
||||
});
|
||||
this.logger.info("awaiting mocked response...");
|
||||
this.logger.info("emitting the \"request\" event for %s listener(s)...", emitter.listenerCount("request"));
|
||||
await handleRequest({
|
||||
request,
|
||||
requestId,
|
||||
controller,
|
||||
emitter
|
||||
});
|
||||
};
|
||||
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;
|
||||
} });
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/XMLHttpRequest/index.ts
|
||||
var XMLHttpRequestInterceptor = class XMLHttpRequestInterceptor extends Interceptor {
|
||||
static {
|
||||
this.interceptorSymbol = Symbol("xhr");
|
||||
}
|
||||
constructor() {
|
||||
super(XMLHttpRequestInterceptor.interceptorSymbol);
|
||||
}
|
||||
checkEnvironment() {
|
||||
return hasConfigurableGlobal("XMLHttpRequest");
|
||||
}
|
||||
setup() {
|
||||
const logger = this.logger.extend("setup");
|
||||
logger.info("patching \"XMLHttpRequest\" module...");
|
||||
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
|
||||
invariant(!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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { XMLHttpRequestInterceptor as t };
|
||||
//# sourceMappingURL=XMLHttpRequest-C8dIZpds.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/XMLHttpRequest-C8dIZpds.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/XMLHttpRequest-C8dIZpds.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
38
node_modules/@mswjs/interceptors/lib/node/bufferUtils-DiCTqG-7.cjs
generated
vendored
Normal file
38
node_modules/@mswjs/interceptors/lib/node/bufferUtils-DiCTqG-7.cjs
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
//#region src/utils/bufferUtils.ts
|
||||
const encoder = new TextEncoder();
|
||||
function encodeBuffer(text) {
|
||||
return encoder.encode(text);
|
||||
}
|
||||
function decodeBuffer(buffer, encoding) {
|
||||
return new TextDecoder(encoding).decode(buffer);
|
||||
}
|
||||
/**
|
||||
* Create an `ArrayBuffer` from the given `Uint8Array`.
|
||||
* Takes the byte offset into account to produce the right buffer
|
||||
* in the case when the buffer is bigger than the data view.
|
||||
*/
|
||||
function toArrayBuffer(array) {
|
||||
return array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'decodeBuffer', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return decodeBuffer;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'encodeBuffer', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return encodeBuffer;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'toArrayBuffer', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return toArrayBuffer;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=bufferUtils-DiCTqG-7.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/bufferUtils-DiCTqG-7.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/bufferUtils-DiCTqG-7.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bufferUtils-DiCTqG-7.cjs","names":[],"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,MAAM,UAAU,IAAI,aAAa;AAEjC,SAAgB,aAAa,MAA0B;AACrD,QAAO,QAAQ,OAAO,KAAK;;AAG7B,SAAgB,aAAa,QAAqB,UAA2B;AAE3E,QADgB,IAAI,YAAY,SAAS,CAC1B,OAAO,OAAO;;;;;;;AAQ/B,SAAgB,cAAc,OAAgC;AAC5D,QAAO,MAAM,OAAO,MAClB,MAAM,YACN,MAAM,aAAa,MAAM,WAC1B"}
|
||||
20
node_modules/@mswjs/interceptors/lib/node/bufferUtils-_8XfKIfX.mjs
generated
vendored
Normal file
20
node_modules/@mswjs/interceptors/lib/node/bufferUtils-_8XfKIfX.mjs
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
//#region src/utils/bufferUtils.ts
|
||||
const encoder = new TextEncoder();
|
||||
function encodeBuffer(text) {
|
||||
return encoder.encode(text);
|
||||
}
|
||||
function decodeBuffer(buffer, encoding) {
|
||||
return new TextDecoder(encoding).decode(buffer);
|
||||
}
|
||||
/**
|
||||
* Create an `ArrayBuffer` from the given `Uint8Array`.
|
||||
* Takes the byte offset into account to produce the right buffer
|
||||
* in the case when the buffer is bigger than the data view.
|
||||
*/
|
||||
function toArrayBuffer(array) {
|
||||
return array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { encodeBuffer as n, toArrayBuffer as r, decodeBuffer as t };
|
||||
//# sourceMappingURL=bufferUtils-_8XfKIfX.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/bufferUtils-_8XfKIfX.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/bufferUtils-_8XfKIfX.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bufferUtils-_8XfKIfX.mjs","names":[],"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,MAAM,UAAU,IAAI,aAAa;AAEjC,SAAgB,aAAa,MAA0B;AACrD,QAAO,QAAQ,OAAO,KAAK;;AAG7B,SAAgB,aAAa,QAAqB,UAA2B;AAE3E,QADgB,IAAI,YAAY,SAAS,CAC1B,OAAO,OAAO;;;;;;;AAQ/B,SAAgB,cAAc,OAAgC;AAC5D,QAAO,MAAM,OAAO,MAClB,MAAM,YACN,MAAM,aAAa,MAAM,WAC1B"}
|
||||
34
node_modules/@mswjs/interceptors/lib/node/chunk-CbDLau6x.cjs
generated
vendored
Normal file
34
node_modules/@mswjs/interceptors/lib/node/chunk-CbDLau6x.cjs
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
//#region rolldown:runtime
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
||||
key = keys[i];
|
||||
if (!__hasOwnProp.call(to, key) && key !== except) {
|
||||
__defProp(to, key, {
|
||||
get: ((k) => from[k]).bind(null, key),
|
||||
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
||||
value: mod,
|
||||
enumerable: true
|
||||
}) : target, mod));
|
||||
|
||||
//#endregion
|
||||
|
||||
Object.defineProperty(exports, '__toESM', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return __toESM;
|
||||
}
|
||||
});
|
||||
272
node_modules/@mswjs/interceptors/lib/node/fetch-BmXpK10r.cjs
generated
vendored
Normal file
272
node_modules/@mswjs/interceptors/lib/node/fetch-BmXpK10r.cjs
generated
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
const require_chunk = require('./chunk-CbDLau6x.cjs');
|
||||
const require_glossary = require('./glossary-BLKRyLBd.cjs');
|
||||
const require_fetchUtils = require('./fetchUtils-BaY5iWXw.cjs');
|
||||
const require_getRawRequest = require('./getRawRequest-BavnMWh_.cjs');
|
||||
const require_handleRequest = require('./handleRequest-Bb7Y-XLw.cjs');
|
||||
const require_hasConfigurableGlobal = require('./hasConfigurableGlobal-C97fWuaA.cjs');
|
||||
let _open_draft_deferred_promise = require("@open-draft/deferred-promise");
|
||||
let outvariant = require("outvariant");
|
||||
let _open_draft_until = require("@open-draft/until");
|
||||
let node_zlib = require("node:zlib");
|
||||
node_zlib = require_chunk.__toESM(node_zlib);
|
||||
|
||||
//#region src/interceptors/fetch/utils/createNetworkError.ts
|
||||
function createNetworkError(cause) {
|
||||
return Object.assign(/* @__PURE__ */ new TypeError("Failed to fetch"), { cause });
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/followRedirect.ts
|
||||
const REQUEST_BODY_HEADERS = [
|
||||
"content-encoding",
|
||||
"content-language",
|
||||
"content-location",
|
||||
"content-type",
|
||||
"content-length"
|
||||
];
|
||||
const kRedirectCount = Symbol("kRedirectCount");
|
||||
/**
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1210
|
||||
*/
|
||||
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");
|
||||
}
|
||||
/**
|
||||
* @note Undici "safely" extracts the request body.
|
||||
* I suspect we cannot dispatch this request again
|
||||
* since its body has been read and the stream is locked.
|
||||
*/
|
||||
requestInit.headers = request.headers;
|
||||
const finalResponse = await fetch(new Request(locationUrl, requestInit));
|
||||
Object.defineProperty(finalResponse, "redirected", {
|
||||
value: true,
|
||||
configurable: true
|
||||
});
|
||||
return finalResponse;
|
||||
}
|
||||
/**
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/util.js#L761
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/brotli-decompress.ts
|
||||
var BrotliDecompressionStream = class extends TransformStream {
|
||||
constructor() {
|
||||
const decompress = node_zlib.default.createBrotliDecompress({
|
||||
flush: node_zlib.default.constants.BROTLI_OPERATION_FLUSH,
|
||||
finishFlush: node_zlib.default.constants.BROTLI_OPERATION_FLUSH
|
||||
});
|
||||
super({ async transform(chunk, controller) {
|
||||
const buffer = Buffer.from(chunk);
|
||||
const decompressed = await new Promise((resolve, reject) => {
|
||||
decompress.write(buffer, (error) => {
|
||||
if (error) reject(error);
|
||||
});
|
||||
decompress.flush();
|
||||
decompress.once("data", (data) => resolve(data));
|
||||
decompress.once("error", (error) => reject(error));
|
||||
decompress.once("end", () => controller.terminate());
|
||||
}).catch((error) => {
|
||||
controller.error(error);
|
||||
});
|
||||
controller.enqueue(decompressed);
|
||||
} });
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/decompression.ts
|
||||
var PipelineStream = class extends TransformStream {
|
||||
constructor(transformStreams, ...strategies) {
|
||||
super({}, ...strategies);
|
||||
const readable = [super.readable, ...transformStreams].reduce((readable$1, transform) => readable$1.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;
|
||||
return new PipelineStream(codings.reduceRight((transformers, coding) => {
|
||||
if (coding === "gzip" || coding === "x-gzip") return transformers.concat(new DecompressionStream("gzip"));
|
||||
else if (coding === "deflate") return transformers.concat(new DecompressionStream("deflate"));
|
||||
else if (coding === "br") return transformers.concat(new BrotliDecompressionStream());
|
||||
else transformers.length = 0;
|
||||
return 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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/index.ts
|
||||
var FetchInterceptor = class FetchInterceptor extends require_fetchUtils.Interceptor {
|
||||
static {
|
||||
this.symbol = Symbol("fetch");
|
||||
}
|
||||
constructor() {
|
||||
super(FetchInterceptor.symbol);
|
||||
}
|
||||
checkEnvironment() {
|
||||
return require_hasConfigurableGlobal.hasConfigurableGlobal("fetch");
|
||||
}
|
||||
async setup() {
|
||||
const pureFetch = globalThis.fetch;
|
||||
(0, outvariant.invariant)(!pureFetch[require_glossary.IS_PATCHED_MODULE], "Failed to patch the \"fetch\" module: already patched.");
|
||||
globalThis.fetch = async (input, init) => {
|
||||
const requestId = require_fetchUtils.createRequestId();
|
||||
/**
|
||||
* @note Resolve potentially relative request URL
|
||||
* against the present `location`. This is mainly
|
||||
* for native `fetch` in JSDOM.
|
||||
* @see https://github.com/mswjs/msw/issues/1625
|
||||
*/
|
||||
const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !require_fetchUtils.canParseUrl(input) ? new URL(input, location.href) : input;
|
||||
const request = new Request(resolvedInput, init);
|
||||
/**
|
||||
* @note Set the raw request only if a Request instance was provided to fetch.
|
||||
*/
|
||||
if (input instanceof Request) require_getRawRequest.setRawRequest(request, input);
|
||||
const responsePromise = new _open_draft_deferred_promise.DeferredPromise();
|
||||
const controller = new require_fetchUtils.RequestController(request, {
|
||||
passthrough: async () => {
|
||||
this.logger.info("request has not been handled, passthrough...");
|
||||
/**
|
||||
* @note Clone the request instance right before performing it.
|
||||
* This preserves any modifications made to the intercepted request
|
||||
* in the "request" listener. This also allows the user to read the
|
||||
* request body in the "response" listener (otherwise "unusable").
|
||||
*/
|
||||
const requestCloneForResponseEvent = request.clone();
|
||||
const { error: responseError, data: originalResponse } = await (0, _open_draft_until.until)(() => pureFetch(request));
|
||||
if (responseError) return responsePromise.reject(responseError);
|
||||
this.logger.info("original fetch performed", originalResponse);
|
||||
if (this.emitter.listenerCount("response") > 0) {
|
||||
this.logger.info("emitting the \"response\" event...");
|
||||
const responseClone = originalResponse.clone();
|
||||
await require_handleRequest.emitAsync(this.emitter, "response", {
|
||||
response: responseClone,
|
||||
isMockedResponse: false,
|
||||
request: requestCloneForResponseEvent,
|
||||
requestId
|
||||
});
|
||||
}
|
||||
responsePromise.resolve(originalResponse);
|
||||
},
|
||||
respondWith: async (rawResponse) => {
|
||||
if (require_handleRequest.isResponseError(rawResponse)) {
|
||||
this.logger.info("request has errored!", { response: rawResponse });
|
||||
responsePromise.reject(createNetworkError(rawResponse));
|
||||
return;
|
||||
}
|
||||
this.logger.info("received mocked response!", { rawResponse });
|
||||
const decompressedStream = decompressResponse(rawResponse);
|
||||
const response = decompressedStream === null ? rawResponse : new require_fetchUtils.FetchResponse(decompressedStream, rawResponse);
|
||||
require_fetchUtils.FetchResponse.setUrl(request.url, response);
|
||||
/**
|
||||
* Undici's handling of following redirect responses.
|
||||
* Treat the "manual" redirect mode as a regular mocked response.
|
||||
* This way, the client can manually follow the redirect it receives.
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1173
|
||||
*/
|
||||
if (require_fetchUtils.FetchResponse.isRedirectResponse(response.status)) {
|
||||
if (request.redirect === "error") {
|
||||
responsePromise.reject(createNetworkError("unexpected redirect"));
|
||||
return;
|
||||
}
|
||||
if (request.redirect === "follow") {
|
||||
followFetchRedirect(request, response).then((response$1) => {
|
||||
responsePromise.resolve(response$1);
|
||||
}, (reason) => {
|
||||
responsePromise.reject(reason);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.emitter.listenerCount("response") > 0) {
|
||||
this.logger.info("emitting the \"response\" event...");
|
||||
await require_handleRequest.emitAsync(this.emitter, "response", {
|
||||
response: response.clone(),
|
||||
isMockedResponse: true,
|
||||
request,
|
||||
requestId
|
||||
});
|
||||
}
|
||||
responsePromise.resolve(response);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request has been aborted!", { reason });
|
||||
responsePromise.reject(reason);
|
||||
}
|
||||
});
|
||||
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"));
|
||||
await require_handleRequest.handleRequest({
|
||||
request,
|
||||
requestId,
|
||||
emitter: this.emitter,
|
||||
controller
|
||||
});
|
||||
return responsePromise;
|
||||
};
|
||||
Object.defineProperty(globalThis.fetch, require_glossary.IS_PATCHED_MODULE, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: true
|
||||
});
|
||||
this.subscriptions.push(() => {
|
||||
Object.defineProperty(globalThis.fetch, require_glossary.IS_PATCHED_MODULE, { value: void 0 });
|
||||
globalThis.fetch = pureFetch;
|
||||
this.logger.info("restored native \"globalThis.fetch\"!", globalThis.fetch.name);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'FetchInterceptor', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return FetchInterceptor;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=fetch-BmXpK10r.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/fetch-BmXpK10r.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/fetch-BmXpK10r.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
265
node_modules/@mswjs/interceptors/lib/node/fetch-G1DVwDKG.mjs
generated
vendored
Normal file
265
node_modules/@mswjs/interceptors/lib/node/fetch-G1DVwDKG.mjs
generated
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
import { t as IS_PATCHED_MODULE } from "./glossary-glQBRnVD.mjs";
|
||||
import { i as RequestController, n as canParseUrl, r as createRequestId, s as Interceptor, t as FetchResponse } from "./fetchUtils-CoU35g3M.mjs";
|
||||
import { n as setRawRequest } from "./getRawRequest-DnwmXyOW.mjs";
|
||||
import { i as emitAsync, n as isResponseError, t as handleRequest } from "./handleRequest-Y97UwBbF.mjs";
|
||||
import { t as hasConfigurableGlobal } from "./hasConfigurableGlobal-DBJA0vjm.mjs";
|
||||
import { DeferredPromise } from "@open-draft/deferred-promise";
|
||||
import { invariant } from "outvariant";
|
||||
import { until } from "@open-draft/until";
|
||||
import zlib from "node:zlib";
|
||||
|
||||
//#region src/interceptors/fetch/utils/createNetworkError.ts
|
||||
function createNetworkError(cause) {
|
||||
return Object.assign(/* @__PURE__ */ new TypeError("Failed to fetch"), { cause });
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/followRedirect.ts
|
||||
const REQUEST_BODY_HEADERS = [
|
||||
"content-encoding",
|
||||
"content-language",
|
||||
"content-location",
|
||||
"content-type",
|
||||
"content-length"
|
||||
];
|
||||
const kRedirectCount = Symbol("kRedirectCount");
|
||||
/**
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1210
|
||||
*/
|
||||
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");
|
||||
}
|
||||
/**
|
||||
* @note Undici "safely" extracts the request body.
|
||||
* I suspect we cannot dispatch this request again
|
||||
* since its body has been read and the stream is locked.
|
||||
*/
|
||||
requestInit.headers = request.headers;
|
||||
const finalResponse = await fetch(new Request(locationUrl, requestInit));
|
||||
Object.defineProperty(finalResponse, "redirected", {
|
||||
value: true,
|
||||
configurable: true
|
||||
});
|
||||
return finalResponse;
|
||||
}
|
||||
/**
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/util.js#L761
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/brotli-decompress.ts
|
||||
var BrotliDecompressionStream = class extends TransformStream {
|
||||
constructor() {
|
||||
const decompress = zlib.createBrotliDecompress({
|
||||
flush: zlib.constants.BROTLI_OPERATION_FLUSH,
|
||||
finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
|
||||
});
|
||||
super({ async transform(chunk, controller) {
|
||||
const buffer = Buffer.from(chunk);
|
||||
const decompressed = await new Promise((resolve, reject) => {
|
||||
decompress.write(buffer, (error) => {
|
||||
if (error) reject(error);
|
||||
});
|
||||
decompress.flush();
|
||||
decompress.once("data", (data) => resolve(data));
|
||||
decompress.once("error", (error) => reject(error));
|
||||
decompress.once("end", () => controller.terminate());
|
||||
}).catch((error) => {
|
||||
controller.error(error);
|
||||
});
|
||||
controller.enqueue(decompressed);
|
||||
} });
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/utils/decompression.ts
|
||||
var PipelineStream = class extends TransformStream {
|
||||
constructor(transformStreams, ...strategies) {
|
||||
super({}, ...strategies);
|
||||
const readable = [super.readable, ...transformStreams].reduce((readable$1, transform) => readable$1.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;
|
||||
return new PipelineStream(codings.reduceRight((transformers, coding) => {
|
||||
if (coding === "gzip" || coding === "x-gzip") return transformers.concat(new DecompressionStream("gzip"));
|
||||
else if (coding === "deflate") return transformers.concat(new DecompressionStream("deflate"));
|
||||
else if (coding === "br") return transformers.concat(new BrotliDecompressionStream());
|
||||
else transformers.length = 0;
|
||||
return 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;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/interceptors/fetch/index.ts
|
||||
var FetchInterceptor = class FetchInterceptor extends Interceptor {
|
||||
static {
|
||||
this.symbol = Symbol("fetch");
|
||||
}
|
||||
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();
|
||||
/**
|
||||
* @note Resolve potentially relative request URL
|
||||
* against the present `location`. This is mainly
|
||||
* for native `fetch` in JSDOM.
|
||||
* @see https://github.com/mswjs/msw/issues/1625
|
||||
*/
|
||||
const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !canParseUrl(input) ? new URL(input, location.href) : input;
|
||||
const request = new Request(resolvedInput, init);
|
||||
/**
|
||||
* @note Set the raw request only if a Request instance was provided to fetch.
|
||||
*/
|
||||
if (input instanceof Request) setRawRequest(request, input);
|
||||
const responsePromise = new DeferredPromise();
|
||||
const controller = new RequestController(request, {
|
||||
passthrough: async () => {
|
||||
this.logger.info("request has not been handled, passthrough...");
|
||||
/**
|
||||
* @note Clone the request instance right before performing it.
|
||||
* This preserves any modifications made to the intercepted request
|
||||
* in the "request" listener. This also allows the user to read the
|
||||
* request body in the "response" listener (otherwise "unusable").
|
||||
*/
|
||||
const requestCloneForResponseEvent = request.clone();
|
||||
const { error: responseError, data: originalResponse } = await until(() => pureFetch(request));
|
||||
if (responseError) return responsePromise.reject(responseError);
|
||||
this.logger.info("original fetch performed", originalResponse);
|
||||
if (this.emitter.listenerCount("response") > 0) {
|
||||
this.logger.info("emitting the \"response\" event...");
|
||||
const responseClone = originalResponse.clone();
|
||||
await emitAsync(this.emitter, "response", {
|
||||
response: responseClone,
|
||||
isMockedResponse: false,
|
||||
request: requestCloneForResponseEvent,
|
||||
requestId
|
||||
});
|
||||
}
|
||||
responsePromise.resolve(originalResponse);
|
||||
},
|
||||
respondWith: async (rawResponse) => {
|
||||
if (isResponseError(rawResponse)) {
|
||||
this.logger.info("request has errored!", { response: rawResponse });
|
||||
responsePromise.reject(createNetworkError(rawResponse));
|
||||
return;
|
||||
}
|
||||
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);
|
||||
/**
|
||||
* Undici's handling of following redirect responses.
|
||||
* Treat the "manual" redirect mode as a regular mocked response.
|
||||
* This way, the client can manually follow the redirect it receives.
|
||||
* @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1173
|
||||
*/
|
||||
if (FetchResponse.isRedirectResponse(response.status)) {
|
||||
if (request.redirect === "error") {
|
||||
responsePromise.reject(createNetworkError("unexpected redirect"));
|
||||
return;
|
||||
}
|
||||
if (request.redirect === "follow") {
|
||||
followFetchRedirect(request, response).then((response$1) => {
|
||||
responsePromise.resolve(response$1);
|
||||
}, (reason) => {
|
||||
responsePromise.reject(reason);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.emitter.listenerCount("response") > 0) {
|
||||
this.logger.info("emitting the \"response\" event...");
|
||||
await emitAsync(this.emitter, "response", {
|
||||
response: response.clone(),
|
||||
isMockedResponse: true,
|
||||
request,
|
||||
requestId
|
||||
});
|
||||
}
|
||||
responsePromise.resolve(response);
|
||||
},
|
||||
errorWith: (reason) => {
|
||||
this.logger.info("request has been aborted!", { reason });
|
||||
responsePromise.reject(reason);
|
||||
}
|
||||
});
|
||||
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"));
|
||||
await handleRequest({
|
||||
request,
|
||||
requestId,
|
||||
emitter: this.emitter,
|
||||
controller
|
||||
});
|
||||
return responsePromise;
|
||||
};
|
||||
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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { FetchInterceptor as t };
|
||||
//# sourceMappingURL=fetch-G1DVwDKG.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/fetch-G1DVwDKG.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/fetch-G1DVwDKG.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
419
node_modules/@mswjs/interceptors/lib/node/fetchUtils-BaY5iWXw.cjs
generated
vendored
Normal file
419
node_modules/@mswjs/interceptors/lib/node/fetchUtils-BaY5iWXw.cjs
generated
vendored
Normal file
@@ -0,0 +1,419 @@
|
||||
const require_chunk = require('./chunk-CbDLau6x.cjs');
|
||||
let _open_draft_logger = require("@open-draft/logger");
|
||||
let strict_event_emitter = require("strict-event-emitter");
|
||||
let _open_draft_deferred_promise = require("@open-draft/deferred-promise");
|
||||
let outvariant = require("outvariant");
|
||||
|
||||
//#region src/Interceptor.ts
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
const INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
|
||||
function getGlobalSymbol(symbol) {
|
||||
return globalThis[symbol] || void 0;
|
||||
}
|
||||
function setGlobalSymbol(symbol, value) {
|
||||
globalThis[symbol] = value;
|
||||
}
|
||||
function deleteGlobalSymbol(symbol) {
|
||||
delete globalThis[symbol];
|
||||
}
|
||||
let InterceptorReadyState = /* @__PURE__ */ function(InterceptorReadyState$1) {
|
||||
InterceptorReadyState$1["INACTIVE"] = "INACTIVE";
|
||||
InterceptorReadyState$1["APPLYING"] = "APPLYING";
|
||||
InterceptorReadyState$1["APPLIED"] = "APPLIED";
|
||||
InterceptorReadyState$1["DISPOSING"] = "DISPOSING";
|
||||
InterceptorReadyState$1["DISPOSED"] = "DISPOSED";
|
||||
return InterceptorReadyState$1;
|
||||
}({});
|
||||
var Interceptor = class {
|
||||
constructor(symbol) {
|
||||
this.symbol = symbol;
|
||||
this.readyState = InterceptorReadyState.INACTIVE;
|
||||
this.emitter = new strict_event_emitter.Emitter();
|
||||
this.subscriptions = [];
|
||||
this.logger = new _open_draft_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 === InterceptorReadyState.APPLIED) {
|
||||
logger.info("intercepted already applied!");
|
||||
return;
|
||||
}
|
||||
if (!this.checkEnvironment()) {
|
||||
logger.info("the interceptor cannot be applied in this environment!");
|
||||
return;
|
||||
}
|
||||
this.readyState = InterceptorReadyState.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 = InterceptorReadyState.APPLIED;
|
||||
return;
|
||||
}
|
||||
logger.info("no running instance found, setting up a new instance...");
|
||||
this.setup();
|
||||
this.setInstance();
|
||||
this.readyState = InterceptorReadyState.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 === InterceptorReadyState.DISPOSING || this.readyState === InterceptorReadyState.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 === InterceptorReadyState.DISPOSED) {
|
||||
logger.info("cannot dispose, already disposed!");
|
||||
return;
|
||||
}
|
||||
logger.info("disposing the interceptor...");
|
||||
this.readyState = InterceptorReadyState.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 = InterceptorReadyState.DISPOSED;
|
||||
}
|
||||
getInstance() {
|
||||
const instance = getGlobalSymbol(this.symbol);
|
||||
this.logger.info("retrieved global instance:", instance?.constructor?.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);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/InterceptorError.ts
|
||||
var InterceptorError = class InterceptorError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "InterceptorError";
|
||||
Object.setPrototypeOf(this, InterceptorError.prototype);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/RequestController.ts
|
||||
var RequestController = class RequestController {
|
||||
static {
|
||||
this.PENDING = 0;
|
||||
}
|
||||
static {
|
||||
this.PASSTHROUGH = 1;
|
||||
}
|
||||
static {
|
||||
this.RESPONSE = 2;
|
||||
}
|
||||
static {
|
||||
this.ERROR = 3;
|
||||
}
|
||||
constructor(request, source) {
|
||||
this.request = request;
|
||||
this.source = source;
|
||||
this.readyState = RequestController.PENDING;
|
||||
this.handled = new _open_draft_deferred_promise.DeferredPromise();
|
||||
}
|
||||
get #handled() {
|
||||
return this.handled;
|
||||
}
|
||||
/**
|
||||
* Perform this request as-is.
|
||||
*/
|
||||
async passthrough() {
|
||||
outvariant.invariant.as(InterceptorError, this.readyState === RequestController.PENDING, "Failed to passthrough the \"%s %s\" request: the request has already been handled", this.request.method, this.request.url);
|
||||
this.readyState = RequestController.PASSTHROUGH;
|
||||
await this.source.passthrough();
|
||||
this.#handled.resolve();
|
||||
}
|
||||
/**
|
||||
* 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.readyState === RequestController.PENDING, "Failed to respond to the \"%s %s\" request with \"%d %s\": the request has already been handled (%d)", this.request.method, this.request.url, response.status, response.statusText || "OK", this.readyState);
|
||||
this.readyState = RequestController.RESPONSE;
|
||||
this.#handled.resolve();
|
||||
/**
|
||||
* @note Although `source.respondWith()` is potentially asynchronous,
|
||||
* do NOT await it for backward-compatibility. Awaiting it will short-circuit
|
||||
* the request listener invocation as soon as a listener responds to a request.
|
||||
* Ideally, that's what we want, but that's not what we promise the user.
|
||||
*/
|
||||
this.source.respondWith(response);
|
||||
}
|
||||
/**
|
||||
* Error this request with the given reason.
|
||||
*
|
||||
* @example
|
||||
* controller.errorWith()
|
||||
* controller.errorWith(new Error('Oops!'))
|
||||
* controller.errorWith({ message: 'Oops!'})
|
||||
*/
|
||||
errorWith(reason) {
|
||||
outvariant.invariant.as(InterceptorError, this.readyState === RequestController.PENDING, "Failed to error the \"%s %s\" request with \"%s\": the request has already been handled (%d)", this.request.method, this.request.url, reason?.toString(), this.readyState);
|
||||
this.readyState = RequestController.ERROR;
|
||||
this.source.errorWith(reason);
|
||||
this.#handled.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/createRequestId.ts
|
||||
/**
|
||||
* Generate a random ID string to represent a request.
|
||||
* @example
|
||||
* createRequestId()
|
||||
* // "f774b6c9c600f"
|
||||
*/
|
||||
function createRequestId() {
|
||||
return Math.random().toString(16).slice(2);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/canParseUrl.ts
|
||||
/**
|
||||
* Returns a boolean indicating whether the given URL string
|
||||
* can be parsed into a `URL` instance.
|
||||
* A substitute for `URL.canParse()` for Node.js 18.
|
||||
*/
|
||||
function canParseUrl(url) {
|
||||
try {
|
||||
new URL(url);
|
||||
return true;
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/getValueBySymbol.ts
|
||||
/**
|
||||
* Returns the value behind the symbol with the given name.
|
||||
*/
|
||||
function getValueBySymbol(symbolName, source) {
|
||||
const symbol = Object.getOwnPropertySymbols(source).find((symbol$1) => {
|
||||
return symbol$1.description === symbolName;
|
||||
});
|
||||
if (symbol) return Reflect.get(source, symbol);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/fetchUtils.ts
|
||||
var FetchResponse = class FetchResponse extends Response {
|
||||
static {
|
||||
this.STATUS_CODES_WITHOUT_BODY = [
|
||||
101,
|
||||
103,
|
||||
204,
|
||||
205,
|
||||
304
|
||||
];
|
||||
}
|
||||
static {
|
||||
this.STATUS_CODES_WITH_REDIRECT = [
|
||||
301,
|
||||
302,
|
||||
303,
|
||||
307,
|
||||
308
|
||||
];
|
||||
}
|
||||
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 || url === "about:" || !canParseUrl(url)) return;
|
||||
const state = getValueBySymbol("state", response);
|
||||
if (state) state.urlList.push(new URL(url));
|
||||
else 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 = {}) {
|
||||
const status = init.status ?? 200;
|
||||
const safeStatus = FetchResponse.isConfigurableStatusCode(status) ? status : 200;
|
||||
const finalBody = FetchResponse.isResponseWithBody(status) ? body : null;
|
||||
super(finalBody, {
|
||||
status: safeStatus,
|
||||
statusText: init.statusText,
|
||||
headers: init.headers
|
||||
});
|
||||
if (status !== safeStatus) {
|
||||
/**
|
||||
* @note Undici keeps an internal "Symbol(state)" that holds
|
||||
* the actual value of response status. Update that in Node.js.
|
||||
*/
|
||||
const state = getValueBySymbol("state", this);
|
||||
if (state) state.status = status;
|
||||
else Object.defineProperty(this, "status", {
|
||||
value: status,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
FetchResponse.setUrl(init.url, this);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'FetchResponse', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return FetchResponse;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'INTERNAL_REQUEST_ID_HEADER_NAME', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return INTERNAL_REQUEST_ID_HEADER_NAME;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'Interceptor', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return Interceptor;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'InterceptorError', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return InterceptorError;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'InterceptorReadyState', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return InterceptorReadyState;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'RequestController', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return RequestController;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'canParseUrl', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return canParseUrl;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'createRequestId', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return createRequestId;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'deleteGlobalSymbol', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return deleteGlobalSymbol;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'getGlobalSymbol', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return getGlobalSymbol;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=fetchUtils-BaY5iWXw.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/fetchUtils-BaY5iWXw.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/fetchUtils-BaY5iWXw.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
359
node_modules/@mswjs/interceptors/lib/node/fetchUtils-CoU35g3M.mjs
generated
vendored
Normal file
359
node_modules/@mswjs/interceptors/lib/node/fetchUtils-CoU35g3M.mjs
generated
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
import { Logger } from "@open-draft/logger";
|
||||
import { Emitter } from "strict-event-emitter";
|
||||
import { DeferredPromise } from "@open-draft/deferred-promise";
|
||||
import { invariant } from "outvariant";
|
||||
|
||||
//#region src/Interceptor.ts
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
const INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
|
||||
function getGlobalSymbol(symbol) {
|
||||
return globalThis[symbol] || void 0;
|
||||
}
|
||||
function setGlobalSymbol(symbol, value) {
|
||||
globalThis[symbol] = value;
|
||||
}
|
||||
function deleteGlobalSymbol(symbol) {
|
||||
delete globalThis[symbol];
|
||||
}
|
||||
let InterceptorReadyState = /* @__PURE__ */ function(InterceptorReadyState$1) {
|
||||
InterceptorReadyState$1["INACTIVE"] = "INACTIVE";
|
||||
InterceptorReadyState$1["APPLYING"] = "APPLYING";
|
||||
InterceptorReadyState$1["APPLIED"] = "APPLIED";
|
||||
InterceptorReadyState$1["DISPOSING"] = "DISPOSING";
|
||||
InterceptorReadyState$1["DISPOSED"] = "DISPOSED";
|
||||
return InterceptorReadyState$1;
|
||||
}({});
|
||||
var Interceptor = class {
|
||||
constructor(symbol) {
|
||||
this.symbol = symbol;
|
||||
this.readyState = InterceptorReadyState.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 === InterceptorReadyState.APPLIED) {
|
||||
logger.info("intercepted already applied!");
|
||||
return;
|
||||
}
|
||||
if (!this.checkEnvironment()) {
|
||||
logger.info("the interceptor cannot be applied in this environment!");
|
||||
return;
|
||||
}
|
||||
this.readyState = InterceptorReadyState.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 = InterceptorReadyState.APPLIED;
|
||||
return;
|
||||
}
|
||||
logger.info("no running instance found, setting up a new instance...");
|
||||
this.setup();
|
||||
this.setInstance();
|
||||
this.readyState = InterceptorReadyState.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 === InterceptorReadyState.DISPOSING || this.readyState === InterceptorReadyState.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 === InterceptorReadyState.DISPOSED) {
|
||||
logger.info("cannot dispose, already disposed!");
|
||||
return;
|
||||
}
|
||||
logger.info("disposing the interceptor...");
|
||||
this.readyState = InterceptorReadyState.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 = InterceptorReadyState.DISPOSED;
|
||||
}
|
||||
getInstance() {
|
||||
const instance = getGlobalSymbol(this.symbol);
|
||||
this.logger.info("retrieved global instance:", instance?.constructor?.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);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/InterceptorError.ts
|
||||
var InterceptorError = class InterceptorError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "InterceptorError";
|
||||
Object.setPrototypeOf(this, InterceptorError.prototype);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/RequestController.ts
|
||||
var RequestController = class RequestController {
|
||||
static {
|
||||
this.PENDING = 0;
|
||||
}
|
||||
static {
|
||||
this.PASSTHROUGH = 1;
|
||||
}
|
||||
static {
|
||||
this.RESPONSE = 2;
|
||||
}
|
||||
static {
|
||||
this.ERROR = 3;
|
||||
}
|
||||
constructor(request, source) {
|
||||
this.request = request;
|
||||
this.source = source;
|
||||
this.readyState = RequestController.PENDING;
|
||||
this.handled = new DeferredPromise();
|
||||
}
|
||||
get #handled() {
|
||||
return this.handled;
|
||||
}
|
||||
/**
|
||||
* Perform this request as-is.
|
||||
*/
|
||||
async passthrough() {
|
||||
invariant.as(InterceptorError, this.readyState === RequestController.PENDING, "Failed to passthrough the \"%s %s\" request: the request has already been handled", this.request.method, this.request.url);
|
||||
this.readyState = RequestController.PASSTHROUGH;
|
||||
await this.source.passthrough();
|
||||
this.#handled.resolve();
|
||||
}
|
||||
/**
|
||||
* 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.readyState === RequestController.PENDING, "Failed to respond to the \"%s %s\" request with \"%d %s\": the request has already been handled (%d)", this.request.method, this.request.url, response.status, response.statusText || "OK", this.readyState);
|
||||
this.readyState = RequestController.RESPONSE;
|
||||
this.#handled.resolve();
|
||||
/**
|
||||
* @note Although `source.respondWith()` is potentially asynchronous,
|
||||
* do NOT await it for backward-compatibility. Awaiting it will short-circuit
|
||||
* the request listener invocation as soon as a listener responds to a request.
|
||||
* Ideally, that's what we want, but that's not what we promise the user.
|
||||
*/
|
||||
this.source.respondWith(response);
|
||||
}
|
||||
/**
|
||||
* Error this request with the given reason.
|
||||
*
|
||||
* @example
|
||||
* controller.errorWith()
|
||||
* controller.errorWith(new Error('Oops!'))
|
||||
* controller.errorWith({ message: 'Oops!'})
|
||||
*/
|
||||
errorWith(reason) {
|
||||
invariant.as(InterceptorError, this.readyState === RequestController.PENDING, "Failed to error the \"%s %s\" request with \"%s\": the request has already been handled (%d)", this.request.method, this.request.url, reason?.toString(), this.readyState);
|
||||
this.readyState = RequestController.ERROR;
|
||||
this.source.errorWith(reason);
|
||||
this.#handled.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/createRequestId.ts
|
||||
/**
|
||||
* Generate a random ID string to represent a request.
|
||||
* @example
|
||||
* createRequestId()
|
||||
* // "f774b6c9c600f"
|
||||
*/
|
||||
function createRequestId() {
|
||||
return Math.random().toString(16).slice(2);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/canParseUrl.ts
|
||||
/**
|
||||
* Returns a boolean indicating whether the given URL string
|
||||
* can be parsed into a `URL` instance.
|
||||
* A substitute for `URL.canParse()` for Node.js 18.
|
||||
*/
|
||||
function canParseUrl(url) {
|
||||
try {
|
||||
new URL(url);
|
||||
return true;
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/getValueBySymbol.ts
|
||||
/**
|
||||
* Returns the value behind the symbol with the given name.
|
||||
*/
|
||||
function getValueBySymbol(symbolName, source) {
|
||||
const symbol = Object.getOwnPropertySymbols(source).find((symbol$1) => {
|
||||
return symbol$1.description === symbolName;
|
||||
});
|
||||
if (symbol) return Reflect.get(source, symbol);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/utils/fetchUtils.ts
|
||||
var FetchResponse = class FetchResponse extends Response {
|
||||
static {
|
||||
this.STATUS_CODES_WITHOUT_BODY = [
|
||||
101,
|
||||
103,
|
||||
204,
|
||||
205,
|
||||
304
|
||||
];
|
||||
}
|
||||
static {
|
||||
this.STATUS_CODES_WITH_REDIRECT = [
|
||||
301,
|
||||
302,
|
||||
303,
|
||||
307,
|
||||
308
|
||||
];
|
||||
}
|
||||
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 || url === "about:" || !canParseUrl(url)) return;
|
||||
const state = getValueBySymbol("state", response);
|
||||
if (state) state.urlList.push(new URL(url));
|
||||
else 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 = {}) {
|
||||
const status = init.status ?? 200;
|
||||
const safeStatus = FetchResponse.isConfigurableStatusCode(status) ? status : 200;
|
||||
const finalBody = FetchResponse.isResponseWithBody(status) ? body : null;
|
||||
super(finalBody, {
|
||||
status: safeStatus,
|
||||
statusText: init.statusText,
|
||||
headers: init.headers
|
||||
});
|
||||
if (status !== safeStatus) {
|
||||
/**
|
||||
* @note Undici keeps an internal "Symbol(state)" that holds
|
||||
* the actual value of response status. Update that in Node.js.
|
||||
*/
|
||||
const state = getValueBySymbol("state", this);
|
||||
if (state) state.status = status;
|
||||
else Object.defineProperty(this, "status", {
|
||||
value: status,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
FetchResponse.setUrl(init.url, this);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { InterceptorError as a, InterceptorReadyState as c, RequestController as i, deleteGlobalSymbol as l, canParseUrl as n, INTERNAL_REQUEST_ID_HEADER_NAME as o, createRequestId as r, Interceptor as s, FetchResponse as t, getGlobalSymbol as u };
|
||||
//# sourceMappingURL=fetchUtils-CoU35g3M.mjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/fetchUtils-CoU35g3M.mjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/fetchUtils-CoU35g3M.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
36
node_modules/@mswjs/interceptors/lib/node/getRawRequest-BavnMWh_.cjs
generated
vendored
Normal file
36
node_modules/@mswjs/interceptors/lib/node/getRawRequest-BavnMWh_.cjs
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
//#region src/getRawRequest.ts
|
||||
const kRawRequest = Symbol("kRawRequest");
|
||||
/**
|
||||
* Returns a raw request instance associated with this request.
|
||||
*
|
||||
* @example
|
||||
* interceptor.on('request', ({ request }) => {
|
||||
* const rawRequest = getRawRequest(request)
|
||||
*
|
||||
* if (rawRequest instanceof http.ClientRequest) {
|
||||
* console.log(rawRequest.rawHeaders)
|
||||
* }
|
||||
* })
|
||||
*/
|
||||
function getRawRequest(request) {
|
||||
return Reflect.get(request, kRawRequest);
|
||||
}
|
||||
function setRawRequest(request, rawRequest) {
|
||||
Reflect.set(request, kRawRequest, rawRequest);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'getRawRequest', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return getRawRequest;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'setRawRequest', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return setRawRequest;
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=getRawRequest-BavnMWh_.cjs.map
|
||||
1
node_modules/@mswjs/interceptors/lib/node/getRawRequest-BavnMWh_.cjs.map
generated
vendored
Normal file
1
node_modules/@mswjs/interceptors/lib/node/getRawRequest-BavnMWh_.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"getRawRequest-BavnMWh_.cjs","names":[],"sources":["../../src/getRawRequest.ts"],"sourcesContent":["const kRawRequest = Symbol('kRawRequest')\n\n/**\n * Returns a raw request instance associated with this request.\n *\n * @example\n * interceptor.on('request', ({ request }) => {\n * const rawRequest = getRawRequest(request)\n *\n * if (rawRequest instanceof http.ClientRequest) {\n * console.log(rawRequest.rawHeaders)\n * }\n * })\n */\nexport function getRawRequest(request: Request): unknown | undefined {\n return Reflect.get(request, kRawRequest)\n}\n\nexport function setRawRequest(request: Request, rawRequest: unknown): void {\n Reflect.set(request, kRawRequest, rawRequest)\n}\n"],"mappings":";;AAAA,MAAM,cAAc,OAAO,cAAc;;;;;;;;;;;;;AAczC,SAAgB,cAAc,SAAuC;AACnE,QAAO,QAAQ,IAAI,SAAS,YAAY;;AAG1C,SAAgB,cAAc,SAAkB,YAA2B;AACzE,SAAQ,IAAI,SAAS,aAAa,WAAW"}
|
||||
24
node_modules/@mswjs/interceptors/lib/node/getRawRequest-DnwmXyOW.mjs
generated
vendored
Normal file
24
node_modules/@mswjs/interceptors/lib/node/getRawRequest-DnwmXyOW.mjs
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
//#region src/getRawRequest.ts
|
||||
const kRawRequest = Symbol("kRawRequest");
|
||||
/**
|
||||
* Returns a raw request instance associated with this request.
|
||||
*
|
||||
* @example
|
||||
* interceptor.on('request', ({ request }) => {
|
||||
* const rawRequest = getRawRequest(request)
|
||||
*
|
||||
* if (rawRequest instanceof http.ClientRequest) {
|
||||
* console.log(rawRequest.rawHeaders)
|
||||
* }
|
||||
* })
|
||||
*/
|
||||
function getRawRequest(request) {
|
||||
return Reflect.get(request, kRawRequest);
|
||||
}
|
||||
function setRawRequest(request, rawRequest) {
|
||||
Reflect.set(request, kRawRequest, rawRequest);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { setRawRequest as n, getRawRequest as t };
|
||||
//# sourceMappingURL=getRawRequest-DnwmXyOW.mjs.map
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user