UNPKG

msw

Version:

Seamless REST/GraphQL API mocking library for browser and Node.js.

1,571 lines (1,556 loc) 124 kB
"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