Files
lcbp3.np-dms.work/frontend/node_modules/msw/lib/browser/index.mjs
2025-09-21 20:29:15 +07:00

3094 lines
97 KiB
JavaScript
Executable File

// 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;
}
// src/browser/setupWorker/start/utils/prepareStartHandler.ts
import { mergeRight } from '../core/utils/internal/mergeRight.mjs';
var DEFAULT_START_OPTIONS = {
serviceWorker: {
url: "/mockServiceWorker.js",
options: null
},
quiet: false,
waitUntilReady: true,
onUnhandledRequest: "warn",
findWorker(scriptURL, mockServiceWorkerUrl) {
return scriptURL === mockServiceWorkerUrl;
}
};
// src/browser/setupWorker/start/createStartHandler.ts
import { devUtils as devUtils6 } from '../core/utils/internal/devUtils.mjs';
// node_modules/.pnpm/@open-draft+until@2.1.0/node_modules/@open-draft/until/lib/index.mjs
var until = async (promise) => {
try {
const data = await promise().catch((error2) => {
throw error2;
});
return { error: null, data };
} catch (error2) {
return { error: error2, data: null };
}
};
// src/browser/setupWorker/start/utils/getWorkerInstance.ts
import { devUtils } from '../core/utils/internal/devUtils.mjs';
// src/browser/utils/getAbsoluteWorkerUrl.ts
function getAbsoluteWorkerUrl(workerUrl) {
return new URL(workerUrl, location.href).href;
}
// src/browser/setupWorker/start/utils/getWorkerByRegistration.ts
function getWorkerByRegistration(registration, absoluteWorkerUrl, findWorker) {
const allStates = [
registration.active,
registration.installing,
registration.waiting
];
const relevantStates = allStates.filter((state) => {
return state != null;
});
const worker = relevantStates.find((worker2) => {
return findWorker(worker2.scriptURL, absoluteWorkerUrl);
});
return worker || null;
}
// src/browser/setupWorker/start/utils/getWorkerInstance.ts
var getWorkerInstance = async (url, options = {}, findWorker) => {
const absoluteWorkerUrl = getAbsoluteWorkerUrl(url);
const mockRegistrations = await navigator.serviceWorker.getRegistrations().then(
(registrations) => registrations.filter(
(registration) => getWorkerByRegistration(registration, absoluteWorkerUrl, findWorker)
)
);
if (!navigator.serviceWorker.controller && mockRegistrations.length > 0) {
location.reload();
}
const [existingRegistration] = mockRegistrations;
if (existingRegistration) {
existingRegistration.update();
return [
getWorkerByRegistration(
existingRegistration,
absoluteWorkerUrl,
findWorker
),
existingRegistration
];
}
const registrationResult = await until(
async () => {
const registration = await navigator.serviceWorker.register(url, options);
return [
// Compare existing worker registration by its worker URL,
// to prevent irrelevant workers to resolve here (such as Codesandbox worker).
getWorkerByRegistration(registration, absoluteWorkerUrl, findWorker),
registration
];
}
);
if (registrationResult.error) {
const isWorkerMissing = registrationResult.error.message.includes("(404)");
if (isWorkerMissing) {
const scopeUrl = new URL(options?.scope || "/", location.href);
throw new Error(
devUtils.formatMessage(`Failed to register a Service Worker for scope ('${scopeUrl.href}') with script ('${absoluteWorkerUrl}'): Service Worker script does not exist at the given path.
Did you forget to run "npx msw init <PUBLIC_DIR>"?
Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/init`)
);
}
throw new Error(
devUtils.formatMessage(
"Failed to register the Service Worker:\n\n%s",
registrationResult.error.message
)
);
}
return registrationResult.data;
};
// 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 }
});
}
};
// src/browser/setupWorker/start/utils/printStartMessage.ts
import { devUtils as devUtils2 } from '../core/utils/internal/devUtils.mjs';
function printStartMessage(args = {}) {
if (args.quiet) {
return;
}
const message = args.message || "Mocking enabled.";
console.groupCollapsed(
`%c${devUtils2.formatMessage(message)}`,
"color:orangered;font-weight:bold;"
);
console.log(
"%cDocumentation: %chttps://mswjs.io/docs",
"font-weight:bold",
"font-weight:normal"
);
console.log("Found an issue? https://github.com/mswjs/msw/issues");
if (args.workerUrl) {
console.log("Worker script URL:", args.workerUrl);
}
if (args.workerScope) {
console.log("Worker scope:", args.workerScope);
}
if (args.client) {
console.log("Client ID: %s (%s)", args.client.id, args.client.frameType);
}
console.groupEnd();
}
// src/browser/setupWorker/start/utils/enableMocking.ts
function enableMocking(context, options) {
const mockingEnabledPromise = new DeferredPromise();
context.workerChannel.postMessage("MOCK_ACTIVATE");
context.workerChannel.once("MOCKING_ENABLED", async (event) => {
context.isMockingEnabled = true;
const worker = await context.workerPromise;
printStartMessage({
quiet: options.quiet,
workerScope: context.registration?.scope,
workerUrl: worker.scriptURL,
client: event.data.client
});
mockingEnabledPromise.resolve(true);
});
return mockingEnabledPromise;
}
// src/browser/utils/pruneGetRequestBody.ts
function pruneGetRequestBody(request) {
if (["HEAD", "GET"].includes(request.method)) {
return void 0;
}
return request.body;
}
// src/browser/utils/deserializeRequest.ts
function deserializeRequest(serializedRequest) {
return new Request(serializedRequest.url, {
...serializedRequest,
body: pruneGetRequestBody(serializedRequest)
});
}
// src/browser/setupWorker/start/createRequestListener.ts
import { RequestHandler } from '../core/handlers/RequestHandler.mjs';
import { handleRequest } from '../core/utils/handleRequest.mjs';
import { devUtils as devUtils3 } from '../core/utils/internal/devUtils.mjs';
import { toResponseInit } from '../core/utils/toResponseInit.mjs';
import { isHandlerKind } from '../core/utils/internal/isHandlerKind.mjs';
var createRequestListener = (context, options) => {
return async (event) => {
if (!context.isMockingEnabled && context.workerStoppedAt && event.data.interceptedAt > context.workerStoppedAt) {
event.postMessage("PASSTHROUGH");
return;
}
const requestId = event.data.id;
const request = deserializeRequest(event.data);
const requestCloneForLogs = request.clone();
const requestClone = request.clone();
RequestHandler.cache.set(request, requestClone);
try {
await handleRequest(
request,
requestId,
context.getRequestHandlers().filter(isHandlerKind("RequestHandler")),
options,
context.emitter,
{
onPassthroughResponse() {
event.postMessage("PASSTHROUGH");
},
async onMockedResponse(response, { handler, parsedResult }) {
const responseClone = response.clone();
const responseCloneForLogs = response.clone();
const responseInit = toResponseInit(response);
if (context.supports.readableStreamTransfer) {
const responseStreamOrNull = response.body;
event.postMessage(
"MOCK_RESPONSE",
{
...responseInit,
body: responseStreamOrNull
},
responseStreamOrNull ? [responseStreamOrNull] : void 0
);
} else {
const responseBufferOrNull = response.body === null ? null : await responseClone.arrayBuffer();
event.postMessage("MOCK_RESPONSE", {
...responseInit,
body: responseBufferOrNull
});
}
if (!options.quiet) {
context.emitter.once("response:mocked", () => {
handler.log({
request: requestCloneForLogs,
response: responseCloneForLogs,
parsedResult
});
});
}
}
}
);
} catch (error2) {
if (error2 instanceof Error) {
devUtils3.error(
`Uncaught exception in the request handler for "%s %s":
%s
This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/http/mocking-responses/error-responses`,
request.method,
request.url,
error2.stack ?? error2
);
event.postMessage("MOCK_RESPONSE", {
status: 500,
statusText: "Request Handler Error",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: error2.name,
message: error2.message,
stack: error2.stack
})
});
}
}
};
};
// src/browser/utils/checkWorkerIntegrity.ts
import { devUtils as devUtils4 } from '../core/utils/internal/devUtils.mjs';
function checkWorkerIntegrity(context) {
const integrityCheckPromise = new DeferredPromise();
context.workerChannel.postMessage("INTEGRITY_CHECK_REQUEST");
context.workerChannel.once("INTEGRITY_CHECK_RESPONSE", (event) => {
const { checksum, packageVersion } = event.data;
if (checksum !== "4db4a41e972cec1b64cc569c66952d82") {
devUtils4.warn(
`The currently registered Service Worker has been generated by a different version of MSW (${packageVersion}) and may not be fully compatible with the installed version.
It's recommended you update your worker script by running this command:
\u2022 npx msw init <PUBLIC_DIR>
You can also automate this process and make the worker script update automatically upon the library installations. Read more: https://mswjs.io/docs/cli/init.`
);
}
integrityCheckPromise.resolve();
});
return integrityCheckPromise;
}
// node_modules/.pnpm/@mswjs+interceptors@0.39.1/node_modules/@mswjs/interceptors/lib/browser/chunk-6HYIRFX2.mjs
var encoder = new TextEncoder();
function encodeBuffer(text) {
return encoder.encode(text);
}
function decodeBuffer(buffer, encoding) {
const decoder = new TextDecoder(encoding);
return decoder.decode(buffer);
}
function toArrayBuffer(array) {
return array.buffer.slice(
array.byteOffset,
array.byteOffset + array.byteLength
);
}
// node_modules/.pnpm/@mswjs+interceptors@0.39.1/node_modules/@mswjs/interceptors/lib/browser/chunk-3RXCRGL2.mjs
var IS_PATCHED_MODULE = Symbol("isPatchedModule");
function canParseUrl(url) {
try {
new URL(url);
return true;
} catch (_error) {
return false;
}
}
function getValueBySymbol(symbolName, source) {
const ownSymbols = Object.getOwnPropertySymbols(source);
const symbol = ownSymbols.find((symbol2) => {
return symbol2.description === symbolName;
});
if (symbol) {
return Reflect.get(source, symbol);
}
return;
}
var _FetchResponse = class extends Response {
static isConfigurableStatusCode(status) {
return status >= 200 && status <= 599;
}
static isRedirectResponse(status) {
return _FetchResponse.STATUS_CODES_WITH_REDIRECT.includes(status);
}
/**
* Returns a boolean indicating whether the given response status
* code represents a response that can have a body.
*/
static isResponseWithBody(status) {
return !_FetchResponse.STATUS_CODES_WITHOUT_BODY.includes(status);
}
static setUrl(url, response) {
if (!url || 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 = {}) {
var _a;
const status = (_a = init.status) != null ? _a : 200;
const safeStatus = _FetchResponse.isConfigurableStatusCode(status) ? status : 200;
const finalBody = _FetchResponse.isResponseWithBody(status) ? body : null;
super(finalBody, {
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
});
}
}
_FetchResponse.setUrl(init.url, this);
}
};
var FetchResponse = _FetchResponse;
FetchResponse.STATUS_CODES_WITHOUT_BODY = [101, 103, 204, 205, 304];
FetchResponse.STATUS_CODES_WITH_REDIRECT = [301, 302, 303, 307, 308];
var kRawRequest = Symbol("kRawRequest");
function setRawRequest(request, rawRequest) {
Reflect.set(request, kRawRequest, rawRequest);
}
// node_modules/.pnpm/@open-draft+logger@0.3.0/node_modules/@open-draft/logger/lib/index.mjs
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var colors_exports = {};
__export(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.39.1/node_modules/@mswjs/interceptors/lib/browser/chunk-QED3Q6Z2.mjs
var INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
function getGlobalSymbol(symbol) {
return (
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587
globalThis[symbol] || void 0
);
}
function setGlobalSymbol(symbol, value) {
globalThis[symbol] = value;
}
function deleteGlobalSymbol(symbol) {
delete globalThis[symbol];
}
var Interceptor = class {
constructor(symbol) {
this.symbol = symbol;
this.readyState = "INACTIVE";
this.emitter = new Emitter();
this.subscriptions = [];
this.logger = new Logger(symbol.description);
this.emitter.setMaxListeners(0);
this.logger.info("constructing the interceptor...");
}
/**
* Determine if this interceptor can be applied
* in the current environment.
*/
checkEnvironment() {
return true;
}
/**
* Apply this interceptor to the current process.
* Returns an already running interceptor instance if it's present.
*/
apply() {
const logger = this.logger.extend("apply");
logger.info("applying the interceptor...");
if (this.readyState === "APPLIED") {
logger.info("intercepted already applied!");
return;
}
const shouldApply = this.checkEnvironment();
if (!shouldApply) {
logger.info("the interceptor cannot be applied in this environment!");
return;
}
this.readyState = "APPLYING";
const runningInstance = this.getInstance();
if (runningInstance) {
logger.info("found a running instance, reusing...");
this.on = (event, listener) => {
logger.info('proxying the "%s" listener', event);
runningInstance.emitter.addListener(event, listener);
this.subscriptions.push(() => {
runningInstance.emitter.removeListener(event, listener);
logger.info('removed proxied "%s" listener!', event);
});
return this;
};
this.readyState = "APPLIED";
return;
}
logger.info("no running instance found, setting up a new instance...");
this.setup();
this.setInstance();
this.readyState = "APPLIED";
}
/**
* Setup the module augments and stubs necessary for this interceptor.
* This method is not run if there's a running interceptor instance
* to prevent instantiating an interceptor multiple times.
*/
setup() {
}
/**
* Listen to the interceptor's public events.
*/
on(event, listener) {
const logger = this.logger.extend("on");
if (this.readyState === "DISPOSING" || this.readyState === "DISPOSED") {
logger.info("cannot listen to events, already disposed!");
return this;
}
logger.info('adding "%s" event listener:', event, listener);
this.emitter.on(event, listener);
return this;
}
once(event, listener) {
this.emitter.once(event, listener);
return this;
}
off(event, listener) {
this.emitter.off(event, listener);
return this;
}
removeAllListeners(event) {
this.emitter.removeAllListeners(event);
return this;
}
/**
* Disposes of any side-effects this interceptor has introduced.
*/
dispose() {
const logger = this.logger.extend("dispose");
if (this.readyState === "DISPOSED") {
logger.info("cannot dispose, already disposed!");
return;
}
logger.info("disposing the interceptor...");
this.readyState = "DISPOSING";
if (!this.getInstance()) {
logger.info("no interceptors running, skipping dispose...");
return;
}
this.clearInstance();
logger.info("global symbol deleted:", getGlobalSymbol(this.symbol));
if (this.subscriptions.length > 0) {
logger.info("disposing of %d subscriptions...", this.subscriptions.length);
for (const dispose of this.subscriptions) {
dispose();
}
this.subscriptions = [];
logger.info("disposed of all subscriptions!", this.subscriptions.length);
}
this.emitter.removeAllListeners();
logger.info("destroyed the listener!");
this.readyState = "DISPOSED";
}
getInstance() {
var _a;
const instance = getGlobalSymbol(this.symbol);
this.logger.info("retrieved global instance:", (_a = instance == null ? void 0 : instance.constructor) == null ? void 0 : _a.name);
return instance;
}
setInstance() {
setGlobalSymbol(this.symbol, this);
this.logger.info("set global instance!", this.symbol.description);
}
clearInstance() {
deleteGlobalSymbol(this.symbol);
this.logger.info("cleared global instance!", this.symbol.description);
}
};
function createRequestId() {
return Math.random().toString(16).slice(2);
}
// node_modules/.pnpm/@mswjs+interceptors@0.39.1/node_modules/@mswjs/interceptors/lib/browser/index.mjs
var BatchInterceptor = class extends Interceptor {
constructor(options) {
BatchInterceptor.symbol = Symbol(options.name);
super(BatchInterceptor.symbol);
this.interceptors = options.interceptors;
}
setup() {
const logger = this.logger.extend("setup");
logger.info("applying all %d interceptors...", this.interceptors.length);
for (const interceptor of this.interceptors) {
logger.info('applying "%s" interceptor...', interceptor.constructor.name);
interceptor.apply();
logger.info("adding interceptor dispose subscription");
this.subscriptions.push(() => interceptor.dispose());
}
}
on(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.on(event, listener);
}
return this;
}
once(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.once(event, listener);
}
return this;
}
off(event, listener) {
for (const interceptor of this.interceptors) {
interceptor.off(event, listener);
}
return this;
}
removeAllListeners(event) {
for (const interceptors of this.interceptors) {
interceptors.removeAllListeners(event);
}
return this;
}
};
// src/browser/setupWorker/start/createResponseListener.ts
function createResponseListener(context) {
return (event) => {
const responseMessage = event.data;
const request = deserializeRequest(responseMessage.request);
if (responseMessage.response.type?.includes("opaque")) {
return;
}
const response = responseMessage.response.status === 0 ? Response.error() : new FetchResponse(
/**
* Responses may be streams here, but when we create a response object
* with null-body status codes, like 204, 205, 304 Response will
* throw when passed a non-null body, so ensure it's null here
* for those codes
*/
FetchResponse.isResponseWithBody(responseMessage.response.status) ? responseMessage.response.body : null,
{
...responseMessage,
/**
* Set response URL if it's not set already.
* @see https://github.com/mswjs/msw/issues/2030
* @see https://developer.mozilla.org/en-US/docs/Web/API/Response/url
*/
url: request.url
}
);
context.emitter.emit(
responseMessage.isMockedResponse ? "response:mocked" : "response:bypass",
{
requestId: responseMessage.request.id,
request,
response
}
);
};
}
// src/browser/setupWorker/start/utils/validateWorkerScope.ts
import { devUtils as devUtils5 } from '../core/utils/internal/devUtils.mjs';
function validateWorkerScope(registration, options) {
if (!options?.quiet && !location.href.startsWith(registration.scope)) {
devUtils5.warn(
`Cannot intercept requests on this page because it's outside of the worker's scope ("${registration.scope}"). If you wish to mock API requests on this page, you must resolve this scope issue.
- (Recommended) Register the worker at the root level ("/") of your application.
- Set the "Service-Worker-Allowed" response header to allow out-of-scope workers.`
);
}
}
// src/browser/setupWorker/start/createStartHandler.ts
var createStartHandler = (context) => {
return function start(options, customOptions) {
const startWorkerInstance = async () => {
context.workerChannel.removeAllListeners();
context.workerChannel.on(
"REQUEST",
createRequestListener(context, options)
);
context.workerChannel.on("RESPONSE", createResponseListener(context));
const instance = await getWorkerInstance(
options.serviceWorker.url,
options.serviceWorker.options,
options.findWorker
);
const [worker, registration] = instance;
if (!worker) {
const missingWorkerMessage = customOptions?.findWorker ? devUtils6.formatMessage(
`Failed to locate the Service Worker registration using a custom "findWorker" predicate.
Please ensure that the custom predicate properly locates the Service Worker registration at "%s".
More details: https://mswjs.io/docs/api/setup-worker/start#findworker
`,
options.serviceWorker.url
) : devUtils6.formatMessage(
`Failed to locate the Service Worker registration.
This most likely means that the worker script URL "%s" cannot resolve against the actual public hostname (%s). This may happen if your application runs behind a proxy, or has a dynamic hostname.
Please consider using a custom "serviceWorker.url" option to point to the actual worker script location, or a custom "findWorker" option to resolve the Service Worker registration manually. More details: https://mswjs.io/docs/api/setup-worker/start`,
options.serviceWorker.url,
location.host
);
throw new Error(missingWorkerMessage);
}
context.workerPromise.resolve(worker);
context.registration = registration;
window.addEventListener("beforeunload", () => {
if (worker.state !== "redundant") {
context.workerChannel.postMessage("CLIENT_CLOSED");
}
window.clearInterval(context.keepAliveInterval);
window.postMessage({ type: "msw/worker:stop" });
});
await checkWorkerIntegrity(context).catch((error2) => {
devUtils6.error(
"Error while checking the worker script integrity. Please report this on GitHub (https://github.com/mswjs/msw/issues) and include the original error below."
);
console.error(error2);
});
context.keepAliveInterval = window.setInterval(
() => context.workerChannel.postMessage("KEEPALIVE_REQUEST"),
5e3
);
validateWorkerScope(registration, context.startOptions);
return registration;
};
const workerRegistration = startWorkerInstance().then(
async (registration) => {
const pendingInstance = registration.installing || registration.waiting;
if (pendingInstance) {
const activationPromise = new DeferredPromise();
pendingInstance.addEventListener("statechange", () => {
if (pendingInstance.state === "activated") {
activationPromise.resolve();
}
});
await activationPromise;
}
await enableMocking(context, options).catch((error2) => {
devUtils6.error(
"Failed to enable mocking. Please report this on GitHub (https://github.com/mswjs/msw/issues) and include the original error below."
);
throw error2;
});
return registration;
}
);
return workerRegistration;
};
};
// src/browser/setupWorker/setupWorker.ts
import { devUtils as devUtils8 } from '../core/utils/internal/devUtils.mjs';
import { SetupApi } from '../core/SetupApi.mjs';
import { mergeRight as mergeRight2 } from '../core/utils/internal/mergeRight.mjs';
// src/browser/utils/supportsReadableStreamTransfer.ts
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;
}
}
// src/browser/setupWorker/setupWorker.ts
import { webSocketInterceptor } from '../core/ws/webSocketInterceptor.mjs';
import { handleWebSocketEvent } from '../core/ws/handleWebSocketEvent.mjs';
import { attachWebSocketLogger } from '../core/ws/utils/attachWebSocketLogger.mjs';
// node_modules/.pnpm/rettime@0.7.0/node_modules/rettime/build/index.js
var kDefaultPrevented = Symbol("kDefaultPrevented");
var kPropagationStopped = Symbol("kPropagationStopped");
var kImmediatePropagationStopped = Symbol("kImmediatePropagationStopped");
var TypedEvent = class extends MessageEvent {
/**
* @note Keep a placeholder property with the return type
* because the type must be set somewhere in order to be
* correctly associated and inferred from the event.
*/
#returnType;
[kDefaultPrevented];
[kPropagationStopped];
[kImmediatePropagationStopped];
constructor(...args) {
super(args[0], args[1]);
this[kDefaultPrevented] = false;
}
get defaultPrevented() {
return this[kDefaultPrevented];
}
preventDefault() {
super.preventDefault();
this[kDefaultPrevented] = true;
}
stopImmediatePropagation() {
super.stopImmediatePropagation();
this[kImmediatePropagationStopped] = true;
}
};
var kListenerOptions = Symbol("kListenerOptions");
var Emitter2 = class {
#listeners;
constructor() {
this.#listeners = {};
}
/**
* Adds a listener for the given event type.
*
* @returns {AbortController} An `AbortController` that can be used to remove the listener.
*/
on(type, listener, options) {
return this.#addListener(type, listener, options);
}
/**
* Adds a one-time listener for the given event type.
*
* @returns {AbortController} An `AbortController` that can be used to remove the listener.
*/
once(type, listener, options) {
return this.on(type, listener, { ...options || {}, once: true });
}
/**
* Prepends a listener for the given event type.
*
* @returns {AbortController} An `AbortController` that can be used to remove the listener.
*/
earlyOn(type, listener, options) {
return this.#addListener(type, listener, options, "prepend");
}
/**
* Prepends a one-time listener for the given event type.
*/
earlyOnce(type, listener, options) {
return this.earlyOn(type, listener, { ...options || {}, once: true });
}
/**
* Emits the given typed event.
*
* @returns {boolean} Returns `true` if the event had any listeners, `false` otherwise.
*/
emit(event) {
if (this.listenerCount(event.type) === 0) {
return false;
}
const proxiedEvent = this.#proxyEvent(event);
for (const listener of this.#listeners[event.type]) {
if (proxiedEvent.event[kPropagationStopped] != null && proxiedEvent.event[kPropagationStopped] !== this) {
return false;
}
if (proxiedEvent.event[kImmediatePropagationStopped]) {
break;
}
this.#callListener(proxiedEvent.event, listener);
}
proxiedEvent.revoke();
return true;
}
/**
* Emits the given typed event and returns a promise that resolves
* when all the listeners for that event have settled.
*
* @returns {Promise<Array<Emitter.ListenerReturnType>>} A promise that resolves
* with the return values of all listeners.
*/
async emitAsPromise(event) {
if (this.listenerCount(event.type) === 0) {
return [];
}
const pendingListeners = [];
const proxiedEvent = this.#proxyEvent(event);
for (const listener of this.#listeners[event.type]) {
if (proxiedEvent.event[kPropagationStopped] != null && proxiedEvent.event[kPropagationStopped] !== this) {
return [];
}
if (proxiedEvent.event[kImmediatePropagationStopped]) {
break;
}
pendingListeners.push(
// Awaiting individual listeners guarantees their call order.
await Promise.resolve(this.#callListener(proxiedEvent.event, listener))
);
}
proxiedEvent.revoke();
return Promise.allSettled(pendingListeners).then((results) => {
return results.map(
(result) => result.status === "fulfilled" ? result.value : result.reason
);
});
}
/**
* Emits the given event and returns a generator that yields
* the result of each listener in the order of their registration.
* This way, you stop exhausting the listeners once you get the expected value.
*/
*emitAsGenerator(event) {
if (this.listenerCount(event.type) === 0) {
return;
}
const proxiedEvent = this.#proxyEvent(event);
for (const listener of this.#listeners[event.type]) {
if (proxiedEvent.event[kPropagationStopped] != null && proxiedEvent.event[kPropagationStopped] !== this) {
return;
}
if (proxiedEvent.event[kImmediatePropagationStopped]) {
break;
}
yield this.#callListener(proxiedEvent.event, listener);
}
proxiedEvent.revoke();
}
/**
* Removes a listener for the given event type.
*/
removeListener(type, listener) {
if (this.listenerCount(type) === 0) {
return;
}
const nextListeners = [];
for (const existingListener of this.#listeners[type]) {
if (existingListener !== listener) {
nextListeners.push(existingListener);
}
}
this.#listeners[type] = nextListeners;
}
/**
* Removes all listeners for the given event type.
* If no event type is provided, removes all existing listeners.
*/
removeAllListeners(type) {
if (type == null) {
this.#listeners = {};
return;
}
this.#listeners[type] = [];
}
/**
* Returns the list of listeners for the given event type.
* If no even type is provided, returns all listeners.
*/
listeners(type) {
if (type == null) {
return Object.values(this.#listeners).flat();
}
return this.#listeners[type] || [];
}
/**
* Returns the number of listeners for the given event type.
* If no even type is provided, returns the total number of listeners.
*/
listenerCount(type) {
return this.listeners(type).length;
}
#addListener(type, listener, options, insertMode = "append") {
this.#listeners[type] ??= [];
if (insertMode === "prepend") {
this.#listeners[type].unshift(listener);
} else {
this.#listeners[type].push(listener);
}
if (options) {
Object.defineProperty(listener, kListenerOptions, {
value: options,
enumerable: false,
writable: false
});
if (options.signal) {
options.signal.addEventListener(
"abort",
() => {
this.removeListener(type, listener);
},
{ once: true }
);
}
}
return this;
}
#proxyEvent(event) {
const { stopPropagation } = event;
event.stopPropagation = new Proxy(event.stopPropagation, {
apply: (target, thisArg, argArray) => {
event[kPropagationStopped] = this;
return Reflect.apply(target, thisArg, argArray);
}
});
return {
event,
revoke() {
event.stopPropagation = stopPropagation;
}
};
}
#callListener(event, listener) {
const returnValue = listener.call(this, event);
if (listener[kListenerOptions]?.once) {
this.removeListener(event.type, listener);
}
return returnValue;
}
};
// src/browser/utils/workerChannel.ts
import { isObject } from '../core/utils/internal/isObject.mjs';
var WorkerEvent = class extends TypedEvent {
#workerEvent;
constructor(workerEvent) {
const type = workerEvent.data.type;
const data = workerEvent.data.payload;
super(
// @ts-expect-error Troublesome `TypedEvent` extension.
type,
{ data }
);
this.#workerEvent = workerEvent;
}
get ports() {
return this.#workerEvent.ports;
}
/**
* Reply directly to this event using its `MessagePort`.
*/
postMessage(type, ...rest) {
this.#workerEvent.ports[0].postMessage(
{ type, data: rest[0] },
{ transfer: rest[1] }
);
}
};
var WorkerChannel = class extends Emitter2 {
constructor(options) {
super();
this.options = options;
navigator.serviceWorker.addEventListener("message", async (event) => {
const worker = await this.options.worker;
if (event.source != null && event.source !== worker) {
return;
}
if (event.data && isObject(event.data) && "type" in event.data) {
this.emit(new WorkerEvent(event));
}
});
}
/**
* Send data to the Service Worker controlling this client.
* This triggers the `message` event listener on ServiceWorkerGlobalScope.
*/
postMessage(type) {
this.options.worker.then((worker) => {
worker.postMessage(type);
});
}
};
// node_modules/.pnpm/@mswjs+interceptors@0.39.1/node_modules/@mswjs/interceptors/lib/browser/chunk-L37TY7LC.mjs
var InterceptorError = class extends Error {
constructor(message) {
super(message);
this.name = "InterceptorError";
Object.setPrototypeOf(this, InterceptorError.prototype);
}
};
var kRequestHandled = Symbol("kRequestHandled");
var kResponsePromise = Symbol("kResponsePromise");
var RequestController = class {
constructor(request) {
this.request = request;
this[kRequestHandled] = false;
this[kResponsePromise] = new DeferredPromise();
}
/**
* Respond to this request with the given `Response` instance.
* @example
* controller.respondWith(new Response())
* controller.respondWith(Response.json({ id }))
* controller.respondWith(Response.error())
*/
respondWith(response) {
invariant.as(
InterceptorError,
!this[kRequestHandled],
'Failed to respond to the "%s %s" request: the "request" event has already been handled.',
this.request.method,
this.request.url
);
this[kRequestHandled] = true;
this[kResponsePromise].resolve(response);
}
/**
* Error this request with the given reason.
*
* @example
* controller.errorWith()
* controller.errorWith(new Error('Oops!'))
* controller.errorWith({ message: 'Oops!'})
*/
errorWith(reason) {
invariant.as(
InterceptorError,
!this[kRequestHandled],
'Failed to error the "%s %s" request: the "request" event has already been handled.',
this.request.method,
this.request.url
);
this[kRequestHandled] = true;
this[kResponsePromise].resolve(reason);
}
};
async function emitAsync(emitter, eventName, ...data) {
const listners = emitter.listeners(eventName);
if (listners.length === 0) {
return;
}
for (const listener of listners) {
await listener.apply(emitter, data);
}
}
function isObject2(value, loose = false) {
return loose ? Object.prototype.toString.call(value).startsWith("[object ") : Object.prototype.toString.call(value) === "[object Object]";
}
function isPropertyAccessible(obj, key) {
try {
obj[key];
return true;
} catch (e) {
return false;
}
}
function createServerErrorResponse(body) {
return new Response(
JSON.stringify(
body instanceof Error ? {
name: body.name,
message: body.message,
stack: body.stack
} : body
),
{
status: 500,
statusText: "Unhandled Exception",
headers: {
"Content-Type": "application/json"
}
}
);
}
function isResponseError(response) {
return response != null && response instanceof Response && isPropertyAccessible(response, "type") && response.type === "error";
}
function isResponseLike(value) {
return isObject2(value, true) && isPropertyAccessible(value, "status") && isPropertyAccessible(value, "statusText") && isPropertyAccessible(value, "bodyUsed");
}
function isNodeLikeError(error2) {
if (error2 == null) {
return false;
}
if (!(error2 instanceof Error)) {
return false;
}
return "code" in error2 && "errno" in error2;
}
async function handleRequest2(options) {
const handleResponse = async (response) => {
if (response instanceof Error) {
options.onError(response);
return true;
}
if (isResponseError(response)) {
options.onRequestError(response);
return true;
}
if (isResponseLike(response)) {
await options.onResponse(response);
return true;
}
if (isObject2(response)) {
options.onError(response);
return true;
}
return false;
};
const handleResponseError = async (error2) => {
if (error2 instanceof InterceptorError) {
throw result.error;
}
if (isNodeLikeError(error2)) {
options.onError(error2);
return true;
}
if (error2 instanceof Response) {
return await handleResponse(error2);
}
return false;
};
options.emitter.once("request", ({ requestId: pendingRequestId }) => {
if (pendingRequestId !== options.requestId) {
return;
}
if (options.controller[kResponsePromise].state === "pending") {
options.controller[kResponsePromise].resolve(void 0);
}
});
const requestAbortPromise = new DeferredPromise();
if (options.request.signal) {
if (options.request.signal.aborted) {
requestAbortPromise.reject(options.request.signal.reason);
} else {
options.request.signal.addEventListener(
"abort",
() => {
requestAbortPromise.reject(options.request.signal.reason);
},
{ once: true }
);
}
}
const result = await until(async () => {
const requestListenersPromise = emitAsync(options.emitter, "request", {
requestId: options.requestId,
request: options.request,
controller: options.controller
});
await Promise.race([
// Short-circuit the request handling promise if the request gets aborted.
requestAbortPromise,
requestListenersPromise,
options.controller[kResponsePromise]
]);
return await options.controller[kResponsePromise];
});
if (requestAbortPromise.state === "rejected") {
options.onError(requestAbortPromise.rejectionReason);
return true;
}
if (result.error) {
if (await handleResponseError(result.error)) {
return true;
}
if (options.emitter.listenerCount("unhandledException") > 0) {
const unhandledExceptionController = new RequestController(
options.request
);
await emitAsync(options.emitter, "unhandledException", {
error: result.error,
request: options.request,
requestId: options.requestId,
controller: unhandledExceptionController
}).then(() => {
if (unhandledExceptionController[kResponsePromise].state === "pending") {
unhandledExceptionController[kResponsePromise].resolve(void 0);
}
});
const nextResult = await until(
() => unhandledExceptionController[kResponsePromise]
);
if (nextResult.error) {
return handleResponseError(nextResult.error);
}
if (nextResult.data) {
return handleResponse(nextResult.data);
}
}
options.onResponse(createServerErrorResponse(result.error));
return true;
}
if (result.data) {
return handleResponse(result.data);
}
return false;
}
// node_modules/.pnpm/@mswjs+interceptors@0.39.1/node_modules/@mswjs/interceptors/lib/browser/chunk-TX5GBTFY.mjs
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/@mswjs+interceptors@0.39.1/node_modules/@mswjs/interceptors/lib/browser/chunk-ARPHZXGT.mjs
function createNetworkError(cause) {
return Object.assign(new TypeError("Failed to fetch"), {
cause
});
}
var REQUEST_BODY_HEADERS = [
"content-encoding",
"content-language",
"content-location",
"content-type",
"content-length"
];
var kRedirectCount = Symbol("kRedirectCount");
async function followFetchRedirect(request, response) {
if (response.status !== 303 && request.body != null) {
return Promise.reject(createNetworkError());
}
const requestUrl = new URL(request.url);
let locationUrl;
try {
locationUrl = new URL(response.headers.get("location"), request.url);
} catch (error2) {
return Promise.reject(createNetworkError(error2));
}
if (!(locationUrl.protocol === "http:" || locationUrl.protocol === "https:")) {
return Promise.reject(
createNetworkError("URL scheme must be a HTTP(S) scheme")
);
}
if (Reflect.get(request, kRedirectCount) > 20) {
return Promise.reject(createNetworkError("redirect count exceeded"));
}
Object.defineProperty(request, kRedirectCount, {
value: (Reflect.get(request, kRedirectCount) || 0) + 1
});
if (request.mode === "cors" && (locationUrl.username || locationUrl.password) && !sameOrigin(requestUrl, locationUrl)) {
return Promise.reject(
createNetworkError('cross origin not allowed for request mode "cors"')
);
}
const requestInit = {};
if ([301, 302].includes(response.status) && request.method === "POST" || response.status === 303 && !["HEAD", "GET"].includes(request.method)) {
requestInit.method = "GET";
requestInit.body = null;
REQUEST_BODY_HEADERS.forEach((headerName) => {
request.headers.delete(headerName);
});
}
if (!sameOrigin(requestUrl, locationUrl)) {
request.headers.delete("authorization");
request.headers.delete("proxy-authorization");
request.headers.delete("cookie");
request.headers.delete("host");
}
requestInit.headers = request.headers;
return fetch(new Request(locationUrl, requestInit));
}
function sameOrigin(left, right) {
if (left.origin === right.origin && left.origin === "null") {
return true;
}
if (left.protocol === right.protocol && left.hostname === right.hostname && left.port === right.port) {
return true;
}
return false;
}
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);
}
});
}
};
var PipelineStream = class extends TransformStream {
constructor(transformStreams, ...strategies) {
super({}, ...strategies);
const readable = [super.readable, ...transformStreams].reduce(
(readable2, transform) => readable2.pipeThrough(transform)
);
Object.defineProperty(this, "readable", {
get() {
return readable;
}
});
}
};
function parseContentEncoding(contentEncoding) {
return contentEncoding.toLowerCase().split(",").map((coding) => coding.trim());
}
function createDecompressionStream(contentEncoding) {
if (contentEncoding === "") {
return null;
}
const codings = parseContentEncoding(contentEncoding);
if (codings.length === 0) {
return null;
}
const transformers = codings.reduceRight(
(transformers2, coding) => {
if (coding === "gzip" || coding === "x-gzip") {
return transformers2.concat(new DecompressionStream("gzip"));
} else if (coding === "deflate") {
return transformers2.concat(new DecompressionStream("deflate"));
} else if (coding === "br") {
return transformers2.concat(new BrotliDecompressionStream());
} else {
transformers2.length = 0;
}
return transformers2;
},
[]
);
return new PipelineStream(transformers);
}
function decompressResponse(response) {
if (response.body === null) {
return null;
}
const decompressionStream = createDecompressionStream(
response.headers.get("content-encoding") || ""
);
if (!decompressionStream) {
return null;
}
response.body.pipeTo(decompressionStream.writable);
return decompressionStream.readable;
}
var _FetchInterceptor = class extends Interceptor {
constructor() {
super(_FetchInterceptor.symbol);
}
checkEnvironment() {
return hasConfigurableGlobal("fetch");
}
async setup() {
const pureFetch = globalThis.fetch;
invariant(
!pureFetch[IS_PATCHED_MODULE],
'Failed to patch the "fetch" module: already patched.'
);
globalThis.fetch = async (input, init) => {
const requestId = createRequestId();
const resolvedInput = typeof input === "string" && typeof location !== "undefined" && !canParseUrl(input) ? new URL(input, location.href) : input;
const request = new Request(resolvedInput, init);
if (input instanceof Request) {
setRawRequest(request, input);
}
const responsePromise = new DeferredPromise();
const controller = new RequestController(request);
this.logger.info("[%s] %s", request.method, request.url);
this.logger.info("awaiting for the mocked response...");
this.logger.info(
'emitting the "request" event for %s listener(s)...',
this.emitter.listenerCount("request")
);
const isRequestHandled = await handleRequest2({
request,
requestId,
emitter: this.emitter,
controller,
onResponse: async (rawResponse) => {
this.logger.info("received mocked response!", {
rawResponse
});
const decompressedStream = decompressResponse(rawResponse);
const response = decompressedStream === null ? rawResponse : new FetchResponse(decompressedStream, rawResponse);
FetchResponse.setUrl(request.url, response);
if (FetchResponse.isRedirectResponse(response.status)) {
if (request.redirect === "error") {
responsePromise.reject(createNetworkError("unexpected redirect"));
return;
}
if (request.redirect === "follow") {
followFetchRedirect(request, response).then(
(response2) => {
responsePromise.resolve(response2);
},
(reason) => {
responsePromise.reject(reason);
}
);
return;
}
}
if (this.emitter.listenerCount("response") > 0) {
this.logger.info('emitting the "response" event...');
await emitAsync(this.emitter, "response", {
// Clone the mocked response for the "response" event listener.
// This way, the listener can read the response and not lock its body
// for the actual fetch consumer.
response: response.clone(),
isMockedResponse: true,
request,
requestId
});
}
responsePromise.resolve(response);
},
onRequestError: (response) => {
this.logger.info("request has errored!", { response });
responsePromise.reject(createNetworkError(response));
},
onError: (error2) => {
this.logger.info("request has been aborted!", { error: error2 });
responsePromise.reject(error2);
}
});
if (isRequestHandled) {
this.logger.info("request has been handled, returning mock promise...");
return responsePromise;
}
this.logger.info(
"no mocked response received, performing request as-is..."
);
const requestCloneForResponseEvent = request.clone();
return pureFetch(request).then(async (response) => {
this.logger.info("original fetch performed", response);
if (this.emitter.listenerCount("response") > 0) {
this.logger.info('emitting the "response" event...');
const responseClone = response.clone();
await emitAsync(this.emitter, "response", {
response: responseClone,
isMockedResponse: false,
request: requestCloneForResponseEvent,
requestId
});
}
return response;
});
};
Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {
enumerable: true,
configurable: true,
value: true
});
this.subscriptions.push(() => {
Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {
value: void 0
});
globalThis.fetch = pureFetch;
this.logger.info(
'restored native "globalThis.fetch"!',
globalThis.fetch.name
);
});
}
};
var FetchInterceptor = _FetchInterceptor;
FetchInterceptor.symbol = Symbol("fetch");
// node_modules/.pnpm/@mswjs+interceptors@0.39.1/node_modules/@mswjs/interceptors/lib/browser/chunk-QKSBFQDK.mjs
function concatArrayBuffer(left, right) {
const result = new Uint8Array(left.byteLength + right.byteLength);
result.set(left, 0);
result.set(right, left.byteLength);
return result;
}
var EventPolyfill = class {
constructor(type, options) {
this.NONE = 0;
this.CAPTURING_PHASE = 1;
this.AT_TARGET = 2;
this.BUBBLING_PHASE = 3;
this.type = "";
this.srcElement = null;
this.currentTarget = null;
this.eventPhase = 0;
this.isTrusted = true;
this.composed = false;
this.cancelable = true;
this.defaultPrevented = false;
this.bubbles = true;
this.lengthComputable = true;
this.loaded = 0;
this.total = 0;
this.cancelBubble = false;
this.returnValue = true;
this.type = type;
this.target = (options == null ? void 0 : options.target) || null;
this.currentTarget = (options == null ? void 0 : options.currentTarget) || null;
this.timeStamp = Date.now();
}
composedPath() {
return [];
}
initEvent(type, bubbles, cancelable) {
this.type = type;
this.bubbles = !!bubbles;
this.cancelable = !!cancelable;
}
preventDefault() {
this.defaultPrevented = true;
}
stopPropagation() {
}
stopImmediatePropagation() {
}
};
var ProgressEventPolyfill = class extends EventPolyfill {
constructor(type, init) {
super(type);
this.lengthComputable = (init == null ? void 0 : init.lengthComputable) || false;
this.composed = (init == null ? void 0 : init.composed) || false;
this.loaded = (init == null ? void 0 : init.loaded) || 0;
this.total = (init == null ? void 0 : init.total) || 0;
}
};
var SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== "undefined";
function createEvent(target, type, init) {
const progressEvents = [
"error",
"progress",
"loadstart",
"loadend",
"load",
"timeout",
"abort"
];
const ProgressEventClass = SUPPORTS_PROGRESS_EVENT ? ProgressEvent : ProgressEventPolyfill;
const event = progressEvents.includes(type) ? new ProgressEventClass(type, {
lengthComputable: true,
loaded: (init == null ? void 0 : init.loaded) || 0,
total: (init == null ? void 0 : init.total) || 0
}) : new EventPolyfill(type, {
target,
currentTarget: target
});
return event;
}
function findPropertySource(target, propertyName) {
if (!(propertyName in target)) {
return null;
}
const hasProperty = Object.prototype.hasOwnProperty.call(target, propertyName);
if (hasProperty) {
return target;
}
const prototype = Reflect.getPrototypeOf(target);
return prototype ? findPropertySource(prototype, propertyName) : null;
}
function createProxy(target, options) {
const proxy = new Proxy(target, optionsToProxyHandler(options));
return proxy;
}
function optionsToProxyHandler(options) {
const { constructorCall, methodCall, getProperty, setProperty } = options;
const handler = {};
if (typeof constructorCall !== "undefined") {
handler.construct = function(target, args, newTarget) {
const next = Reflect.construct.bind(null, target, args, newTarget);
return constructorCall.call(newTarget, args, next);
};
}
handler.set = function(target, propertyName, nextValue) {
const next = () => {
const propertySource = findPropertySource(target, propertyName) || target;
const ownDescriptors = Reflect.getOwnPropertyDescriptor(
propertySource,
propertyName
);
if (typeof (ownDescriptors == null ? void 0 : ownDescriptors.set) !== "undefined") {
ownDescriptors.set.apply(target, [nextValue]);
return true;
}
return Reflect.defineProperty(propertySource, propertyName, {
writable: true,
enumerable: true,
configurable: true,
value: nextValue
});
};
if (typeof setProperty !== "undefined") {
return setProperty.call(target, [propertyName, nextValue], next);
}
return next();
};
handler.get = function(target, propertyName, receiver) {
const next = () => target[propertyName];
const value = typeof getProperty !== "undefined" ? getProperty.call(target, [propertyName, receiver], next) : next();
if (typeof value === "function") {
return (...args) => {
const next2 = value.bind(target, ...args);
if (typeof methodCall !== "undefined") {
return methodCall.call(target, [propertyName, args], next2);
}
return next2();
};
}
return value;
};
return handler;
}
function isDomParserSupportedType(type) {
const supportedTypes = [
"application/xhtml+xml",
"application/xml",
"image/svg+xml",
"text/html",
"text/xml"
];
return supportedTypes.some((supportedType) => {
return type.startsWith(supportedType);
});
}
function parseJson(data) {
try {
const json = JSON.parse(data);
return json;
} catch (_) {
return null;
}
}
function createResponse(request, body) {
const responseBodyOrNull = FetchResponse.isResponseWithBody(request.status) ? body : null;
return new FetchResponse(responseBodyOrNull, {
url: request.responseURL,
status: request.status,
statusText: request.statusText,
headers: createHeadersFromXMLHttpReqestHeaders(
request.getAllResponseHeaders()
)
});
}
function createHeadersFromXMLHttpReqestHeaders(headersString) {
const headers = new Headers();
const lines = headersString.split(/[\r\n]+/);
for (const line of lines) {
if (line.trim() === "") {
continue;
}
const [name, ...parts] = line.split(": ");
const value = parts.join(": ");
headers.append(name, value);
}
return headers;
}
async function getBodyByteLength(input) {
const explicitContentLength = input.headers.get("content-length");
if (explicitContentLength != null && explicitContentLength !== "") {
return Number(explicitContentLength);
}
const buffer = await input.arrayBuffer();
return buffer.byteLength;
}
var kIsRequestHandled = Symbol("kIsRequestHandled");
var IS_NODE2 = isNodeProcess();
var kFetchRequest = Symbol("kFetchRequest");
var XMLHttpRequestController = class {
constructor(initialRequest, logger) {
this.initialRequest = initialRequest;
this.logger = logger;
this.method = "GET";
this.url = null;
this[kIsRequestHandled] = false;
this.events = /* @__PURE__ */ new Map();
this.uploadEvents = /* @__PURE__ */ new Map();
this.requestId = createRequestId();
this.requestHeaders = new Headers();
this.responseBuffer = new Uint8Array();
this.request = createProxy(initialRequest, {
setProperty: ([propertyName, nextValue], invoke) => {
switch (propertyName) {
case "ontimeout": {
const eventName = propertyName.slice(
2
);
this.request.addEventListener(eventName, nextValue);
return invoke();
}
default: {
return invoke();
}
}
},
methodCall: ([methodName, args], invoke) => {
var _a;
switch (methodName) {
case "open": {
const [method, url] = args;
if (typeof url === "undefined") {
this.method = "GET";
this.url = toAbsoluteUrl(method);
} else {
this.method = method;
this.url = toAbsoluteUrl(url);
}
this.logger = this.logger.extend(`${this.method} ${this.url.href}`);
this.logger.info("open", this.method, this.url.href);
return invoke();
}
case "addEventListener": {
const [eventName, listener] = args;
this.registerEvent(eventName, listener);
this.logger.info("addEventListener", eventName, listener);
return invoke();
}
case "setRequestHeader": {
const [name, value] = args;
this.requestHeaders.set(name, value);
this.logger.info("setRequestHeader", name, value);
return invoke();
}
case "send": {
const [body] = args;
this.request.addEventListener("load", () => {
if (typeof this.onResponse !== "undefined") {
const fetchResponse = createResponse(
this.request,
/**
* The `response` property is the right way to read
* the ambiguous response body, as the request's "responseType" may differ.
* @see https://xhr.spec.whatwg.org/#the-response-attribute
*/
this.request.response
);
this.onResponse.call(this, {
response: fetchResponse,
isMockedResponse: this[kIsRequestHandled],
request: fetchRequest,
requestId: this.requestId
});
}
});
const requestBody = typeof body === "string" ? encodeBuffer(body) : body;
const fetchRequest = this.toFetchApiRequest(requestBody);
this[kFetchRequest] = fetchRequest.clone();
const onceRequestSettled = ((_a = this.onRequest) == null ? void 0 : _a.call(this, {
request: fetchRequest,
requestId: this.requestId
})) || Promise.resolve();
onceRequestSettled.finally(() => {
if (!this[kIsRequestHandled]) {
this.logger.info(
"request callback settled but request has not been handled (readystate %d), performing as-is...",
this.request.readyState
);
if (IS_NODE2) {
this.request.setRequestHeader(
INTERNAL_REQUEST_ID_HEADER_NAME,
this.requestId
);
}
return invoke();
}
});
break;
}
default: {
return invoke();
}
}
}
});
define(
this.request,
"upload",
createProxy(this.request.upload, {
setProperty: ([propertyName, nextValue], invoke) => {
switch (propertyName) {
case "onloadstart":
case "onprogress":
case "onaboart":
case "onerror":
case "onload":
case "ontimeout":
case "onloadend": {
const eventName = propertyName.slice(
2
);
this.registerUploadEvent(eventName, nextValue);
}
}
return invoke();
},
methodCall: ([methodName, args], invoke) => {
switch (methodName) {
case "addEventListener": {
const [eventName, listener] = args;
this.registerUploadEvent(eventName, listener);
this.logger.info("upload.addEventListener", eventName, listener);
return invoke();
}
}
}
})
);
}
registerEvent(eventName, listener) {
const prevEvents = this.events.get(eventName) || [];
const nextEvents = prevEvents.concat(listener);
this.events.set(eventName, nextEvents);
this.logger.info('registered event "%s"', eventName, listener);
}
registerUploadEvent(eventName, listener) {
const prevEvents = this.uploadEvents.get(eventName) || [];
const nextEvents = prevEvents.concat(listener);
this.uploadEvents.set(eventName, nextEvents);
this.logger.info('registered upload event "%s"', eventName, listener);
}
/**
* Responds to the current request with the given
* Fetch API `Response` instance.
*/
async respondWith(response) {
this[kIsRequestHandled] = true;
if (this[kFetchRequest]) {
const totalRequestBodyLength = await getBodyByteLength(
this[kFetchRequest]
);
this.trigger("loadstart", this.request.upload, {
loaded: 0,
total: totalRequestBodyLength
});
this.trigger("progress", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
this.trigger("load", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
this.trigger("loadend", this.request.upload, {
loaded: totalRequestBodyLength,
total: totalRequestBodyLength
});
}
this.logger.info(
"responding with a mocked response: %d %s",
response.status,
response.statusText
);
define(this.request, "status", response.status);
define(this.request, "statusText", response.statusText);
define(this.request, "responseURL", this.url.href);
this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {
apply: (_, __, args) => {
this.logger.info("getResponseHeader", args[0]);
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
this.logger.info("headers not received yet, returning null");
return null;
}
const headerValue = response.headers.get(args[0]);
this.logger.info(
'resolved response header "%s" to',
args[0],
headerValue
);
return headerValue;
}
});
this.request.getAllResponseHeaders = new Proxy(
this.request.getAllResponseHeaders,
{
apply: () => {
this.logger.info("getAllResponseHeaders");
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
this.logger.info("headers not received yet, returning empty string");
return "";
}
const headersList = Array.from(response.headers.entries());
const allHeaders = headersList.map(([headerName, headerValue]) => {
return `${headerName}: ${headerValue}`;
}).join("\r\n");
this.logger.info("resolved all response headers to", allHeaders);
return allHeaders;
}
}
);
Object.defineProperties(this.request, {
response: {
enumerable: true,
configurable: false,
get: () => this.response
},
responseText: {
enumerable: true,
configurable: false,
get: () => this.responseText
},
responseXML: {
enumerable: true,
configurable: false,
get: () => this.responseXML
}
});
const totalResponseBodyLength = await getBodyByteLength(response.clone());
this.logger.info("calculated response body length", totalResponseBodyLength);
this.trigger("loadstart", this.request, {
loaded: 0,
total: totalResponseBodyLength
});
this.setReadyState(this.request.HEADERS_RECEIVED);
this.setReadyState(this.request.LOADING);
const finalizeResponse = () => {
this.logger.info("finalizing the mocked response...");
this.setReadyState(this.request.DONE);
this.trigger("load", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
this.trigger("loadend", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
};
if (response.body) {
this.logger.info("mocked response has body, streaming...");
const reader = response.body.getReader();
const readNextResponseBodyChunk = async () => {
const { value, done } = await reader.read();
if (done) {
this.logger.info("response body stream done!");
finalizeResponse();
return;
}
if (value) {
this.logger.info("read response body chunk:", value);
this.responseBuffer = concatArrayBuffer(this.responseBuffer, value);
this.trigger("progress", this.request, {
loaded: this.responseBuffer.byteLength,
total: totalResponseBodyLength
});
}
readNextResponseBodyChunk();
};
readNextResponseBodyChunk();
} else {
finalizeResponse();
}
}
responseBufferToText() {
return decodeBuffer(this.responseBuffer);
}
get response() {
this.logger.info(
"getResponse (responseType: %s)",
this.request.responseType
);
if (this.request.readyState !== this.request.DONE) {
return null;
}
switch (this.request.responseType) {
case "json": {
const responseJson = parseJson(this.responseBufferToText());
this.logger.info("resolved response JSON", responseJson);
return responseJson;
}
case "arraybuffer": {
const arrayBuffer = toArrayBuffer(this.responseBuffer);
this.logger.info("resolved response ArrayBuffer", arrayBuffer);
return arrayBuffer;
}
case "blob": {
const mimeType = this.request.getResponseHeader("Content-Type") || "text/plain";
const responseBlob = new Blob([this.responseBufferToText()], {
type: mimeType
});
this.logger.info(
"resolved response Blob (mime type: %s)",
responseBlob,
mimeType
);
return responseBlob;
}
default: {
const responseText = this.responseBufferToText();
this.logger.info(
'resolving "%s" response type as text',
this.request.responseType,
responseText
);
return responseText;
}
}
}
get responseText() {
invariant(
this.request.responseType === "" || this.request.responseType === "text",
"InvalidStateError: The object is in invalid state."
);
if (this.request.readyState !== this.request.LOADING && this.request.readyState !== this.request.DONE) {
return "";
}
const responseText = this.responseBufferToText();
this.logger.info('getResponseText: "%s"', responseText);
return responseText;
}
get responseXML() {
invariant(
this.request.responseType === "" || this.request.responseType === "document",
"InvalidStateError: The object is in invalid state."
);
if (this.request.readyState !== this.request.DONE) {
return null;
}
const contentType = this.request.getResponseHeader("Content-Type") || "";
if (typeof DOMParser === "undefined") {
console.warn(
"Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly."
);
return null;
}
if (isDomParserSupportedType(contentType)) {
return new DOMParser().parseFromString(
this.responseBufferToText(),
contentType
);
}
return null;
}
errorWith(error2) {
this[kIsRequestHandled] = true;
this.logger.info("responding with an error");
this.setReadyState(this.request.DONE);
this.trigger("error", this.request);
this.trigger("loadend", this.request);
}
/**
* Transitions this request's `readyState` to the given one.
*/
setReadyState(nextReadyState) {
this.logger.info(
"setReadyState: %d -> %d",
this.request.readyState,
nextReadyState
);
if (this.request.readyState === nextReadyState) {
this.logger.info("ready state identical, skipping transition...");
return;
}
define(this.request, "readyState", nextReadyState);
this.logger.info("set readyState to: %d", nextReadyState);
if (nextReadyState !== this.request.UNSENT) {
this.logger.info('triggerring "readystatechange" event...');
this.trigger("readystatechange", this.request);
}
}
/**
* Triggers given event on the `XMLHttpRequest` instance.
*/
trigger(eventName, target, options) {
const callback = target[`on${eventName}`];
const event = createEvent(target, eventName, options);
this.logger.info('trigger "%s"', eventName, options || "");
if (typeof callback === "function") {
this.logger.info('found a direct "%s" callback, calling...', eventName);
callback.call(target, event);
}
const events = target instanceof XMLHttpRequestUpload ? this.uploadEvents : this.events;
for (const [registeredEventName, listeners] of events) {
if (registeredEventName === eventName) {
this.logger.info(
'found %d listener(s) for "%s" event, calling...',
listeners.length,
eventName
);
listeners.forEach((listener) => listener.call(target, event));
}
}
}
/**
* Converts this `XMLHttpRequest` instance into a Fetch API `Request` instance.
*/
toFetchApiRequest(body) {
this.logger.info("converting request to a Fetch API Request...");
const resolvedBody = body instanceof Document ? body.documentElement.innerText : body;
const fetchRequest = new Request(this.url.href, {
method: this.method,
headers: this.requestHeaders,
/**
* @see https://xhr.spec.whatwg.org/#cross-origin-credentials
*/
credentials: this.request.withCredentials ? "include" : "same-origin",
body: ["GET", "HEAD"].includes(this.method.toUpperCase()) ? null : resolvedBody
});
const proxyHeaders = createProxy(fetchRequest.headers, {
methodCall: ([methodName, args], invoke) => {
switch (methodName) {
case "append":
case "set": {
const [headerName, headerValue] = args;
this.request.setRequestHeader(headerName, headerValue);
break;
}
case "delete": {
const [headerName] = args;
console.warn(
`XMLHttpRequest: Cannot remove a "${headerName}" header from the Fetch API representation of the "${fetchRequest.method} ${fetchRequest.url}" request. XMLHttpRequest headers cannot be removed.`
);
break;
}
}
return invoke();
}
});
define(fetchRequest, "headers", proxyHeaders);
setRawRequest(fetchRequest, this.request);
this.logger.info("converted request to a Fetch API Request!", fetchRequest);
return fetchRequest;
}
};
function toAbsoluteUrl(url) {
if (typeof location === "undefined") {
return new URL(url);
}
return new URL(url.toString(), location.href);
}
function define(target, property, value) {
Reflect.defineProperty(target, property, {
// Ensure writable properties to allow redefining readonly properties.
writable: true,
enumerable: true,
value
});
}
function createXMLHttpRequestProxy({
emitter,
logger
}) {
const XMLHttpRequestProxy = new Proxy(globalThis.XMLHttpRequest, {
construct(target, args, newTarget) {
logger.info("constructed new XMLHttpRequest");
const originalRequest = Reflect.construct(
target,
args,
newTarget
);
const prototypeDescriptors = Object.getOwnPropertyDescriptors(
target.prototype
);
for (const propertyName in prototypeDescriptors) {
Reflect.defineProperty(
originalRequest,
propertyName,
prototypeDescriptors[propertyName]
);
}
const xhrRequestController = new XMLHttpRequestController(
originalRequest,
logger
);
xhrRequestController.onRequest = async function({ request, requestId }) {
const controller = new RequestController(request);
this.logger.info("awaiting mocked response...");
this.logger.info(
'emitting the "request" event for %s listener(s)...',
emitter.listenerCount("request")
);
const isRequestHandled = await handleRequest2({
request,
requestId,
controller,
emitter,
onResponse: async (response) => {
await this.respondWith(response);
},
onRequestError: () => {
this.errorWith(new TypeError("Network error"));
},
onError: (error2) => {
this.logger.info("request errored!", { error: error2 });
if (error2 instanceof Error) {
this.errorWith(error2);
}
}
});
if (!isRequestHandled) {
this.logger.info(
"no mocked response received, performing request as-is..."
);
}
};
xhrRequestController.onResponse = async function({
response,
isMockedResponse,
request,
requestId
}) {
this.logger.info(
'emitting the "response" event for %s listener(s)...',
emitter.listenerCount("response")
);
emitter.emit("response", {
response,
isMockedResponse,
request,
requestId
});
};
return xhrRequestController.request;
}
});
return XMLHttpRequestProxy;
}
var _XMLHttpRequestInterceptor = class extends Interceptor {
constructor() {
super(_XMLHttpRequestInterceptor.interceptorSymbol);
}
checkEnvironment() {
return hasConfigurableGlobal("XMLHttpRequest");
}
setup() {
const logger = this.logger.extend("setup");
logger.info('patching "XMLHttpRequest" module...');
const PureXMLHttpRequest = globalThis.XMLHttpRequest;
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
);
});
}
};
var XMLHttpRequestInterceptor = _XMLHttpRequestInterceptor;
XMLHttpRequestInterceptor.interceptorSymbol = Symbol("xhr");
// src/browser/setupWorker/start/createFallbackRequestListener.ts
import { handleRequest as handleRequest3 } from '../core/utils/handleRequest.mjs';
import { isHandlerKind as isHandlerKind2 } from '../core/utils/internal/isHandlerKind.mjs';
function createFallbackRequestListener(context, options) {
const interceptor = new BatchInterceptor({
name: "fallback",
interceptors: [new FetchInterceptor(), new XMLHttpRequestInterceptor()]
});
interceptor.on("request", async ({ request, requestId, controller }) => {
const requestCloneForLogs = request.clone();
const response = await handleRequest3(
request,
requestId,
context.getRequestHandlers().filter(isHandlerKind2("RequestHandler")),
options,
context.emitter,
{
onMockedResponse(_, { handler, parsedResult }) {
if (!options.quiet) {
context.emitter.once("response:mocked", ({ response: response2 }) => {
handler.log({
request: requestCloneForLogs,
response: response2,
parsedResult
});
});
}
}
}
);
if (response) {
controller.respondWith(response);
}
});
interceptor.on(
"response",
({ response, isMockedResponse, request, requestId }) => {
context.emitter.emit(
isMockedResponse ? "response:mocked" : "response:bypass",
{
response,
request,
requestId
}
);
}
);
interceptor.apply();
return interceptor;
}
// src/browser/setupWorker/stop/utils/printStopMessage.ts
import { devUtils as devUtils7 } from '../core/utils/internal/devUtils.mjs';
function printStopMessage(args = {}) {
if (args.quiet) {
return;
}
console.log(
`%c${devUtils7.formatMessage("Mocking disabled.")}`,
"color:orangered;font-weight:bold;"
);
}
// src/browser/setupWorker/setupWorker.ts
var SetupWorkerApi = class extends SetupApi {
context;
constructor(...handlers) {
super(...handlers);
invariant(
!isNodeProcess(),
devUtils8.formatMessage(
"Failed to execute `setupWorker` in a non-browser environment. Consider using `setupServer` for Node.js environment instead."
)
);
this.context = this.createWorkerContext();
}
createWorkerContext() {
const workerPromise = new DeferredPromise();
return {
// Mocking is not considered enabled until the worker
// signals back the successful activation event.
isMockingEnabled: false,
startOptions: null,
workerPromise,
registration: void 0,
getRequestHandlers: () => {
return this.handlersController.currentHandlers();
},
emitter: this.emitter,
workerChannel: new WorkerChannel({
worker: workerPromise
}),
supports: {
serviceWorkerApi: "serviceWorker" in navigator && location.protocol !== "file:",
readableStreamTransfer: supportsReadableStreamTransfer()
}
};
}
async start(options = {}) {
if ("waitUntilReady" in options) {
devUtils8.warn(
'The "waitUntilReady" option has been deprecated. Please remove it from this "worker.start()" call. Follow the recommended Browser integration (https://mswjs.io/docs/integrations/browser) to eliminate any race conditions between the Service Worker registration and any requests made by your application on initial render.'
);
}
if (this.context.isMockingEnabled) {
devUtils8.warn(
`Found a redundant "worker.start()" call. Note that starting the worker while mocking is already enabled will have no effect. Consider removing this "worker.start()" call.`
);
return this.context.registration;
}
this.context.workerStoppedAt = void 0;
this.context.startOptions = mergeRight2(
DEFAULT_START_OPTIONS,
options
);
handleWebSocketEvent({
getUnhandledRequestStrategy: () => {
return this.context.startOptions.onUnhandledRequest;
},
getHandlers: () => {
return this.handlersController.currentHandlers();
},
onMockedConnection: (connection) => {
if (!this.context.startOptions.quiet) {
attachWebSocketLogger(connection);
}
},
onPassthroughConnection() {
}
});
webSocketInterceptor.apply();
this.subscriptions.push(() => {
webSocketInterceptor.dispose();
});
if (!this.context.supports.serviceWorkerApi) {
const fallbackInterceptor = createFallbackRequestListener(
this.context,
this.context.startOptions
);
this.subscriptions.push(() => {
fallbackInterceptor.dispose();
});
this.context.isMockingEnabled = true;
printStartMessage({
message: "Mocking enabled (fallback mode).",
quiet: this.context.startOptions.quiet
});
return void 0;
}
const startHandler = createStartHandler(this.context);
const registration = await startHandler(this.context.startOptions, options);
this.context.isMockingEnabled = true;
return registration;
}
stop() {
super.dispose();
if (!this.context.isMockingEnabled) {
devUtils8.warn(
'Found a redundant "worker.stop()" call. Notice that stopping the worker after it has already been stopped has no effect. Consider removing this "worker.stop()" call.'
);
return;
}
this.context.isMockingEnabled = false;
this.context.workerStoppedAt = Date.now();
this.context.emitter.removeAllListeners();
if (this.context.supports.serviceWorkerApi) {
this.context.workerChannel.removeAllListeners("RESPONSE");
window.clearInterval(this.context.keepAliveInterval);
}
window.postMessage({ type: "msw/worker:stop" });
printStopMessage({
quiet: this.context.startOptions?.quiet
});
}
};
function setupWorker(...handlers) {
return new SetupWorkerApi(...handlers);
}
export {
SetupWorkerApi,
setupWorker
};
//# sourceMappingURL=index.mjs.map