msw
Version:
1,571 lines (1,556 loc) • 124 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/browser/index.ts
var index_exports = {};
__export(index_exports, {
SetupWorkerApi: () => SetupWorkerApi,
setupWorker: () => setupWorker
});
module.exports = __toCommonJS(index_exports);
// node_modules/.pnpm/outvariant@1.4.3/node_modules/outvariant/lib/index.mjs
var POSITIONALS_EXP = /(%?)(%([sdijo]))/g;
function serializePositional(positional, flag) {
switch (flag) {
case "s":
return positional;
case "d":
case "i":
return Number(positional);
case "j":
return JSON.stringify(positional);
case "o": {
if (typeof positional === "string") {
return positional;
}
const json = JSON.stringify(positional);
if (json === "{}" || json === "[]" || /^\[object .+?\]$/.test(json)) {
return positional;
}
return json;
}
}
}
function format(message, ...positionals) {
if (positionals.length === 0) {
return message;
}
let positionalIndex = 0;
let formattedMessage = message.replace(
POSITIONALS_EXP,
(match, isEscaped, _, flag) => {
const positional = positionals[positionalIndex];
const value = serializePositional(positional, flag);
if (!isEscaped) {
positionalIndex++;
return value;
}
return match;
}
);
if (positionalIndex < positionals.length) {
formattedMessage += ` ${positionals.slice(positionalIndex).join(" ")}`;
}
formattedMessage = formattedMessage.replace(/%{2,2}/g, "%");
return formattedMessage;
}
var STACK_FRAMES_TO_IGNORE = 2;
function cleanErrorStack(error2) {
if (!error2.stack) {
return;
}
const nextStack = error2.stack.split("\n");
nextStack.splice(1, STACK_FRAMES_TO_IGNORE);
error2.stack = nextStack.join("\n");
}
var InvariantError = class extends Error {
constructor(message, ...positionals) {
super(message);
this.message = message;
this.name = "Invariant Violation";
this.message = format(message, ...positionals);
cleanErrorStack(this);
}
};
var invariant = (predicate, message, ...positionals) => {
if (!predicate) {
throw new InvariantError(message, ...positionals);
}
};
invariant.as = (ErrorConstructor, predicate, message, ...positionals) => {
if (!predicate) {
const formatMessage = positionals.length === 0 ? message : format(message, ...positionals);
let error2;
try {
error2 = Reflect.construct(ErrorConstructor, [
formatMessage
]);
} catch (err) {
error2 = ErrorConstructor(formatMessage);
}
throw error2;
}
};
// node_modules/.pnpm/is-node-process@1.2.0/node_modules/is-node-process/lib/index.mjs
function isNodeProcess() {
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
return true;
}
if (typeof process !== "undefined") {
const type = process.type;
if (type === "renderer" || type === "worker") {
return false;
}
return !!(process.versions && process.versions.node);
}
return false;
}
// node_modules/.pnpm/@open-draft+logger@0.3.0/node_modules/@open-draft/logger/lib/index.mjs
var __defProp2 = Object.defineProperty;
var __export2 = (target, all) => {
for (var name in all)
__defProp2(target, name, { get: all[name], enumerable: true });
};
var colors_exports = {};
__export2(colors_exports, {
blue: () => blue,
gray: () => gray,
green: () => green,
red: () => red,
yellow: () => yellow
});
function yellow(text) {
return `\x1B[33m${text}\x1B[0m`;
}
function blue(text) {
return `\x1B[34m${text}\x1B[0m`;
}
function gray(text) {
return `\x1B[90m${text}\x1B[0m`;
}
function red(text) {
return `\x1B[31m${text}\x1B[0m`;
}
function green(text) {
return `\x1B[32m${text}\x1B[0m`;
}
var IS_NODE = isNodeProcess();
var Logger = class {
constructor(name) {
this.name = name;
this.prefix = `[${this.name}]`;
const LOGGER_NAME = getVariable("DEBUG");
const LOGGER_LEVEL = getVariable("LOG_LEVEL");
const isLoggingEnabled = LOGGER_NAME === "1" || LOGGER_NAME === "true" || typeof LOGGER_NAME !== "undefined" && this.name.startsWith(LOGGER_NAME);
if (isLoggingEnabled) {
this.debug = isDefinedAndNotEquals(LOGGER_LEVEL, "debug") ? noop : this.debug;
this.info = isDefinedAndNotEquals(LOGGER_LEVEL, "info") ? noop : this.info;
this.success = isDefinedAndNotEquals(LOGGER_LEVEL, "success") ? noop : this.success;
this.warning = isDefinedAndNotEquals(LOGGER_LEVEL, "warning") ? noop : this.warning;
this.error = isDefinedAndNotEquals(LOGGER_LEVEL, "error") ? noop : this.error;
} else {
this.info = noop;
this.success = noop;
this.warning = noop;
this.error = noop;
this.only = noop;
}
}
prefix;
extend(domain) {
return new Logger(`${this.name}:${domain}`);
}
/**
* Print a debug message.
* @example
* logger.debug('no duplicates found, creating a document...')
*/
debug(message, ...positionals) {
this.logEntry({
level: "debug",
message: gray(message),
positionals,
prefix: this.prefix,
colors: {
prefix: "gray"
}
});
}
/**
* Print an info message.
* @example
* logger.info('start parsing...')
*/
info(message, ...positionals) {
this.logEntry({
level: "info",
message,
positionals,
prefix: this.prefix,
colors: {
prefix: "blue"
}
});
const performance2 = new PerformanceEntry();
return (message2, ...positionals2) => {
performance2.measure();
this.logEntry({
level: "info",
message: `${message2} ${gray(`${performance2.deltaTime}ms`)}`,
positionals: positionals2,
prefix: this.prefix,
colors: {
prefix: "blue"
}
});
};
}
/**
* Print a success message.
* @example
* logger.success('successfully created document')
*/
success(message, ...positionals) {
this.logEntry({
level: "info",
message,
positionals,
prefix: `\u2714 ${this.prefix}`,
colors: {
timestamp: "green",
prefix: "green"
}
});
}
/**
* Print a warning.
* @example
* logger.warning('found legacy document format')
*/
warning(message, ...positionals) {
this.logEntry({
level: "warning",
message,
positionals,
prefix: `\u26A0 ${this.prefix}`,
colors: {
timestamp: "yellow",
prefix: "yellow"
}
});
}
/**
* Print an error message.
* @example
* logger.error('something went wrong')
*/
error(message, ...positionals) {
this.logEntry({
level: "error",
message,
positionals,
prefix: `\u2716 ${this.prefix}`,
colors: {
timestamp: "red",
prefix: "red"
}
});
}
/**
* Execute the given callback only when the logging is enabled.
* This is skipped in its entirety and has no runtime cost otherwise.
* This executes regardless of the log level.
* @example
* logger.only(() => {
* logger.info('additional info')
* })
*/
only(callback) {
callback();
}
createEntry(level, message) {
return {
timestamp: /* @__PURE__ */ new Date(),
level,
message
};
}
logEntry(args) {
const {
level,
message,
prefix,
colors: customColors,
positionals = []
} = args;
const entry = this.createEntry(level, message);
const timestampColor = customColors?.timestamp || "gray";
const prefixColor = customColors?.prefix || "gray";
const colorize = {
timestamp: colors_exports[timestampColor],
prefix: colors_exports[prefixColor]
};
const write = this.getWriter(level);
write(
[colorize.timestamp(this.formatTimestamp(entry.timestamp))].concat(prefix != null ? colorize.prefix(prefix) : []).concat(serializeInput(message)).join(" "),
...positionals.map(serializeInput)
);
}
formatTimestamp(timestamp) {
return `${timestamp.toLocaleTimeString(
"en-GB"
)}:${timestamp.getMilliseconds()}`;
}
getWriter(level) {
switch (level) {
case "debug":
case "success":
case "info": {
return log;
}
case "warning": {
return warn;
}
case "error": {
return error;
}
}
}
};
var PerformanceEntry = class {
startTime;
endTime;
deltaTime;
constructor() {
this.startTime = performance.now();
}
measure() {
this.endTime = performance.now();
const deltaTime = this.endTime - this.startTime;
this.deltaTime = deltaTime.toFixed(2);
}
};
var noop = () => void 0;
function log(message, ...positionals) {
if (IS_NODE) {
process.stdout.write(format(message, ...positionals) + "\n");
return;
}
console.log(message, ...positionals);
}
function warn(message, ...positionals) {
if (IS_NODE) {
process.stderr.write(format(message, ...positionals) + "\n");
return;
}
console.warn(message, ...positionals);
}
function error(message, ...positionals) {
if (IS_NODE) {
process.stderr.write(format(message, ...positionals) + "\n");
return;
}
console.error(message, ...positionals);
}
function getVariable(variableName) {
if (IS_NODE) {
return process.env[variableName];
}
return globalThis[variableName]?.toString();
}
function isDefinedAndNotEquals(value, expected) {
return value !== void 0 && value !== expected;
}
function serializeInput(message) {
if (typeof message === "undefined") {
return "undefined";
}
if (message === null) {
return "null";
}
if (typeof message === "string") {
return message;
}
if (typeof message === "object") {
return JSON.stringify(message);
}
return message.toString();
}
// node_modules/.pnpm/strict-event-emitter@0.5.1/node_modules/strict-event-emitter/lib/index.mjs
var MemoryLeakError = class extends Error {
constructor(emitter, type, count) {
super(
`Possible EventEmitter memory leak detected. ${count} ${type.toString()} listeners added. Use emitter.setMaxListeners() to increase limit`
);
this.emitter = emitter;
this.type = type;
this.count = count;
this.name = "MaxListenersExceededWarning";
}
};
var _Emitter = class {
static listenerCount(emitter, eventName) {
return emitter.listenerCount(eventName);
}
constructor() {
this.events = /* @__PURE__ */ new Map();
this.maxListeners = _Emitter.defaultMaxListeners;
this.hasWarnedAboutPotentialMemoryLeak = false;
}
_emitInternalEvent(internalEventName, eventName, listener) {
this.emit(
internalEventName,
...[eventName, listener]
);
}
_getListeners(eventName) {
return Array.prototype.concat.apply([], this.events.get(eventName)) || [];
}
_removeListener(listeners, listener) {
const index = listeners.indexOf(listener);
if (index > -1) {
listeners.splice(index, 1);
}
return [];
}
_wrapOnceListener(eventName, listener) {
const onceListener = (...data) => {
this.removeListener(eventName, onceListener);
return listener.apply(this, data);
};
Object.defineProperty(onceListener, "name", { value: listener.name });
return onceListener;
}
setMaxListeners(maxListeners) {
this.maxListeners = maxListeners;
return this;
}
/**
* Returns the current max listener value for the `Emitter` which is
* either set by `emitter.setMaxListeners(n)` or defaults to
* `Emitter.defaultMaxListeners`.
*/
getMaxListeners() {
return this.maxListeners;
}
/**
* Returns an array listing the events for which the emitter has registered listeners.
* The values in the array will be strings or Symbols.
*/
eventNames() {
return Array.from(this.events.keys());
}
/**
* Synchronously calls each of the listeners registered for the event named `eventName`,
* in the order they were registered, passing the supplied arguments to each.
* Returns `true` if the event has listeners, `false` otherwise.
*
* @example
* const emitter = new Emitter<{ hello: [string] }>()
* emitter.emit('hello', 'John')
*/
emit(eventName, ...data) {
const listeners = this._getListeners(eventName);
listeners.forEach((listener) => {
listener.apply(this, data);
});
return listeners.length > 0;
}
addListener(eventName, listener) {
this._emitInternalEvent("newListener", eventName, listener);
const nextListeners = this._getListeners(eventName).concat(listener);
this.events.set(eventName, nextListeners);
if (this.maxListeners > 0 && this.listenerCount(eventName) > this.maxListeners && !this.hasWarnedAboutPotentialMemoryLeak) {
this.hasWarnedAboutPotentialMemoryLeak = true;
const memoryLeakWarning = new MemoryLeakError(
this,
eventName,
this.listenerCount(eventName)
);
console.warn(memoryLeakWarning);
}
return this;
}
on(eventName, listener) {
return this.addListener(eventName, listener);
}
once(eventName, listener) {
return this.addListener(
eventName,
this._wrapOnceListener(eventName, listener)
);
}
prependListener(eventName, listener) {
const listeners = this._getListeners(eventName);
if (listeners.length > 0) {
const nextListeners = [listener].concat(listeners);
this.events.set(eventName, nextListeners);
} else {
this.events.set(eventName, listeners.concat(listener));
}
return this;
}
prependOnceListener(eventName, listener) {
return this.prependListener(
eventName,
this._wrapOnceListener(eventName, listener)
);
}
removeListener(eventName, listener) {
const listeners = this._getListeners(eventName);
if (listeners.length > 0) {
this._removeListener(listeners, listener);
this.events.set(eventName, listeners);
this._emitInternalEvent("removeListener", eventName, listener);
}
return this;
}
/**
* Alias for `emitter.removeListener()`.
*
* @example
* emitter.off('hello', listener)
*/
off(eventName, listener) {
return this.removeListener(eventName, listener);
}
removeAllListeners(eventName) {
if (eventName) {
this.events.delete(eventName);
} else {
this.events.clear();
}
return this;
}
/**
* Returns a copy of the array of listeners for the event named `eventName`.
*/
listeners(eventName) {
return Array.from(this._getListeners(eventName));
}
/**
* Returns the number of listeners listening to the event named `eventName`.
*/
listenerCount(eventName) {
return this._getListeners(eventName).length;
}
rawListeners(eventName) {
return this.listeners(eventName);
}
};
var Emitter = _Emitter;
Emitter.defaultMaxListeners = 10;
// node_modules/.pnpm/@mswjs+interceptors@0.41.3/node_modules/@mswjs/interceptors/lib/browser/createRequestId-DQcIlohW.mjs
var 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];
}
var 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);
}
};
function createRequestId() {
return Math.random().toString(16).slice(2);
}
// node_modules/.pnpm/@mswjs+interceptors@0.41.3/node_modules/@mswjs/interceptors/lib/browser/resolveWebSocketUrl-C83-x9iE.mjs
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:")
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;
}
// node_modules/.pnpm/@mswjs+interceptors@0.41.3/node_modules/@mswjs/interceptors/lib/browser/hasConfigurableGlobal-npXitu1-.mjs
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);
}
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;
}
// node_modules/.pnpm/@open-draft+deferred-promise@2.2.0/node_modules/@open-draft/deferred-promise/build/index.mjs
function createDeferredExecutor() {
const executor = (resolve, reject) => {
executor.state = "pending";
executor.resolve = (data) => {
if (executor.state !== "pending") {
return;
}
executor.result = data;
const onFulfilled = (value) => {
executor.state = "fulfilled";
return value;
};
return resolve(
data instanceof Promise ? data : Promise.resolve(data).then(onFulfilled)
);
};
executor.reject = (reason) => {
if (executor.state !== "pending") {
return;
}
queueMicrotask(() => {
executor.state = "rejected";
});
return reject(executor.rejectionReason = reason);
};
};
return executor;
}
var DeferredPromise = class extends Promise {
#executor;
resolve;
reject;
constructor(executor = null) {
const deferredExecutor = createDeferredExecutor();
super((originalResolve, originalReject) => {
deferredExecutor(originalResolve, originalReject);
executor?.(deferredExecutor.resolve, deferredExecutor.reject);
});
this.#executor = deferredExecutor;
this.resolve = this.#executor.resolve;
this.reject = this.#executor.reject;
}
get state() {
return this.#executor.state;
}
get rejectionReason() {
return this.#executor.rejectionReason;
}
then(onFulfilled, onRejected) {
return this.#decorate(super.then(onFulfilled, onRejected));
}
catch(onRejected) {
return this.#decorate(super.catch(onRejected));
}
finally(onfinally) {
return this.#decorate(super.finally(onfinally));
}
#decorate(promise) {
return Object.defineProperties(promise, {
resolve: { configurable: true, value: this.resolve },
reject: { configurable: true, value: this.reject }
});
}
};
// node_modules/.pnpm/@mswjs+interceptors@0.41.3/node_modules/@mswjs/interceptors/lib/browser/interceptors/WebSocket/index.mjs
function bindEvent(target, event) {
Object.defineProperties(event, {
target: {
value: target,
enumerable: true,
writable: true
},
currentTarget: {
value: target,
enumerable: true,
writable: true
}
});
return event;
}
var kCancelable = Symbol("kCancelable");
var kDefaultPrevented = Symbol("kDefaultPrevented");
var CancelableMessageEvent = class extends MessageEvent {
constructor(type, init) {
super(type, init);
this[kCancelable] = !!init.cancelable;
this[kDefaultPrevented] = false;
}
get cancelable() {
return this[kCancelable];
}
set cancelable(nextCancelable) {
this[kCancelable] = nextCancelable;
}
get defaultPrevented() {
return this[kDefaultPrevented];
}
set defaultPrevented(nextDefaultPrevented) {
this[kDefaultPrevented] = nextDefaultPrevented;
}
preventDefault() {
if (this.cancelable && !this[kDefaultPrevented]) this[kDefaultPrevented] = true;
}
};
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;
}
};
var kEmitter$1 = Symbol("kEmitter");
var kBoundListener$1 = Symbol("kBoundListener");
var WebSocketClientConnection = class {
constructor(socket, transport) {
this.socket = socket;
this.transport = transport;
this.id = createRequestId();
this.url = new URL(socket.url);
this[kEmitter$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();
});
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);
}
};
var WEBSOCKET_CLOSE_CODE_RANGE_ERROR = "InvalidAccessError: close code out of user configurable range";
var kPassthroughPromise = Symbol("kPassthroughPromise");
var kOnSend = Symbol("kOnSend");
var kClose = Symbol("kClose");
var WebSocketOverride = class extends EventTarget {
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] : "";
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;
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) {
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;
}
var kEmitter = Symbol("kEmitter");
var kBoundListener = Symbol("kBoundListener");
var kSend = Symbol("kSend");
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)
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
}));
this[kEmitter].dispatchEvent(messageEvent);
if (!messageEvent.defaultPrevented) this.client.dispatchEvent(bindEvent(
/**
* @note Bind the forwarded original server events
* to the mock WebSocket instance so it would
* dispatch them straight away.
*/
this.client,
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);
}
};
var WebSocketClassTransport = class extends EventTarget {
constructor(socket) {
super();
this.socket = socket;
this.socket.addEventListener("close", (event) => {
this.dispatchEvent(bindEvent(this.socket, new CloseEvent("close", event)));
});
this.socket[kOnSend] = (data) => {
this.dispatchEvent(bindEvent(this.socket, new CancelableMessageEvent("outgoing", {
data,
origin: this.socket.url,
cancelable: true
})));
};
}
addEventListener(type, callback, options) {
return super.addEventListener(type, callback, options);
}
dispatchEvent(event) {
return super.dispatchEvent(event);
}
send(data) {
queueMicrotask(() => {
if (this.socket.readyState === this.socket.CLOSING || this.socket.readyState === this.socket.CLOSED) return;
const dispatchEvent = () => {
this.socket.dispatchEvent(bindEvent(
/**
* @note Setting this event's "target" to the
* WebSocket override instance is important.
* This way it can tell apart original incoming events
* (must be forwarded to the transport) from the
* mocked message events like the one below
* (must be dispatched on the client instance).
*/
this.socket,
new MessageEvent("message", {
data,
origin: this.socket.url
})
));
};
if (this.socket.readyState === this.socket.CONNECTING) this.socket.addEventListener("open", () => {
dispatchEvent();
}, { once: true });
else dispatchEvent();
});
}
close(code, reason) {
this.socket[kClose](code, reason);
}
};
var WebSocketInterceptor = class WebSocketInterceptor2 extends Interceptor {
static {
this.symbol = Symbol("websocket");
}
constructor() {
super(WebSocketInterceptor2.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 (error2) {
if (error2 instanceof Error) {
socket.dispatchEvent(new Event("error"));
if (socket.readyState !== WebSocket.CLOSING && socket.readyState !== WebSocket.CLOSED) socket[kClose](1011, error2.message, false);
console.error(error2);
}
}
});
return socket;
} });
Object.defineProperty(globalThis, "WebSocket", {
value: WebSocketProxy,
configurable: true
});
this.subscriptions.push(() => {
Object.defineProperty(globalThis, "WebSocket", originalWebSocketDescriptor);
});
}
};
// src/browser/setup-worker.ts
var import_define_network = require("../core/experimental/define-network");
var import_interceptor_source2 = require("../core/experimental/sources/interceptor-source");
var import_compat = require("../core/experimental/compat");
var import_devUtils5 = require("../core/utils/internal/devUtils");
// src/browser/utils/supports.ts
function supportsServiceWorker() {
return typeof navigator !== "undefined" && "serviceWorker" in navigator && typeof location !== "undefined" && location.protocol !== "file:";
}
function supportsReadableStreamTransfer() {
try {
const stream = new ReadableStream({
start: (controller) => controller.close()
});
const message = new MessageChannel();
message.port1.postMessage(stream, [stream]);
return true;
} catch {
return false;
}
}
// node_modules/.pnpm/@open-draft+deferred-promise@3.0.0/node_modules/@open-draft/deferred-promise/build/index.mjs
function createDeferredExecutor2() {
const executor = ((resolve, reject) => {
executor.state = "pending";
executor.resolve = (data) => {
if (executor.state !== "pending") return;
executor.result = data;
const onFulfilled = (value) => {
executor.state = "fulfilled";
return value;
};
return resolve(data instanceof Promise ? data : Promise.resolve(data).then(onFulfilled));
};
executor.reject = (reason) => {
if (executor.state !== "pending") return;
queueMicrotask(() => {
executor.state = "rejected";
});
return reject(executor.rejectionReason = reason);
};
});
return executor;
}
var DeferredPromise2 = class extends Promise {
#executor;
resolve;
reject;
constructor(executor = null) {
const deferredExecutor = createDeferredExecutor2();
super((originalResolve, originalReject) => {
deferredExecutor(originalResolve, originalReject);
executor?.(deferredExecutor.resolve, deferredExecutor.reject);
});
this.#executor = deferredExecutor;
this.resolve = this.#executor.resolve;
this.reject = this.#executor.reject;
}
get state() {
return this.#executor.state;
}
get rejectionReason() {
return this.#executor.rejectionReason;
}
then(onFulfilled, onRejected) {
return this.#decorate(super.then(onFulfilled, onRejected));
}
catch(onRejected) {
return this.#decorate(super.catch(onRejected));
}
finally(onfinally) {
return this.#decorate(super.finally(onfinally));
}
#decorate(promise) {
return Object.defineProperties(promise, {
resolve: {
configurable: true,
value: this.resolve
},
reject: {
configurable: true,
value: this.reject
}
});
}
};
// node_modules/.pnpm/@mswjs+interceptors@0.41.3/node_modules/@mswjs/interceptors/lib/browser/getRawRequest-BTaNLFr0.mjs
var IS_PATCHED_MODULE = Symbol("isPatchedModule");
var InterceptorError = class InterceptorError2 extends Error {
constructor(message) {
super(message);
this.name = "InterceptorError";
Object.setPrototypeOf(this, InterceptorError2.prototype);
}
};
var RequestController = class RequestController2 {
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 = RequestController2.PENDING;
this.handled = new DeferredPromise();
}
get #handled() {
return this.handled;
}
/**
* Perform this request as-is.
*/
async passthrough() {
invariant.as(InterceptorError, this.readyState === RequestController2.PENDING, 'Failed to passthrough the "%s %s" request: the request has already been handled', this.request.method, this.request.url);
this.readyState = RequestController2.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 === RequestController2.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 = RequestController2.RESPONSE;
this.#handled.resolve();
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 === RequestController2.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 = RequestController2.ERROR;
this.source.errorWith(reason);
this.#handled.resolve();
}
};
function canParseUrl(url) {
try {
new URL(url);
return true;
} catch (_error) {
return false;
}
}
function getValueBySymbol(symbolName, source) {
const symbol = Object.getOwnPropertySymbols(source).find((symbol$1) => {
return symbol$1.description === symbolName;
});
if (symbol) return Reflect.get(source, symbol);
}
var FetchResponse = class FetchResponse2 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 FetchResponse2.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 !FetchResponse2.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 = FetchResponse2.isConfigurableStatusCode(status) ? status : 200;
const finalBody = FetchResponse2.isResponseWithBody(status) ? body : null;
super(finalBody, {
status: safeStatus,
statusText: init.statusText,
headers: init.headers
});
if (status !== safeStatus) {
const state = getValueBySymbol("state", this);
if (state) state.status = status;
else Object.defineProperty(this, "status", {
value: status,
enumerable: true,
configurable: true,
writable: false
});
}
FetchResponse2.setUrl(init.url, this);
}
};
var kRawRequest = Symbol("kRawRequest");
function setRawRequest(request, rawRequest) {
Reflect.set(request, kRawRequest, rawRequest);
}
// node_modules/.pnpm/@mswjs+interceptors@0.41.3/node_modules/@mswjs/interceptors/lib/browser/bufferUtils-BiiO6HZv.mjs
var encoder = new TextEncoder();
function encodeBuffer(text) {
return encoder.encode(text);
}
function decodeBuffer(buffer, encoding) {
return new TextDecode