From fc8c4baf67409db16727eb9881c927c2b8a60a21 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Sat, 10 Jan 2026 19:50:41 +0100 Subject: [PATCH 01/68] feat(wip): implement the `defineNetwork` API --- src/core/new/define-network.ts | 100 +++++++++++ src/core/new/frames/http-frame.ts | 190 +++++++++++++++++++++ src/core/new/frames/network-frame.ts | 48 ++++++ src/core/new/frames/websocket-frame.ts | 68 ++++++++ src/core/new/handlers-controller.ts | 68 ++++++++ src/core/new/on-unhandled-frame.ts | 109 ++++++++++++ src/core/new/request-utils.ts | 39 +++++ src/core/new/sources/interceptor-source.ts | 183 ++++++++++++++++++++ src/core/new/sources/network-source.ts | 34 ++++ 9 files changed, 839 insertions(+) create mode 100644 src/core/new/define-network.ts create mode 100644 src/core/new/frames/http-frame.ts create mode 100644 src/core/new/frames/network-frame.ts create mode 100644 src/core/new/frames/websocket-frame.ts create mode 100644 src/core/new/handlers-controller.ts create mode 100644 src/core/new/on-unhandled-frame.ts create mode 100644 src/core/new/request-utils.ts create mode 100644 src/core/new/sources/interceptor-source.ts create mode 100644 src/core/new/sources/network-source.ts diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts new file mode 100644 index 000000000..95e94848b --- /dev/null +++ b/src/core/new/define-network.ts @@ -0,0 +1,100 @@ +import { Emitter } from 'rettime' +import { type NetworkSource } from './sources/network-source' + +import { pipeEvents } from '../utils/internal/pipeEvents' +import { type NetworkFrameResolutionContext } from './frames/network-frame' +import { onUnhandledFrame, UnhandledFrameHandle } from './on-unhandled-frame' +import { isHandlerKind } from '../utils/internal/isHandlerKind' +import { + AnyHandler, + type HandlersController, + InMemoryHandlersController, +} from './handlers-controller' +import { toReadonlyArray } from '../utils/internal/toReadonlyArray' + +export interface DefineNetworkOptions { + sources: Array + handlers?: Array + context?: NetworkFrameResolutionContext + controller?: HandlersController + onUnhandledFrame?: UnhandledFrameHandle +} + +export interface NetworkApi extends NetworkHandlersApi { + enable: () => Promise + disable: () => Promise +} + +export interface NetworkHandlersApi { + use: (...handlers: Array) => void + resetHandlers: (...handlers: Array) => void + restoreHandlers: () => void + listHandlers: () => void +} + +export function defineNetwork(options: DefineNetworkOptions): NetworkApi { + const events = new Emitter() + const handlersController = + options.controller || new InMemoryHandlersController(options.handlers || []) + + return { + async enable() { + await Promise.all( + options.sources.map(async (source) => { + source.on('frame', async ({ data: frame }) => { + pipeEvents(frame.events, events) + + const handlerPredicate = + frame.protocol === 'http' + ? isHandlerKind('RequestHandler') + : frame.protocol === 'ws' + ? isHandlerKind('EventHandler') + : () => false + + const handlers = + handlersController.currentHandlers.filter(handlerPredicate) || [] + + const isHandledFrame = await frame.resolve( + handlers, + options.context, + ) + + if (isHandledFrame === false) { + await onUnhandledFrame( + frame, + options.onUnhandledFrame || 'warn', + ).catch((error) => { + frame.errorWith(error) + }) + } + }) + + await source.enable() + }), + ) + }, + async disable() { + await Promise.all( + options.sources.map(async (source) => { + await source.disable() + }), + ) + }, + use(...handlers) { + handlersController.use(handlers) + }, + resetHandlers(...handlers) { + handlersController.reset(handlers) + }, + restoreHandlers() { + for (const handler of handlersController.currentHandlers) { + if ('isUsed' in handler) { + handler.isUsed = false + } + } + }, + listHandlers() { + return toReadonlyArray(handlersController.currentHandlers) + }, + } +} diff --git a/src/core/new/frames/http-frame.ts b/src/core/new/frames/http-frame.ts new file mode 100644 index 000000000..9838f4b4f --- /dev/null +++ b/src/core/new/frames/http-frame.ts @@ -0,0 +1,190 @@ +import { TypedEvent } from 'rettime' +import { createRequestId } from '@mswjs/interceptors' +import { NetworkFrame, NetworkFrameResolutionContext } from './network-frame' +import { toPublicUrl } from '~/core/utils/request/toPublicUrl' +import { type HttpHandler } from '~/core/handlers/HttpHandler' +import { until } from 'until-async' +import { executeHandlers } from '~/core/utils/executeHandlers' +import { storeResponseCookies } from '~/core/utils/request/storeResponseCookies' +import { isPassthroughResponse, shouldBypassRequest } from '../request-utils' + +interface HttpNetworkFrameOptions { + id?: string + request: Request +} + +type HttpNetworkFrameEventMap = { + 'request:start': TypedEvent<{ + requestId: string + request: Request + }> + 'request:match': TypedEvent<{ + requestId: string + request: Request + }> + 'request:unhandled': TypedEvent<{ + requestId: string + request: Request + }> + 'request:end': TypedEvent<{ + requestId: string + request: Request + }> + response: TypedEvent<{ + requestId: string + request: Request + response: Response + isMockedResponse: boolean + }> + unhandledException: TypedEvent<{ + error: Error + requestId: string + request: Request + }> +} + +export abstract class HttpNetworkFrame extends NetworkFrame< + 'http', + { + id: string + request: Request + }, + HttpNetworkFrameEventMap +> { + constructor(options: HttpNetworkFrameOptions) { + const id = options.id || createRequestId() + super('http', { id, request: options.request }) + } + + public abstract respondWith(response?: Response): void + + public async getUnhandledFrameMessage(): Promise { + const { request } = this.data + + const url = new URL(request.url) + const publicUrl = toPublicUrl(url) + url.search + const requestBody = + request.body == null ? null : await request.clone().text() + + const details = `\n\n \u2022 ${request.method} ${publicUrl}\n\n${requestBody ? ` \u2022 Request body: ${requestBody}\n\n` : ''}` + const message = `intercepted a request without a matching request handler:${details}If you still wish to intercept this unhandled request, please create a request handler for it.\nRead more: https://mswjs.io/docs/http/intercepting-requests` + + return message + } + + public async resolve( + handlers: Array, + resolutionContext?: NetworkFrameResolutionContext, + ): Promise { + const { id: requestId, request } = this.data + const requestCloneForLogs = resolutionContext?.quiet + ? null + : request.clone() + + this.events.emit( + new TypedEvent('request:start', { data: { requestId, request } }), + ) + + // Requests wrapped in explicit `bypass(request)`. + if (shouldBypassRequest(request)) { + this.passthrough() + return null + } + + const [lookupError, lookupResult] = await until(() => { + return executeHandlers({ + requestId, + request, + handlers, + resolutionContext: { + baseUrl: resolutionContext?.baseUrl?.toString(), + }, + }) + }) + + if (lookupError != null) { + this.events.emit( + new TypedEvent('unhandledException', { + data: { + error: lookupError, + requestId, + request, + }, + }), + ) + + this.errorWith(lookupError) + return null + } + + // No matching handlers. + if (lookupResult == null) { + this.events.emit( + new TypedEvent('request:unhandled', { + data: { requestId, request }, + }), + ) + + this.events.emit( + new TypedEvent('request:end', { + data: { requestId, request }, + }), + ) + + this.passthrough() + return false + } + + const { response, handler, parsedResult } = lookupResult + + // Handlers that returned no mocked response. + if (response == null) { + this.events.emit( + new TypedEvent('request:end', { + data: { requestId, request }, + }), + ) + + this.passthrough() + return null + } + + // Handlers that returned explicit `passthrough()`. + if (isPassthroughResponse(response)) { + this.events.emit( + new TypedEvent('request:end', { + data: { requestId, request }, + }), + ) + + this.passthrough() + return null + } + + await storeResponseCookies(request, response) + + this.events.emit( + new TypedEvent('request:match', { + data: { requestId, request }, + }), + ) + + this.respondWith(response.clone()) + + this.events.emit( + new TypedEvent('request:end', { + data: { requestId, request }, + }), + ) + + if (!resolutionContext?.quiet) { + handler.log({ + request: requestCloneForLogs!, + response, + parsedResult, + }) + } + + return true + } +} diff --git a/src/core/new/frames/network-frame.ts b/src/core/new/frames/network-frame.ts new file mode 100644 index 000000000..31fb7abd0 --- /dev/null +++ b/src/core/new/frames/network-frame.ts @@ -0,0 +1,48 @@ +import { Emitter, type DefaultEventMap } from 'rettime' +import { type AnyHandler } from '../handlers-controller' + +export interface NetworkFrameResolutionContext { + baseUrl?: string | URL + quiet?: boolean +} + +export abstract class NetworkFrame< + Protocol extends string, + Data, + Events extends DefaultEventMap, +> { + public events: Emitter + + constructor( + public readonly protocol: Protocol, + public readonly data: Data, + ) { + this.events = new Emitter() + } + + /** + * Resolve the current frame against the given list of handlers. + * Optionally, use a custom resolution context to control behaviors + * like `baseUrl`. + */ + public abstract resolve( + handlers: Array, + resolutionContext?: NetworkFrameResolutionContext, + ): Promise + + /** + * Perform this network frame as-is. + */ + public abstract passthrough(): void + + /** + * Error the underling network frame. + * @param reason The reason for the error. + */ + public abstract errorWith(reason?: unknown): void + + /** + * Get a message to be used when this frame is unhandled. + */ + public abstract getUnhandledFrameMessage(): Promise +} diff --git a/src/core/new/frames/websocket-frame.ts b/src/core/new/frames/websocket-frame.ts new file mode 100644 index 000000000..64eda4210 --- /dev/null +++ b/src/core/new/frames/websocket-frame.ts @@ -0,0 +1,68 @@ +import { TypedEvent } from 'rettime' +import { type WebSocketConnectionData } from '@mswjs/interceptors/lib/browser/interceptors/WebSocket' +import { type WebSocketHandler } from '~/core/handlers/WebSocketHandler' +import { NetworkFrame, NetworkFrameResolutionContext } from './network-frame' + +export interface WebSocketNetworkFrameOptions { + connection: WebSocketConnectionData +} + +export type WebSocketNetworkFrameEventMap = { + connection: TypedEvent<{ + url: URL + protocols: string | Array | undefined + }> +} + +export abstract class WebSocketNetworkFrame extends NetworkFrame< + 'ws', + { + connection: WebSocketConnectionData + }, + WebSocketNetworkFrameEventMap +> { + constructor(options: WebSocketNetworkFrameOptions) { + super('ws', { + connection: options.connection, + }) + } + + public async resolve( + handlers: Array, + resolutionContext?: NetworkFrameResolutionContext, + ): Promise { + const { connection } = this.data + + this.events.emit( + new TypedEvent('connection', { + data: { + url: connection.client.url, + protocols: connection.info.protocols, + }, + }), + ) + + if (handlers.length === 0) { + return + } + + await Promise.all( + handlers.map(async (handler) => { + const matches = await handler.run(connection, { + baseUrl: resolutionContext?.baseUrl?.toString(), + }) + + if (matches) { + // + } + }), + ) + } + + public async getUnhandledFrameMessage(): Promise { + const { connection } = this.data + const details = `\n\n \u2022 ${connection.client.url}\n\n` + + return `intercepted a WebSocket connection without a matching event handler:${details}If you still wish to intercept this unhandled connection, please create an event handler for it.\nRead more: https://mswjs.io/docs/websocket` + } +} diff --git a/src/core/new/handlers-controller.ts b/src/core/new/handlers-controller.ts new file mode 100644 index 000000000..d66e912eb --- /dev/null +++ b/src/core/new/handlers-controller.ts @@ -0,0 +1,68 @@ +import { invariant } from 'outvariant' +import { type HttpHandler } from '~/core/handlers/HttpHandler' +import { type WebSocketHandler } from '~/core/handlers/WebSocketHandler' +import { devUtils } from '../utils/internal/devUtils' + +export type AnyHandler = HttpHandler | WebSocketHandler + +function validateHandlers(handlers: Array): boolean { + return handlers.every((handler) => !Array.isArray(handler)) +} + +export abstract class HandlersController { + constructor(initialHandlers: Array) { + invariant( + validateHandlers(initialHandlers), + devUtils.formatMessage( + 'Failed to create a handlers controller: invalid handlers. Did you forget to spread the handlers array?', + ), + ) + } + + public abstract get currentHandlers(): Array + + public use(nextHandlers: Array): void { + invariant( + validateHandlers(nextHandlers), + devUtils.formatMessage( + 'Failed to prepend runtime handlers: invalid handlers. Did you forget to spread the handlers array?', + ), + ) + } + + public reset(nextHandlers: Array): void { + invariant( + nextHandlers.length > 0 ? validateHandlers(nextHandlers) : true, + devUtils.formatMessage( + 'Failed to replace initial handlers during reset: invalid handlers. Did you forget to spread the handlers array?', + ), + ) + } +} + +export class InMemoryHandlersController extends HandlersController { + #handlers: Array + #initialHandlers: Array + + constructor(initialHandlers: Array) { + super(initialHandlers) + + this.#initialHandlers = initialHandlers + this.#handlers = [...initialHandlers] + } + + get currentHandlers() { + return this.#handlers + } + + public use(nextHandlers: Array): void { + super.use(nextHandlers) + this.#handlers.unshift(...nextHandlers) + } + + public reset(nextHandlers: Array): void { + super.reset(nextHandlers) + this.#handlers = + nextHandlers.length > 0 ? [...nextHandlers] : [...this.#initialHandlers] + } +} diff --git a/src/core/new/on-unhandled-frame.ts b/src/core/new/on-unhandled-frame.ts new file mode 100644 index 000000000..510c63641 --- /dev/null +++ b/src/core/new/on-unhandled-frame.ts @@ -0,0 +1,109 @@ +import { UnhandledRequestStrategy } from 'src/iife' +import { isCommonAssetRequest } from '../isCommonAssetRequest' +import { devUtils, InternalError } from '../utils/internal/devUtils' +import { type NetworkFrame } from './sources/network-source' + +export type UnhandledFrameHandle = + | UnhandledFrameStrategy + | UnhandledFrameCallback + +export type UnhandledFrameStrategy = 'bypass' | 'warn' | 'error' + +export type UnhandledFrameCallback = (args: { + frame: NetworkFrame + defaults: UnhandledFrameDefaults +}) => Promise | void + +export type UnhandledFrameDefaults = { + warn: () => void + error: () => void +} + +export async function onUnhandledFrame( + frame: NetworkFrame, + handle: UnhandledFrameHandle, +): Promise { + // Ignore unhandled common HTTP assets. + if (frame.protocol === 'http' && isCommonAssetRequest(frame.data.request)) { + return + } + + const applyStrategy = async (strategy: UnhandledFrameStrategy) => { + if (strategy === 'bypass') { + return + } + + const message = frame.getUnhandledFrameMessage() + + switch (strategy) { + case 'warn': { + return devUtils.warn('Warning: %s', message) + } + + case 'error': { + // Print a developer-friendly error. + devUtils.error('Error: %s', message) + + return Promise.reject( + new InternalError( + devUtils.formatMessage( + 'Cannot bypass a request when using the "error" strategy for the "onUnhandledRequest" option.', + ), + ), + ) + } + + default: { + throw new InternalError( + devUtils.formatMessage( + 'Failed to react to an unhandled network frame: unknown strategy "%s". Please provide one of the supported strategies ("bypass", "warn", "error") or a custom callback function as the value of the "onUnhandledRequest" option.', + strategy satisfies never, + ), + ) + } + } + } + + if (typeof handle === 'function') { + return handle({ + frame, + defaults: { + warn: applyStrategy.bind(null, 'warn'), + error: applyStrategy.bind(null, 'error'), + }, + }) + } + + return applyStrategy(handle) +} + +export function fromLegacyOnUnhandledRequest( + getLegacyValue: () => UnhandledRequestStrategy | undefined, +): UnhandledFrameCallback { + return ({ frame, defaults }) => { + const legacyOnUnhandledRequestStrategy = getLegacyValue() + + if (legacyOnUnhandledRequestStrategy === undefined) { + return + } + + if (typeof legacyOnUnhandledRequestStrategy === 'function') { + const request = + frame.protocol === 'http' + ? frame.data.request + : new Request(frame.data.connection.client.url, { + headers: { + connection: 'upgrade', + upgrade: 'websocket', + }, + }) + + return legacyOnUnhandledRequestStrategy(request, { + warning: defaults.warn, + error: defaults.error, + }) + } + + return onUnhandledFrame(frame, legacyOnUnhandledRequestStrategy) + } +} diff --git a/src/core/new/request-utils.ts b/src/core/new/request-utils.ts new file mode 100644 index 000000000..afbdad06d --- /dev/null +++ b/src/core/new/request-utils.ts @@ -0,0 +1,39 @@ +export const REQUEST_INTENTION_HEADER_NAME = 'x-msw-intention' + +export enum RequestIntention { + passthrough = 'passthrough', +} + +export function shouldBypassRequest(request: Request): boolean { + return !!request.headers.get('accept')?.includes('msw/passthrough') +} + +export function isPassthroughResponse(response: Response): boolean { + return ( + response.status === 302 && + response.headers.get(REQUEST_INTENTION_HEADER_NAME) === + RequestIntention.passthrough + ) +} + +/** + * Remove the internal passthrough instruction from the request's `Accept` header. + */ +export function deleteRequestPassthroughHeader(request: Request): void { + const acceptHeader = request.headers.get('accept') + + /** + * @note Remove the internal bypass request header. + * In the browser, this is done by the worker script. + * In Node.js, it has to be done here. + */ + if (acceptHeader) { + const nextAcceptHeader = acceptHeader.replace(/(,\s+)?msw\/passthrough/, '') + + if (nextAcceptHeader) { + request.headers.set('accept', nextAcceptHeader) + } else { + request.headers.delete('accept') + } + } +} diff --git a/src/core/new/sources/interceptor-source.ts b/src/core/new/sources/interceptor-source.ts new file mode 100644 index 000000000..123ac24b9 --- /dev/null +++ b/src/core/new/sources/interceptor-source.ts @@ -0,0 +1,183 @@ +import { TypedEvent } from 'rettime' +import { + BatchInterceptor, + Interceptor, + RequestController, + type HttpRequestEventMap, +} from '@mswjs/interceptors' +import type { + WebSocketConnectionData, + WebSocketEventMap, +} from '@mswjs/interceptors/lib/browser/interceptors/WebSocket' +import { NetworkSource } from './network-source' +import { InternalError } from '~/core/utils/internal/devUtils' +import { HttpNetworkFrame } from '../frames/http-frame' +import { WebSocketNetworkFrame } from '../frames/websocket-frame' +import { deleteRequestPassthroughHeader } from '../request-utils' + +export interface InterceptorSourceOptions { + interceptors: Array> +} + +/** + * Create a network source from the given list of interceptors. + */ +export class InterceptorSource extends NetworkSource< + HttpNetworkFrame | WebSocketNetworkFrame +> { + #interceptor: BatchInterceptor< + InterceptorSourceOptions['interceptors'], + HttpRequestEventMap | WebSocketEventMap + > + + #frames: Map + + constructor(options: InterceptorSourceOptions) { + super() + + this.#interceptor = new BatchInterceptor({ + name: 'interceptor-source', + interceptors: options.interceptors, + }) + this.#frames = new Map() + } + + public async enable(): Promise { + this.#interceptor.apply() + + this.#interceptor + .on('request', this.#handleRequest.bind(this)) + .on('response', this.#handleResponse.bind(this)) + .on('connection', this.#handleWebSocketConnection.bind(this)) + } + + public async disable(): Promise { + await super.disable() + this.#interceptor.dispose() + + /** + * @todo We can also abort any pending frames here, given we implement + * the `NetworkFrame.abort()` method. + */ + this.#frames.clear() + } + + async #handleRequest({ + requestId, + request, + controller, + }: HttpRequestEventMap['request'][0]): Promise { + const httpFrame = new InterceptorHttpNetworkFrame({ + id: requestId, + request, + controller, + }) + + this.#frames.set(requestId, httpFrame) + await this.queue(httpFrame) + } + + async #handleResponse({ + requestId, + request, + response, + isMockedResponse, + }: HttpRequestEventMap['response'][0]): Promise { + const httpFrame = this.#frames.get(requestId) + this.#frames.delete(requestId) + + if (httpFrame == null) { + return + } + + httpFrame.events.emit( + new TypedEvent('response', { + data: { + requestId, + request, + response, + isMockedResponse, + }, + }), + ) + } + + async #handleWebSocketConnection( + connection: WebSocketEventMap['connection'][0], + ): Promise { + await this.queue( + new InterceptorWebSocketNetworkFrame({ + connection, + }), + ) + } +} + +class InterceptorHttpNetworkFrame extends HttpNetworkFrame { + #controller: RequestController + + constructor(options: { + id: string + request: Request + controller: RequestController + }) { + super({ + id: options.id, + request: options.request, + }) + + this.#controller = options.controller + } + + public passthrough(): void { + deleteRequestPassthroughHeader(this.data.request) + } + + public respondWith(response?: Response): void { + if (response) { + this.#controller.respondWith(response) + } + } + + public errorWith(reason?: unknown): void { + if (reason instanceof Response) { + return this.respondWith(reason) + } + + if (reason instanceof InternalError) { + this.#controller.errorWith(reason) + } + + throw reason + } +} + +class InterceptorWebSocketNetworkFrame extends WebSocketNetworkFrame { + constructor(args: { connection: WebSocketConnectionData }) { + super({ connection: args.connection }) + } + + public errorWith(reason?: unknown): void { + if (reason instanceof Error) { + const { client } = this.data.connection + + /** + * Use `client.errorWith(reason)` in the future. + * @see https://github.com/mswjs/interceptors/issues/747 + */ + const errorEvent = new Event('error') + + Object.defineProperty(errorEvent, 'cause', { + enumerable: true, + configurable: false, + value: reason, + }) + + client.socket.dispatchEvent(errorEvent) + } + } + + public passthrough() { + this.data.connection.server.connect() + } +} diff --git a/src/core/new/sources/network-source.ts b/src/core/new/sources/network-source.ts new file mode 100644 index 000000000..3045bcd50 --- /dev/null +++ b/src/core/new/sources/network-source.ts @@ -0,0 +1,34 @@ +import { Emitter, TypedEvent } from 'rettime' +import { type HttpNetworkFrame } from '../frames/http-frame' +import { type WebSocketNetworkFrame } from '../frames/websocket-frame' + +export type NetworkFrame = HttpNetworkFrame | WebSocketNetworkFrame + +type NetworkSourceEventMap = { + frame: TypedEvent +} + +export abstract class NetworkSource { + protected emitter: Emitter> + + constructor() { + this.emitter = new Emitter() + } + + public abstract enable(): Promise + + public async queue(frame: Frame): Promise { + await this.emitter.emitAsPromise(new TypedEvent('frame', { data: frame })) + } + + public on>( + type: Type, + listener: Emitter.ListenerType, + ): void { + this.emitter.on(type, listener) + } + + public async disable(): Promise { + this.emitter.removeAllListeners() + } +} From 30f32a80c5924b50d3e86552cb41df7596798a89 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Sat, 10 Jan 2026 19:56:51 +0100 Subject: [PATCH 02/68] fix(ws): implement the handler lookup handling --- src/core/handlers/WebSocketHandler.ts | 5 +++++ src/core/new/frames/websocket-frame.ts | 28 ++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/core/handlers/WebSocketHandler.ts b/src/core/handlers/WebSocketHandler.ts index 22ea65f6e..ebceda3b7 100644 --- a/src/core/handlers/WebSocketHandler.ts +++ b/src/core/handlers/WebSocketHandler.ts @@ -13,6 +13,7 @@ import { } from '../utils/matching/matchRequestUrl' import { getCallFrame } from '../utils/internal/getCallFrame' import type { HandlerKind } from './common' +import { attachWebSocketLogger } from '../ws/utils/attachWebSocketLogger' type WebSocketHandlerParsedResult = { match: Match @@ -138,6 +139,10 @@ export class WebSocketHandler { // This is what the developer adds listeners for. return this[kEmitter].emit('connection', connection) } + + public log(connection: WebSocketConnectionData): void { + attachWebSocketLogger(connection) + } } function createStopPropagationListener(handler: WebSocketHandler) { diff --git a/src/core/new/frames/websocket-frame.ts b/src/core/new/frames/websocket-frame.ts index 64eda4210..ea1d50a95 100644 --- a/src/core/new/frames/websocket-frame.ts +++ b/src/core/new/frames/websocket-frame.ts @@ -1,7 +1,10 @@ import { TypedEvent } from 'rettime' import { type WebSocketConnectionData } from '@mswjs/interceptors/lib/browser/interceptors/WebSocket' import { type WebSocketHandler } from '~/core/handlers/WebSocketHandler' -import { NetworkFrame, NetworkFrameResolutionContext } from './network-frame' +import { + NetworkFrame, + type NetworkFrameResolutionContext, +} from './network-frame' export interface WebSocketNetworkFrameOptions { connection: WebSocketConnectionData @@ -30,7 +33,7 @@ export abstract class WebSocketNetworkFrame extends NetworkFrame< public async resolve( handlers: Array, resolutionContext?: NetworkFrameResolutionContext, - ): Promise { + ): Promise { const { connection } = this.data this.events.emit( @@ -43,20 +46,33 @@ export abstract class WebSocketNetworkFrame extends NetworkFrame< ) if (handlers.length === 0) { - return + return false } - await Promise.all( + const matchingHandlers = await Promise.all( handlers.map(async (handler) => { const matches = await handler.run(connection, { baseUrl: resolutionContext?.baseUrl?.toString(), }) - if (matches) { - // + if (!matches) { + return null } + + if (!resolutionContext?.quiet) { + handler.log(connection) + } + + return handler }), ) + + if (matchingHandlers.every((handler) => handler == null)) { + this.passthrough() + return null + } + + return true } public async getUnhandledFrameMessage(): Promise { From f65e91dad2290f31953834879feb144a2f3e7b18 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Sun, 11 Jan 2026 12:15:40 +0100 Subject: [PATCH 03/68] fix: implement `setupServer` and `SetupServerCommonApi` --- package.json | 2 +- pnpm-lock.yaml | 10 ++--- src/core/index.ts | 7 +++ src/core/new/compat.ts | 60 +++++++++++++++++++++++++ src/core/new/define-network.ts | 13 ++++-- src/core/new/on-unhandled-frame.ts | 32 ------------- src/node/async-handlers-controller.ts | 49 ++++++++++++++++++++ src/node/glossary.ts | 13 +++--- src/node/setup-server-common.ts | 65 +++++++++++++++++++++++++++ src/node/setup-server.ts | 54 ++++++++++++++++++++++ 10 files changed, 257 insertions(+), 48 deletions(-) create mode 100644 src/core/new/compat.ts create mode 100644 src/node/async-handlers-controller.ts create mode 100644 src/node/setup-server-common.ts create mode 100644 src/node/setup-server.ts diff --git a/package.json b/package.json index 88613c8bb..ccea88024 100644 --- a/package.json +++ b/package.json @@ -248,7 +248,7 @@ "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", - "rettime": "^0.7.0", + "rettime": "^0.9.0", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6a413cd56..c37ca3f13 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,8 +42,8 @@ importers: specifier: ^1.1.1 version: 1.1.1 rettime: - specifier: ^0.7.0 - version: 0.7.0 + specifier: ^0.9.0 + version: 0.9.0 statuses: specifier: ^2.0.2 version: 2.0.2 @@ -4315,8 +4315,8 @@ packages: resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} engines: {node: '>=10'} - rettime@0.7.0: - resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} + rettime@0.9.0: + resolution: {integrity: sha512-mj6hOrwD8UA+jFqyCiSBxm8MI+qhYeSqS0aNcGfPkVmmCyHNFRr3hoQUTTZ3iBgk1x4ZNXnvSzluFZM4kcx/gA==} reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} @@ -9711,7 +9711,7 @@ snapshots: ret@0.5.0: {} - rettime@0.7.0: {} + rettime@0.9.0: {} reusify@1.0.4: {} diff --git a/src/core/index.ts b/src/core/index.ts index 8d063a138..b441e4500 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -92,6 +92,13 @@ export { bypass } from './bypass' export { passthrough } from './passthrough' export { isCommonAssetRequest } from './isCommonAssetRequest' +export { defineNetwork, type NetworkApi } from './new/define-network' +export { + type AnyHandler, + HandlersController, + InMemoryHandlersController, +} from './new/handlers-controller' + // Validate environmental globals before executing any code. // This ensures that the library gives user-friendly errors // when ran in the environments that require additional polyfills diff --git a/src/core/new/compat.ts b/src/core/new/compat.ts new file mode 100644 index 000000000..7b72bd70e --- /dev/null +++ b/src/core/new/compat.ts @@ -0,0 +1,60 @@ +/** + * Collection of helpers for briding the compatibility between the old and the new APIs. + */ +import { Emitter } from 'rettime' +import { + Emitter as LegacyEmitter, + EventMap as LegacyEventMap, +} from 'strict-event-emitter' +import { type UnhandledRequestStrategy } from '~/core/utils/request/onUnhandledRequest' +import { + onUnhandledFrame, + type UnhandledFrameCallback, +} from './on-unhandled-frame' + +export function toLegacyEmitter( + emitter: Emitter, +): LegacyEmitter { + const legacy = new LegacyEmitter() + + legacy + .addListener('newListener', (type, listener) => { + emitter.on(type as any, (event) => listener(event.data)) + }) + .addListener('removeListener', (type, listener) => { + emitter.removeListener(type as any, listener) + }) + + return legacy +} + +export function fromLegacyOnUnhandledRequest( + getLegacyValue: () => UnhandledRequestStrategy | undefined, +): UnhandledFrameCallback { + return ({ frame, defaults }) => { + const legacyOnUnhandledRequestStrategy = getLegacyValue() + + if (legacyOnUnhandledRequestStrategy === undefined) { + return + } + + if (typeof legacyOnUnhandledRequestStrategy === 'function') { + const request = + frame.protocol === 'http' + ? frame.data.request + : new Request(frame.data.connection.client.url, { + headers: { + connection: 'upgrade', + upgrade: 'websocket', + }, + }) + + return legacyOnUnhandledRequestStrategy(request, { + warning: defaults.warn, + error: defaults.error, + }) + } + + return onUnhandledFrame(frame, legacyOnUnhandledRequestStrategy) + } +} diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index 95e94848b..1a04864b0 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -1,7 +1,5 @@ import { Emitter } from 'rettime' import { type NetworkSource } from './sources/network-source' - -import { pipeEvents } from '../utils/internal/pipeEvents' import { type NetworkFrameResolutionContext } from './frames/network-frame' import { onUnhandledFrame, UnhandledFrameHandle } from './on-unhandled-frame' import { isHandlerKind } from '../utils/internal/isHandlerKind' @@ -23,13 +21,14 @@ export interface DefineNetworkOptions { export interface NetworkApi extends NetworkHandlersApi { enable: () => Promise disable: () => Promise + events: Emitter } export interface NetworkHandlersApi { use: (...handlers: Array) => void resetHandlers: (...handlers: Array) => void restoreHandlers: () => void - listHandlers: () => void + listHandlers: () => ReadonlyArray } export function defineNetwork(options: DefineNetworkOptions): NetworkApi { @@ -38,11 +37,17 @@ export function defineNetwork(options: DefineNetworkOptions): NetworkApi { options.controller || new InMemoryHandlersController(options.handlers || []) return { + events, async enable() { await Promise.all( options.sources.map(async (source) => { source.on('frame', async ({ data: frame }) => { - pipeEvents(frame.events, events) + /** + * @fixme Rettime has trouble typing `.on` when the emitter + * has a union of eventmap types. Add a type test and a runtime test + * for this use case (piping events). + */ + frame.events.on((event) => events.emit(event)) const handlerPredicate = frame.protocol === 'http' diff --git a/src/core/new/on-unhandled-frame.ts b/src/core/new/on-unhandled-frame.ts index 510c63641..c298d2aeb 100644 --- a/src/core/new/on-unhandled-frame.ts +++ b/src/core/new/on-unhandled-frame.ts @@ -1,4 +1,3 @@ -import { UnhandledRequestStrategy } from 'src/iife' import { isCommonAssetRequest } from '../isCommonAssetRequest' import { devUtils, InternalError } from '../utils/internal/devUtils' import { type NetworkFrame } from './sources/network-source' @@ -76,34 +75,3 @@ export async function onUnhandledFrame( return applyStrategy(handle) } - -export function fromLegacyOnUnhandledRequest( - getLegacyValue: () => UnhandledRequestStrategy | undefined, -): UnhandledFrameCallback { - return ({ frame, defaults }) => { - const legacyOnUnhandledRequestStrategy = getLegacyValue() - - if (legacyOnUnhandledRequestStrategy === undefined) { - return - } - - if (typeof legacyOnUnhandledRequestStrategy === 'function') { - const request = - frame.protocol === 'http' - ? frame.data.request - : new Request(frame.data.connection.client.url, { - headers: { - connection: 'upgrade', - upgrade: 'websocket', - }, - }) - - return legacyOnUnhandledRequestStrategy(request, { - warning: defaults.warn, - error: defaults.error, - }) - } - - return onUnhandledFrame(frame, legacyOnUnhandledRequestStrategy) - } -} diff --git a/src/node/async-handlers-controller.ts b/src/node/async-handlers-controller.ts new file mode 100644 index 000000000..ca31fe5f1 --- /dev/null +++ b/src/node/async-handlers-controller.ts @@ -0,0 +1,49 @@ +import { AsyncLocalStorage } from 'node:async_hooks' +import { type AnyHandler, HandlersController } from '~/core/index' + +export interface AsyncHandlersControllerContext { + initialHandlers: Array + handlers: Array +} + +export class AsyncHandlersController extends HandlersController { + #fallbackContext: AsyncHandlersControllerContext + + public context: AsyncLocalStorage + + constructor(initialHandlers: Array) { + super(initialHandlers) + + this.context = new AsyncLocalStorage() + this.#fallbackContext = { + initialHandlers: [...initialHandlers], + handlers: [], + } + } + + get currentHandlers() { + const { initialHandlers, handlers } = this.#getContext() + return [...initialHandlers, ...handlers] + } + + public use(nextHandlers: Array): void { + super.use(nextHandlers) + + this.#getContext().handlers.unshift(...nextHandlers) + } + + public reset(nextHandlers: Array): void { + super.reset(nextHandlers) + + const context = this.#getContext() + context.handlers = [] + + if (nextHandlers.length > 0) { + context.initialHandlers = [...nextHandlers] + } + } + + #getContext() { + return this.context.getStore() || this.#fallbackContext + } +} diff --git a/src/node/glossary.ts b/src/node/glossary.ts index 7f52c9f91..29f1a1598 100644 --- a/src/node/glossary.ts +++ b/src/node/glossary.ts @@ -1,19 +1,20 @@ import type { PartialDeep } from 'type-fest' -import type { RequestHandler } from '~/core/handlers/RequestHandler' -import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' +import { AnyHandler } from '~/core' import type { LifeCycleEventEmitter, LifeCycleEventsMap, SharedOptions, } from '~/core/sharedOptions' +export interface ListenOptions extends SharedOptions {} + export interface SetupServerCommon { /** * Starts requests interception based on the previously provided request handlers. * * @see {@link https://mswjs.io/docs/api/setup-server/listen `server.listen()` API reference} */ - listen(options?: PartialDeep): void + listen(options?: PartialDeep): void /** * Stops requests interception by restoring all augmented modules. @@ -27,7 +28,7 @@ export interface SetupServerCommon { * * @see {@link https://mswjs.io/docs/api/setup-server/use `server.use()` API reference} */ - use(...handlers: Array): void + use(...handlers: Array): void /** * Marks all request handlers that respond using `res.once()` as unused. @@ -41,14 +42,14 @@ export interface SetupServerCommon { * * @see {@link https://mswjs.io/docs/api/setup-server/reset-handlers `server.reset-handlers()` API reference} */ - resetHandlers(...nextHandlers: Array): void + resetHandlers(...nextHandlers: Array): void /** * Returns a readonly list of currently active request handlers. * * @see {@link https://mswjs.io/docs/api/setup-server/list-handlers `server.listHandlers()` API reference} */ - listHandlers(): ReadonlyArray + listHandlers(): ReadonlyArray /** * Life-cycle events. diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts new file mode 100644 index 000000000..f9bfd8ce2 --- /dev/null +++ b/src/node/setup-server-common.ts @@ -0,0 +1,65 @@ +import type { PartialDeep } from 'type-fest' +import { Interceptor } from '@mswjs/interceptors' +import { ListenOptions, SetupServerCommon } from './glossary' +import { + AnyHandler, + defineNetwork, + LifeCycleEventsMap, + NetworkApi, +} from '~/core' +import { HandlersController } from '~/core/new/handlers-controller' +import { InterceptorSource } from '~/core/new/sources/interceptor-source' +import { + fromLegacyOnUnhandledRequest, + toLegacyEmitter, +} from '~/core/new/compat' + +export class SetupServerCommonApi implements SetupServerCommon { + #listenOptions?: PartialDeep + + protected network: NetworkApi + + constructor( + interceptors: Array>, + handlers: Array, + handlersController?: HandlersController, + ) { + this.network = defineNetwork({ + sources: [new InterceptorSource({ interceptors })], + handlers, + controller: handlersController, + onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { + return this.#listenOptions?.onUnhandledRequest || 'warn' + }), + }) + } + + get events() { + return toLegacyEmitter(this.network.events) + } + + public listen(options?: PartialDeep): void { + this.#listenOptions = options + this.network.enable() + } + + public use(...handlers: Array): void { + this.network.use(...handlers) + } + + public resetHandlers(...nextHandlers: Array): void { + return this.network.resetHandlers(...nextHandlers) + } + + public restoreHandlers(): void { + return this.network.restoreHandlers() + } + + public listHandlers(): ReadonlyArray { + return this.network.listHandlers() + } + + public close(): void { + this.network.disable() + } +} diff --git a/src/node/setup-server.ts b/src/node/setup-server.ts new file mode 100644 index 000000000..a73728061 --- /dev/null +++ b/src/node/setup-server.ts @@ -0,0 +1,54 @@ +import { Interceptor } from '@mswjs/interceptors' +import { ClientRequestInterceptor } from '@mswjs/interceptors/lib/node/interceptors/ClientRequest' +import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/lib/node/interceptors/XMLHttpRequest' +import { FetchInterceptor } from '@mswjs/interceptors/lib/node/interceptors/fetch' +import { WebSocketInterceptor } from '@mswjs/interceptors/lib/browser/interceptors/WebSocket' +import { SetupServer } from './glossary' +import { type AnyHandler } from '~/core/new/handlers-controller' +import { AsyncHandlersController } from './async-handlers-controller' +import { SetupServerCommonApi } from './setup-server-common' + +/** + * Enables request interception in Node.js with the given request handlers. + * @see {@link https://mswjs.io/docs/api/setup-server `setupServer()` API reference} + */ +export function setupServer(...handlers: Array): SetupServerApi { + return new SetupServerApi(handlers, [ + new ClientRequestInterceptor(), + new XMLHttpRequestInterceptor(), + new FetchInterceptor(), + new WebSocketInterceptor(), + ]) +} + +export class SetupServerApi + extends SetupServerCommonApi + implements SetupServer +{ + #handlersController: AsyncHandlersController + + constructor( + handlers: Array, + interceptors: Array>, + ) { + const controller = new AsyncHandlersController(handlers) + super(interceptors, handlers, controller) + + this.#handlersController = controller + } + + public boundary, ReturnType>( + callback: (...args: Args) => ReturnType, + ): (...args: Args) => ReturnType { + return (...args: Args): ReturnType => { + return this.#handlersController.context.run( + { + initialHandlers: this.#handlersController.currentHandlers, + handlers: [], + }, + callback, + ...args, + ) + } + } +} From 2b64a7fd552312f8b18d6d76ae0af402462253cb Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Sun, 11 Jan 2026 12:52:30 +0100 Subject: [PATCH 04/68] fix: implement `setupWorker` --- src/browser/setup-worker.ts | 84 ++++ src/browser/sources/fallback-http-source.ts | 33 ++ src/browser/sources/service-worker-source.ts | 388 +++++++++++++++++++ src/core/index.ts | 7 - src/core/new/frames/websocket-frame.ts | 2 +- src/core/new/sources/interceptor-source.ts | 2 +- src/core/new/sources/network-source.ts | 2 +- src/node/setup-server-common.ts | 9 +- src/node/setup-server.ts | 8 +- 9 files changed, 515 insertions(+), 20 deletions(-) create mode 100644 src/browser/setup-worker.ts create mode 100644 src/browser/sources/fallback-http-source.ts create mode 100644 src/browser/sources/service-worker-source.ts diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts new file mode 100644 index 000000000..ea97f2990 --- /dev/null +++ b/src/browser/setup-worker.ts @@ -0,0 +1,84 @@ +import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' +import { + defineNetwork, + NetworkApi, + NetworkHandlersApi, +} from '~/core/new/define-network' +import { type AnyHandler } from '~/core/new/handlers-controller' +import { InterceptorSource } from '~/core/new/sources/interceptor-source' +import { fromLegacyOnUnhandledRequest } from '~/core/new/compat' +import { supportsServiceWorker } from './utils/supports' +import { ServiceWorkerSource } from './sources/service-worker-source' +import { FallbackHttpSource } from './sources/fallback-http-source' +import { type FindWorker } from './setupWorker/glossary' +import { type UnhandledRequestStrategy } from '~/core/utils/request/onUnhandledRequest' + +interface SetupWorkerApi extends NetworkHandlersApi { + start: (options?: SetupWorkerStartOptions) => Promise + stop: () => void +} + +interface SetupWorkerStartOptions { + quiet?: boolean + serviceWorker?: { + url?: string | URL + options?: RegistrationOptions + } + findWorker?: FindWorker + onUnhandledRequest?: UnhandledRequestStrategy +} + +const DEFAULT_WORKER_URL = '/mockServiceWorker.js' + +/** + * Sets up a requests interception in the browser with the given request handlers. + * @param {Array} handlers List of request handlers. + * + * @see {@link https://mswjs.io/docs/api/setup-worker `setupWorker()` API reference} + */ +export function setupWorker(...handlers: Array): SetupWorkerApi { + let network: NetworkApi + + return { + async start(options) { + const httpSource = supportsServiceWorker() + ? new ServiceWorkerSource({ + serviceWorker: { + url: DEFAULT_WORKER_URL, + }, + findWorker: undefined, + }) + : new FallbackHttpSource() + + network = defineNetwork({ + sources: [ + httpSource, + new InterceptorSource({ + interceptors: [new WebSocketInterceptor()], + }), + ], + handlers, + onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { + return options?.onUnhandledRequest || 'warn' + }), + }) + + await network.enable() + }, + stop() { + network.disable() + }, + use(...handlers) { + return network.use(...handlers) + }, + resetHandlers(...handlers) { + return network.resetHandlers(...handlers) + }, + restoreHandlers() { + return network.restoreHandlers() + }, + listHandlers() { + return network.listHandlers() + }, + } +} diff --git a/src/browser/sources/fallback-http-source.ts b/src/browser/sources/fallback-http-source.ts new file mode 100644 index 000000000..6825cff85 --- /dev/null +++ b/src/browser/sources/fallback-http-source.ts @@ -0,0 +1,33 @@ +import { FetchInterceptor } from '@mswjs/interceptors/fetch' +import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' +import { InterceptorSource } from '~/core/new/sources/interceptor-source' +import { devUtils } from '~/core/utils/internal/devUtils' + +export class FallbackHttpSource extends InterceptorSource { + constructor() { + super({ + interceptors: [new XMLHttpRequestInterceptor(), new FetchInterceptor()], + }) + } + + public async enable(): Promise { + await super.enable() + this.#printStartMessage() + } + + #printStartMessage(): void { + console.groupCollapsed( + `%c${devUtils.formatMessage('Mocking enabled (fallback mode).')}`, + 'color:orangered;font-weight:bold;', + ) + // eslint-disable-next-line no-console + console.log( + '%cDocumentation: %chttps://mswjs.io/docs', + 'font-weight:bold', + 'font-weight:normal', + ) + // eslint-disable-next-line no-console + console.log('Found an issue? https://github.com/mswjs/msw/issues') + console.groupEnd() + } +} diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts new file mode 100644 index 000000000..b1f26dece --- /dev/null +++ b/src/browser/sources/service-worker-source.ts @@ -0,0 +1,388 @@ +import { invariant } from 'outvariant' +import { DeferredPromise } from '@open-draft/deferred-promise' +import { FetchResponse } from '@mswjs/interceptors' +import { NetworkSource } from '~/core/new/sources/network-source' +import { + supportsReadableStreamTransfer, + supportsServiceWorker, +} from '../utils/supports' +import { getWorkerInstance } from '../setupWorker/start/utils/getWorkerInstance' +import { devUtils } from '~/core/utils/internal/devUtils' +import { WorkerChannel, WorkerChannelEventMap } from '../utils/workerChannel' +import { FindWorker } from '../setupWorker/glossary' +import { Emitter, TypedEvent } from 'rettime' +import { deserializeRequest } from '../utils/deserializeRequest' +import { RequestHandler } from '~/core/handlers/RequestHandler' +import { HttpNetworkFrame } from '~/core/new/frames/http-frame' +import { HttpResponse } from '~/core/HttpResponse' +import { toResponseInit } from '~/core/utils/toResponseInit' + +export interface ServiceWorkerSourceOptions { + quiet?: boolean + serviceWorker: { + url: string + options?: RegistrationOptions + } + findWorker?: FindWorker +} + +type RequestEvent = Emitter.EventType< + WorkerChannel, + 'REQUEST', + WorkerChannelEventMap +> + +type ResponseEvent = Emitter.EventType< + WorkerChannel, + 'RESPONSE', + WorkerChannelEventMap +> + +export class ServiceWorkerSource extends NetworkSource { + #frames: Map + #channel: WorkerChannel + #workerPromise: DeferredPromise + #keepAliveInterval?: number + #stoppedAt?: number + + constructor(private readonly options: ServiceWorkerSourceOptions) { + super() + + invariant( + supportsServiceWorker(), + 'Failed to use Service Worker as the network source: the Service Worker API is not supported in this environment', + ) + + this.#frames = new Map() + this.#workerPromise = new DeferredPromise() + this.#channel = new WorkerChannel({ + worker: this.#workerPromise, + }) + } + + public async enable(): Promise { + this.#stoppedAt = undefined + + if (this.#workerPromise.state !== 'pending') { + this.#workerPromise = new DeferredPromise() + } + + const registration = await this.#startWorker() + const pendingInstance = registration.installing || registration.waiting + + if (pendingInstance) { + const controller = new AbortController() + const activationPromise = new DeferredPromise() + activationPromise.then(() => controller.abort()) + + pendingInstance.addEventListener( + 'statechange', + () => { + if (pendingInstance.state === 'activated') { + activationPromise.resolve() + } + }, + { signal: controller.signal }, + ) + + await activationPromise + } + + this.#channel.postMessage('MOCK_ACTIVATE') + + const confirmationPromise = new DeferredPromise() + this.#channel.once('MOCKING_ENABLED', async (event) => { + confirmationPromise.resolve() + + this.#printStartMessage({ + registration, + client: event.data.client, + }) + }) + await confirmationPromise + + return registration + } + + public async disable(): Promise { + await super.disable() + + this.#frames.clear() + this.#stoppedAt = Date.now() + this.#channel.removeAllListeners() + } + + async #startWorker(): Promise { + if (this.#keepAliveInterval) { + clearInterval(this.#keepAliveInterval) + } + + const workerUrl = this.options.serviceWorker.url + + const [worker, registration] = await getWorkerInstance( + workerUrl, + this.options.serviceWorker.options, + this.options.findWorker || this.#defaultFindWorker, + ) + + if (worker == null) { + const missingWorkerMessage = this.options?.findWorker + ? devUtils.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 + `, + workerUrl, + ) + : devUtils.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`, + workerUrl, + location.host, + ) + + throw new Error(missingWorkerMessage) + } + + this.#workerPromise.resolve(worker) + this.#channel.on('REQUEST', this.#handleRequest.bind(this)) + this.#channel.on('RESPONSE', this.#handleResponse.bind(this)) + + window.addEventListener('beforeunload', () => { + if (worker.state !== 'redundant') { + this.#channel.postMessage('CLIENT_CLOSED') + } + + clearInterval(this.#keepAliveInterval) + + window.postMessage({ type: 'msw/worker:stop' }) + }) + + await this.#checkWorkerIntegrity().catch((error) => { + devUtils.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(error) + }) + + this.#keepAliveInterval = window.setInterval(() => { + this.#channel.postMessage('KEEPALIVE_REQUEST') + }, 5000) + + return registration + } + + async #handleRequest(event: RequestEvent): Promise { + // Passthrough any requests performed after the interception was stopped. + if (this.#stoppedAt && event.data.interceptedAt > this.#stoppedAt) { + return event.postMessage('PASSTHROUGH') + } + + const request = deserializeRequest(event.data) + RequestHandler.cache.set(request, request.clone()) + + const frame = new ServiceWorkerHttpNetworkFrame({ + event, + request, + }) + this.#frames.set(event.data.id, frame) + + await this.queue(frame) + } + + async #handleResponse(event: ResponseEvent): Promise { + const { request, response, isMockedResponse } = event.data + + /** + * CORS requests with `mode: "no-cors"` result in "opaque" responses. + * That kind of responses cannot be manipulated in JavaScript due + * to the security considerations. + * @see https://fetch.spec.whatwg.org/#concept-filtered-response-opaque + * @see https://github.com/mswjs/msw/issues/529 + */ + if (response.type?.includes('opaque')) { + return + } + + const frame = this.#frames.get(request.id) + this.#frames.delete(request.id) + + invariant( + frame != null, + 'Failed to handle a worker response for request "%s %s": request frame is missing', + request.method, + request.url, + ) + + const fetchRequest = deserializeRequest(request) + const fetchResponse = + response.status === 0 + ? Response.error() + : new FetchResponse(response.body, response) + + frame.events.emit( + new TypedEvent('response', { + data: { + requestId: request.id, + request: fetchRequest, + response: fetchResponse, + isMockedResponse, + }, + }), + ) + } + + #defaultFindWorker: FindWorker = (workerUrl, mockServiceWorkerUrl) => { + return workerUrl === mockServiceWorkerUrl + } + + async #checkWorkerIntegrity(): Promise { + const integrityCheckPromise = new DeferredPromise() + + this.#channel.postMessage('INTEGRITY_CHECK_REQUEST') + this.#channel.once('INTEGRITY_CHECK_RESPONSE', (event) => { + const { checksum, packageVersion } = event.data + + // Compare the response from the Service Worker and the + // global variable set during the build. + + // The integrity is validated based on the worker script's checksum + // that's derived from its minified content during the build. + // The "SERVICE_WORKER_CHECKSUM" global variable is injected by the build. + if (checksum !== SERVICE_WORKER_CHECKSUM) { + devUtils.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 + + 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 + } + + #printStartMessage(args: { + registration: ServiceWorkerRegistration + client: WorkerChannelEventMap['MOCKING_ENABLED']['data']['client'] + }): void { + if (this.options.quiet) { + return + } + + const { registration, client } = args + const serviceWorkerUrl = this.options.serviceWorker.url + + console.groupCollapsed( + `%c${devUtils.formatMessage('Mocking enabled.')}`, + 'color:orangered;font-weight:bold;', + ) + // eslint-disable-next-line no-console + console.log( + '%cDocumentation: %chttps://mswjs.io/docs', + 'font-weight:bold', + 'font-weight:normal', + ) + // eslint-disable-next-line no-console + console.log('Found an issue? https://github.com/mswjs/msw/issues') + + // eslint-disable-next-line no-console + console.log('Worker script URL:', serviceWorkerUrl) + + // eslint-disable-next-line no-console + console.log('Worker scope:', registration.scope) + + if (client) { + // eslint-disable-next-line no-console + console.log('Client ID: %s (%s)', client.id, client.frameType) + } + + console.groupEnd() + } +} + +class ServiceWorkerHttpNetworkFrame extends HttpNetworkFrame { + #event: RequestEvent + + constructor(options: { event: RequestEvent; request: Request }) { + super({ request: options.request }) + this.#event = options.event + } + + public passthrough(): void { + this.#event.postMessage('PASSTHROUGH') + } + + public respondWith(response?: Response): void { + if (response) { + this.#respondWith(response) + } + } + + public errorWith(reason?: unknown): void { + if (reason instanceof Response) { + return this.respondWith(reason) + } + + if (reason instanceof Error) { + devUtils.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`, + this.data.request.method, + this.data.request.url, + reason.stack ?? reason, + ) + + // Treat exceptions during the request handling as 500 responses. + // This should alert the developer that there's a problem. + this.respondWith( + HttpResponse.json( + { + name: reason.name, + message: reason.message, + stack: reason.stack, + }, + { + status: 500, + statusText: 'Request Handler Error', + }, + ), + ) + } + } + + async #respondWith(response: Response): Promise { + let responseBody: ReadableStream | ArrayBuffer | null + let transfer: [ReadableStream] | undefined + const responseInit = toResponseInit(response) + + if (supportsReadableStreamTransfer()) { + responseBody = response.body + transfer = response.body == null ? undefined : [response.body] + } else { + responseBody = + response.body == null ? null : await response.clone().arrayBuffer() + } + + this.#event.postMessage( + 'MOCK_RESPONSE', + { + ...responseInit, + body: responseBody, + }, + transfer, + ) + } +} diff --git a/src/core/index.ts b/src/core/index.ts index b441e4500..8d063a138 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -92,13 +92,6 @@ export { bypass } from './bypass' export { passthrough } from './passthrough' export { isCommonAssetRequest } from './isCommonAssetRequest' -export { defineNetwork, type NetworkApi } from './new/define-network' -export { - type AnyHandler, - HandlersController, - InMemoryHandlersController, -} from './new/handlers-controller' - // Validate environmental globals before executing any code. // This ensures that the library gives user-friendly errors // when ran in the environments that require additional polyfills diff --git a/src/core/new/frames/websocket-frame.ts b/src/core/new/frames/websocket-frame.ts index ea1d50a95..70a62ace6 100644 --- a/src/core/new/frames/websocket-frame.ts +++ b/src/core/new/frames/websocket-frame.ts @@ -1,5 +1,5 @@ import { TypedEvent } from 'rettime' -import { type WebSocketConnectionData } from '@mswjs/interceptors/lib/browser/interceptors/WebSocket' +import { type WebSocketConnectionData } from '@mswjs/interceptors/WebSocket' import { type WebSocketHandler } from '~/core/handlers/WebSocketHandler' import { NetworkFrame, diff --git a/src/core/new/sources/interceptor-source.ts b/src/core/new/sources/interceptor-source.ts index 123ac24b9..f20701fd0 100644 --- a/src/core/new/sources/interceptor-source.ts +++ b/src/core/new/sources/interceptor-source.ts @@ -8,7 +8,7 @@ import { import type { WebSocketConnectionData, WebSocketEventMap, -} from '@mswjs/interceptors/lib/browser/interceptors/WebSocket' +} from '@mswjs/interceptors/WebSocket' import { NetworkSource } from './network-source' import { InternalError } from '~/core/utils/internal/devUtils' import { HttpNetworkFrame } from '../frames/http-frame' diff --git a/src/core/new/sources/network-source.ts b/src/core/new/sources/network-source.ts index 3045bcd50..cca40956e 100644 --- a/src/core/new/sources/network-source.ts +++ b/src/core/new/sources/network-source.ts @@ -15,7 +15,7 @@ export abstract class NetworkSource { this.emitter = new Emitter() } - public abstract enable(): Promise + public abstract enable(): Promise public async queue(frame: Frame): Promise { await this.emitter.emitAsPromise(new TypedEvent('frame', { data: frame })) diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts index f9bfd8ce2..ecfae93c1 100644 --- a/src/node/setup-server-common.ts +++ b/src/node/setup-server-common.ts @@ -1,12 +1,9 @@ import type { PartialDeep } from 'type-fest' import { Interceptor } from '@mswjs/interceptors' import { ListenOptions, SetupServerCommon } from './glossary' -import { - AnyHandler, - defineNetwork, - LifeCycleEventsMap, - NetworkApi, -} from '~/core' +import { type LifeCycleEventsMap } from '~/core' +import { type NetworkApi, defineNetwork } from '~/core/new/define-network' +import { type AnyHandler } from '~/core/new/handlers-controller' import { HandlersController } from '~/core/new/handlers-controller' import { InterceptorSource } from '~/core/new/sources/interceptor-source' import { diff --git a/src/node/setup-server.ts b/src/node/setup-server.ts index a73728061..1151ed7b2 100644 --- a/src/node/setup-server.ts +++ b/src/node/setup-server.ts @@ -1,8 +1,8 @@ import { Interceptor } from '@mswjs/interceptors' -import { ClientRequestInterceptor } from '@mswjs/interceptors/lib/node/interceptors/ClientRequest' -import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/lib/node/interceptors/XMLHttpRequest' -import { FetchInterceptor } from '@mswjs/interceptors/lib/node/interceptors/fetch' -import { WebSocketInterceptor } from '@mswjs/interceptors/lib/browser/interceptors/WebSocket' +import { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest' +import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' +import { FetchInterceptor } from '@mswjs/interceptors/fetch' +import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' import { SetupServer } from './glossary' import { type AnyHandler } from '~/core/new/handlers-controller' import { AsyncHandlersController } from './async-handlers-controller' From 980f4bebf966cd374a4b793a307d008c8cbd803e Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Sun, 11 Jan 2026 12:55:25 +0100 Subject: [PATCH 05/68] chore: remove legacy `msw/node` apis --- src/native/index.ts | 8 +- src/node/SetupServerApi.ts | 87 ---------------- src/node/SetupServerCommonApi.ts | 169 ------------------------------- src/node/glossary.ts | 2 +- src/node/index.ts | 4 +- src/node/setupServer.ts | 15 --- 6 files changed, 7 insertions(+), 278 deletions(-) delete mode 100644 src/node/SetupServerApi.ts delete mode 100644 src/node/SetupServerCommonApi.ts delete mode 100644 src/node/setupServer.ts diff --git a/src/native/index.ts b/src/native/index.ts index 64fb526a3..c7941bdab 100644 --- a/src/native/index.ts +++ b/src/native/index.ts @@ -1,16 +1,16 @@ import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' -import type { RequestHandler } from '~/core/handlers/RequestHandler' -import { SetupServerCommonApi } from '../node/SetupServerCommonApi' +import { SetupServerCommonApi } from '../node/setup-server-common' +import { type AnyHandler } from '~/core/new/handlers-controller' /** * Sets up a requests interception in React Native with the given request handlers. - * @param {RequestHandler[]} handlers List of request handlers. + * @param {Array} handlers List of request handlers. * * @see {@link https://mswjs.io/docs/api/setup-server `setupServer()` API reference} */ export function setupServer( - ...handlers: Array + ...handlers: Array ): SetupServerCommonApi { // Provision request interception via patching the `XMLHttpRequest` class only // in React Native. There is no `http`/`https` modules in that environment. diff --git a/src/node/SetupServerApi.ts b/src/node/SetupServerApi.ts deleted file mode 100644 index e8c83cd14..000000000 --- a/src/node/SetupServerApi.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { AsyncLocalStorage } from 'node:async_hooks' -import type { HttpRequestEventMap, Interceptor } from '@mswjs/interceptors' -import { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest' -import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' -import { FetchInterceptor } from '@mswjs/interceptors/fetch' -import { HandlersController } from '~/core/SetupApi' -import type { RequestHandler } from '~/core/handlers/RequestHandler' -import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' -import type { SetupServer } from './glossary' -import { SetupServerCommonApi } from './SetupServerCommonApi' - -const store = new AsyncLocalStorage() - -type RequestHandlersContext = { - initialHandlers: Array - handlers: Array -} - -/** - * A handlers controller that utilizes `AsyncLocalStorage` in Node.js - * to prevent the request handlers list from being a shared state - * across multiple tests. - */ -class AsyncHandlersController implements HandlersController { - private rootContext: RequestHandlersContext - - constructor(initialHandlers: Array) { - this.rootContext = { initialHandlers, handlers: [] } - } - - get context(): RequestHandlersContext { - return store.getStore() || this.rootContext - } - - public prepend(runtimeHandlers: Array) { - this.context.handlers.unshift(...runtimeHandlers) - } - - public reset(nextHandlers: Array) { - const context = this.context - context.handlers = [] - context.initialHandlers = - nextHandlers.length > 0 ? nextHandlers : context.initialHandlers - } - - public currentHandlers(): Array { - const { initialHandlers, handlers } = this.context - return handlers.concat(initialHandlers) - } -} -export class SetupServerApi - extends SetupServerCommonApi - implements SetupServer -{ - constructor( - handlers: Array, - interceptors: Array> = [ - new ClientRequestInterceptor(), - new XMLHttpRequestInterceptor(), - new FetchInterceptor(), - ], - ) { - super(interceptors, handlers) - - this.handlersController = new AsyncHandlersController(handlers) - } - - public boundary, R>( - callback: (...args: Args) => R, - ): (...args: Args) => R { - return (...args: Args): R => { - return store.run( - { - initialHandlers: this.handlersController.currentHandlers(), - handlers: [], - }, - callback, - ...args, - ) - } - } - - public close(): void { - super.close() - store.disable() - } -} diff --git a/src/node/SetupServerCommonApi.ts b/src/node/SetupServerCommonApi.ts deleted file mode 100644 index c5581ffbc..000000000 --- a/src/node/SetupServerCommonApi.ts +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @note This API is extended by both "msw/node" and "msw/native" - * so be minding about the things you import! - */ -import type { RequiredDeep } from 'type-fest' -import { invariant } from 'outvariant' -import { - BatchInterceptor, - InterceptorReadyState, - type HttpRequestEventMap, - type Interceptor, -} from '@mswjs/interceptors' -import type { LifeCycleEventsMap, SharedOptions } from '~/core/sharedOptions' -import { SetupApi } from '~/core/SetupApi' -import { handleRequest } from '~/core/utils/handleRequest' -import type { RequestHandler } from '~/core/handlers/RequestHandler' -import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' -import { mergeRight } from '~/core/utils/internal/mergeRight' -import { InternalError, devUtils } from '~/core/utils/internal/devUtils' -import type { SetupServerCommon } from './glossary' -import { handleWebSocketEvent } from '~/core/ws/handleWebSocketEvent' -import { webSocketInterceptor } from '~/core/ws/webSocketInterceptor' -import { isHandlerKind } from '~/core/utils/internal/isHandlerKind' - -const DEFAULT_LISTEN_OPTIONS: RequiredDeep = { - onUnhandledRequest: 'warn', -} - -export class SetupServerCommonApi - extends SetupApi - implements SetupServerCommon -{ - protected readonly interceptor: BatchInterceptor< - Array>, - HttpRequestEventMap - > - private resolvedOptions: RequiredDeep - - constructor( - interceptors: Array>, - handlers: Array, - ) { - super(...handlers) - - this.interceptor = new BatchInterceptor({ - name: 'setup-server', - interceptors, - }) - - this.resolvedOptions = {} as RequiredDeep - } - - /** - * Subscribe to all requests that are using the interceptor object - */ - private init(): void { - this.interceptor.on( - 'request', - async ({ request, requestId, controller }) => { - const response = await handleRequest( - request, - requestId, - this.handlersController - .currentHandlers() - .filter(isHandlerKind('RequestHandler')), - this.resolvedOptions, - this.emitter, - { - onPassthroughResponse(request) { - const acceptHeader = request.headers.get('accept') - - /** - * @note Remove the internal bypass request header. - * In the browser, this is done by the worker script. - * In Node.js, it has to be done here. - */ - if (acceptHeader) { - const nextAcceptHeader = acceptHeader.replace( - /(,\s+)?msw\/passthrough/, - '', - ) - - if (nextAcceptHeader) { - request.headers.set('accept', nextAcceptHeader) - } else { - request.headers.delete('accept') - } - } - }, - }, - ) - - if (response) { - controller.respondWith(response) - } - - return - }, - ) - - this.interceptor.on('unhandledException', ({ error }) => { - if (error instanceof InternalError) { - throw error - } - }) - - this.interceptor.on( - 'response', - ({ response, isMockedResponse, request, requestId }) => { - this.emitter.emit( - isMockedResponse ? 'response:mocked' : 'response:bypass', - { - response, - request, - requestId, - }, - ) - }, - ) - - // Preconfigure the WebSocket interception but don't enable it just yet. - // It will be enabled when the server starts. - handleWebSocketEvent({ - getUnhandledRequestStrategy: () => { - return this.resolvedOptions.onUnhandledRequest - }, - getHandlers: () => { - return this.handlersController.currentHandlers() - }, - onMockedConnection: () => {}, - onPassthroughConnection: () => {}, - }) - } - - public listen(options: Partial = {}): void { - this.resolvedOptions = mergeRight( - DEFAULT_LISTEN_OPTIONS, - options, - ) as RequiredDeep - - // Apply the interceptor when starting the server. - // Attach the event listeners to the interceptor here - // so they get re-attached whenever `.listen()` is called. - this.interceptor.apply() - this.init() - this.subscriptions.push(() => this.interceptor.dispose()) - - // Apply the WebSocket interception. - webSocketInterceptor.apply() - this.subscriptions.push(() => webSocketInterceptor.dispose()) - - // Assert that the interceptor has been applied successfully. - // Also guards us from forgetting to call "interceptor.apply()" - // as a part of the "listen" method. - invariant( - [InterceptorReadyState.APPLYING, InterceptorReadyState.APPLIED].includes( - this.interceptor.readyState, - ), - devUtils.formatMessage( - 'Failed to start "setupServer": the interceptor failed to apply. This is likely an issue with the library and you should report it at "%s".', - ), - 'https://github.com/mswjs/msw/issues/new/choose', - ) - } - - public close(): void { - this.dispose() - } -} diff --git a/src/node/glossary.ts b/src/node/glossary.ts index 29f1a1598..c72916251 100644 --- a/src/node/glossary.ts +++ b/src/node/glossary.ts @@ -1,5 +1,5 @@ import type { PartialDeep } from 'type-fest' -import { AnyHandler } from '~/core' +import { type AnyHandler } from '~/core/new/handlers-controller' import type { LifeCycleEventEmitter, LifeCycleEventsMap, diff --git a/src/node/index.ts b/src/node/index.ts index d9b2ea46c..8ccac8652 100644 --- a/src/node/index.ts +++ b/src/node/index.ts @@ -1,3 +1,3 @@ export type { SetupServer } from './glossary' -export { SetupServerApi } from './SetupServerApi' -export { setupServer } from './setupServer' +export { setupServer, SetupServerApi } from './setup-server' +export { SetupServerCommonApi } from './setup-server-common' diff --git a/src/node/setupServer.ts b/src/node/setupServer.ts deleted file mode 100644 index cb2ee7ec4..000000000 --- a/src/node/setupServer.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { RequestHandler } from '~/core/handlers/RequestHandler' -import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' -import { SetupServerApi } from './SetupServerApi' - -/** - * Sets up a requests interception in Node.js with the given request handlers. - * @param {RequestHandler[]} handlers List of request handlers. - * - * @see {@link https://mswjs.io/docs/api/setup-server `setupServer()` API reference} - */ -export const setupServer = ( - ...handlers: Array -): SetupServerApi => { - return new SetupServerApi(handlers) -} From 92d4fb7174eb35be492b27ed783d844b15c850d9 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Sun, 11 Jan 2026 14:27:24 +0100 Subject: [PATCH 06/68] chore: comment on the `WebSocketInterceptor` type error --- src/node/setup-server.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/node/setup-server.ts b/src/node/setup-server.ts index 1151ed7b2..2d5c0fc9f 100644 --- a/src/node/setup-server.ts +++ b/src/node/setup-server.ts @@ -17,7 +17,13 @@ export function setupServer(...handlers: Array): SetupServerApi { new ClientRequestInterceptor(), new XMLHttpRequestInterceptor(), new FetchInterceptor(), - new WebSocketInterceptor(), + /** + * @fixme WebSocketInterceptor is in a browser-only export of Interceptors + * while the Interceptor class imported from the root module points to `lib/node`. + * An absolute madness to solve as it requires to duplicate the build config we have + * in MSW: shared core, CJS/ESM patching, .d.ts patching... + */ + new WebSocketInterceptor() as any, ]) } From 28d69b4836568234d33c2d8de547f865e3472c78 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 13 Jan 2026 12:00:55 +0100 Subject: [PATCH 07/68] fix: annotate network frames on source level as unknown --- src/core/new/define-network.ts | 9 ++++----- src/core/new/frames/http-frame.ts | 2 +- src/core/new/sources/interceptor-source.ts | 4 +--- src/core/new/sources/network-source.ts | 17 ++++++++--------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index 1a04864b0..40b04fc97 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -42,13 +42,12 @@ export function defineNetwork(options: DefineNetworkOptions): NetworkApi { await Promise.all( options.sources.map(async (source) => { source.on('frame', async ({ data: frame }) => { - /** - * @fixme Rettime has trouble typing `.on` when the emitter - * has a union of eventmap types. Add a type test and a runtime test - * for this use case (piping events). - */ frame.events.on((event) => events.emit(event)) + /** + * @fixme Handler filtering on each frame is expensive. + * Refactor the way we store handlers into a Map>. + */ const handlerPredicate = frame.protocol === 'http' ? isHandlerKind('RequestHandler') diff --git a/src/core/new/frames/http-frame.ts b/src/core/new/frames/http-frame.ts index 9838f4b4f..c5ece34dc 100644 --- a/src/core/new/frames/http-frame.ts +++ b/src/core/new/frames/http-frame.ts @@ -13,7 +13,7 @@ interface HttpNetworkFrameOptions { request: Request } -type HttpNetworkFrameEventMap = { +export type HttpNetworkFrameEventMap = { 'request:start': TypedEvent<{ requestId: string request: Request diff --git a/src/core/new/sources/interceptor-source.ts b/src/core/new/sources/interceptor-source.ts index f20701fd0..bc71472f3 100644 --- a/src/core/new/sources/interceptor-source.ts +++ b/src/core/new/sources/interceptor-source.ts @@ -22,9 +22,7 @@ export interface InterceptorSourceOptions { /** * Create a network source from the given list of interceptors. */ -export class InterceptorSource extends NetworkSource< - HttpNetworkFrame | WebSocketNetworkFrame -> { +export class InterceptorSource extends NetworkSource { #interceptor: BatchInterceptor< InterceptorSourceOptions['interceptors'], HttpRequestEventMap | WebSocketEventMap diff --git a/src/core/new/sources/network-source.ts b/src/core/new/sources/network-source.ts index cca40956e..194074cf9 100644 --- a/src/core/new/sources/network-source.ts +++ b/src/core/new/sources/network-source.ts @@ -1,15 +1,14 @@ import { Emitter, TypedEvent } from 'rettime' -import { type HttpNetworkFrame } from '../frames/http-frame' -import { type WebSocketNetworkFrame } from '../frames/websocket-frame' +import { type NetworkFrame } from '../frames/network-frame' -export type NetworkFrame = HttpNetworkFrame | WebSocketNetworkFrame +type AnyNetworkFrame = NetworkFrame -type NetworkSourceEventMap = { - frame: TypedEvent +type NetworkSourceEventMap = { + frame: TypedEvent } -export abstract class NetworkSource { - protected emitter: Emitter> +export abstract class NetworkSource { + protected emitter: Emitter constructor() { this.emitter = new Emitter() @@ -17,11 +16,11 @@ export abstract class NetworkSource { public abstract enable(): Promise - public async queue(frame: Frame): Promise { + public async queue(frame: AnyNetworkFrame): Promise { await this.emitter.emitAsPromise(new TypedEvent('frame', { data: frame })) } - public on>( + public on( type: Type, listener: Emitter.ListenerType, ): void { From c7bc89e80772d6d42dbfc192318b25452cf883b1 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 13 Jan 2026 12:32:36 +0100 Subject: [PATCH 08/68] chore: use instanceof checks for frame handling --- src/core/new/compat.ts | 27 ++++++++++++++++++-------- src/core/new/define-network.ts | 2 +- src/core/new/on-unhandled-frame.ts | 12 ++++++++---- src/core/new/sources/network-source.ts | 2 +- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/core/new/compat.ts b/src/core/new/compat.ts index 7b72bd70e..f7018b3fe 100644 --- a/src/core/new/compat.ts +++ b/src/core/new/compat.ts @@ -2,6 +2,7 @@ * Collection of helpers for briding the compatibility between the old and the new APIs. */ import { Emitter } from 'rettime' +import { invariant } from 'outvariant' import { Emitter as LegacyEmitter, EventMap as LegacyEventMap, @@ -11,6 +12,8 @@ import { onUnhandledFrame, type UnhandledFrameCallback, } from './on-unhandled-frame' +import { HttpNetworkFrame } from './frames/http-frame' +import { WebSocketNetworkFrame } from './frames/websocket-frame' export function toLegacyEmitter( emitter: Emitter, @@ -19,7 +22,7 @@ export function toLegacyEmitter( legacy .addListener('newListener', (type, listener) => { - emitter.on(type as any, (event) => listener(event.data)) + emitter.on(type as string, (event) => listener(event.data)) }) .addListener('removeListener', (type, listener) => { emitter.removeListener(type as any, listener) @@ -40,14 +43,22 @@ export function fromLegacyOnUnhandledRequest( if (typeof legacyOnUnhandledRequestStrategy === 'function') { const request = - frame.protocol === 'http' + frame instanceof HttpNetworkFrame ? frame.data.request - : new Request(frame.data.connection.client.url, { - headers: { - connection: 'upgrade', - upgrade: 'websocket', - }, - }) + : frame instanceof WebSocketNetworkFrame + ? new Request(frame.data.connection.client.url, { + headers: { + connection: 'upgrade', + upgrade: 'websocket', + }, + }) + : null + + invariant( + request != null, + 'Failed to coerce a network frame to a legacy `onUnhandledRequest` strategy: unknown frame protocol "%s"', + frame.protocol, + ) return legacyOnUnhandledRequestStrategy(request, { warning: defaults.warn, diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index 40b04fc97..78c00d3ac 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -21,7 +21,7 @@ export interface DefineNetworkOptions { export interface NetworkApi extends NetworkHandlersApi { enable: () => Promise disable: () => Promise - events: Emitter + events: Emitter /** @fixme Infer event maps from sources */ } export interface NetworkHandlersApi { diff --git a/src/core/new/on-unhandled-frame.ts b/src/core/new/on-unhandled-frame.ts index c298d2aeb..1e99fb301 100644 --- a/src/core/new/on-unhandled-frame.ts +++ b/src/core/new/on-unhandled-frame.ts @@ -1,6 +1,7 @@ import { isCommonAssetRequest } from '../isCommonAssetRequest' import { devUtils, InternalError } from '../utils/internal/devUtils' -import { type NetworkFrame } from './sources/network-source' +import { HttpNetworkFrame } from './frames/http-frame' +import { type AnyNetworkFrame } from './sources/network-source' export type UnhandledFrameHandle = | UnhandledFrameStrategy @@ -9,7 +10,7 @@ export type UnhandledFrameHandle = export type UnhandledFrameStrategy = 'bypass' | 'warn' | 'error' export type UnhandledFrameCallback = (args: { - frame: NetworkFrame + frame: AnyNetworkFrame defaults: UnhandledFrameDefaults }) => Promise | void @@ -19,11 +20,14 @@ export type UnhandledFrameDefaults = { } export async function onUnhandledFrame( - frame: NetworkFrame, + frame: AnyNetworkFrame, handle: UnhandledFrameHandle, ): Promise { // Ignore unhandled common HTTP assets. - if (frame.protocol === 'http' && isCommonAssetRequest(frame.data.request)) { + if ( + frame instanceof HttpNetworkFrame && + isCommonAssetRequest(frame.data.request) + ) { return } diff --git a/src/core/new/sources/network-source.ts b/src/core/new/sources/network-source.ts index 194074cf9..158b7d560 100644 --- a/src/core/new/sources/network-source.ts +++ b/src/core/new/sources/network-source.ts @@ -1,7 +1,7 @@ import { Emitter, TypedEvent } from 'rettime' import { type NetworkFrame } from '../frames/network-frame' -type AnyNetworkFrame = NetworkFrame +export type AnyNetworkFrame = NetworkFrame type NetworkSourceEventMap = { frame: TypedEvent From 9caaf66f9df1f627018a2eca36f671e783a6d5b2 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 13 Jan 2026 12:35:57 +0100 Subject: [PATCH 09/68] chore: ignore `BatchInterceptor` listener type inference issue --- src/core/new/sources/interceptor-source.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/new/sources/interceptor-source.ts b/src/core/new/sources/interceptor-source.ts index bc71472f3..22ffeebbf 100644 --- a/src/core/new/sources/interceptor-source.ts +++ b/src/core/new/sources/interceptor-source.ts @@ -43,10 +43,13 @@ export class InterceptorSource extends NetworkSource { public async enable(): Promise { this.#interceptor.apply() + /** + * @todo @fixme BatchInterceptor infers event types but not listener types. + */ this.#interceptor - .on('request', this.#handleRequest.bind(this)) - .on('response', this.#handleResponse.bind(this)) - .on('connection', this.#handleWebSocketConnection.bind(this)) + .on('request', this.#handleRequest.bind(this) as any) + .on('response', this.#handleResponse.bind(this) as any) + .on('connection', this.#handleWebSocketConnection.bind(this) as any) } public async disable(): Promise { From 3f4b90f38242209eb3481d17000555f17974ddab Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 13 Jan 2026 12:37:29 +0100 Subject: [PATCH 10/68] chore: do not reference `~/core` in core --- src/core/new/compat.ts | 2 +- src/core/new/frames/http-frame.ts | 8 ++++---- src/core/new/frames/websocket-frame.ts | 2 +- src/core/new/handlers-controller.ts | 4 ++-- src/core/new/sources/interceptor-source.ts | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/new/compat.ts b/src/core/new/compat.ts index f7018b3fe..56646f7c8 100644 --- a/src/core/new/compat.ts +++ b/src/core/new/compat.ts @@ -7,7 +7,7 @@ import { Emitter as LegacyEmitter, EventMap as LegacyEventMap, } from 'strict-event-emitter' -import { type UnhandledRequestStrategy } from '~/core/utils/request/onUnhandledRequest' +import { type UnhandledRequestStrategy } from '../utils/request/onUnhandledRequest' import { onUnhandledFrame, type UnhandledFrameCallback, diff --git a/src/core/new/frames/http-frame.ts b/src/core/new/frames/http-frame.ts index c5ece34dc..36ff65aa9 100644 --- a/src/core/new/frames/http-frame.ts +++ b/src/core/new/frames/http-frame.ts @@ -1,11 +1,11 @@ import { TypedEvent } from 'rettime' import { createRequestId } from '@mswjs/interceptors' import { NetworkFrame, NetworkFrameResolutionContext } from './network-frame' -import { toPublicUrl } from '~/core/utils/request/toPublicUrl' -import { type HttpHandler } from '~/core/handlers/HttpHandler' +import { toPublicUrl } from '../../utils/request/toPublicUrl' +import { type HttpHandler } from '../../handlers/HttpHandler' import { until } from 'until-async' -import { executeHandlers } from '~/core/utils/executeHandlers' -import { storeResponseCookies } from '~/core/utils/request/storeResponseCookies' +import { executeHandlers } from '../../utils/executeHandlers' +import { storeResponseCookies } from '../../utils/request/storeResponseCookies' import { isPassthroughResponse, shouldBypassRequest } from '../request-utils' interface HttpNetworkFrameOptions { diff --git a/src/core/new/frames/websocket-frame.ts b/src/core/new/frames/websocket-frame.ts index 70a62ace6..ce66d789c 100644 --- a/src/core/new/frames/websocket-frame.ts +++ b/src/core/new/frames/websocket-frame.ts @@ -1,6 +1,6 @@ import { TypedEvent } from 'rettime' import { type WebSocketConnectionData } from '@mswjs/interceptors/WebSocket' -import { type WebSocketHandler } from '~/core/handlers/WebSocketHandler' +import { type WebSocketHandler } from '../../handlers/WebSocketHandler' import { NetworkFrame, type NetworkFrameResolutionContext, diff --git a/src/core/new/handlers-controller.ts b/src/core/new/handlers-controller.ts index d66e912eb..a2920d585 100644 --- a/src/core/new/handlers-controller.ts +++ b/src/core/new/handlers-controller.ts @@ -1,6 +1,6 @@ import { invariant } from 'outvariant' -import { type HttpHandler } from '~/core/handlers/HttpHandler' -import { type WebSocketHandler } from '~/core/handlers/WebSocketHandler' +import { type HttpHandler } from '../handlers/HttpHandler' +import { type WebSocketHandler } from '../handlers/WebSocketHandler' import { devUtils } from '../utils/internal/devUtils' export type AnyHandler = HttpHandler | WebSocketHandler diff --git a/src/core/new/sources/interceptor-source.ts b/src/core/new/sources/interceptor-source.ts index 22ffeebbf..115ab10ba 100644 --- a/src/core/new/sources/interceptor-source.ts +++ b/src/core/new/sources/interceptor-source.ts @@ -10,7 +10,7 @@ import type { WebSocketEventMap, } from '@mswjs/interceptors/WebSocket' import { NetworkSource } from './network-source' -import { InternalError } from '~/core/utils/internal/devUtils' +import { InternalError } from '../../utils/internal/devUtils' import { HttpNetworkFrame } from '../frames/http-frame' import { WebSocketNetworkFrame } from '../frames/websocket-frame' import { deleteRequestPassthroughHeader } from '../request-utils' From d3659be8b8040f7622637a671f1d9ce336877dfd Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 13 Jan 2026 16:16:55 +0100 Subject: [PATCH 11/68] chore: use `rettime` for life cycle events --- src/browser/setupWorker/setupWorker.ts | 5 +- src/core/SetupApi.ts | 18 +-- src/core/new/compat.ts | 21 --- src/core/new/frames/http-frame.ts | 123 ++++++++++++------ src/core/new/handlers-controller.ts | 4 +- src/core/new/on-unhandled-frame.ts | 2 +- src/core/new/sources/interceptor-source.ts | 25 ++-- src/core/sharedOptions.ts | 57 +------- src/node/async-handlers-controller.ts | 7 +- src/node/glossary.ts | 12 +- src/node/setup-server-common.ts | 13 +- .../life-cycle-events/on.node.test.ts | 4 +- .../ws-api/on-unhandled-request/error.test.ts | 8 +- .../ws-api/on-unhandled-request/warn.test.ts | 8 +- 14 files changed, 147 insertions(+), 160 deletions(-) diff --git a/src/browser/setupWorker/setupWorker.ts b/src/browser/setupWorker/setupWorker.ts index 66748eb26..291b4e5d6 100644 --- a/src/browser/setupWorker/setupWorker.ts +++ b/src/browser/setupWorker/setupWorker.ts @@ -13,7 +13,6 @@ import { createStartHandler } from './start/createStartHandler' import { devUtils } from '~/core/utils/internal/devUtils' import { SetupApi } from '~/core/SetupApi' import { mergeRight } from '~/core/utils/internal/mergeRight' -import type { LifeCycleEventsMap } from '~/core/sharedOptions' import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' import { webSocketInterceptor } from '~/core/ws/webSocketInterceptor' import { handleWebSocketEvent } from '~/core/ws/handleWebSocketEvent' @@ -23,9 +22,11 @@ import { createFallbackRequestListener } from './start/createFallbackRequestList import { printStartMessage } from './start/utils/printStartMessage' import { printStopMessage } from './stop/utils/printStopMessage' import { supportsServiceWorker } from '../utils/supports' +import type { HttpNetworkFrameEventMap } from '~/core/new/frames/http-frame' +import type { WebSocketNetworkFrameEventMap } from '~/core/new/frames/websocket-frame' export class SetupWorkerApi - extends SetupApi + extends SetupApi implements SetupWorker { private context: SetupWorkerInternalContext diff --git a/src/core/SetupApi.ts b/src/core/SetupApi.ts index e908e5994..e9e3024f0 100644 --- a/src/core/SetupApi.ts +++ b/src/core/SetupApi.ts @@ -1,5 +1,5 @@ import { invariant } from 'outvariant' -import { EventMap, Emitter } from 'strict-event-emitter' +import { Emitter, type DefaultEventMap } from 'rettime' import { RequestHandler } from './handlers/RequestHandler' import { LifeCycleEventEmitter } from './sharedOptions' import { devUtils } from './utils/internal/devUtils' @@ -44,12 +44,14 @@ export class InMemoryHandlersController implements HandlersController { /** * Generic class for the mock API setup. */ -export abstract class SetupApi extends Disposable { +export abstract class SetupApi< + EventMap extends DefaultEventMap, +> extends Disposable { protected handlersController: HandlersController - protected readonly emitter: Emitter - protected readonly publicEmitter: Emitter + protected readonly emitter: Emitter + protected readonly publicEmitter: Emitter - public readonly events: LifeCycleEventEmitter + public readonly events: LifeCycleEventEmitter constructor(...initialHandlers: Array) { super() @@ -63,8 +65,8 @@ export abstract class SetupApi extends Disposable { this.handlersController = new InMemoryHandlersController(initialHandlers) - this.emitter = new Emitter() - this.publicEmitter = new Emitter() + this.emitter = new Emitter() + this.publicEmitter = new Emitter() pipeEvents(this.emitter, this.publicEmitter) this.events = this.createLifeCycleEvents() @@ -111,7 +113,7 @@ export abstract class SetupApi extends Disposable { return toReadonlyArray(this.handlersController.currentHandlers()) } - private createLifeCycleEvents(): LifeCycleEventEmitter { + private createLifeCycleEvents(): LifeCycleEventEmitter { return { on: (...args: any[]) => { return (this.publicEmitter.on as any)(...args) diff --git a/src/core/new/compat.ts b/src/core/new/compat.ts index 56646f7c8..4ea424d32 100644 --- a/src/core/new/compat.ts +++ b/src/core/new/compat.ts @@ -1,12 +1,7 @@ /** * Collection of helpers for briding the compatibility between the old and the new APIs. */ -import { Emitter } from 'rettime' import { invariant } from 'outvariant' -import { - Emitter as LegacyEmitter, - EventMap as LegacyEventMap, -} from 'strict-event-emitter' import { type UnhandledRequestStrategy } from '../utils/request/onUnhandledRequest' import { onUnhandledFrame, @@ -15,22 +10,6 @@ import { import { HttpNetworkFrame } from './frames/http-frame' import { WebSocketNetworkFrame } from './frames/websocket-frame' -export function toLegacyEmitter( - emitter: Emitter, -): LegacyEmitter { - const legacy = new LegacyEmitter() - - legacy - .addListener('newListener', (type, listener) => { - emitter.on(type as string, (event) => listener(event.data)) - }) - .addListener('removeListener', (type, listener) => { - emitter.removeListener(type as any, listener) - }) - - return legacy -} - export function fromLegacyOnUnhandledRequest( getLegacyValue: () => UnhandledRequestStrategy | undefined, ): UnhandledFrameCallback { diff --git a/src/core/new/frames/http-frame.ts b/src/core/new/frames/http-frame.ts index 36ff65aa9..f64bc2388 100644 --- a/src/core/new/frames/http-frame.ts +++ b/src/core/new/frames/http-frame.ts @@ -1,9 +1,9 @@ import { TypedEvent } from 'rettime' +import { until } from 'until-async' import { createRequestId } from '@mswjs/interceptors' import { NetworkFrame, NetworkFrameResolutionContext } from './network-frame' import { toPublicUrl } from '../../utils/request/toPublicUrl' import { type HttpHandler } from '../../handlers/HttpHandler' -import { until } from 'until-async' import { executeHandlers } from '../../utils/executeHandlers' import { storeResponseCookies } from '../../utils/request/storeResponseCookies' import { isPassthroughResponse, shouldBypassRequest } from '../request-utils' @@ -13,34 +13,82 @@ interface HttpNetworkFrameOptions { request: Request } -export type HttpNetworkFrameEventMap = { - 'request:start': TypedEvent<{ +export class RequestEvent< + DataType extends { requestId: string; request: Request } = { requestId: string request: Request - }> - 'request:match': TypedEvent<{ - requestId: string - request: Request - }> - 'request:unhandled': TypedEvent<{ + }, + ReturnType = void, + EventType extends string = string, +> extends TypedEvent { + public readonly requestId: string + public readonly request: Request + + constructor(type: EventType, data: DataType) { + super(...([type] as any)) + this.requestId = data.requestId + this.request = data.request + } +} + +export class ResponseEvent< + DataType extends { requestId: string request: Request - }> - 'request:end': TypedEvent<{ + response: Response + } = { requestId: string request: Request - }> - response: TypedEvent<{ + response: Response + }, + ReturnType = void, + EventType extends string = string, +> extends TypedEvent { + public readonly requestId: string + public readonly request: Request + public readonly response: Response + + constructor(type: EventType, data: DataType) { + super(...([type] as any)) + this.requestId = data.requestId + this.request = data.request + this.response = data.response + } +} + +export class UnhandledExceptionEvent< + DataType extends { + error: Error requestId: string request: Request - response: Response - isMockedResponse: boolean - }> - unhandledException: TypedEvent<{ + } = { error: Error requestId: string request: Request - }> + }, + ReturnType = void, + EventType extends string = string, +> extends TypedEvent { + public readonly error: Error + public readonly requestId: string + public readonly request: Request + + constructor(type: EventType, data: DataType) { + super(...([type] as any)) + this.error = data.error + this.requestId = data.requestId + this.request = data.request + } +} + +export type HttpNetworkFrameEventMap = { + 'request:start': RequestEvent + 'request:match': RequestEvent + 'request:unhandled': RequestEvent + 'request:end': RequestEvent + 'response:mocked': ResponseEvent + 'response:bypass': ResponseEvent + unhandledException: UnhandledExceptionEvent } export abstract class HttpNetworkFrame extends NetworkFrame< @@ -81,9 +129,7 @@ export abstract class HttpNetworkFrame extends NetworkFrame< ? null : request.clone() - this.events.emit( - new TypedEvent('request:start', { data: { requestId, request } }), - ) + this.events.emit(new RequestEvent('request:start', { requestId, request })) // Requests wrapped in explicit `bypass(request)`. if (shouldBypassRequest(request)) { @@ -104,12 +150,10 @@ export abstract class HttpNetworkFrame extends NetworkFrame< if (lookupError != null) { this.events.emit( - new TypedEvent('unhandledException', { - data: { - error: lookupError, - requestId, - request, - }, + new UnhandledExceptionEvent('unhandledException', { + error: lookupError, + requestId, + request, }), ) @@ -120,14 +164,16 @@ export abstract class HttpNetworkFrame extends NetworkFrame< // No matching handlers. if (lookupResult == null) { this.events.emit( - new TypedEvent('request:unhandled', { - data: { requestId, request }, + new RequestEvent('request:unhandled', { + requestId, + request, }), ) this.events.emit( - new TypedEvent('request:end', { - data: { requestId, request }, + new RequestEvent('request:end', { + requestId, + request, }), ) @@ -140,8 +186,9 @@ export abstract class HttpNetworkFrame extends NetworkFrame< // Handlers that returned no mocked response. if (response == null) { this.events.emit( - new TypedEvent('request:end', { - data: { requestId, request }, + new RequestEvent('request:end', { + requestId, + request, }), ) @@ -152,8 +199,9 @@ export abstract class HttpNetworkFrame extends NetworkFrame< // Handlers that returned explicit `passthrough()`. if (isPassthroughResponse(response)) { this.events.emit( - new TypedEvent('request:end', { - data: { requestId, request }, + new RequestEvent('request:end', { + requestId, + request, }), ) @@ -172,8 +220,9 @@ export abstract class HttpNetworkFrame extends NetworkFrame< this.respondWith(response.clone()) this.events.emit( - new TypedEvent('request:end', { - data: { requestId, request }, + new RequestEvent('request:end', { + requestId, + request, }), ) diff --git a/src/core/new/handlers-controller.ts b/src/core/new/handlers-controller.ts index a2920d585..c50e32635 100644 --- a/src/core/new/handlers-controller.ts +++ b/src/core/new/handlers-controller.ts @@ -14,7 +14,7 @@ export abstract class HandlersController { invariant( validateHandlers(initialHandlers), devUtils.formatMessage( - 'Failed to create a handlers controller: invalid handlers. Did you forget to spread the handlers array?', + '[MSW] Failed to apply given request handlers: invalid input. Did you forget to spread the request handlers Array?', ), ) } @@ -25,7 +25,7 @@ export abstract class HandlersController { invariant( validateHandlers(nextHandlers), devUtils.formatMessage( - 'Failed to prepend runtime handlers: invalid handlers. Did you forget to spread the handlers array?', + '[MSW] Failed to call "use()" with the given request handlers: invalid input. Did you forget to spread the array of request handlers?', ), ) } diff --git a/src/core/new/on-unhandled-frame.ts b/src/core/new/on-unhandled-frame.ts index 1e99fb301..f77d1e5d4 100644 --- a/src/core/new/on-unhandled-frame.ts +++ b/src/core/new/on-unhandled-frame.ts @@ -36,7 +36,7 @@ export async function onUnhandledFrame( return } - const message = frame.getUnhandledFrameMessage() + const message = await frame.getUnhandledFrameMessage() switch (strategy) { case 'warn': { diff --git a/src/core/new/sources/interceptor-source.ts b/src/core/new/sources/interceptor-source.ts index 115ab10ba..22317e00a 100644 --- a/src/core/new/sources/interceptor-source.ts +++ b/src/core/new/sources/interceptor-source.ts @@ -1,4 +1,3 @@ -import { TypedEvent } from 'rettime' import { BatchInterceptor, Interceptor, @@ -11,7 +10,7 @@ import type { } from '@mswjs/interceptors/WebSocket' import { NetworkSource } from './network-source' import { InternalError } from '../../utils/internal/devUtils' -import { HttpNetworkFrame } from '../frames/http-frame' +import { HttpNetworkFrame, ResponseEvent } from '../frames/http-frame' import { WebSocketNetworkFrame } from '../frames/websocket-frame' import { deleteRequestPassthroughHeader } from '../request-utils' @@ -91,16 +90,18 @@ export class InterceptorSource extends NetworkSource { return } - httpFrame.events.emit( - new TypedEvent('response', { - data: { - requestId, - request, - response, - isMockedResponse, - }, - }), - ) + queueMicrotask(() => { + httpFrame.events.emit( + new ResponseEvent( + isMockedResponse ? 'response:mocked' : 'response:bypass', + { + requestId, + request, + response, + }, + ), + ) + }) } async #handleWebSocketConnection( diff --git a/src/core/sharedOptions.ts b/src/core/sharedOptions.ts index ad7f151a2..683c48c0a 100644 --- a/src/core/sharedOptions.ts +++ b/src/core/sharedOptions.ts @@ -1,4 +1,4 @@ -import type { Emitter } from 'strict-event-emitter' +import type { Emitter, DefaultEventMap } from 'rettime' import type { UnhandledRequestStrategy } from './utils/request/onUnhandledRequest' export interface SharedOptions { @@ -13,54 +13,7 @@ export interface SharedOptions { onUnhandledRequest?: UnhandledRequestStrategy } -export type LifeCycleEventsMap = { - 'request:start': [ - args: { - request: Request - requestId: string - }, - ] - 'request:match': [ - args: { - request: Request - requestId: string - }, - ] - 'request:unhandled': [ - args: { - request: Request - requestId: string - }, - ] - 'request:end': [ - args: { - request: Request - requestId: string - }, - ] - 'response:mocked': [ - args: { - response: Response - request: Request - requestId: string - }, - ] - 'response:bypass': [ - args: { - response: Response - request: Request - requestId: string - }, - ] - unhandledException: [ - args: { - error: Error - request: Request - requestId: string - }, - ] -} - -export type LifeCycleEventEmitter< - EventsMap extends Record, -> = Pick, 'on' | 'removeListener' | 'removeAllListeners'> +export type LifeCycleEventEmitter = Pick< + Emitter, + 'on' | 'removeListener' | 'removeAllListeners' +> diff --git a/src/node/async-handlers-controller.ts b/src/node/async-handlers-controller.ts index ca31fe5f1..2aea5029e 100644 --- a/src/node/async-handlers-controller.ts +++ b/src/node/async-handlers-controller.ts @@ -1,5 +1,8 @@ import { AsyncLocalStorage } from 'node:async_hooks' -import { type AnyHandler, HandlersController } from '~/core/index' +import { + type AnyHandler, + HandlersController, +} from '~/core/new/handlers-controller' export interface AsyncHandlersControllerContext { initialHandlers: Array @@ -23,7 +26,7 @@ export class AsyncHandlersController extends HandlersController { get currentHandlers() { const { initialHandlers, handlers } = this.#getContext() - return [...initialHandlers, ...handlers] + return [...handlers, ...initialHandlers] } public use(nextHandlers: Array): void { diff --git a/src/node/glossary.ts b/src/node/glossary.ts index c72916251..e36004155 100644 --- a/src/node/glossary.ts +++ b/src/node/glossary.ts @@ -1,10 +1,8 @@ import type { PartialDeep } from 'type-fest' +import { type HttpNetworkFrameEventMap } from '~/core/new/frames/http-frame' +import { type WebSocketNetworkFrameEventMap } from '~/core/new/frames/websocket-frame' import { type AnyHandler } from '~/core/new/handlers-controller' -import type { - LifeCycleEventEmitter, - LifeCycleEventsMap, - SharedOptions, -} from '~/core/sharedOptions' +import type { LifeCycleEventEmitter, SharedOptions } from '~/core/sharedOptions' export interface ListenOptions extends SharedOptions {} @@ -57,7 +55,9 @@ export interface SetupServerCommon { * * @see {@link https://mswjs.io/docs/api/life-cycle-events Life-cycle Events API reference} */ - events: LifeCycleEventEmitter + events: LifeCycleEventEmitter< + HttpNetworkFrameEventMap | WebSocketNetworkFrameEventMap + > } export interface SetupServer extends SetupServerCommon { diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts index ecfae93c1..4925761e4 100644 --- a/src/node/setup-server-common.ts +++ b/src/node/setup-server-common.ts @@ -1,15 +1,11 @@ import type { PartialDeep } from 'type-fest' import { Interceptor } from '@mswjs/interceptors' -import { ListenOptions, SetupServerCommon } from './glossary' -import { type LifeCycleEventsMap } from '~/core' +import type { ListenOptions, SetupServerCommon } from './glossary' import { type NetworkApi, defineNetwork } from '~/core/new/define-network' import { type AnyHandler } from '~/core/new/handlers-controller' import { HandlersController } from '~/core/new/handlers-controller' import { InterceptorSource } from '~/core/new/sources/interceptor-source' -import { - fromLegacyOnUnhandledRequest, - toLegacyEmitter, -} from '~/core/new/compat' +import { fromLegacyOnUnhandledRequest } from '~/core/new/compat' export class SetupServerCommonApi implements SetupServerCommon { #listenOptions?: PartialDeep @@ -28,11 +24,14 @@ export class SetupServerCommonApi implements SetupServerCommon { onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { return this.#listenOptions?.onUnhandledRequest || 'warn' }), + context: { + quiet: true, + }, }) } get events() { - return toLegacyEmitter(this.network.events) + return this.network.events } public listen(options?: PartialDeep): void { diff --git a/test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts b/test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts index 00c77d5f0..0e8482851 100644 --- a/test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts +++ b/test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts @@ -14,7 +14,7 @@ const server = setupServer() function spyOnEvents(server: SetupServerApi) { const listener = vi.fn() const wrapListener = (eventName: string, listener: any) => { - return (...args) => listener(eventName, ...args) + return (...args: Array) => listener(eventName, ...args) } server.events.on('request:start', wrapListener('request:start', listener)) @@ -60,7 +60,7 @@ afterAll(async () => { await httpServer.close() }) -test('emits events for a handled request and mocked response', async () => { +test.only('emits events for a handled request and mocked response', async () => { const listener = spyOnEvents(server) const url = httpServer.http.url('/user') await fetch(url) diff --git a/test/node/ws-api/on-unhandled-request/error.test.ts b/test/node/ws-api/on-unhandled-request/error.test.ts index 9c4837d2f..cfe416971 100644 --- a/test/node/ws-api/on-unhandled-request/error.test.ts +++ b/test/node/ws-api/on-unhandled-request/error.test.ts @@ -39,12 +39,12 @@ it( expect(console.error).toHaveBeenCalledWith( `\ -[MSW] Error: intercepted a request without a matching request handler: +[MSW] Error: intercepted a WebSocket connection without a matching event handler: - • GET wss://localhost:4321/ + • wss://localhost:4321/ -If you still wish to intercept this unhandled request, please create a request handler for it. -Read more: https://mswjs.io/docs/http/intercepting-requests`, +If you still wish to intercept this unhandled connection, please create an event handler for it. +Read more: https://mswjs.io/docs/websocket`, ) expect(errorListener).toHaveBeenCalledOnce() diff --git a/test/node/ws-api/on-unhandled-request/warn.test.ts b/test/node/ws-api/on-unhandled-request/warn.test.ts index 401b66d34..fb8b52e89 100644 --- a/test/node/ws-api/on-unhandled-request/warn.test.ts +++ b/test/node/ws-api/on-unhandled-request/warn.test.ts @@ -34,12 +34,12 @@ it( expect(console.warn).toHaveBeenCalledWith( `\ -[MSW] Warning: intercepted a request without a matching request handler: +[MSW] Warning: intercepted a WebSocket connection without a matching event handler: - • GET wss://localhost:4321/ + • wss://localhost:4321/ -If you still wish to intercept this unhandled request, please create a request handler for it. -Read more: https://mswjs.io/docs/http/intercepting-requests`, +If you still wish to intercept this unhandled connection, please create an event handler for it. +Read more: https://mswjs.io/docs/websocket`, ) }), ) From 2ee72e340a274cbdb4687715e85b04e58e328428 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 13 Jan 2026 16:49:09 +0100 Subject: [PATCH 12/68] fix(ts): infer event maps from network sources --- src/browser/setupWorker/glossary.ts | 9 +-- src/core/new/define-network.ts | 98 +++++++++++++++++--------- src/core/new/frames/network-frame.ts | 3 + src/core/new/sources/network-source.ts | 22 ++++-- src/node/setup-server-common.ts | 4 +- test/typings/define-network.test-d.ts | 48 +++++++++++++ 6 files changed, 133 insertions(+), 51 deletions(-) create mode 100644 test/typings/define-network.test-d.ts diff --git a/src/browser/setupWorker/glossary.ts b/src/browser/setupWorker/glossary.ts index 54e05cd29..2c30a0ea2 100644 --- a/src/browser/setupWorker/glossary.ts +++ b/src/browser/setupWorker/glossary.ts @@ -1,11 +1,6 @@ -import { Emitter } from 'strict-event-emitter' import type { HttpRequestEventMap, Interceptor } from '@mswjs/interceptors' import type { DeferredPromise } from '@open-draft/deferred-promise' -import { - LifeCycleEventEmitter, - LifeCycleEventsMap, - SharedOptions, -} from '~/core/sharedOptions' +import { LifeCycleEventEmitter, SharedOptions } from '~/core/sharedOptions' import { RequestHandler } from '~/core/handlers/RequestHandler' import type { RequiredDeep } from '~/core/typeUtils' import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' @@ -22,7 +17,7 @@ export type SetupWorkerInternalContext = { workerPromise: DeferredPromise registration: ServiceWorkerRegistration | undefined getRequestHandlers: () => Array - emitter: Emitter + emitter: LifeCycleEventEmitter keepAliveInterval?: number workerChannel: WorkerChannel fallbackInterceptor?: Interceptor diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index 78c00d3ac..8f0bfbdde 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -1,5 +1,9 @@ -import { Emitter } from 'rettime' -import { type NetworkSource } from './sources/network-source' +import { Emitter, type DefaultEventMap } from 'rettime' +import { + type NetworkSource, + type ExtractSourceEvents, + type AnyNetworkFrame, +} from './sources/network-source' import { type NetworkFrameResolutionContext } from './frames/network-frame' import { onUnhandledFrame, UnhandledFrameHandle } from './on-unhandled-frame' import { isHandlerKind } from '../utils/internal/isHandlerKind' @@ -10,18 +14,34 @@ import { } from './handlers-controller' import { toReadonlyArray } from '../utils/internal/toReadonlyArray' -export interface DefineNetworkOptions { - sources: Array +type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ( + k: infer I, +) => void + ? I + : never + +type MergeEventMaps>> = + UnionToIntersection> extends infer R + ? R extends Record + ? R + : DefaultEventMap + : DefaultEventMap + +export interface DefineNetworkOptions< + Sources extends ReadonlyArray>, +> { + sources: Sources handlers?: Array context?: NetworkFrameResolutionContext controller?: HandlersController onUnhandledFrame?: UnhandledFrameHandle } -export interface NetworkApi extends NetworkHandlersApi { +export interface NetworkApi + extends NetworkHandlersApi { enable: () => Promise disable: () => Promise - events: Emitter /** @fixme Infer event maps from sources */ + events: Emitter } export interface NetworkHandlersApi { @@ -31,8 +51,10 @@ export interface NetworkHandlersApi { listHandlers: () => ReadonlyArray } -export function defineNetwork(options: DefineNetworkOptions): NetworkApi { - const events = new Emitter() +export function defineNetwork< + Sources extends ReadonlyArray>, +>(options: DefineNetworkOptions): NetworkApi> { + const events = new Emitter>() const handlersController = options.controller || new InMemoryHandlersController(options.handlers || []) @@ -41,37 +63,43 @@ export function defineNetwork(options: DefineNetworkOptions): NetworkApi { async enable() { await Promise.all( options.sources.map(async (source) => { - source.on('frame', async ({ data: frame }) => { - frame.events.on((event) => events.emit(event)) + source.on( + 'frame', + async ({ data: frame }: { data: AnyNetworkFrame }) => { + frame.events.on((event) => { + events.emit(event as any) + }) - /** - * @fixme Handler filtering on each frame is expensive. - * Refactor the way we store handlers into a Map>. - */ - const handlerPredicate = - frame.protocol === 'http' - ? isHandlerKind('RequestHandler') - : frame.protocol === 'ws' - ? isHandlerKind('EventHandler') - : () => false + /** + * @fixme Handler filtering on each frame is expensive. + * Refactor the way we store handlers into a Map>. + */ + const handlerPredicate = + frame.protocol === 'http' + ? isHandlerKind('RequestHandler') + : frame.protocol === 'ws' + ? isHandlerKind('EventHandler') + : () => false - const handlers = - handlersController.currentHandlers.filter(handlerPredicate) || [] + const handlers = + handlersController.currentHandlers.filter(handlerPredicate) || + [] - const isHandledFrame = await frame.resolve( - handlers, - options.context, - ) + const isHandledFrame = await frame.resolve( + handlers, + options.context, + ) - if (isHandledFrame === false) { - await onUnhandledFrame( - frame, - options.onUnhandledFrame || 'warn', - ).catch((error) => { - frame.errorWith(error) - }) - } - }) + if (isHandledFrame === false) { + await onUnhandledFrame( + frame, + options.onUnhandledFrame || 'warn', + ).catch((error) => { + frame.errorWith(error) + }) + } + }, + ) await source.enable() }), diff --git a/src/core/new/frames/network-frame.ts b/src/core/new/frames/network-frame.ts index 31fb7abd0..73cd9bf6a 100644 --- a/src/core/new/frames/network-frame.ts +++ b/src/core/new/frames/network-frame.ts @@ -1,6 +1,9 @@ import { Emitter, type DefaultEventMap } from 'rettime' import { type AnyHandler } from '../handlers-controller' +export type ExtractFrameEvents = + Frame extends NetworkFrame ? Events : never + export interface NetworkFrameResolutionContext { baseUrl?: string | URL quiet?: boolean diff --git a/src/core/new/sources/network-source.ts b/src/core/new/sources/network-source.ts index 158b7d560..4183b4ae7 100644 --- a/src/core/new/sources/network-source.ts +++ b/src/core/new/sources/network-source.ts @@ -1,14 +1,22 @@ import { Emitter, TypedEvent } from 'rettime' -import { type NetworkFrame } from '../frames/network-frame' +import { + type NetworkFrame, + type ExtractFrameEvents, +} from '../frames/network-frame' export type AnyNetworkFrame = NetworkFrame -type NetworkSourceEventMap = { - frame: TypedEvent +type NetworkSourceEventMap = { + frame: TypedEvent } -export abstract class NetworkSource { - protected emitter: Emitter +export type ExtractSourceEvents = + Source extends NetworkSource ? ExtractFrameEvents : never + +export abstract class NetworkSource< + Frame extends AnyNetworkFrame = AnyNetworkFrame, +> { + protected emitter: Emitter> constructor() { this.emitter = new Emitter() @@ -16,11 +24,11 @@ export abstract class NetworkSource { public abstract enable(): Promise - public async queue(frame: AnyNetworkFrame): Promise { + public async queue(frame: Frame): Promise { await this.emitter.emitAsPromise(new TypedEvent('frame', { data: frame })) } - public on( + public on>( type: Type, listener: Emitter.ListenerType, ): void { diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts index 4925761e4..efb00c1bf 100644 --- a/src/node/setup-server-common.ts +++ b/src/node/setup-server-common.ts @@ -10,7 +10,7 @@ import { fromLegacyOnUnhandledRequest } from '~/core/new/compat' export class SetupServerCommonApi implements SetupServerCommon { #listenOptions?: PartialDeep - protected network: NetworkApi + protected network: NetworkApi constructor( interceptors: Array>, @@ -31,7 +31,7 @@ export class SetupServerCommonApi implements SetupServerCommon { } get events() { - return this.network.events + return this.network.events as any } public listen(options?: PartialDeep): void { diff --git a/test/typings/define-network.test-d.ts b/test/typings/define-network.test-d.ts new file mode 100644 index 000000000..3113bd533 --- /dev/null +++ b/test/typings/define-network.test-d.ts @@ -0,0 +1,48 @@ +import { DefaultEventMap, Emitter, TypedEvent } from 'rettime' +import { defineNetwork } from '../../src/core/new/define-network' +import { NetworkSource } from '../../src/core/new/sources/network-source' +import { NetworkFrame } from '../../src/core/new/frames/network-frame' + +it('uses an empty event map when no sources were provided', () => { + expectTypeOf( + defineNetwork({ + sources: [], + }).events, + ).toExtend> +}) + +it('infers event map type from a single source', () => { + type HttpFrame = NetworkFrame<'http', void, { hello: TypedEvent<'world'> }> + + class HttpSource extends NetworkSource { + public async enable() {} + } + + defineNetwork({ + sources: [new HttpSource()], + }).events.on((event) => { + expectTypeOf(event.type).toExtend<'hello'>() + expectTypeOf(event.data).toExtend<'world'>() + expectTypeOf(event.data).not.toBeAny() + }) +}) + +it('combines event maps from different sources', () => { + type HttpFrame = NetworkFrame<'http', void, { hello: TypedEvent<'world'> }> + class HttpSource extends NetworkSource { + public async enable() {} + } + + type SmtpFrame = NetworkFrame<'smtp', void, { goodbye: TypedEvent<'cosmos'> }> + class SmtpSource extends NetworkSource { + public async enable() {} + } + + defineNetwork({ + sources: [new HttpSource(), new SmtpSource()], + }).events.on((event) => { + expectTypeOf(event.type).toExtend<'hello' | 'goodbye'>() + expectTypeOf(event.data).toExtend<'world' | 'cosmos'>() + expectTypeOf(event.data).not.toBeAny() + }) +}) From c47b26fd914336982318f90f4fa07783f41360df Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Tue, 13 Jan 2026 17:09:03 +0100 Subject: [PATCH 13/68] chore: remove old `setupWorker` --- src/browser/{setupWorker => }/glossary.ts | 2 +- src/browser/index.ts | 5 +- ...node.test.ts => setup-worker.node.test.ts} | 6 +- src/browser/setup-worker.ts | 6 +- src/browser/setupWorker/setupWorker.ts | 185 ------------------ .../start/createFallbackRequestListener.ts | 71 ------- .../start/createRequestListener.ts | 138 ------------- .../start/createResponseListener.ts | 57 ------ .../setupWorker/start/createStartHandler.ts | 137 ------------- .../setupWorker/start/utils/enableMocking.ts | 30 --- .../start/utils/getWorkerByRegistration.ts | 25 --- .../start/utils/getWorkerInstance.ts | 97 --------- .../start/utils/prepareStartHandler.test.ts | 59 ------ .../start/utils/prepareStartHandler.ts | 44 ----- .../start/utils/printStartMessage.test.ts | 84 -------- .../start/utils/printStartMessage.ts | 51 ----- .../start/utils/validateWorkerScope.ts | 18 -- .../stop/utils/printStopMessage.test.ts | 26 --- .../stop/utils/printStopMessage.ts | 13 -- src/browser/sources/service-worker-source.ts | 6 +- src/browser/utils/checkWorkerIntegrity.ts | 42 ---- src/browser/utils/deserializeRequest.ts | 2 +- src/browser/utils/pruneGetRequestBody.ts | 2 +- src/browser/utils/workerChannel.ts | 2 +- src/core/SetupApi.ts | 129 ------------ src/core/index.ts | 2 +- src/core/new/define-network.ts | 14 +- src/core/new/setup-api.ts | 59 ++++++ 28 files changed, 81 insertions(+), 1231 deletions(-) rename src/browser/{setupWorker => }/glossary.ts (98%) rename src/browser/{setupWorker/setupWorker.node.test.ts => setup-worker.node.test.ts} (69%) delete mode 100644 src/browser/setupWorker/setupWorker.ts delete mode 100644 src/browser/setupWorker/start/createFallbackRequestListener.ts delete mode 100644 src/browser/setupWorker/start/createRequestListener.ts delete mode 100644 src/browser/setupWorker/start/createResponseListener.ts delete mode 100644 src/browser/setupWorker/start/createStartHandler.ts delete mode 100644 src/browser/setupWorker/start/utils/enableMocking.ts delete mode 100644 src/browser/setupWorker/start/utils/getWorkerByRegistration.ts delete mode 100644 src/browser/setupWorker/start/utils/getWorkerInstance.ts delete mode 100644 src/browser/setupWorker/start/utils/prepareStartHandler.test.ts delete mode 100644 src/browser/setupWorker/start/utils/prepareStartHandler.ts delete mode 100644 src/browser/setupWorker/start/utils/printStartMessage.test.ts delete mode 100644 src/browser/setupWorker/start/utils/printStartMessage.ts delete mode 100644 src/browser/setupWorker/start/utils/validateWorkerScope.ts delete mode 100644 src/browser/setupWorker/stop/utils/printStopMessage.test.ts delete mode 100644 src/browser/setupWorker/stop/utils/printStopMessage.ts delete mode 100644 src/browser/utils/checkWorkerIntegrity.ts delete mode 100644 src/core/SetupApi.ts create mode 100644 src/core/new/setup-api.ts diff --git a/src/browser/setupWorker/glossary.ts b/src/browser/glossary.ts similarity index 98% rename from src/browser/setupWorker/glossary.ts rename to src/browser/glossary.ts index 2c30a0ea2..a7eb1e881 100644 --- a/src/browser/setupWorker/glossary.ts +++ b/src/browser/glossary.ts @@ -4,7 +4,7 @@ import { LifeCycleEventEmitter, SharedOptions } from '~/core/sharedOptions' import { RequestHandler } from '~/core/handlers/RequestHandler' import type { RequiredDeep } from '~/core/typeUtils' import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' -import type { WorkerChannel } from '../utils/workerChannel' +import type { WorkerChannel } from './utils/workerChannel' export interface StringifiedResponse extends ResponseInit { body: string | ArrayBuffer | ReadableStream | null diff --git a/src/browser/index.ts b/src/browser/index.ts index 0eafbe76f..1200dd07d 100644 --- a/src/browser/index.ts +++ b/src/browser/index.ts @@ -1,3 +1,2 @@ -export { setupWorker } from './setupWorker/setupWorker' -export type { SetupWorker, StartOptions } from './setupWorker/glossary' -export { SetupWorkerApi } from './setupWorker/setupWorker' +export { setupWorker } from './setup-worker' +export type { SetupWorker, StartOptions } from './glossary' diff --git a/src/browser/setupWorker/setupWorker.node.test.ts b/src/browser/setup-worker.node.test.ts similarity index 69% rename from src/browser/setupWorker/setupWorker.node.test.ts rename to src/browser/setup-worker.node.test.ts index 6c3f0fb42..85135ecae 100644 --- a/src/browser/setupWorker/setupWorker.node.test.ts +++ b/src/browser/setup-worker.node.test.ts @@ -1,7 +1,5 @@ -/** - * @vitest-environment node - */ -import { setupWorker } from './setupWorker' +// @vitest-environment node +import { setupWorker } from './setup-worker' test('returns an error when run in a Node.js environment', () => { expect(setupWorker).toThrow( diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index ea97f2990..390d68b95 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -10,7 +10,7 @@ import { fromLegacyOnUnhandledRequest } from '~/core/new/compat' import { supportsServiceWorker } from './utils/supports' import { ServiceWorkerSource } from './sources/service-worker-source' import { FallbackHttpSource } from './sources/fallback-http-source' -import { type FindWorker } from './setupWorker/glossary' +import { type FindWorker } from './glossary' import { type UnhandledRequestStrategy } from '~/core/utils/request/onUnhandledRequest' interface SetupWorkerApi extends NetworkHandlersApi { @@ -37,7 +37,7 @@ const DEFAULT_WORKER_URL = '/mockServiceWorker.js' * @see {@link https://mswjs.io/docs/api/setup-worker `setupWorker()` API reference} */ export function setupWorker(...handlers: Array): SetupWorkerApi { - let network: NetworkApi + let network: NetworkApi<[ServiceWorkerSource]> return { async start(options) { @@ -54,7 +54,7 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { sources: [ httpSource, new InterceptorSource({ - interceptors: [new WebSocketInterceptor()], + interceptors: [new WebSocketInterceptor() as any], }), ], handlers, diff --git a/src/browser/setupWorker/setupWorker.ts b/src/browser/setupWorker/setupWorker.ts deleted file mode 100644 index 291b4e5d6..000000000 --- a/src/browser/setupWorker/setupWorker.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { invariant } from 'outvariant' -import { isNodeProcess } from 'is-node-process' -import { DeferredPromise } from '@open-draft/deferred-promise' -import type { - SetupWorkerInternalContext, - StartReturnType, - StartOptions, - SetupWorker, -} from './glossary' -import { RequestHandler } from '~/core/handlers/RequestHandler' -import { DEFAULT_START_OPTIONS } from './start/utils/prepareStartHandler' -import { createStartHandler } from './start/createStartHandler' -import { devUtils } from '~/core/utils/internal/devUtils' -import { SetupApi } from '~/core/SetupApi' -import { mergeRight } from '~/core/utils/internal/mergeRight' -import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' -import { webSocketInterceptor } from '~/core/ws/webSocketInterceptor' -import { handleWebSocketEvent } from '~/core/ws/handleWebSocketEvent' -import { attachWebSocketLogger } from '~/core/ws/utils/attachWebSocketLogger' -import { WorkerChannel } from '../utils/workerChannel' -import { createFallbackRequestListener } from './start/createFallbackRequestListener' -import { printStartMessage } from './start/utils/printStartMessage' -import { printStopMessage } from './stop/utils/printStopMessage' -import { supportsServiceWorker } from '../utils/supports' -import type { HttpNetworkFrameEventMap } from '~/core/new/frames/http-frame' -import type { WebSocketNetworkFrameEventMap } from '~/core/new/frames/websocket-frame' - -export class SetupWorkerApi - extends SetupApi - implements SetupWorker -{ - private context: SetupWorkerInternalContext - - constructor(...handlers: Array) { - super(...handlers) - - invariant( - !isNodeProcess(), - devUtils.formatMessage( - 'Failed to execute `setupWorker` in a non-browser environment. Consider using `setupServer` for Node.js environment instead.', - ), - ) - - this.context = this.createWorkerContext() - } - - private createWorkerContext(): SetupWorkerInternalContext { - const workerPromise = new DeferredPromise() - - return { - // Mocking is not considered enabled until the worker - // signals back the successful activation event. - isMockingEnabled: false, - startOptions: null as any, - workerPromise, - registration: undefined, - getRequestHandlers: () => { - return this.handlersController.currentHandlers() - }, - emitter: this.emitter, - workerChannel: new WorkerChannel({ - worker: workerPromise, - }), - } - } - - public async start(options: StartOptions = {}): StartReturnType { - if ('waitUntilReady' in options) { - devUtils.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.', - ) - } - - // Warn the developer on multiple "worker.start()" calls. - // While this will not affect the worker in any way, - // it likely indicates an issue with the developer's code. - if (this.context.isMockingEnabled) { - devUtils.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 = undefined - - this.context.startOptions = mergeRight( - DEFAULT_START_OPTIONS, - options, - ) as SetupWorkerInternalContext['startOptions'] - - // Enable the WebSocket interception. - handleWebSocketEvent({ - getUnhandledRequestStrategy: () => { - return this.context.startOptions.onUnhandledRequest - }, - getHandlers: () => { - return this.handlersController.currentHandlers() - }, - onMockedConnection: (connection) => { - if (!this.context.startOptions.quiet) { - // Attach the logger for mocked connections since - // those won't be visible in the browser's devtools. - attachWebSocketLogger(connection) - } - }, - onPassthroughConnection() {}, - }) - webSocketInterceptor.apply() - - this.subscriptions.push(() => { - webSocketInterceptor.dispose() - }) - - // Use a fallback interception algorithm in the environments - // where the Service Worker API isn't supported. - if (!supportsServiceWorker()) { - 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 undefined - } - - const startHandler = createStartHandler(this.context) - const registration = await startHandler(this.context.startOptions, options) - - this.context.isMockingEnabled = true - - return registration - } - - public stop(): void { - super.dispose() - - if (!this.context.isMockingEnabled) { - devUtils.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 (supportsServiceWorker()) { - this.context.workerChannel.removeAllListeners('RESPONSE') - window.clearInterval(this.context.keepAliveInterval) - } - - // Post the internal stop message on the window - // to let any logic know when the worker has stopped. - // E.g. the WebSocket client manager needs this to know - // when to clear its in-memory clients list. - window.postMessage({ type: 'msw/worker:stop' }) - - printStopMessage({ - quiet: this.context.startOptions?.quiet, - }) - } -} - -/** - * Sets up a requests interception in the browser with the given request handlers. - * @param {RequestHandler[]} handlers List of request handlers. - * - * @see {@link https://mswjs.io/docs/api/setup-worker `setupWorker()` API reference} - */ -export function setupWorker( - ...handlers: Array -): SetupWorker { - return new SetupWorkerApi(...handlers) -} diff --git a/src/browser/setupWorker/start/createFallbackRequestListener.ts b/src/browser/setupWorker/start/createFallbackRequestListener.ts deleted file mode 100644 index 6d5b6915e..000000000 --- a/src/browser/setupWorker/start/createFallbackRequestListener.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { - Interceptor, - BatchInterceptor, - HttpRequestEventMap, -} from '@mswjs/interceptors' -import { FetchInterceptor } from '@mswjs/interceptors/fetch' -import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' -import { SetupWorkerInternalContext, StartOptions } from '../glossary' -import type { RequiredDeep } from '~/core/typeUtils' -import { handleRequest } from '~/core/utils/handleRequest' -import { isHandlerKind } from '~/core/utils/internal/isHandlerKind' - -export function createFallbackRequestListener( - context: SetupWorkerInternalContext, - options: RequiredDeep, -): Interceptor { - 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 handleRequest( - request, - requestId, - context.getRequestHandlers().filter(isHandlerKind('RequestHandler')), - options, - context.emitter, - { - resolutionContext: { - quiet: options.quiet, - }, - onMockedResponse(_, { handler, parsedResult }) { - if (!options.quiet) { - context.emitter.once('response:mocked', ({ response }) => { - handler.log({ - request: requestCloneForLogs, - response, - 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 -} diff --git a/src/browser/setupWorker/start/createRequestListener.ts b/src/browser/setupWorker/start/createRequestListener.ts deleted file mode 100644 index 9f18b5e08..000000000 --- a/src/browser/setupWorker/start/createRequestListener.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { Emitter } from 'rettime' -import { StartOptions, SetupWorkerInternalContext } from '../glossary' -import { deserializeRequest } from '../../utils/deserializeRequest' -import { supportsReadableStreamTransfer } from '../../utils/supports' -import { RequestHandler } from '~/core/handlers/RequestHandler' -import { handleRequest } from '~/core/utils/handleRequest' -import { RequiredDeep } from '~/core/typeUtils' -import { devUtils } from '~/core/utils/internal/devUtils' -import { toResponseInit } from '~/core/utils/toResponseInit' -import { isHandlerKind } from '~/core/utils/internal/isHandlerKind' - -const SUPPORTS_READABLE_STREAM_TRANSFER = supportsReadableStreamTransfer() - -export const createRequestListener = ( - context: SetupWorkerInternalContext, - options: RequiredDeep, -): Emitter.ListenerType => { - return async (event) => { - // Treat any incoming requests from the worker as passthrough - // if `worker.stop()` has been called for this client. - 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() - - // Make this the first request clone before the - // request resolution pipeline even starts. - // Store the clone in cache so the first matching - // request handler would skip the cloning phase. - const requestClone = request.clone() - RequestHandler.cache.set(request, requestClone) - - try { - await handleRequest( - request, - requestId, - context.getRequestHandlers().filter(isHandlerKind('RequestHandler')), - options, - context.emitter, - { - resolutionContext: { - quiet: options.quiet, - }, - onPassthroughResponse() { - event.postMessage('PASSTHROUGH') - }, - async onMockedResponse(response, { handler, parsedResult }) { - // Clone the mocked response so its body could be read - // to buffer to be sent to the worker and also in the - // ".log()" method of the request handler. - const responseClone = response.clone() - const responseCloneForLogs = response.clone() - const responseInit = toResponseInit(response) - - /** - * @note Safari doesn't support transferring a "ReadableStream". - * Check that the browser supports that before sending it to the worker. - */ - if (SUPPORTS_READABLE_STREAM_TRANSFER) { - const responseStreamOrNull = response.body - - event.postMessage( - 'MOCK_RESPONSE', - { - ...responseInit, - body: responseStreamOrNull, - }, - responseStreamOrNull ? [responseStreamOrNull] : undefined, - ) - } else { - /** - * @note If we are here, this means the current environment doesn't - * support "ReadableStream" as transferable. In that case, - * attempt to read the non-empty response body as ArrayBuffer, if it's not empty. - * @see https://github.com/mswjs/msw/issues/1827 - */ - 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 (error) { - if (error instanceof Error) { - devUtils.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, - error.stack ?? error, - ) - - // Treat all other exceptions in a request handler as unintended, - // alerting that there is a problem that needs fixing. - event.postMessage('MOCK_RESPONSE', { - status: 500, - statusText: 'Request Handler Error', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - name: error.name, - message: error.message, - stack: error.stack, - }), - }) - } - } - } -} diff --git a/src/browser/setupWorker/start/createResponseListener.ts b/src/browser/setupWorker/start/createResponseListener.ts deleted file mode 100644 index 8c52dd366..000000000 --- a/src/browser/setupWorker/start/createResponseListener.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { FetchResponse } from '@mswjs/interceptors' -import type { Emitter } from 'rettime' -import type { SetupWorkerInternalContext } from '../glossary' -import { deserializeRequest } from '../../utils/deserializeRequest' - -export function createResponseListener( - context: SetupWorkerInternalContext, -): Emitter.ListenerType { - return (event) => { - const responseMessage = event.data - const request = deserializeRequest(responseMessage.request) - - /** - * CORS requests with `mode: "no-cors"` result in "opaque" responses. - * That kind of responses cannot be manipulated in JavaScript due - * to the security considerations. - * @see https://fetch.spec.whatwg.org/#concept-filtered-response-opaque - * @see https://github.com/mswjs/msw/issues/529 - */ - 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.response, - /** - * 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, - }, - ) - } -} diff --git a/src/browser/setupWorker/start/createStartHandler.ts b/src/browser/setupWorker/start/createStartHandler.ts deleted file mode 100644 index 8ea497cb7..000000000 --- a/src/browser/setupWorker/start/createStartHandler.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { devUtils } from '~/core/utils/internal/devUtils' -import { getWorkerInstance } from './utils/getWorkerInstance' -import { enableMocking } from './utils/enableMocking' -import type { SetupWorkerInternalContext, StartHandler } from '../glossary' -import { createRequestListener } from './createRequestListener' -import { checkWorkerIntegrity } from '../../utils/checkWorkerIntegrity' -import { createResponseListener } from './createResponseListener' -import { validateWorkerScope } from './utils/validateWorkerScope' -import { DeferredPromise } from '@open-draft/deferred-promise' - -export const createStartHandler = ( - context: SetupWorkerInternalContext, -): StartHandler => { - return function start(options, customOptions) { - const startWorkerInstance = async () => { - // Remove all previously existing event listeners. - // This way none of the listeners persists between Fast refresh - // of the application's code. - context.workerChannel.removeAllListeners() - - // Handle requests signaled by the worker. - context.workerChannel.on( - 'REQUEST', - createRequestListener(context, options), - ) - - // Handle responses signaled by the worker. - 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 - ? devUtils.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, - ) - : devUtils.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') { - // Notify the Service Worker that this client has closed. - // Internally, it's similar to disabling the mocking, only - // client close event has a handler that self-terminates - // the Service Worker when there are no open clients. - context.workerChannel.postMessage('CLIENT_CLOSED') - } - - // Make sure we're always clearing the interval - there are reports that not doing this can - // cause memory leaks in headless browser environments. - window.clearInterval(context.keepAliveInterval) - - // Notify others about this client disconnecting. - // E.g. this will purge the in-memory WebSocket clients since - // starting the worker again will assign them new IDs. - window.postMessage({ type: 'msw/worker:stop' }) - }) - - // Check if the active Service Worker has been generated - // by the currently installed version of MSW. - await checkWorkerIntegrity(context).catch((error) => { - devUtils.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(error) - }) - - context.keepAliveInterval = window.setInterval( - () => context.workerChannel.postMessage('KEEPALIVE_REQUEST'), - 5000, - ) - - // Warn the user when loading the page that lies outside - // of the worker's scope. - 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() - } - }) - - // Wait until the worker is activated. - // Assume the worker is already activated if there's no pending registration - // (i.e. when reloading the page after a successful activation). - await activationPromise - } - - // Print the activation message only after the worker has been activated. - await enableMocking(context, options).catch((error) => { - devUtils.error( - 'Failed to enable mocking. Please report this on GitHub (https://github.com/mswjs/msw/issues) and include the original error below.', - ) - throw error - }) - - return registration - }, - ) - - return workerRegistration - } -} diff --git a/src/browser/setupWorker/start/utils/enableMocking.ts b/src/browser/setupWorker/start/utils/enableMocking.ts deleted file mode 100644 index 649bb1812..000000000 --- a/src/browser/setupWorker/start/utils/enableMocking.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { DeferredPromise } from '@open-draft/deferred-promise' -import type { StartOptions, SetupWorkerInternalContext } from '../../glossary' -import { printStartMessage } from './printStartMessage' - -/** - * Signals the worker to enable the interception of requests. - */ -export function enableMocking( - context: SetupWorkerInternalContext, - options: StartOptions, -): Promise { - 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 -} diff --git a/src/browser/setupWorker/start/utils/getWorkerByRegistration.ts b/src/browser/setupWorker/start/utils/getWorkerByRegistration.ts deleted file mode 100644 index 9481aa5cc..000000000 --- a/src/browser/setupWorker/start/utils/getWorkerByRegistration.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { FindWorker } from '../../glossary' - -/** - * Attempts to resolve a Service Worker instance from a given registration, - * regardless of its state (active, installing, waiting). - */ -export function getWorkerByRegistration( - registration: ServiceWorkerRegistration, - absoluteWorkerUrl: string, - findWorker: FindWorker, -): ServiceWorker | null { - const allStates = [ - registration.active, - registration.installing, - registration.waiting, - ] - const relevantStates = allStates.filter((state): state is ServiceWorker => { - return state != null - }) - const worker = relevantStates.find((worker) => { - return findWorker(worker.scriptURL, absoluteWorkerUrl) - }) - - return worker || null -} diff --git a/src/browser/setupWorker/start/utils/getWorkerInstance.ts b/src/browser/setupWorker/start/utils/getWorkerInstance.ts deleted file mode 100644 index 492083009..000000000 --- a/src/browser/setupWorker/start/utils/getWorkerInstance.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { until } from 'until-async' -import { devUtils } from '~/core/utils/internal/devUtils' -import { getAbsoluteWorkerUrl } from '../../../utils/getAbsoluteWorkerUrl' -import { getWorkerByRegistration } from './getWorkerByRegistration' -import { ServiceWorkerInstanceTuple, FindWorker } from '../../glossary' - -/** - * Returns an active Service Worker instance. - * When not found, registers a new Service Worker. - */ -export const getWorkerInstance = async ( - url: string, - options: RegistrationOptions = {}, - findWorker: FindWorker, -): Promise => { - // Resolve the absolute Service Worker URL. - 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) { - // Reload the page when it has associated workers, but no active controller. - // The absence of a controller can mean either: - // - page has no Service Worker associated with it - // - page has been hard-reloaded and its workers won't be used until the next reload. - // Since we've checked that there are registrations associated with this page, - // at this point we are sure it's hard reload that falls into this clause. - location.reload() - } - - const [existingRegistration] = mockRegistrations - - if (existingRegistration) { - // Schedule the worker update in the background. - // Update ensures the existing worker is up-to-date. - existingRegistration.update() - - // Return the worker reference immediately. - return [ - getWorkerByRegistration( - existingRegistration, - absoluteWorkerUrl, - findWorker, - ), - existingRegistration, - ] - } - - // When the Service Worker wasn't found, register it anew and return the reference. - const [registrationError, registrationResult] = await until< - Error, - ServiceWorkerInstanceTuple - >(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, - ] - }) - - // Handle Service Worker registration errors. - if (registrationError) { - const isWorkerMissing = registrationError.message.includes('(404)') - - // Produce a custom error message when given a non-existing Service Worker url. - // Suggest developers to check their setup. - 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 "? - -Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/init`), - ) - } - - // Fallback error message for any other registration errors. - throw new Error( - devUtils.formatMessage( - 'Failed to register the Service Worker:\n\n%s', - registrationError.message, - ), - ) - } - - return registrationResult -} diff --git a/src/browser/setupWorker/start/utils/prepareStartHandler.test.ts b/src/browser/setupWorker/start/utils/prepareStartHandler.test.ts deleted file mode 100644 index f2c66e8d2..000000000 --- a/src/browser/setupWorker/start/utils/prepareStartHandler.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { SetupWorkerInternalContext, StartOptions } from '../../glossary' -import { - DEFAULT_START_OPTIONS, - resolveStartOptions, - prepareStartHandler, -} from './prepareStartHandler' - -describe('resolveStartOptions', () => { - test('returns default options given no custom start options', () => { - expect(resolveStartOptions()).toEqual(DEFAULT_START_OPTIONS) - expect(resolveStartOptions(undefined)).toEqual(DEFAULT_START_OPTIONS) - expect(resolveStartOptions({})).toEqual(DEFAULT_START_OPTIONS) - }) - - test('deeply merges the default and custom start options', () => { - expect( - resolveStartOptions({ - quiet: true, - serviceWorker: { - url: './custom.js', - }, - }), - ).toEqual({ - ...DEFAULT_START_OPTIONS, - quiet: true, - serviceWorker: { - url: './custom.js', - options: null, - }, - }) - }) -}) - -describe('prepareStartHandler', () => { - test('exposes resolved start options to the generated star handler', () => { - const createStartHandler = vi.fn() - const context: SetupWorkerInternalContext = {} as any - const startHandler = prepareStartHandler(createStartHandler, context) - expect(startHandler).toBeInstanceOf(Function) - - const initialOptions: StartOptions = { - quiet: true, - serviceWorker: { - url: './custom.js', - }, - } - const resolvedOptions = resolveStartOptions(initialOptions) - startHandler(initialOptions) - - // Calls the handler creator with both resolved and initial options. - expect(createStartHandler).toHaveBeenCalledWith( - resolvedOptions, - initialOptions, - ) - - // Sets the resolved options on the internal context. - expect(context).toHaveProperty('startOptions', resolvedOptions) - }) -}) diff --git a/src/browser/setupWorker/start/utils/prepareStartHandler.ts b/src/browser/setupWorker/start/utils/prepareStartHandler.ts deleted file mode 100644 index e98fe832c..000000000 --- a/src/browser/setupWorker/start/utils/prepareStartHandler.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { RequiredDeep } from '~/core/typeUtils' -import { mergeRight } from '~/core/utils/internal/mergeRight' -import { - SetupWorker, - SetupWorkerInternalContext, - StartHandler, - StartOptions, -} from '../../glossary' - -export const DEFAULT_START_OPTIONS: RequiredDeep = { - serviceWorker: { - url: '/mockServiceWorker.js', - options: null as any, - }, - quiet: false, - waitUntilReady: true, - onUnhandledRequest: 'warn', - findWorker(scriptURL, mockServiceWorkerUrl) { - return scriptURL === mockServiceWorkerUrl - }, -} - -/** - * Returns resolved worker start options, merging the default options - * with the given custom options. - */ -export function resolveStartOptions( - initialOptions?: StartOptions, -): RequiredDeep { - return mergeRight( - DEFAULT_START_OPTIONS, - initialOptions || {}, - ) as RequiredDeep -} - -export function prepareStartHandler( - handler: StartHandler, - context: SetupWorkerInternalContext, -): SetupWorker['start'] { - return (initialOptions) => { - context.startOptions = resolveStartOptions(initialOptions) - return handler(context.startOptions, initialOptions || {}) - } -} diff --git a/src/browser/setupWorker/start/utils/printStartMessage.test.ts b/src/browser/setupWorker/start/utils/printStartMessage.test.ts deleted file mode 100644 index 9098b1591..000000000 --- a/src/browser/setupWorker/start/utils/printStartMessage.test.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { printStartMessage } from './printStartMessage' - -beforeEach(() => { - vi.spyOn(console, 'groupCollapsed').mockImplementation(() => void 0) - vi.spyOn(console, 'log').mockImplementation(() => void 0) -}) - -afterEach(() => { - vi.restoreAllMocks() -}) - -test('prints out a default start message into console', () => { - printStartMessage({ - workerScope: 'http://localhost:3000/', - workerUrl: 'http://localhost:3000/worker.js', - }) - - expect(console.groupCollapsed).toHaveBeenCalledWith( - '%c[MSW] Mocking enabled.', - expect.anything(), - ) - - // Includes a link to the documentation. - expect(console.log).toHaveBeenCalledWith( - '%cDocumentation: %chttps://mswjs.io/docs', - expect.anything(), - expect.anything(), - ) - - // Includes a link to the GitHub issues page. - expect(console.log).toHaveBeenCalledWith( - 'Found an issue? https://github.com/mswjs/msw/issues', - ) - - // Includes service worker scope. - expect(console.log).toHaveBeenCalledWith( - 'Worker scope:', - 'http://localhost:3000/', - ) - - // Includes service worker script location. - expect(console.log).toHaveBeenCalledWith( - 'Worker script URL:', - 'http://localhost:3000/worker.js', - ) -}) - -test('supports printing a custom start message', () => { - printStartMessage({ message: 'Custom start message' }) - - expect(console.groupCollapsed).toHaveBeenCalledWith( - '%c[MSW] Custom start message', - expect.anything(), - ) -}) - -test('does not print any messages when log level is quiet', () => { - printStartMessage({ quiet: true }) - - expect(console.groupCollapsed).not.toHaveBeenCalled() - expect(console.log).not.toHaveBeenCalled() -}) - -test('prints a worker scope in the start message', () => { - printStartMessage({ - workerScope: 'http://localhost:3000/user', - }) - - expect(console.log).toHaveBeenCalledWith( - 'Worker scope:', - 'http://localhost:3000/user', - ) -}) - -test('prints a worker script url in the start message', () => { - printStartMessage({ - workerUrl: 'http://localhost:3000/mockServiceWorker.js', - }) - - expect(console.log).toHaveBeenCalledWith( - 'Worker script URL:', - 'http://localhost:3000/mockServiceWorker.js', - ) -}) diff --git a/src/browser/setupWorker/start/utils/printStartMessage.ts b/src/browser/setupWorker/start/utils/printStartMessage.ts deleted file mode 100644 index cdfba380b..000000000 --- a/src/browser/setupWorker/start/utils/printStartMessage.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { ServiceWorkerIncomingEventsMap } from '../../glossary' -import { devUtils } from '~/core/utils/internal/devUtils' - -interface PrintStartMessageArgs { - quiet?: boolean - message?: string - workerUrl?: string - workerScope?: string - client?: ServiceWorkerIncomingEventsMap['MOCKING_ENABLED']['client'] -} - -/** - * Prints a worker activation message in the browser's console. - */ -export function printStartMessage(args: PrintStartMessageArgs = {}) { - if (args.quiet) { - return - } - - const message = args.message || 'Mocking enabled.' - - console.groupCollapsed( - `%c${devUtils.formatMessage(message)}`, - 'color:orangered;font-weight:bold;', - ) - // eslint-disable-next-line no-console - console.log( - '%cDocumentation: %chttps://mswjs.io/docs', - 'font-weight:bold', - 'font-weight:normal', - ) - // eslint-disable-next-line no-console - console.log('Found an issue? https://github.com/mswjs/msw/issues') - - if (args.workerUrl) { - // eslint-disable-next-line no-console - console.log('Worker script URL:', args.workerUrl) - } - - if (args.workerScope) { - // eslint-disable-next-line no-console - console.log('Worker scope:', args.workerScope) - } - - if (args.client) { - // eslint-disable-next-line no-console - console.log('Client ID: %s (%s)', args.client.id, args.client.frameType) - } - - console.groupEnd() -} diff --git a/src/browser/setupWorker/start/utils/validateWorkerScope.ts b/src/browser/setupWorker/start/utils/validateWorkerScope.ts deleted file mode 100644 index 0e93412c2..000000000 --- a/src/browser/setupWorker/start/utils/validateWorkerScope.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { devUtils } from '~/core/utils/internal/devUtils' -import { StartOptions } from '../../glossary' - -export function validateWorkerScope( - registration: ServiceWorkerRegistration, - options?: StartOptions, -): void { - if (!options?.quiet && !location.href.startsWith(registration.scope)) { - devUtils.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.\ -`, - ) - } -} diff --git a/src/browser/setupWorker/stop/utils/printStopMessage.test.ts b/src/browser/setupWorker/stop/utils/printStopMessage.test.ts deleted file mode 100644 index 8e2b21416..000000000 --- a/src/browser/setupWorker/stop/utils/printStopMessage.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { printStopMessage } from './printStopMessage' - -beforeAll(() => { - vi.spyOn(global.console, 'log').mockImplementation(() => void 0) -}) - -afterEach(() => { - vi.resetAllMocks() -}) - -afterAll(() => { - vi.restoreAllMocks() -}) - -test('prints a stop message to the console', () => { - printStopMessage() - expect(console.log).toHaveBeenCalledWith( - '%c[MSW] Mocking disabled.', - 'color:orangered;font-weight:bold;', - ) -}) - -test('does not print any message when log level is quiet', () => { - printStopMessage({ quiet: true }) - expect(console.log).not.toHaveBeenCalled() -}) diff --git a/src/browser/setupWorker/stop/utils/printStopMessage.ts b/src/browser/setupWorker/stop/utils/printStopMessage.ts deleted file mode 100644 index c3c75aac3..000000000 --- a/src/browser/setupWorker/stop/utils/printStopMessage.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { devUtils } from '~/core/utils/internal/devUtils' - -export function printStopMessage(args: { quiet?: boolean } = {}): void { - if (args.quiet) { - return - } - - // eslint-disable-next-line no-console - console.log( - `%c${devUtils.formatMessage('Mocking disabled.')}`, - 'color:orangered;font-weight:bold;', - ) -} diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index b1f26dece..c3121f83b 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -9,7 +9,7 @@ import { import { getWorkerInstance } from '../setupWorker/start/utils/getWorkerInstance' import { devUtils } from '~/core/utils/internal/devUtils' import { WorkerChannel, WorkerChannelEventMap } from '../utils/workerChannel' -import { FindWorker } from '../setupWorker/glossary' +import { FindWorker } from '../glossary' import { Emitter, TypedEvent } from 'rettime' import { deserializeRequest } from '../utils/deserializeRequest' import { RequestHandler } from '~/core/handlers/RequestHandler' @@ -38,7 +38,7 @@ type ResponseEvent = Emitter.EventType< WorkerChannelEventMap > -export class ServiceWorkerSource extends NetworkSource { +export class ServiceWorkerSource extends NetworkSource { #frames: Map #channel: WorkerChannel #workerPromise: DeferredPromise @@ -225,7 +225,7 @@ export class ServiceWorkerSource extends NetworkSource { : new FetchResponse(response.body, response) frame.events.emit( - new TypedEvent('response', { + new TypedEvent(isMockedResponse ? 'response:mocked' : 'response:bypass', { data: { requestId: request.id, request: fetchRequest, diff --git a/src/browser/utils/checkWorkerIntegrity.ts b/src/browser/utils/checkWorkerIntegrity.ts deleted file mode 100644 index 47a3bfc80..000000000 --- a/src/browser/utils/checkWorkerIntegrity.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { devUtils } from '~/core/utils/internal/devUtils' -import type { SetupWorkerInternalContext } from '../setupWorker/glossary' -import { DeferredPromise } from '@open-draft/deferred-promise' - -/** - * Check whether the registered Service Worker has been - * generated by the installed version of the library. - * Prints a warning message if the worker scripts mismatch. - */ -export function checkWorkerIntegrity( - context: SetupWorkerInternalContext, -): Promise { - const integrityCheckPromise = new DeferredPromise() - - // Request the integrity checksum from the registered worker. - context.workerChannel.postMessage('INTEGRITY_CHECK_REQUEST') - context.workerChannel.once('INTEGRITY_CHECK_RESPONSE', (event) => { - const { checksum, packageVersion } = event.data - - // Compare the response from the Service Worker and the - // global variable set during the build. - - // The integrity is validated based on the worker script's checksum - // that's derived from its minified content during the build. - // The "SERVICE_WORKER_CHECKSUM" global variable is injected by the build. - if (checksum !== SERVICE_WORKER_CHECKSUM) { - devUtils.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 - -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 -} diff --git a/src/browser/utils/deserializeRequest.ts b/src/browser/utils/deserializeRequest.ts index aae0c5c72..db82d2156 100644 --- a/src/browser/utils/deserializeRequest.ts +++ b/src/browser/utils/deserializeRequest.ts @@ -1,5 +1,5 @@ import { pruneGetRequestBody } from './pruneGetRequestBody' -import type { ServiceWorkerIncomingRequest } from '../setupWorker/glossary' +import type { ServiceWorkerIncomingRequest } from '../glossary' /** * Converts a given request received from the Service Worker diff --git a/src/browser/utils/pruneGetRequestBody.ts b/src/browser/utils/pruneGetRequestBody.ts index b17602217..2354f8059 100644 --- a/src/browser/utils/pruneGetRequestBody.ts +++ b/src/browser/utils/pruneGetRequestBody.ts @@ -1,4 +1,4 @@ -import type { ServiceWorkerIncomingRequest } from '../setupWorker/glossary' +import type { ServiceWorkerIncomingRequest } from '../glossary' type Input = Pick diff --git a/src/browser/utils/workerChannel.ts b/src/browser/utils/workerChannel.ts index 88cf70935..b9c0972b1 100644 --- a/src/browser/utils/workerChannel.ts +++ b/src/browser/utils/workerChannel.ts @@ -1,7 +1,7 @@ import { invariant } from 'outvariant' import { Emitter, TypedEvent } from 'rettime' import { isObject } from '~/core/utils/internal/isObject' -import type { StringifiedResponse } from '../setupWorker/glossary' +import type { StringifiedResponse } from '../glossary' import { supportsServiceWorker } from '../utils/supports' export interface WorkerChannelOptions { diff --git a/src/core/SetupApi.ts b/src/core/SetupApi.ts deleted file mode 100644 index e9e3024f0..000000000 --- a/src/core/SetupApi.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { invariant } from 'outvariant' -import { Emitter, type DefaultEventMap } from 'rettime' -import { RequestHandler } from './handlers/RequestHandler' -import { LifeCycleEventEmitter } from './sharedOptions' -import { devUtils } from './utils/internal/devUtils' -import { pipeEvents } from './utils/internal/pipeEvents' -import { toReadonlyArray } from './utils/internal/toReadonlyArray' -import { Disposable } from './utils/internal/Disposable' -import type { WebSocketHandler } from './handlers/WebSocketHandler' - -export abstract class HandlersController { - abstract prepend( - runtimeHandlers: Array, - ): void - abstract reset(nextHandles: Array): void - abstract currentHandlers(): Array -} - -export class InMemoryHandlersController implements HandlersController { - private handlers: Array - - constructor( - private initialHandlers: Array, - ) { - this.handlers = [...initialHandlers] - } - - public prepend( - runtimeHandles: Array, - ): void { - this.handlers.unshift(...runtimeHandles) - } - - public reset(nextHandlers: Array): void { - this.handlers = - nextHandlers.length > 0 ? [...nextHandlers] : [...this.initialHandlers] - } - - public currentHandlers(): Array { - return this.handlers - } -} - -/** - * Generic class for the mock API setup. - */ -export abstract class SetupApi< - EventMap extends DefaultEventMap, -> extends Disposable { - protected handlersController: HandlersController - protected readonly emitter: Emitter - protected readonly publicEmitter: Emitter - - public readonly events: LifeCycleEventEmitter - - constructor(...initialHandlers: Array) { - super() - - invariant( - this.validateHandlers(initialHandlers), - devUtils.formatMessage( - `Failed to apply given request handlers: invalid input. Did you forget to spread the request handlers Array?`, - ), - ) - - this.handlersController = new InMemoryHandlersController(initialHandlers) - - this.emitter = new Emitter() - this.publicEmitter = new Emitter() - pipeEvents(this.emitter, this.publicEmitter) - - this.events = this.createLifeCycleEvents() - - this.subscriptions.push(() => { - this.emitter.removeAllListeners() - this.publicEmitter.removeAllListeners() - }) - } - - private validateHandlers(handlers: ReadonlyArray): boolean { - // Guard against incorrect call signature of the setup API. - return handlers.every((handler) => !Array.isArray(handler)) - } - - public use( - ...runtimeHandlers: Array - ): void { - invariant( - this.validateHandlers(runtimeHandlers), - devUtils.formatMessage( - `Failed to call "use()" with the given request handlers: invalid input. Did you forget to spread the array of request handlers?`, - ), - ) - - this.handlersController.prepend(runtimeHandlers) - } - - public restoreHandlers(): void { - this.handlersController.currentHandlers().forEach((handler) => { - if ('isUsed' in handler) { - handler.isUsed = false - } - }) - } - - public resetHandlers( - ...nextHandlers: Array - ): void { - this.handlersController.reset(nextHandlers) - } - - public listHandlers(): ReadonlyArray { - return toReadonlyArray(this.handlersController.currentHandlers()) - } - - private createLifeCycleEvents(): LifeCycleEventEmitter { - return { - on: (...args: any[]) => { - return (this.publicEmitter.on as any)(...args) - }, - removeListener: (...args: any[]) => { - return (this.publicEmitter.removeListener as any)(...args) - }, - removeAllListeners: (...args: any[]) => { - return this.publicEmitter.removeAllListeners(...args) - }, - } - } -} diff --git a/src/core/index.ts b/src/core/index.ts index 8d063a138..2ed43a40d 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,6 +1,6 @@ import { checkGlobals } from './utils/internal/checkGlobals' -export { SetupApi } from './SetupApi' +export { SetupApi } from './new/setup-api' /* HTTP handlers */ export { RequestHandler } from './handlers/RequestHandler' diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index 8f0bfbdde..5354b943c 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -20,7 +20,7 @@ type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ( ? I : never -type MergeEventMaps>> = +type MergeEventMaps>> = UnionToIntersection> extends infer R ? R extends Record ? R @@ -28,7 +28,7 @@ type MergeEventMaps>> = : DefaultEventMap export interface DefineNetworkOptions< - Sources extends ReadonlyArray>, + Sources extends Array>, > { sources: Sources handlers?: Array @@ -37,11 +37,11 @@ export interface DefineNetworkOptions< onUnhandledFrame?: UnhandledFrameHandle } -export interface NetworkApi +export interface NetworkApi>> extends NetworkHandlersApi { enable: () => Promise disable: () => Promise - events: Emitter + events: Emitter> } export interface NetworkHandlersApi { @@ -51,9 +51,9 @@ export interface NetworkHandlersApi { listHandlers: () => ReadonlyArray } -export function defineNetwork< - Sources extends ReadonlyArray>, ->(options: DefineNetworkOptions): NetworkApi> { +export function defineNetwork>>( + options: DefineNetworkOptions, +): NetworkApi { const events = new Emitter>() const handlersController = options.controller || new InMemoryHandlersController(options.handlers || []) diff --git a/src/core/new/setup-api.ts b/src/core/new/setup-api.ts new file mode 100644 index 000000000..79829d79c --- /dev/null +++ b/src/core/new/setup-api.ts @@ -0,0 +1,59 @@ +import { DefaultEventMap, Emitter } from 'rettime' +import { LifeCycleEventEmitter } from '../sharedOptions' +import { + AnyHandler, + HandlersController, + InMemoryHandlersController, +} from './handlers-controller' +import { Disposable } from '../utils/internal/Disposable' +import { toReadonlyArray } from '../utils/internal/toReadonlyArray' + +/** + * Generic class for the mock API setup. + * Preserved only for backward compatibility. + * @deprecated + */ +export abstract class SetupApi< + EventMap extends DefaultEventMap, +> extends Disposable { + protected handlersController: HandlersController + protected emitter: Emitter + protected publicEmitter: Emitter + + public readonly events: LifeCycleEventEmitter + + constructor(...initialHandlers: Array) { + super() + + this.handlersController = new InMemoryHandlersController(initialHandlers) + + this.emitter = new Emitter() + this.publicEmitter = new Emitter() + this.events = this.emitter + + this.subscriptions.push(() => { + this.emitter.removeAllListeners() + this.publicEmitter.removeAllListeners() + }) + } + + public use(...runtimeHandlers: Array): void { + this.handlersController.use(runtimeHandlers) + } + + public restoreHandlers(): void { + this.handlersController.currentHandlers.forEach((handler) => { + if ('isUsed' in handler) { + handler.isUsed = false + } + }) + } + + public resetHandlers(...nextHandlers: Array): void { + this.handlersController.reset(nextHandlers) + } + + public listHandlers(): ReadonlyArray { + return toReadonlyArray(this.handlersController.currentHandlers) + } +} From 1a9a94b206bc976bd5fa64b1575d5bd95fe46735 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 10:19:01 +0100 Subject: [PATCH 14/68] chore: use `#core` import alias --- .nvmrc | 2 +- config/replaceCoreImports.js | 4 +- config/scripts/patch-ts.js | 16 +-- package.json | 6 +- src/browser/glossary.ts | 42 +++----- src/browser/setup-worker.ts | 10 +- src/browser/sources/fallback-http-source.ts | 4 +- src/browser/sources/service-worker-source.ts | 16 +-- src/browser/tsconfig.browser.json | 9 +- .../utils/get-worker-by-registration.ts | 27 ++++++ src/browser/utils/get-worker-instance.ts | 97 +++++++++++++++++++ src/browser/utils/pruneGetRequestBody.test.ts | 4 +- src/browser/utils/workerChannel.ts | 2 +- src/core/new/sources/network-source.ts | 8 +- src/core/sharedOptions.ts | 51 ++++++++++ src/core/sse.ts | 2 +- src/iife/index.ts | 2 +- src/native/index.ts | 2 +- src/node/async-handlers-controller.ts | 2 +- src/node/glossary.ts | 8 +- src/node/setup-server-common.ts | 10 +- src/node/setup-server.ts | 2 +- src/tsconfig.core.json | 8 ++ src/tsconfig.node.json | 11 ++- src/tsconfig.src.json | 2 - src/tsconfig.worker.json | 3 +- tsconfig.base.json | 7 +- tsup.config.ts | 2 +- vitest.config.mts | 2 +- 29 files changed, 271 insertions(+), 90 deletions(-) create mode 100644 src/browser/utils/get-worker-by-registration.ts create mode 100644 src/browser/utils/get-worker-instance.ts create mode 100644 src/tsconfig.core.json diff --git a/.nvmrc b/.nvmrc index 9a2a0e219..54c65116f 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v20 +v24 diff --git a/config/replaceCoreImports.js b/config/replaceCoreImports.js index b86f57b55..c4dff75d4 100644 --- a/config/replaceCoreImports.js +++ b/config/replaceCoreImports.js @@ -1,5 +1,5 @@ -const CORE_ESM_IMPORT_PATTERN = /from ["'](~\/core(.*))["'](;)?/gm -const CORE_CJS_IMPORT_PATTERN = /require\(["'](~\/core(.*))["']\)(;)?/gm +const CORE_ESM_IMPORT_PATTERN = /from ["'](#core(.*))["'](;)?/gm +const CORE_CJS_IMPORT_PATTERN = /require\(["'](#core(.*))["']\)(;)?/gm function getCoreImportPattern(isEsm) { return isEsm ? CORE_ESM_IMPORT_PATTERN : CORE_CJS_IMPORT_PATTERN diff --git a/config/scripts/patch-ts.js b/config/scripts/patch-ts.js index 7c17ff477..95ada4fe3 100644 --- a/config/scripts/patch-ts.js +++ b/config/scripts/patch-ts.js @@ -29,13 +29,13 @@ async function patchTypeDefs() { if (typeDefsWithCoreImports.length === 0) { console.log( - 'Found no .d.ts modules containing the "~/core" import, skipping...', + 'Found no .d.ts modules containing the "#core" import, skipping...', ) return process.exit(0) } console.log( - 'Found %d module(s) with the "~/core" import, resolving...', + 'Found %d module(s) with the "#core" import, resolving...', typeDefsWithCoreImports.length, ) @@ -56,9 +56,9 @@ async function patchTypeDefs() { typeDefsWithCoreImports.length, ) - // Next, validate that we left no "~/core" imports unresolved. + // Next, validate that we left no "#core" imports unresolved. const result = await execAsync( - `grep "~/core" ./**/*.d.{ts,mts} -R -l || exit 0`, + `grep "#core" ./**/*.d.{ts,mts} -R -l || exit 0`, { cwd: BUILD_DIR, shell: '/bin/bash', @@ -67,7 +67,7 @@ async function patchTypeDefs() { invariant( result.stderr === '', - 'Failed to validate the .d.ts modules for the presence of the "~/core" import. See the original error below.', + 'Failed to validate the .d.ts modules for the presence of the "#core" import. See the original error below.', result.stderr, ) @@ -77,7 +77,7 @@ async function patchTypeDefs() { .filter(Boolean) console.error( - `Found .d.ts modules containing unresolved "~/core" import after the patching: + `Found .d.ts modules containing unresolved "#core" import after the patching: ${modulesWithUnresolvedImports.map((path) => ` - ${new URL(path, BUILD_DIR).pathname}`).join('\n')} `, @@ -86,7 +86,7 @@ ${modulesWithUnresolvedImports.map((path) => ` - ${new URL(path, BUILD_DIR).pat return process.exit(1) } - // Ensure that the .d.ts files compile without errors after resolving the "~/core" imports. + // Ensure that the .d.ts files compile without errors after resolving the "#core" imports. console.log('Compiling the .d.ts modules with tsc...') const tscCompilation = await execAsync( `tsc --noEmit --skipLibCheck ${typeDefsPaths.join(' ')}`, @@ -135,7 +135,7 @@ ${modulesWithUnresolvedImports.map((path) => ` - ${new URL(path, BUILD_DIR).pat } console.log( - 'The "~/core" imports resolved successfully in %d .d.ts modules! 🎉', + 'The "#core" imports resolved successfully in %d .d.ts modules! 🎉', typeDefsWithCoreImports.length, ) } diff --git a/package.json b/package.json index ccea88024..f3589c7f0 100644 --- a/package.json +++ b/package.json @@ -162,12 +162,12 @@ "./mockServiceWorker.js": "./lib/mockServiceWorker.js", "./package.json": "./package.json" }, + "imports": { + "#core": "./src/core" + }, "bin": { "msw": "cli/index.js" }, - "engines": { - "node": ">=18" - }, "scripts": { "start": "tsup --watch", "clean": "rimraf ./lib", diff --git a/src/browser/glossary.ts b/src/browser/glossary.ts index a7eb1e881..f7b45b70f 100644 --- a/src/browser/glossary.ts +++ b/src/browser/glossary.ts @@ -1,28 +1,13 @@ -import type { HttpRequestEventMap, Interceptor } from '@mswjs/interceptors' -import type { DeferredPromise } from '@open-draft/deferred-promise' -import { LifeCycleEventEmitter, SharedOptions } from '~/core/sharedOptions' -import { RequestHandler } from '~/core/handlers/RequestHandler' -import type { RequiredDeep } from '~/core/typeUtils' -import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' -import type { WorkerChannel } from './utils/workerChannel' +import type { LifeCycleEventEmitter, SharedOptions } from '#core/sharedOptions' +import type { RequiredDeep } from '#core/typeUtils' +import type { HttpNetworkFrameEventMap } from '#core/new/frames/http-frame' +import type { WebSocketNetworkFrameEventMap } from '#core/new/frames/websocket-frame' +import { AnyHandler } from '#core/new/handlers-controller' export interface StringifiedResponse extends ResponseInit { body: string | ArrayBuffer | ReadableStream | null } -export type SetupWorkerInternalContext = { - isMockingEnabled: boolean - workerStoppedAt?: number - startOptions: RequiredDeep - workerPromise: DeferredPromise - registration: ServiceWorkerRegistration | undefined - getRequestHandlers: () => Array - emitter: LifeCycleEventEmitter - keepAliveInterval?: number - workerChannel: WorkerChannel - fallbackInterceptor?: Interceptor -} - export type ServiceWorkerInstanceTuple = [ ServiceWorker | null, ServiceWorkerRegistration, @@ -57,6 +42,7 @@ export interface StartOptions extends SharedOptions { * Defers any network requests until the Service Worker * instance is activated. * @default true + * @deprecated */ waitUntilReady?: boolean @@ -93,11 +79,11 @@ export interface SetupWorker { /** * Prepends given request handlers to the list of existing handlers. - * @param {RequestHandler[]} handlers List of runtime request handlers. + * @param {Array} handlers List of runtime request handlers. * * @see {@link https://mswjs.io/docs/api/setup-worker/use `worker.use()` API reference} */ - use: (...handlers: Array) => void + use: (...handlers: Array) => void /** * Marks all request handlers that respond using `res.once()` as unused. @@ -108,20 +94,18 @@ export interface SetupWorker { /** * Resets request handlers to the initial list given to the `setupWorker` call, or to the explicit next request handlers list, if given. - * @param {RequestHandler[]} nextHandlers List of the new initial request handlers. + * @param {Array} nextHandlers List of the new initial request handlers. * * @see {@link https://mswjs.io/docs/api/setup-worker/reset-handlers `worker.resetHandlers()` API reference} */ - resetHandlers: ( - ...nextHandlers: Array - ) => void + resetHandlers: (...nextHandlers: Array) => void /** * Returns a readonly list of currently active request handlers. * * @see {@link https://mswjs.io/docs/api/setup-worker/list-handlers `worker.listHandlers()` API reference} */ - listHandlers(): ReadonlyArray + listHandlers: () => ReadonlyArray /** * Life-cycle events. @@ -129,5 +113,7 @@ export interface SetupWorker { * * @see {@link https://mswjs.io/docs/api/life-cycle-events Life-cycle Events API reference} */ - events: LifeCycleEventEmitter + events: LifeCycleEventEmitter< + HttpNetworkFrameEventMap | WebSocketNetworkFrameEventMap + > } diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 390d68b95..f591bc1ad 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -3,15 +3,15 @@ import { defineNetwork, NetworkApi, NetworkHandlersApi, -} from '~/core/new/define-network' -import { type AnyHandler } from '~/core/new/handlers-controller' -import { InterceptorSource } from '~/core/new/sources/interceptor-source' -import { fromLegacyOnUnhandledRequest } from '~/core/new/compat' +} from '#core/new/define-network' +import { type AnyHandler } from '#core/new/handlers-controller' +import { InterceptorSource } from '#core/new/sources/interceptor-source' +import { type UnhandledRequestStrategy } from '#core/utils/request/onUnhandledRequest' +import { fromLegacyOnUnhandledRequest } from '#core/new/compat' import { supportsServiceWorker } from './utils/supports' import { ServiceWorkerSource } from './sources/service-worker-source' import { FallbackHttpSource } from './sources/fallback-http-source' import { type FindWorker } from './glossary' -import { type UnhandledRequestStrategy } from '~/core/utils/request/onUnhandledRequest' interface SetupWorkerApi extends NetworkHandlersApi { start: (options?: SetupWorkerStartOptions) => Promise diff --git a/src/browser/sources/fallback-http-source.ts b/src/browser/sources/fallback-http-source.ts index 6825cff85..3dc11791d 100644 --- a/src/browser/sources/fallback-http-source.ts +++ b/src/browser/sources/fallback-http-source.ts @@ -1,7 +1,7 @@ import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' -import { InterceptorSource } from '~/core/new/sources/interceptor-source' -import { devUtils } from '~/core/utils/internal/devUtils' +import { InterceptorSource } from '#core/new/sources/interceptor-source' +import { devUtils } from '#core/utils/internal/devUtils' export class FallbackHttpSource extends InterceptorSource { constructor() { diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index c3121f83b..c7e8d42d2 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -1,21 +1,21 @@ import { invariant } from 'outvariant' +import { Emitter, TypedEvent } from 'rettime' import { DeferredPromise } from '@open-draft/deferred-promise' import { FetchResponse } from '@mswjs/interceptors' -import { NetworkSource } from '~/core/new/sources/network-source' +import { NetworkSource } from '#core/new/sources/network-source' +import { RequestHandler } from '#core/handlers/RequestHandler' +import { HttpNetworkFrame } from '#core/new/frames/http-frame' +import { HttpResponse } from '#core/HttpResponse' +import { toResponseInit } from '#core/utils/toResponseInit' +import { devUtils } from '#core/utils/internal/devUtils' import { supportsReadableStreamTransfer, supportsServiceWorker, } from '../utils/supports' -import { getWorkerInstance } from '../setupWorker/start/utils/getWorkerInstance' -import { devUtils } from '~/core/utils/internal/devUtils' +import { getWorkerInstance } from '../utils/get-worker-instance' import { WorkerChannel, WorkerChannelEventMap } from '../utils/workerChannel' import { FindWorker } from '../glossary' -import { Emitter, TypedEvent } from 'rettime' import { deserializeRequest } from '../utils/deserializeRequest' -import { RequestHandler } from '~/core/handlers/RequestHandler' -import { HttpNetworkFrame } from '~/core/new/frames/http-frame' -import { HttpResponse } from '~/core/HttpResponse' -import { toResponseInit } from '~/core/utils/toResponseInit' export interface ServiceWorkerSourceOptions { quiet?: boolean diff --git a/src/browser/tsconfig.browser.json b/src/browser/tsconfig.browser.json index 6a44514da..9056a5805 100644 --- a/src/browser/tsconfig.browser.json +++ b/src/browser/tsconfig.browser.json @@ -1,9 +1,14 @@ { "extends": "../tsconfig.src.json", + "include": ["../../global.d.ts", "./global.browser.d.ts", "./**/*.ts"], + "references": [ + { + "path": "../tsconfig.core.json" + } + ], "compilerOptions": { // Expose browser-specific libraries only for the // source code under the "src/browser" directory. "lib": ["DOM", "WebWorker", "DOM.Iterable"] - }, - "include": ["../../global.d.ts", "./global.browser.d.ts", "./**/*.ts"] + } } diff --git a/src/browser/utils/get-worker-by-registration.ts b/src/browser/utils/get-worker-by-registration.ts new file mode 100644 index 000000000..62d9141b8 --- /dev/null +++ b/src/browser/utils/get-worker-by-registration.ts @@ -0,0 +1,27 @@ +import type { FindWorker } from '../glossary' + +/** + * Attempts to resolve a Service Worker instance from a given registration, + * regardless of its state (active, installing, waiting). + */ +export function getWorkerByRegistration( + registration: ServiceWorkerRegistration, + absoluteWorkerUrl: string, + findWorker: FindWorker, +): ServiceWorker | null { + const allStates = [ + registration.active, + registration.installing, + registration.waiting, + ] + + const relevantStates = allStates.filter((state): state is ServiceWorker => { + return state != null + }) + + const worker = relevantStates.find((worker) => { + return findWorker(worker.scriptURL, absoluteWorkerUrl) + }) + + return worker || null +} diff --git a/src/browser/utils/get-worker-instance.ts b/src/browser/utils/get-worker-instance.ts new file mode 100644 index 000000000..536968ab4 --- /dev/null +++ b/src/browser/utils/get-worker-instance.ts @@ -0,0 +1,97 @@ +import { until } from 'until-async' +import { devUtils } from '#core/utils/internal/devUtils' +import { getAbsoluteWorkerUrl } from './getAbsoluteWorkerUrl' +import { getWorkerByRegistration } from './get-worker-by-registration' +import type { ServiceWorkerInstanceTuple, FindWorker } from '../glossary' + +/** + * Returns an active Service Worker instance. + * When not found, registers a new Service Worker. + */ +export const getWorkerInstance = async ( + url: string, + options: RegistrationOptions = {}, + findWorker: FindWorker, +): Promise => { + // Resolve the absolute Service Worker URL. + 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) { + // Reload the page when it has associated workers, but no active controller. + // The absence of a controller can mean either: + // - page has no Service Worker associated with it + // - page has been hard-reloaded and its workers won't be used until the next reload. + // Since we've checked that there are registrations associated with this page, + // at this point we are sure it's hard reload that falls into this clause. + location.reload() + } + + const [existingRegistration] = mockRegistrations + + if (existingRegistration) { + // Schedule the worker update in the background. + // Update ensures the existing worker is up-to-date. + existingRegistration.update() + + // Return the worker reference immediately. + return [ + getWorkerByRegistration( + existingRegistration, + absoluteWorkerUrl, + findWorker, + ), + existingRegistration, + ] + } + + // When the Service Worker wasn't found, register it anew and return the reference. + const [registrationError, registrationResult] = await until< + Error, + ServiceWorkerInstanceTuple + >(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, + ] + }) + + // Handle Service Worker registration errors. + if (registrationError) { + const isWorkerMissing = registrationError.message.includes('(404)') + + // Produce a custom error message when given a non-existing Service Worker url. + // Suggest developers to check their setup. + 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 "? + +Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/init`), + ) + } + + // Fallback error message for any other registration errors. + throw new Error( + devUtils.formatMessage( + 'Failed to register the Service Worker:\n\n%s', + registrationError.message, + ), + ) + } + + return registrationResult +} diff --git a/src/browser/utils/pruneGetRequestBody.test.ts b/src/browser/utils/pruneGetRequestBody.test.ts index 46de5d4f8..aed4b42ce 100644 --- a/src/browser/utils/pruneGetRequestBody.test.ts +++ b/src/browser/utils/pruneGetRequestBody.test.ts @@ -1,6 +1,4 @@ -/** - * @vitest-environment jsdom - */ +// @vitest-environment jsdom import { TextEncoder } from 'util' import { pruneGetRequestBody } from './pruneGetRequestBody' diff --git a/src/browser/utils/workerChannel.ts b/src/browser/utils/workerChannel.ts index b9c0972b1..7b39f7114 100644 --- a/src/browser/utils/workerChannel.ts +++ b/src/browser/utils/workerChannel.ts @@ -1,6 +1,6 @@ import { invariant } from 'outvariant' import { Emitter, TypedEvent } from 'rettime' -import { isObject } from '~/core/utils/internal/isObject' +import { isObject } from '#core/utils/internal/isObject' import type { StringifiedResponse } from '../glossary' import { supportsServiceWorker } from '../utils/supports' diff --git a/src/core/new/sources/network-source.ts b/src/core/new/sources/network-source.ts index 4183b4ae7..2be5177c9 100644 --- a/src/core/new/sources/network-source.ts +++ b/src/core/new/sources/network-source.ts @@ -25,7 +25,13 @@ export abstract class NetworkSource< public abstract enable(): Promise public async queue(frame: Frame): Promise { - await this.emitter.emitAsPromise(new TypedEvent('frame', { data: frame })) + await this.emitter.emitAsPromise( + new TypedEvent( + // @ts-expect-error Trouble handling a conditional type parameter. + 'frame', + { data: frame }, + ), + ) } public on>( diff --git a/src/core/sharedOptions.ts b/src/core/sharedOptions.ts index 683c48c0a..4c55b53b4 100644 --- a/src/core/sharedOptions.ts +++ b/src/core/sharedOptions.ts @@ -13,6 +13,57 @@ export interface SharedOptions { onUnhandledRequest?: UnhandledRequestStrategy } +/** + * @deprecated + */ +export type LifeCycleEventsMap = { + 'request:start': [ + args: { + request: Request + requestId: string + }, + ] + 'request:match': [ + args: { + request: Request + requestId: string + }, + ] + 'request:unhandled': [ + args: { + request: Request + requestId: string + }, + ] + 'request:end': [ + args: { + request: Request + requestId: string + }, + ] + 'response:mocked': [ + args: { + response: Response + request: Request + requestId: string + }, + ] + 'response:bypass': [ + args: { + response: Response + request: Request + requestId: string + }, + ] + unhandledException: [ + args: { + error: Error + request: Request + requestId: string + }, + ] +} + export type LifeCycleEventEmitter = Pick< Emitter, 'on' | 'removeListener' | 'removeAllListeners' diff --git a/src/core/sse.ts b/src/core/sse.ts index 89d4c0887..aa726d9d5 100644 --- a/src/core/sse.ts +++ b/src/core/sse.ts @@ -6,7 +6,7 @@ import { type HttpRequestResolverExtras, type HttpRequestParsedResult, } from './handlers/HttpHandler' -import type { ResponseResolutionContext } from '~/core/utils/executeHandlers' +import type { ResponseResolutionContext } from '#core/utils/executeHandlers' import type { Path, PathParams } from './utils/matching/matchRequestUrl' import { delay } from './delay' import { getTimestamp } from './utils/logging/getTimestamp' diff --git a/src/iife/index.ts b/src/iife/index.ts index 189ebc2ec..829e2c979 100644 --- a/src/iife/index.ts +++ b/src/iife/index.ts @@ -1,2 +1,2 @@ -export * from '~/core' +export * from '#core' export * from '../browser' diff --git a/src/native/index.ts b/src/native/index.ts index c7941bdab..7d79ea60b 100644 --- a/src/native/index.ts +++ b/src/native/index.ts @@ -1,7 +1,7 @@ import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' import { SetupServerCommonApi } from '../node/setup-server-common' -import { type AnyHandler } from '~/core/new/handlers-controller' +import { type AnyHandler } from '#core/new/handlers-controller' /** * Sets up a requests interception in React Native with the given request handlers. diff --git a/src/node/async-handlers-controller.ts b/src/node/async-handlers-controller.ts index 2aea5029e..678c4cc19 100644 --- a/src/node/async-handlers-controller.ts +++ b/src/node/async-handlers-controller.ts @@ -2,7 +2,7 @@ import { AsyncLocalStorage } from 'node:async_hooks' import { type AnyHandler, HandlersController, -} from '~/core/new/handlers-controller' +} from '#core/new/handlers-controller' export interface AsyncHandlersControllerContext { initialHandlers: Array diff --git a/src/node/glossary.ts b/src/node/glossary.ts index e36004155..0043c26e0 100644 --- a/src/node/glossary.ts +++ b/src/node/glossary.ts @@ -1,8 +1,8 @@ import type { PartialDeep } from 'type-fest' -import { type HttpNetworkFrameEventMap } from '~/core/new/frames/http-frame' -import { type WebSocketNetworkFrameEventMap } from '~/core/new/frames/websocket-frame' -import { type AnyHandler } from '~/core/new/handlers-controller' -import type { LifeCycleEventEmitter, SharedOptions } from '~/core/sharedOptions' +import { type HttpNetworkFrameEventMap } from '#core/new/frames/http-frame' +import { type WebSocketNetworkFrameEventMap } from '#core/new/frames/websocket-frame' +import { type AnyHandler } from '#core/new/handlers-controller' +import type { LifeCycleEventEmitter, SharedOptions } from '#core/sharedOptions' export interface ListenOptions extends SharedOptions {} diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts index efb00c1bf..0d70f6d82 100644 --- a/src/node/setup-server-common.ts +++ b/src/node/setup-server-common.ts @@ -1,11 +1,11 @@ import type { PartialDeep } from 'type-fest' import { Interceptor } from '@mswjs/interceptors' import type { ListenOptions, SetupServerCommon } from './glossary' -import { type NetworkApi, defineNetwork } from '~/core/new/define-network' -import { type AnyHandler } from '~/core/new/handlers-controller' -import { HandlersController } from '~/core/new/handlers-controller' -import { InterceptorSource } from '~/core/new/sources/interceptor-source' -import { fromLegacyOnUnhandledRequest } from '~/core/new/compat' +import { type NetworkApi, defineNetwork } from '#core/new/define-network' +import { type AnyHandler } from '#core/new/handlers-controller' +import { HandlersController } from '#core/new/handlers-controller' +import { InterceptorSource } from '#core/new/sources/interceptor-source' +import { fromLegacyOnUnhandledRequest } from '#core/new/compat' export class SetupServerCommonApi implements SetupServerCommon { #listenOptions?: PartialDeep diff --git a/src/node/setup-server.ts b/src/node/setup-server.ts index 2d5c0fc9f..7196d0410 100644 --- a/src/node/setup-server.ts +++ b/src/node/setup-server.ts @@ -4,7 +4,7 @@ import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' import { SetupServer } from './glossary' -import { type AnyHandler } from '~/core/new/handlers-controller' +import { type AnyHandler } from '#core/new/handlers-controller' import { AsyncHandlersController } from './async-handlers-controller' import { SetupServerCommonApi } from './setup-server-common' diff --git a/src/tsconfig.core.json b/src/tsconfig.core.json new file mode 100644 index 000000000..723150293 --- /dev/null +++ b/src/tsconfig.core.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.src.json", + "include": ["./core/**/*.ts"], + "files": [], + "compilerOptions": { + "composite": true + } +} diff --git a/src/tsconfig.node.json b/src/tsconfig.node.json index c98a860ae..c71d2c27c 100644 --- a/src/tsconfig.node.json +++ b/src/tsconfig.node.json @@ -1,8 +1,13 @@ { "extends": "./tsconfig.src.json", + "include": ["./node", "./native"], + "exclude": ["**/*.test.ts"], + "references": [ + { + "path": "./tsconfig.src.json" + } + ], "compilerOptions": { "types": ["node"] - }, - "include": ["./node", "./native"], - "exclude": ["**/*.test.ts"] + } } diff --git a/src/tsconfig.src.json b/src/tsconfig.src.json index 87ad65fc8..58f2e8991 100644 --- a/src/tsconfig.src.json +++ b/src/tsconfig.src.json @@ -1,6 +1,4 @@ { - // Common configuration for everything - // living in the "src" directory. "extends": "../tsconfig.base.json", "compilerOptions": { "composite": true diff --git a/src/tsconfig.worker.json b/src/tsconfig.worker.json index 26b178ebb..d0f218d5c 100644 --- a/src/tsconfig.worker.json +++ b/src/tsconfig.worker.json @@ -1,10 +1,11 @@ { "include": ["./mockServiceWorker.js"], + "files": [], "compilerOptions": { + "composite": true, "strict": true, "allowJs": true, "checkJs": true, - "noEmit": true, "target": "esnext", "module": "esnext", "lib": ["esnext"], diff --git a/tsconfig.base.json b/tsconfig.base.json index 655909c98..39ca0d911 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -3,14 +3,13 @@ "strict": true, "target": "esnext", "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "strictNullChecks": true, "skipLibCheck": true, "allowSyntheticDefaultImports": false, - "baseUrl": "./", "paths": { - "~/core": ["src/core"], - "~/core/*": ["src/core/*"] + "#core": ["./src/core"], + "#core/*": ["./src/core/*"] } }, "include": ["./global.d.ts"], diff --git a/tsup.config.ts b/tsup.config.ts index 76fe8e8d6..9855bb47a 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -16,7 +16,7 @@ const ecosystemDependencies = /^@mswjs\/(.+)$/ // Externalize the core functionality (reused across environments) // so that it can be shared between the environments. -const mswCore = /\/core(\/.+)?$/ +const mswCore = /#core(\/.+)?$/ const SERVICE_WORKER_CHECKSUM = getWorkerChecksum() diff --git a/vitest.config.mts b/vitest.config.mts index 641e0942b..fe79735ef 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -14,7 +14,7 @@ export default defineConfig({ alias: { ...mswExports, ...customViteEnvironments, - '~/core': fromRoot('src/core'), + '#core': fromRoot('src/core'), }, typecheck: { // Load the TypeScript configuration to the unit tests. From 2d33af0a1da1686ca20612364483bffea477d222 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 10:24:16 +0100 Subject: [PATCH 15/68] fix(setupWorker): add node.js environment check --- src/browser/setup-worker.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index f591bc1ad..087c217e3 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -12,6 +12,9 @@ import { supportsServiceWorker } from './utils/supports' import { ServiceWorkerSource } from './sources/service-worker-source' import { FallbackHttpSource } from './sources/fallback-http-source' import { type FindWorker } from './glossary' +import { invariant } from 'outvariant' +import { isNodeProcess } from 'is-node-process' +import { devUtils } from '#core/utils/internal/devUtils' interface SetupWorkerApi extends NetworkHandlersApi { start: (options?: SetupWorkerStartOptions) => Promise @@ -39,6 +42,13 @@ const DEFAULT_WORKER_URL = '/mockServiceWorker.js' export function setupWorker(...handlers: Array): SetupWorkerApi { let network: NetworkApi<[ServiceWorkerSource]> + invariant( + !isNodeProcess(), + devUtils.formatMessage( + 'Failed to execute `setupWorker` in a non-browser environment', + ), + ) + return { async start(options) { const httpSource = supportsServiceWorker() From bfbe16c6a7f28aff172771b3ba6ef540f993286a Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 10:25:31 +0100 Subject: [PATCH 16/68] chore: fix some tests --- src/core/new/frames/http-frame.ts | 6 +++--- src/native/index.ts | 2 +- src/node/glossary.ts | 6 +++--- src/tsconfig.core.json | 2 +- .../request/body/body-blob.node.test.ts | Bin 1441 -> 1459 bytes .../request/body/body-form-data.node.test.ts | 6 +++--- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/new/frames/http-frame.ts b/src/core/new/frames/http-frame.ts index f64bc2388..4b666cc91 100644 --- a/src/core/new/frames/http-frame.ts +++ b/src/core/new/frames/http-frame.ts @@ -25,7 +25,7 @@ export class RequestEvent< public readonly request: Request constructor(type: EventType, data: DataType) { - super(...([type] as any)) + super(...([type, {}] as any)) this.requestId = data.requestId this.request = data.request } @@ -49,7 +49,7 @@ export class ResponseEvent< public readonly response: Response constructor(type: EventType, data: DataType) { - super(...([type] as any)) + super(...([type, {}] as any)) this.requestId = data.requestId this.request = data.request this.response = data.response @@ -74,7 +74,7 @@ export class UnhandledExceptionEvent< public readonly request: Request constructor(type: EventType, data: DataType) { - super(...([type] as any)) + super(...([type, {}] as any)) this.error = data.error this.requestId = data.requestId this.request = data.request diff --git a/src/native/index.ts b/src/native/index.ts index 7d79ea60b..9cb053045 100644 --- a/src/native/index.ts +++ b/src/native/index.ts @@ -1,7 +1,7 @@ import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' -import { SetupServerCommonApi } from '../node/setup-server-common' import { type AnyHandler } from '#core/new/handlers-controller' +import { SetupServerCommonApi } from '../node/setup-server-common' /** * Sets up a requests interception in React Native with the given request handlers. diff --git a/src/node/glossary.ts b/src/node/glossary.ts index 0043c26e0..b1be5b3d1 100644 --- a/src/node/glossary.ts +++ b/src/node/glossary.ts @@ -1,7 +1,7 @@ import type { PartialDeep } from 'type-fest' -import { type HttpNetworkFrameEventMap } from '#core/new/frames/http-frame' -import { type WebSocketNetworkFrameEventMap } from '#core/new/frames/websocket-frame' -import { type AnyHandler } from '#core/new/handlers-controller' +import type { HttpNetworkFrameEventMap } from '#core/new/frames/http-frame' +import type { WebSocketNetworkFrameEventMap } from '#core/new/frames/websocket-frame' +import type { AnyHandler } from '#core/new/handlers-controller' import type { LifeCycleEventEmitter, SharedOptions } from '#core/sharedOptions' export interface ListenOptions extends SharedOptions {} diff --git a/src/tsconfig.core.json b/src/tsconfig.core.json index 723150293..dfc88cb0f 100644 --- a/src/tsconfig.core.json +++ b/src/tsconfig.core.json @@ -1,5 +1,5 @@ { - "extends": "../tsconfig.src.json", + "extends": "./tsconfig.src.json", "include": ["./core/**/*.ts"], "files": [], "compilerOptions": { diff --git a/test/node/rest-api/request/body/body-blob.node.test.ts b/test/node/rest-api/request/body/body-blob.node.test.ts index 3a817c3810855ccd0ea8ee762369aa973cb4a3bb..c95a23d857efa05174cb326ce04a215057e44a5d 100644 GIT binary patch delta 94 zcmZ3;y_tK%W+t`7^2E#%h180I)Z`M4qSWGo{Ji2+y`-G{Bn?eXJ)l5-PFZU4<_k={ L#HyWK#i|Yfk98vD delta 76 zcmdnYy^wpuW+vIxih|VS5{<<2#LNSGd DN9`M| diff --git a/test/node/rest-api/request/body/body-form-data.node.test.ts b/test/node/rest-api/request/body/body-form-data.node.test.ts index 06b98ab69..7fb346808 100644 --- a/test/node/rest-api/request/body/body-form-data.node.test.ts +++ b/test/node/rest-api/request/body/body-form-data.node.test.ts @@ -47,7 +47,7 @@ it('supports FormData request body', async () => { }) const json = await res.json() - expect(res.status).toBe(200) + expect.soft(res.status).toBe(200) expect(json).toEqual([ ['username', 'john.maverick'], ['password', 'secret123'], @@ -66,8 +66,8 @@ it('respects Blob size in request body', async () => { body: formData, }) - expect(response.status).toBe(200) - expect(await response.json()).toEqual({ + expect.soft(response.status).toBe(200) + await expect(response.json()).resolves.toEqual({ name: 'data.json', size: blob.size, content: await blob.text(), From 12ddb9f4ab78d2bbe7251379f8f388986517b0e0 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 10:31:26 +0100 Subject: [PATCH 17/68] fix(onUnhandledFrame): check for common assets after function check --- src/core/new/frames/http-frame.ts | 5 +++-- src/core/new/on-unhandled-frame.ts | 21 ++++++++++++------- .../life-cycle-events/on.node.test.ts | 2 +- .../callback.node.test.ts | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/core/new/frames/http-frame.ts b/src/core/new/frames/http-frame.ts index 4b666cc91..72033af0c 100644 --- a/src/core/new/frames/http-frame.ts +++ b/src/core/new/frames/http-frame.ts @@ -212,8 +212,9 @@ export abstract class HttpNetworkFrame extends NetworkFrame< await storeResponseCookies(request, response) this.events.emit( - new TypedEvent('request:match', { - data: { requestId, request }, + new RequestEvent('request:match', { + requestId, + request, }), ) diff --git a/src/core/new/on-unhandled-frame.ts b/src/core/new/on-unhandled-frame.ts index f77d1e5d4..cd3a3b8e6 100644 --- a/src/core/new/on-unhandled-frame.ts +++ b/src/core/new/on-unhandled-frame.ts @@ -23,14 +23,6 @@ export async function onUnhandledFrame( frame: AnyNetworkFrame, handle: UnhandledFrameHandle, ): Promise { - // Ignore unhandled common HTTP assets. - if ( - frame instanceof HttpNetworkFrame && - isCommonAssetRequest(frame.data.request) - ) { - return - } - const applyStrategy = async (strategy: UnhandledFrameStrategy) => { if (strategy === 'bypass') { return @@ -77,5 +69,18 @@ export async function onUnhandledFrame( }) } + /** + * Ignore unhandled common HTTP assets. + * @note Calling this here applies the common assets check + * only to the scenarios when `onUnhandledFrame` was set to a predefined strategy. + * When using a custom function, you need to check for common assets manually. + */ + if ( + frame instanceof HttpNetworkFrame && + isCommonAssetRequest(frame.data.request) + ) { + return + } + return applyStrategy(handle) } diff --git a/test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts b/test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts index 0e8482851..b531b0663 100644 --- a/test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts +++ b/test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts @@ -60,7 +60,7 @@ afterAll(async () => { await httpServer.close() }) -test.only('emits events for a handled request and mocked response', async () => { +test('emits events for a handled request and mocked response', async () => { const listener = spyOnEvents(server) const url = httpServer.http.url('/user') await fetch(url) diff --git a/test/node/msw-api/setup-server/scenarios/on-unhandled-request/callback.node.test.ts b/test/node/msw-api/setup-server/scenarios/on-unhandled-request/callback.node.test.ts index edf7db895..75b2636ff 100644 --- a/test/node/msw-api/setup-server/scenarios/on-unhandled-request/callback.node.test.ts +++ b/test/node/msw-api/setup-server/scenarios/on-unhandled-request/callback.node.test.ts @@ -19,7 +19,7 @@ beforeAll(() => { }) afterEach(() => { - vi.resetAllMocks() + vi.clearAllMocks() }) afterAll(() => { From 48160ece65e9786c3f578ccc83edb5c0609ef76e Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 11:15:23 +0100 Subject: [PATCH 18/68] fix: use node 24, surface lookup errors --- .nvmrc | 2 +- package.json | 2 +- pnpm-lock.yaml | 10 ++++----- src/core/new/define-network.ts | 7 +++++- src/core/new/frames/http-frame.ts | 20 ++++++++++++------ .../request/body/body-blob.node.test.ts | Bin 1459 -> 1599 bytes 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/.nvmrc b/.nvmrc index 54c65116f..53d1c14db 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v24 +v22 diff --git a/package.json b/package.json index f3589c7f0..d38638067 100644 --- a/package.json +++ b/package.json @@ -248,7 +248,7 @@ "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", - "rettime": "^0.9.0", + "rettime": "^0.9.1", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c37ca3f13..e0ab5b763 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,8 +42,8 @@ importers: specifier: ^1.1.1 version: 1.1.1 rettime: - specifier: ^0.9.0 - version: 0.9.0 + specifier: ^0.9.1 + version: 0.9.1 statuses: specifier: ^2.0.2 version: 2.0.2 @@ -4315,8 +4315,8 @@ packages: resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} engines: {node: '>=10'} - rettime@0.9.0: - resolution: {integrity: sha512-mj6hOrwD8UA+jFqyCiSBxm8MI+qhYeSqS0aNcGfPkVmmCyHNFRr3hoQUTTZ3iBgk1x4ZNXnvSzluFZM4kcx/gA==} + rettime@0.9.1: + resolution: {integrity: sha512-UszoaHy8mQkQZCbEYjw+J21ZZ+VhiTAYK47Tl+wm8VSbTRronhJiheSNlRo0ED/6zUG9vbIY7gRu7ZfColdVnw==} reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} @@ -9711,7 +9711,7 @@ snapshots: ret@0.5.0: {} - rettime@0.9.0: {} + rettime@0.9.1: {} reusify@1.0.4: {} diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index 5354b943c..54d328110 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -66,8 +66,13 @@ export function defineNetwork>>( source.on( 'frame', async ({ data: frame }: { data: AnyNetworkFrame }) => { + /** + * @fixme This typeless listener makes it so all emits are treated as + * having a listener. That makes it hard for the library to know whether + * the user has actually defined any listeners. + */ frame.events.on((event) => { - events.emit(event as any) + events.emit(event) }) /** diff --git a/src/core/new/frames/http-frame.ts b/src/core/new/frames/http-frame.ts index 72033af0c..d26acd673 100644 --- a/src/core/new/frames/http-frame.ts +++ b/src/core/new/frames/http-frame.ts @@ -7,6 +7,7 @@ import { type HttpHandler } from '../../handlers/HttpHandler' import { executeHandlers } from '../../utils/executeHandlers' import { storeResponseCookies } from '../../utils/request/storeResponseCookies' import { isPassthroughResponse, shouldBypassRequest } from '../request-utils' +import { devUtils } from '../../utils/internal/devUtils' interface HttpNetworkFrameOptions { id?: string @@ -149,13 +150,18 @@ export abstract class HttpNetworkFrame extends NetworkFrame< }) if (lookupError != null) { - this.events.emit( - new UnhandledExceptionEvent('unhandledException', { - error: lookupError, - requestId, - request, - }), - ) + if ( + !this.events.emit( + new UnhandledExceptionEvent('unhandledException', { + error: lookupError, + requestId, + request, + }), + ) + ) { + // Surface the error to the developer since they haven't handled it. + devUtils.error('HAH!') + } this.errorWith(lookupError) return null diff --git a/test/node/rest-api/request/body/body-blob.node.test.ts b/test/node/rest-api/request/body/body-blob.node.test.ts index c95a23d857efa05174cb326ce04a215057e44a5d..68b5dfb110062f2c6fdff6531b35d6481d8c4ed2 100644 GIT binary patch delta 156 zcmdnYy`N{pW+vy6) From 7e2bf32864db6374aa782841905651e22fac42e5 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 11:55:16 +0100 Subject: [PATCH 19/68] chore: fix type issues, run on node 22 --- .github/workflows/ci.yml | 12 ++++++------ .github/workflows/compat.yml | 4 ++-- .github/workflows/release-preview.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/smoke-test.yml | 2 +- .github/workflows/typescript-nightly.yml | 4 ++-- src/core/new/handlers-controller.ts | 3 ++- src/core/utils/cookieStore.ts | 3 ++- src/tsconfig.node.json | 2 +- test/browser/msw-api/integrity-check.test.ts | 2 +- test/modules/module-utils.ts | 4 ++-- test/tsconfig.json | 2 +- test/typings/tsconfig.json | 2 +- test/typings/vitest.config.ts | 2 +- 14 files changed, 24 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f94459f4..d1918c887 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'pnpm' - name: Install dependencies @@ -93,7 +93,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'pnpm' - name: Restore build cache @@ -129,7 +129,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'pnpm' - name: Restore build cache @@ -195,7 +195,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'pnpm' - name: Install dependencies @@ -220,7 +220,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'pnpm' - name: Restore build cache @@ -263,7 +263,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'pnpm' - name: Restore build cache diff --git a/.github/workflows/compat.yml b/.github/workflows/compat.yml index 7e93f9b19..dbe2f418f 100644 --- a/.github/workflows/compat.yml +++ b/.github/workflows/compat.yml @@ -17,7 +17,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Set up pnpm uses: pnpm/action-setup@v4 @@ -62,7 +62,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - uses: pnpm/action-setup@v4 with: diff --git a/.github/workflows/release-preview.yml b/.github/workflows/release-preview.yml index c31bdec83..718bd1e69 100644 --- a/.github/workflows/release-preview.yml +++ b/.github/workflows/release-preview.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Set up pnpm uses: pnpm/action-setup@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8645ea6fc..2b2edf601 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 always-auth: true registry-url: https://registry.npmjs.org diff --git a/.github/workflows/smoke-test.yml b/.github/workflows/smoke-test.yml index f7bfbd3ae..c881f2c93 100644 --- a/.github/workflows/smoke-test.yml +++ b/.github/workflows/smoke-test.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Set up pnpm uses: pnpm/action-setup@v4 diff --git a/.github/workflows/typescript-nightly.yml b/.github/workflows/typescript-nightly.yml index 61200ab55..022f54759 100644 --- a/.github/workflows/typescript-nightly.yml +++ b/.github/workflows/typescript-nightly.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Get latest TypeScript version id: get-versions @@ -42,7 +42,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Set up pnpm uses: pnpm/action-setup@v4 diff --git a/src/core/new/handlers-controller.ts b/src/core/new/handlers-controller.ts index c50e32635..41b006022 100644 --- a/src/core/new/handlers-controller.ts +++ b/src/core/new/handlers-controller.ts @@ -1,9 +1,10 @@ import { invariant } from 'outvariant' import { type HttpHandler } from '../handlers/HttpHandler' +import { type GraphQLHandler } from '../handlers/GraphQLHandler' import { type WebSocketHandler } from '../handlers/WebSocketHandler' import { devUtils } from '../utils/internal/devUtils' -export type AnyHandler = HttpHandler | WebSocketHandler +export type AnyHandler = HttpHandler | GraphQLHandler | WebSocketHandler function validateHandlers(handlers: Array): boolean { return handlers.every((handler) => !Array.isArray(handler)) diff --git a/src/core/utils/cookieStore.ts b/src/core/utils/cookieStore.ts index b62a0e603..671b1fd2b 100644 --- a/src/core/utils/cookieStore.ts +++ b/src/core/utils/cookieStore.ts @@ -4,6 +4,7 @@ import { Cookie, CookieJar, MemoryCookieStore, + SerializedCookie, type MemoryCookieStoreIndex, } from 'tough-cookie' import { jsonParse } from './internal/jsonParse' @@ -76,7 +77,7 @@ class CookieStore { return } - const data = [] + const data: Array = [] const { idx } = this.#memoryStore for (const domain in idx) { diff --git a/src/tsconfig.node.json b/src/tsconfig.node.json index c71d2c27c..af3707338 100644 --- a/src/tsconfig.node.json +++ b/src/tsconfig.node.json @@ -8,6 +8,6 @@ } ], "compilerOptions": { - "types": ["node"] + "types": ["@types/node"] } } diff --git a/test/browser/msw-api/integrity-check.test.ts b/test/browser/msw-api/integrity-check.test.ts index 8916272e3..be9599049 100644 --- a/test/browser/msw-api/integrity-check.test.ts +++ b/test/browser/msw-api/integrity-check.test.ts @@ -1,7 +1,7 @@ import fs from 'node:fs' import { test, expect } from '../playwright.extend' import copyServiceWorker from '../../../config/copyServiceWorker' -import packageJson from '../../../package.json' assert { type: 'json' } +import packageJson from '../../../package.json' with { type: 'json' } // @ts-expect-error Importing a Javascript module. import { SERVICE_WORKER_SOURCE_PATH } from '../../../config/constants.js' diff --git a/test/modules/module-utils.ts b/test/modules/module-utils.ts index 9d56131d7..4ae2f2397 100644 --- a/test/modules/module-utils.ts +++ b/test/modules/module-utils.ts @@ -2,7 +2,7 @@ import fs from 'node:fs' import url from 'node:url' import { spawnSync } from 'node:child_process' import { invariant } from 'outvariant' -import packageJson from '../../package.json' assert { type: 'json' } +import packageJson from '../../package.json' with { type: 'json' } async function getLibraryTarball(): Promise { const ROOT_PATH = new URL('../..', import.meta.url) @@ -25,7 +25,7 @@ async function getLibraryTarball(): Promise { invariant( fs.existsSync(packPath), - 'Failed to pack the library at "%s"', + 'Failed to pack the library at "%s": packing does not produce the package file', packPath, ) diff --git a/test/tsconfig.json b/test/tsconfig.json index 4a22db762..cddde0e2e 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -14,7 +14,7 @@ "esModuleInterop": true, "declaration": false, "noEmit": true, - "types": ["node", "vitest/globals"] + "types": ["@types/node", "vitest/globals"] }, "include": ["**/*.ts"] } diff --git a/test/typings/tsconfig.json b/test/typings/tsconfig.json index 078d82067..2b9c3618a 100644 --- a/test/typings/tsconfig.json +++ b/test/typings/tsconfig.json @@ -10,7 +10,7 @@ "strictBindCallApply": true, "strictFunctionTypes": true, "rootDir": "../..", - "lib": ["dom"] + "lib": ["dom", "es2015", "DOM.Iterable"] }, "include": ["../../global.d.ts", "**/*.test-d.ts"], "exclude": ["node_modules"] diff --git a/test/typings/vitest.config.ts b/test/typings/vitest.config.ts index e24c96598..eb09f91aa 100644 --- a/test/typings/vitest.config.ts +++ b/test/typings/vitest.config.ts @@ -3,7 +3,7 @@ import url from 'node:url' import path from 'node:path' import { defineConfig } from 'vitest/config' import { invariant } from 'outvariant' -import tsPackageJson from 'typescript/package.json' assert { type: 'json' } +import tsPackageJson from 'typescript/package.json' with { type: 'json' } import { mswExports } from '../support/alias' const TEST_ROOT = url.fileURLToPath(new URL('./', import.meta.url)) From 36d8f5a5d535d964d983a4a990f965097ee0acf8 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 15:08:55 +0100 Subject: [PATCH 20/68] fix(setupWorker): print stop message on `.disable()` --- src/browser/sources/service-worker-source.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index c7e8d42d2..b289cf622 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -110,6 +110,8 @@ export class ServiceWorkerSource extends NetworkSource { @@ -308,6 +310,18 @@ export class ServiceWorkerSource extends NetworkSource Date: Wed, 14 Jan 2026 15:15:57 +0100 Subject: [PATCH 21/68] fix(defineNetwork): merge `controller` and `handlers` options --- src/core/new/define-network.ts | 10 ++++++---- src/node/setup-server-common.ts | 4 +--- src/node/setup-server.ts | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index 54d328110..158566503 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -9,7 +9,7 @@ import { onUnhandledFrame, UnhandledFrameHandle } from './on-unhandled-frame' import { isHandlerKind } from '../utils/internal/isHandlerKind' import { AnyHandler, - type HandlersController, + HandlersController, InMemoryHandlersController, } from './handlers-controller' import { toReadonlyArray } from '../utils/internal/toReadonlyArray' @@ -31,9 +31,8 @@ export interface DefineNetworkOptions< Sources extends Array>, > { sources: Sources - handlers?: Array + handlers?: Array | HandlersController context?: NetworkFrameResolutionContext - controller?: HandlersController onUnhandledFrame?: UnhandledFrameHandle } @@ -55,8 +54,11 @@ export function defineNetwork>>( options: DefineNetworkOptions, ): NetworkApi { const events = new Emitter>() + const handlersController = - options.controller || new InMemoryHandlersController(options.handlers || []) + options.handlers instanceof HandlersController + ? options.handlers + : new InMemoryHandlersController(options.handlers || []) return { events, diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts index 0d70f6d82..bfbcc0eb2 100644 --- a/src/node/setup-server-common.ts +++ b/src/node/setup-server-common.ts @@ -14,13 +14,11 @@ export class SetupServerCommonApi implements SetupServerCommon { constructor( interceptors: Array>, - handlers: Array, - handlersController?: HandlersController, + handlers: Array | HandlersController, ) { this.network = defineNetwork({ sources: [new InterceptorSource({ interceptors })], handlers, - controller: handlersController, onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { return this.#listenOptions?.onUnhandledRequest || 'warn' }), diff --git a/src/node/setup-server.ts b/src/node/setup-server.ts index 7196d0410..a5f2a0f29 100644 --- a/src/node/setup-server.ts +++ b/src/node/setup-server.ts @@ -38,7 +38,7 @@ export class SetupServerApi interceptors: Array>, ) { const controller = new AsyncHandlersController(handlers) - super(interceptors, handlers, controller) + super(interceptors, controller) this.#handlersController = controller } From fd3776e1c70d07a5ff41f9282bb4a4a2d8396a93 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 15:17:24 +0100 Subject: [PATCH 22/68] chore(setupWorker): reorder imports --- src/browser/setup-worker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 087c217e3..a3104557b 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -1,3 +1,5 @@ +import { invariant } from 'outvariant' +import { isNodeProcess } from 'is-node-process' import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' import { defineNetwork, @@ -8,13 +10,11 @@ import { type AnyHandler } from '#core/new/handlers-controller' import { InterceptorSource } from '#core/new/sources/interceptor-source' import { type UnhandledRequestStrategy } from '#core/utils/request/onUnhandledRequest' import { fromLegacyOnUnhandledRequest } from '#core/new/compat' +import { devUtils } from '#core/utils/internal/devUtils' import { supportsServiceWorker } from './utils/supports' import { ServiceWorkerSource } from './sources/service-worker-source' import { FallbackHttpSource } from './sources/fallback-http-source' import { type FindWorker } from './glossary' -import { invariant } from 'outvariant' -import { isNodeProcess } from 'is-node-process' -import { devUtils } from '#core/utils/internal/devUtils' interface SetupWorkerApi extends NetworkHandlersApi { start: (options?: SetupWorkerStartOptions) => Promise From 99cc047d698afef94ed49ff5d3f0735d56d2330b Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 14 Jan 2026 15:20:44 +0100 Subject: [PATCH 23/68] fix(setupWorker): forward start options to service worker source --- src/browser/setup-worker.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index a3104557b..654847475 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -54,9 +54,11 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { const httpSource = supportsServiceWorker() ? new ServiceWorkerSource({ serviceWorker: { - url: DEFAULT_WORKER_URL, + url: + options?.serviceWorker?.url?.toString() || DEFAULT_WORKER_URL, + options: options?.serviceWorker?.options, }, - findWorker: undefined, + findWorker: options?.findWorker, }) : new FallbackHttpSource() @@ -71,6 +73,9 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { return options?.onUnhandledRequest || 'warn' }), + context: { + quiet: options?.quiet, + }, }) await network.enable() From 6359d63871c76830a7418024cc549cc712ed69b7 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Thu, 15 Jan 2026 10:49:05 +0100 Subject: [PATCH 24/68] fix(setupWorker): print `worker.scriptURL` in the start message --- src/browser/index.ts | 2 +- src/browser/setup-worker.ts | 2 +- src/browser/sources/service-worker-source.ts | 22 ++++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/browser/index.ts b/src/browser/index.ts index 1200dd07d..79cd66359 100644 --- a/src/browser/index.ts +++ b/src/browser/index.ts @@ -1,2 +1,2 @@ -export { setupWorker } from './setup-worker' +export { setupWorker, type SetupWorkerApi } from './setup-worker' export type { SetupWorker, StartOptions } from './glossary' diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 654847475..404a9ef59 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -16,7 +16,7 @@ import { ServiceWorkerSource } from './sources/service-worker-source' import { FallbackHttpSource } from './sources/fallback-http-source' import { type FindWorker } from './glossary' -interface SetupWorkerApi extends NetworkHandlersApi { +export interface SetupWorkerApi extends NetworkHandlersApi { start: (options?: SetupWorkerStartOptions) => Promise stop: () => void } diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index b289cf622..a94ce0e54 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -67,18 +67,17 @@ export class ServiceWorkerSource extends NetworkSource() activationPromise.then(() => controller.abort()) - pendingInstance.addEventListener( + worker.addEventListener( 'statechange', () => { - if (pendingInstance.state === 'activated') { + if (worker.state === 'activated') { activationPromise.resolve() } }, @@ -114,7 +113,7 @@ export class ServiceWorkerSource extends NetworkSource { + async #startWorker() { if (this.#keepAliveInterval) { clearInterval(this.#keepAliveInterval) } @@ -151,6 +150,7 @@ export class ServiceWorkerSource extends NetworkSource { @@ -273,16 +273,16 @@ export class ServiceWorkerSource extends NetworkSource Date: Wed, 28 Jan 2026 16:22:01 +0100 Subject: [PATCH 25/68] fix(defineNetwork): implement `.configure()` for late config options --- pnpm-lock.yaml | 5510 +++++++---------- src/browser/setup-worker.ts | 18 +- src/browser/sources/service-worker-source.ts | 31 +- src/core/new/define-network.ts | 48 +- src/core/new/frames/http-frame.ts | 7 +- .../msw-api/setup-worker/start/start.test.ts | 2 +- 6 files changed, 2413 insertions(+), 3203 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e0ab5b763..16ca44d07 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@inquirer/confirm': specifier: ^5.0.0 - version: 5.0.2(@types/node@20.19.25) + version: 5.1.21(@types/node@20.19.30) '@mswjs/interceptors': specifier: ^0.40.0 version: 0.40.0 @@ -22,7 +22,7 @@ importers: version: 2.0.6 cookie: specifier: ^1.0.2 - version: 1.0.2 + version: 1.1.1 graphql: specifier: ^16.12.0 version: 16.12.0 @@ -55,7 +55,7 @@ importers: version: 6.0.0 type-fest: specifier: ^5.2.0 - version: 5.2.0 + version: 5.4.2 until-async: specifier: ^3.0.2 version: 3.0.2 @@ -65,19 +65,19 @@ importers: devDependencies: '@commitlint/cli': specifier: ^20.1.0 - version: 20.1.0(@types/node@20.19.25)(typescript@5.9.3) + version: 20.3.1(@types/node@20.19.30)(typescript@5.9.3) '@commitlint/config-conventional': specifier: ^20.0.0 - version: 20.0.0 + version: 20.3.1 '@epic-web/test-server': specifier: ^0.1.6 version: 0.1.6 '@eslint/eslintrc': specifier: ^3.3.1 - version: 3.3.1 + version: 3.3.3 '@eslint/js': specifier: ^9.39.1 - version: 9.39.1 + version: 9.39.2 '@fastify/websocket': specifier: ^11.2.0 version: 11.2.0 @@ -89,40 +89,40 @@ importers: version: 0.4.2 '@ossjs/release': specifier: ^0.10.0 - version: 0.10.0 + version: 0.10.1 '@playwright/test': specifier: ^1.50.1 - version: 1.56.1 + version: 1.58.0 '@types/express': specifier: ^5.0.5 - version: 5.0.5 + version: 5.0.6 '@types/json-bigint': specifier: ^1.0.4 version: 1.0.4 '@types/node': specifier: ~20.19.25 - version: 20.19.25 + version: 20.19.30 '@types/serviceworker': specifier: ^0.0.167 version: 0.0.167 '@typescript-eslint/eslint-plugin': specifier: ^8.47.0 - version: 8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': specifier: ^8.47.0 - version: 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@web/dev-server': specifier: ^0.4.6 version: 0.4.6 axios: specifier: ^1.13.2 - version: 1.13.2 + version: 1.13.4 babel-minify: specifier: ^0.5.1 version: 0.5.2 commitizen: specifier: ^4.3.1 - version: 4.3.1(@types/node@20.19.25)(typescript@5.9.3) + version: 4.3.1(@types/node@20.19.30)(typescript@5.9.3) cross-env: specifier: ^10.1.0 version: 10.1.0 @@ -131,28 +131,28 @@ importers: version: 4.1.0 cz-conventional-changelog: specifier: 3.3.0 - version: 3.3.0(@types/node@20.19.25)(typescript@5.9.3) + version: 3.3.0(@types/node@20.19.30)(typescript@5.9.3) esbuild: specifier: ^0.27.0 - version: 0.27.0 + version: 0.27.2 esbuild-loader: specifier: ^4.4.0 - version: 4.4.0(webpack@5.96.1(@swc/core@1.13.5)(esbuild@0.27.0)) + version: 4.4.2(webpack@5.104.1(esbuild@0.27.2)) eslint: specifier: ^9.39.1 - version: 9.39.1(jiti@2.6.1) + version: 9.39.2(jiti@2.6.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.39.1(jiti@2.6.1)) + version: 10.1.8(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(@types/eslint@8.56.7)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.8.1) express: specifier: ^5.1.0 - version: 5.1.0 + version: 5.2.1 fastify: specifier: ^5.6.2 - version: 5.6.2 + version: 5.7.2 fs-teardown: specifier: ^0.3.0 version: 0.3.2 @@ -167,22 +167,22 @@ importers: version: 1.0.0 knip: specifier: ^5.70.1 - version: 5.70.1(@types/node@20.19.25)(typescript@5.9.3) + version: 5.82.1(@types/node@20.19.30)(typescript@5.9.3) lint-staged: specifier: ^15.2.10 - version: 15.2.10 + version: 15.5.2 msw: specifier: workspace:* version: 'link:' page-with: specifier: ^0.6.1 - version: 0.6.1(@swc/core@1.13.5)(esbuild@0.27.0) + version: 0.6.1(esbuild@0.27.2) prettier: specifier: ^3.6.2 - version: 3.6.2 + version: 3.8.1 publint: specifier: ^0.3.15 - version: 0.3.15 + version: 0.3.17 regenerator-runtime: specifier: ^0.14.1 version: 0.14.1 @@ -194,207 +194,162 @@ importers: version: 2.13.1 tsup: specifier: ^8.5.1 - version: 8.5.1(@swc/core@1.13.5)(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.5.1) + version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.8.2) typescript: specifier: ^5.9.3 version: 5.9.3 typescript-eslint: specifier: ^8.47.0 - version: 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) undici: specifier: ^7.16.0 - version: 7.16.0 + version: 7.19.2 url-loader: specifier: ^4.1.1 - version: 4.1.1(webpack@5.96.1(@swc/core@1.13.5)(esbuild@0.27.0)) + version: 4.1.1(webpack@5.104.1(esbuild@0.27.2)) vitest: specifier: ^4.0.13 - version: 4.0.13(@types/debug@4.1.12)(@types/node@20.19.25)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.30.1)(yaml@2.5.1) + version: 4.0.18(@types/node@20.19.30)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.46.0)(yaml@2.8.2) vitest-environment-miniflare: specifier: ^2.14.4 - version: 2.14.4(vitest@4.0.13(@types/debug@4.1.12)(@types/node@20.19.25)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.30.1)(yaml@2.5.1)) + version: 2.14.4(vitest@4.0.18(@types/node@20.19.30)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.46.0)(yaml@2.8.2)) webpack: specifier: ^5.95.0 - version: 5.96.1(@swc/core@1.13.5)(esbuild@0.27.0) + version: 5.104.1(esbuild@0.27.2) webpack-http-server: specifier: ^0.5.0 - version: 0.5.0(@swc/core@1.13.5)(esbuild@0.27.0) + version: 0.5.0(esbuild@0.27.2) packages: - '@75lb/deep-merge@1.1.1': - resolution: {integrity: sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==} - engines: {node: '>=12.17'} - - '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@babel/code-frame@7.24.2': - resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.24.1': - resolution: {integrity: sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==} - engines: {node: '>=6.9.0'} + '@asamuzakjp/css-color@3.2.0': + resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} - '@babel/core@7.24.3': - resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==} + '@babel/code-frame@7.28.6': + resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} - '@babel/generator@7.24.1': - resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==} + '@babel/compat-data@7.28.6': + resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + '@babel/core@7.28.6': + resolution: {integrity: sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==} engines: {node: '>=6.9.0'} - '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + '@babel/generator@7.28.6': + resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.24.3': - resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.23.3': - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-simple-access@7.22.5': - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.22.6': - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.24.1': - resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.22.20': - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.23.5': - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.24.1': - resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==} - engines: {node: '>=6.9.0'} - - '@babel/highlight@7.24.2': - resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.24.1': - resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} + '@babel/parser@7.28.6': + resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/template@7.24.0': - resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.24.1': - resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} + '@babel/traverse@7.28.6': + resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} engines: {node: '>=6.9.0'} - '@babel/types@7.24.0': - resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + '@babel/types@7.28.6': + resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} - '@cloudflare/workers-types@4.20250430.0': - resolution: {integrity: sha512-JWAX7ZhQ7KjkdJwASgG58MZ/pQ15brlnZ9/0YBwDQ0hrJ/LaK392aTRFlj2r/PRKDZ5dOuujRywNYaNpfeFiEA==} + '@cloudflare/workers-types@4.20260128.0': + resolution: {integrity: sha512-oid8qPnF4K5Wmgf66bUUrGycwL8BOCGm9ptQOoQNR/jhY5TmDObLtPjJm+BmDklkpAkaM1FnqKY9lo+FNo78AA==} - '@commitlint/cli@20.1.0': - resolution: {integrity: sha512-pW5ujjrOovhq5RcYv5xCpb4GkZxkO2+GtOdBW2/qrr0Ll9tl3PX0aBBobGQl3mdZUbOBgwAexEQLeH6uxL0VYg==} + '@commitlint/cli@20.3.1': + resolution: {integrity: sha512-NtInjSlyev/+SLPvx/ulz8hRE25Wf5S9dLNDcIwazq0JyB4/w1ROF/5nV0ObPTX8YpRaKYeKtXDYWqumBNHWsw==} engines: {node: '>=v18'} hasBin: true - '@commitlint/config-conventional@20.0.0': - resolution: {integrity: sha512-q7JroPIkDBtyOkVe9Bca0p7kAUYxZMxkrBArCfuD3yN4KjRAenP9PmYwnn7rsw8Q+hHq1QB2BRmBh0/Z19ZoJw==} - engines: {node: '>=v18'} - - '@commitlint/config-validator@19.0.3': - resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} + '@commitlint/config-conventional@20.3.1': + resolution: {integrity: sha512-NCzwvxepstBZbmVXsvg49s+shCxlJDJPWxXqONVcAtJH9wWrOlkMQw/zyl+dJmt8lyVopt5mwQ3mR5M2N2rUWg==} engines: {node: '>=v18'} - '@commitlint/config-validator@20.0.0': - resolution: {integrity: sha512-BeyLMaRIJDdroJuYM2EGhDMGwVBMZna9UiIqV9hxj+J551Ctc6yoGuGSmghOy/qPhBSuhA6oMtbEiTmxECafsg==} + '@commitlint/config-validator@20.3.1': + resolution: {integrity: sha512-ErVLC/IsHhcvxCyh+FXo7jy12/nkQySjWXYgCoQbZLkFp4hysov8KS6CdxBB0cWjbZWjvNOKBMNoUVqkmGmahw==} engines: {node: '>=v18'} - '@commitlint/ensure@20.0.0': - resolution: {integrity: sha512-WBV47Fffvabe68n+13HJNFBqiMH5U1Ryls4W3ieGwPC0C7kJqp3OVQQzG2GXqOALmzrgAB+7GXmyy8N9ct8/Fg==} - engines: {node: '>=v18'} - - '@commitlint/execute-rule@19.0.0': - resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} + '@commitlint/ensure@20.3.1': + resolution: {integrity: sha512-h664FngOEd7bHAm0j8MEKq+qm2mH+V+hwJiIE2bWcw3pzJMlO0TPKtk0ATyRAtV6jQw+xviRYiIjjSjfajiB5w==} engines: {node: '>=v18'} '@commitlint/execute-rule@20.0.0': resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} engines: {node: '>=v18'} - '@commitlint/format@20.0.0': - resolution: {integrity: sha512-zrZQXUcSDmQ4eGGrd+gFESiX0Rw+WFJk7nW4VFOmxub4mAATNKBQ4vNw5FgMCVehLUKG2OT2LjOqD0Hk8HvcRg==} - engines: {node: '>=v18'} - - '@commitlint/is-ignored@20.0.0': - resolution: {integrity: sha512-ayPLicsqqGAphYIQwh9LdAYOVAQ9Oe5QCgTNTj+BfxZb9b/JW222V5taPoIBzYnAP0z9EfUtljgBk+0BN4T4Cw==} + '@commitlint/format@20.3.1': + resolution: {integrity: sha512-jfsjGPFTd2Yti2YHwUH4SPRPbWKAJAwrfa3eNa9bXEdrXBb9mCwbIrgYX38LdEJK9zLJ3AsLBP4/FLEtxyu2AA==} engines: {node: '>=v18'} - '@commitlint/lint@20.0.0': - resolution: {integrity: sha512-kWrX8SfWk4+4nCexfLaQT3f3EcNjJwJBsSZ5rMBw6JCd6OzXufFHgel2Curos4LKIxwec9WSvs2YUD87rXlxNQ==} + '@commitlint/is-ignored@20.3.1': + resolution: {integrity: sha512-tWwAoh93QvAhxgp99CzCuHD86MgxE4NBtloKX+XxQxhfhSwHo7eloiar/yzx53YW9eqSLP95zgW2KDDk4/WX+A==} engines: {node: '>=v18'} - '@commitlint/load@19.2.0': - resolution: {integrity: sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==} + '@commitlint/lint@20.3.1': + resolution: {integrity: sha512-LaOtrQ24+6SfUaWg8A+a+Wc77bvLbO5RIr6iy9F7CI3/0iq1uPEWgGRCwqWTuLGHkZDAcwaq0gZ01zpwZ1jCGw==} engines: {node: '>=v18'} - '@commitlint/load@20.1.0': - resolution: {integrity: sha512-qo9ER0XiAimATQR5QhvvzePfeDfApi/AFlC1G+YN+ZAY8/Ua6IRrDrxRvQAr+YXUKAxUsTDSp9KXeXLBPsNRWg==} + '@commitlint/load@20.3.1': + resolution: {integrity: sha512-YDD9XA2XhgYgbjju8itZ/weIvOOobApDqwlPYCX5NLO/cPtw2UMO5Cmn44Ks8RQULUVI5fUT6roKvyxcoLbNmw==} engines: {node: '>=v18'} '@commitlint/message@20.0.0': resolution: {integrity: sha512-gLX4YmKnZqSwkmSB9OckQUrI5VyXEYiv3J5JKZRxIp8jOQsWjZgHSG/OgEfMQBK9ibdclEdAyIPYggwXoFGXjQ==} engines: {node: '>=v18'} - '@commitlint/parse@20.0.0': - resolution: {integrity: sha512-j/PHCDX2bGM5xGcWObOvpOc54cXjn9g6xScXzAeOLwTsScaL4Y+qd0pFC6HBwTtrH92NvJQc+2Lx9HFkVi48cg==} - engines: {node: '>=v18'} - - '@commitlint/read@20.0.0': - resolution: {integrity: sha512-Ti7Y7aEgxsM1nkwA4ZIJczkTFRX/+USMjNrL9NXwWQHqNqrBX2iMi+zfuzZXqfZ327WXBjdkRaytJ+z5vNqTOA==} + '@commitlint/parse@20.3.1': + resolution: {integrity: sha512-TuUTdbLpyUNLgDzLDYlI2BeTE6V/COZbf3f8WwsV0K6eq/2nSpNTMw7wHtXb+YxeY9wwxBp/Ldad4P+YIxHJoA==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@19.1.0': - resolution: {integrity: sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==} + '@commitlint/read@20.3.1': + resolution: {integrity: sha512-nCmJAdIg3OdNVUpQW0Idk/eF/vfOo2W2xzmvRmNeptLrzFK7qhwwl/kIwy1Q1LZrKHUFNj7PGNpIT5INbgZWzA==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@20.1.0': - resolution: {integrity: sha512-cxKXQrqHjZT3o+XPdqDCwOWVFQiae++uwd9dUBC7f2MdV58ons3uUvASdW7m55eat5sRiQ6xUHyMWMRm6atZWw==} + '@commitlint/resolve-extends@20.3.1': + resolution: {integrity: sha512-iGTGeyaoDyHDEZNjD8rKeosjSNs8zYanmuowY4ful7kFI0dnY4b5QilVYaFQJ6IM27S57LAeH5sKSsOHy4bw5w==} engines: {node: '>=v18'} - '@commitlint/rules@20.0.0': - resolution: {integrity: sha512-gvg2k10I/RfvHn5I5sxvVZKM1fl72Sqrv2YY/BnM7lMHcYqO0E2jnRWoYguvBfEcZ39t+rbATlciggVe77E4zA==} + '@commitlint/rules@20.3.1': + resolution: {integrity: sha512-/uic4P+4jVNpqQxz02+Y6vvIC0A2J899DBztA1j6q3f3MOKwydlNrojSh0dQmGDxxT1bXByiRtDhgFnOFnM6Pg==} engines: {node: '>=v18'} '@commitlint/to-lines@20.0.0': @@ -405,19 +360,43 @@ packages: resolution: {integrity: sha512-drXaPSP2EcopukrUXvUXmsQMu3Ey/FuJDc/5oiW4heoCfoE5BdLQyuc7veGeE3aoQaTVqZnh4D5WTWe2vefYKg==} engines: {node: '>=v18'} - '@commitlint/types@19.0.3': - resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} + '@commitlint/types@20.3.1': + resolution: {integrity: sha512-VmIFV/JkBRhDRRv7N5B7zEUkNZIx9Mp+8Pe65erz0rKycXLsi8Epcw0XJ+btSeRXgTzE7DyOyA9bkJ9mn/yqVQ==} engines: {node: '>=v18'} - '@commitlint/types@20.0.0': - resolution: {integrity: sha512-bVUNBqG6aznYcYjTjnc3+Cat/iBgbgpflxbIBTnsHTX0YVpnmINPEkSRWymT2Q8aSH3Y7aKnEbunilkYe8TybA==} - engines: {node: '>=v18'} + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} - '@emnapi/core@1.7.1': - resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - '@emnapi/runtime@1.7.1': - resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} @@ -429,320 +408,170 @@ packages: resolution: {integrity: sha512-n6+dZKI2I3J8f3vjIFAYh5trgAJl0crji76+K1aoiRJqEYjdsCX/nVgBrkBCwPpBqhv9NZ1XlMqzfOafkqY5EQ==} engines: {node: '>=20'} - '@esbuild/aix-ppc64@0.25.3': - resolution: {integrity: sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==} + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.0': - resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.25.3': - resolution: {integrity: sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==} + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.0': - resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.25.3': - resolution: {integrity: sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.27.0': - resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.3': - resolution: {integrity: sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==} + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.0': - resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.25.3': - resolution: {integrity: sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.27.0': - resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.3': - resolution: {integrity: sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==} + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.0': - resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.25.3': - resolution: {integrity: sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.27.0': - resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.3': - resolution: {integrity: sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.0': - resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.3': - resolution: {integrity: sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.27.0': - resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.3': - resolution: {integrity: sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==} + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.0': - resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.25.3': - resolution: {integrity: sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==} + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.0': - resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.25.3': - resolution: {integrity: sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.27.0': - resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.3': - resolution: {integrity: sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==} + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.0': - resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.25.3': - resolution: {integrity: sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.27.0': - resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.3': - resolution: {integrity: sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==} + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.0': - resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.25.3': - resolution: {integrity: sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.27.0': - resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.3': - resolution: {integrity: sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.27.0': - resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.3': - resolution: {integrity: sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-arm64@0.27.0': - resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.3': - resolution: {integrity: sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==} + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.0': - resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.3': - resolution: {integrity: sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==} + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.27.0': - resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.3': - resolution: {integrity: sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.0': - resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.27.0': - resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.3': - resolution: {integrity: sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==} + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.0': - resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.25.3': - resolution: {integrity: sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.27.0': - resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==} + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.3': - resolution: {integrity: sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==} + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.0': - resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.25.3': - resolution: {integrity: sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.27.0': - resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.8.0': - resolution: {integrity: sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/config-array@0.21.1': @@ -757,12 +586,12 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.39.1': - resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.7': @@ -803,17 +632,17 @@ packages: peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - '@hono/node-server@1.19.6': - resolution: {integrity: sha512-Shz/KjlIeAhfiuE93NDKVdZ7HdBVLQAfdbaXEaoAVO3ic9ibRSLGIQGkcBbFyuLr+7/1D5ZCINM8B+6IvXeMtw==} + '@hono/node-server@1.19.9': + resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 - '@hono/node-ws@1.2.0': - resolution: {integrity: sha512-OBPQ8OSHBw29mj00wT/xGYtB6HY54j0fNSdVZ7gZM3TUeq0So11GXaWtFf1xWxQNfumKIsj0wRuLKWfVsO5GgQ==} + '@hono/node-ws@1.3.0': + resolution: {integrity: sha512-ju25YbbvLuXdqBCmLZLqnNYu1nbHIQjoyUqA8ApZOeL1k4skuiTcw5SW77/5SUYo2Xi2NVBJoVlfQurnKEp03Q==} engines: {node: '>=18.14.1'} peerDependencies: - '@hono/node-server': ^1.11.1 + '@hono/node-server': ^1.19.2 hono: ^4.6.0 '@humanfs/core@0.19.1': @@ -835,25 +664,40 @@ packages: '@iarna/toml@2.2.5': resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} - '@inquirer/confirm@5.0.2': - resolution: {integrity: sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==} + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/core@10.1.0': - resolution: {integrity: sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==} + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/figures@1.0.8': - resolution: {integrity: sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==} + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} engines: {node: '>=18'} - '@inquirer/type@3.0.1': - resolution: {integrity: sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==} + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} @@ -863,104 +707,111 @@ packages: resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} engines: {node: 20 || >=22} - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.6': - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@miniflare/cache@2.14.4': resolution: {integrity: sha512-ayzdjhcj+4mjydbNK7ZGDpIXNliDbQY4GPcY2KrYw0v1OSUdj5kZUkygD09fqoGRfAks0d91VelkyRsAXX8FQA==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/core@2.14.4': resolution: {integrity: sha512-FMmZcC1f54YpF4pDWPtdQPIO8NXfgUxCoR9uyrhxKJdZu7M6n8QKopPVNuaxR40jcsdxb7yKoQoFWnHfzJD9GQ==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/d1@2.14.4': resolution: {integrity: sha512-pMBVq9XWxTDdm+RRCkfXZP+bREjPg1JC8s8C0JTovA9OGmLQXqGTnFxIaS9vf1d8k3uSUGhDzPTzHr0/AUW1gA==} engines: {node: '>=16.7'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/durable-objects@2.14.4': resolution: {integrity: sha512-+JrmHP6gHHrjxV8S3axVw5lGHLgqmAGdcO/1HJUPswAyJEd3Ah2YnKhpo+bNmV4RKJCtEq9A2hbtVjBTD2YzwA==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/html-rewriter@2.14.4': resolution: {integrity: sha512-GB/vZn7oLbnhw+815SGF+HU5EZqSxbhIa3mu2L5MzZ2q5VOD5NHC833qG8c2GzDPhIaZ99ITY+ZJmbR4d+4aNQ==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/kv@2.14.4': resolution: {integrity: sha512-QlERH0Z+klwLg0xw+/gm2yC34Nnr/I0GcQ+ASYqXeIXBwjqOtMBa3YVQnocaD+BPy/6TUtSpOAShHsEj76R2uw==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/queues@2.14.4': resolution: {integrity: sha512-aXQ5Ik8Iq1KGMBzGenmd6Js/jJgqyYvjom95/N9GptCGpiVWE5F0XqC1SL5rCwURbHN+aWY191o8XOFyY2nCUA==} engines: {node: '>=16.7'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/r2@2.14.4': resolution: {integrity: sha512-4ctiZWh7Ty7LB3brUjmbRiGMqwyDZgABYaczDtUidblo2DxX4JZPnJ/ZAyxMPNJif32kOJhcg6arC2hEthR9Sw==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/runner-vm@2.14.4': resolution: {integrity: sha512-Nog0bB9SVhPbZAkTWfO4lpLAUsBXKEjlb4y+y66FJw77mPlmPlVdpjElCvmf8T3VN/pqh83kvELGM+/fucMf4g==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/shared-test-environment@2.14.4': resolution: {integrity: sha512-FdU2/8wEd00vIu+MfofLiHcfZWz+uCbE2VTL85KpyYfBsNGAbgRtzFMpOXdoXLqQfRu6MBiRwWpb2FbMrBzi7g==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/shared@2.14.4': resolution: {integrity: sha512-upl4RSB3hyCnITOFmRZjJj4A72GmkVrtfZTilkdq5Qe5TTlzsjVeDJp7AuNUM9bM8vswRo+N5jOiot6O4PVwwQ==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/sites@2.14.4': resolution: {integrity: sha512-O5npWopi+fw9W9Ki0gy99nuBbgDva/iXy8PDC4dAXDB/pz45nISDqldabk0rL2t4W2+lY6LXKzdOw+qJO1GQTA==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/storage-file@2.14.4': resolution: {integrity: sha512-JxcmX0hXf4cB0cC9+s6ZsgYCq+rpyUKRPCGzaFwymWWplrO3EjPVxKCcMxG44jsdgsII6EZihYUN2J14wwCT7A==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/storage-memory@2.14.4': resolution: {integrity: sha512-9jB5BqNkMZ3SFjbPFeiVkLi1BuSahMhc/W1Y9H0W89qFDrrD+z7EgRgDtHTG1ZRyi9gIlNtt9qhkO1B6W2qb2A==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/watcher@2.14.4': resolution: {integrity: sha512-PYn05ET2USfBAeXF6NZfWl0O32KVyE8ncQ/ngysrh3hoIV7l3qGGH7ubeFx+D8VWQ682qYhwGygUzQv2j1tGGg==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@miniflare/web-sockets@2.14.4': resolution: {integrity: sha512-stTxvLdJ2IcGOs76AnvGYAzGvx8JvQPRxC5DW0P5zdAAnhL33noqb5LKdPt3P37BKp9FzBKZHuihQI9oVqwm0g==} engines: {node: '>=16.13'} + deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4 '@mswjs/interceptors@0.40.0': resolution: {integrity: sha512-EFd6cVbHsgLa6wa4RljGj6Wk75qoHxUSyc5asLyyPSyuhIcdS2Q3Phw6ImS1q+CkALthJRShiYfKANcQMuMqsQ==} engines: {node: '>=18'} - '@napi-rs/wasm-runtime@1.0.7': - resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -986,119 +837,120 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@ossjs/release@0.10.0': - resolution: {integrity: sha512-Cj8pV7aY9xDOCunv4B8mXTfwK/sDxy6NeYxcrFXs/dedazmqCsyeM97IEGB+pMBZrcUJbjSY+/Ed7H/Cowdovw==} + '@ossjs/release@0.10.1': + resolution: {integrity: sha512-Djr1DXVTeR476ZdNC0RYPQQuX7Hx+CnEex1AyBBnsizQ7KqsidW99iooDFxT36jy8ReXwdTgIsjP2OSdyjfbLQ==} engines: {node: '>=20.0.0'} hasBin: true - '@oxc-resolver/binding-android-arm-eabi@11.13.2': - resolution: {integrity: sha512-vWd1NEaclg/t2DtEmYzRRBNQOueMI8tixw/fSNZ9XETXLRJiAjQMYpYeflQdRASloGze6ZelHE/wIBNt4S+pkw==} + '@oxc-resolver/binding-android-arm-eabi@11.16.4': + resolution: {integrity: sha512-6XUHilmj8D6Ggus+sTBp64x/DUQ7LgC/dvTDdUOt4iMQnDdSep6N1mnvVLIiG+qM5tRnNHravNzBJnUlYwRQoA==} cpu: [arm] os: [android] - '@oxc-resolver/binding-android-arm64@11.13.2': - resolution: {integrity: sha512-jxZrYcxgpI6IuQpguQVAQNrZfUyiYfMVqR4pKVU3PRLCM7AsfXNKp0TIgcvp+l6dYVdoZ1MMMMa5Ayjd09rNOw==} + '@oxc-resolver/binding-android-arm64@11.16.4': + resolution: {integrity: sha512-5ODwd1F5mdkm6JIg1CNny9yxIrCzrkKpxmqas7Alw23vE0Ot8D4ykqNBW5Z/nIZkXVEo5VDmnm0sMBBIANcpeQ==} cpu: [arm64] os: [android] - '@oxc-resolver/binding-darwin-arm64@11.13.2': - resolution: {integrity: sha512-RDS3HUe1FvgjNS1xfBUqiEJ8938Zb5r7iKABwxEblp3K4ufZZNAtoaHjdUH2TJ0THDmuf0OxxVUO/Y+4Ep4QfQ==} + '@oxc-resolver/binding-darwin-arm64@11.16.4': + resolution: {integrity: sha512-egwvDK9DMU4Q8F4BG74/n4E22pQ0lT5ukOVB6VXkTj0iG2fnyoStHoFaBnmDseLNRA4r61Mxxz8k940CIaJMDg==} cpu: [arm64] os: [darwin] - '@oxc-resolver/binding-darwin-x64@11.13.2': - resolution: {integrity: sha512-tDcyWtkUzkt6auJLP2dOjL84BxqHkKW4mz2lNRIGPTq7b+HBraB+m8RdRH6BgqTvbnNECOxR3XAMaKBKC8J51g==} + '@oxc-resolver/binding-darwin-x64@11.16.4': + resolution: {integrity: sha512-HMkODYrAG4HaFNCpaYzSQFkxeiz2wzl+smXwxeORIQVEo1WAgUrWbvYT/0RNJg/A8z2aGMGK5KWTUr2nX5GiMw==} cpu: [x64] os: [darwin] - '@oxc-resolver/binding-freebsd-x64@11.13.2': - resolution: {integrity: sha512-fpaeN8Q0kWvKns9uSMg6CcKo7cdgmWt6J91stPf8sdM+EKXzZ0YcRnWWyWF8SM16QcLUPCy5Iwt5Z8aYBGaZYA==} + '@oxc-resolver/binding-freebsd-x64@11.16.4': + resolution: {integrity: sha512-mkcKhIdSlUqnndD928WAVVFMEr1D5EwHOBGHadypW0PkM0h4pn89ZacQvU7Qs/Z2qquzvbyw8m4Mq3jOYI+4Dw==} cpu: [x64] os: [freebsd] - '@oxc-resolver/binding-linux-arm-gnueabihf@11.13.2': - resolution: {integrity: sha512-idBgJU5AvSsGOeaIWiFBKbNBjpuduHsJmrG4CBbEUNW/Ykx+ISzcuj1PHayiYX6R9stVsRhj3d2PyymfC5KWRg==} + '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.4': + resolution: {integrity: sha512-ZJvzbmXI/cILQVcJL9S2Fp7GLAIY4Yr6mpGb+k6LKLUSEq85yhG+rJ9eWCqgULVIf2BFps/NlmPTa7B7oj8jhQ==} cpu: [arm] os: [linux] - '@oxc-resolver/binding-linux-arm-musleabihf@11.13.2': - resolution: {integrity: sha512-BlBvQUhvvIM/7s96KlKhMk0duR2sj8T7Hyii46/5QnwfN/pHwobvOL5czZ6/SKrHNB/F/qDY4hGsBuB1y7xgTg==} + '@oxc-resolver/binding-linux-arm-musleabihf@11.16.4': + resolution: {integrity: sha512-iZUB0W52uB10gBUDAi79eTnzqp1ralikCAjfq7CdokItwZUVJXclNYANnzXmtc0Xr0ox+YsDsG2jGcj875SatA==} cpu: [arm] os: [linux] - '@oxc-resolver/binding-linux-arm64-gnu@11.13.2': - resolution: {integrity: sha512-lUmDTmYOGpbIK+FBfZ0ySaQTo7g1Ia/WnDnQR2wi/0AtehZIg/ZZIgiT/fD0iRvKEKma612/0PVo8dXdAKaAGA==} + '@oxc-resolver/binding-linux-arm64-gnu@11.16.4': + resolution: {integrity: sha512-qNQk0H6q1CnwS9cnvyjk9a+JN8BTbxK7K15Bb5hYfJcKTG1hfloQf6egndKauYOO0wu9ldCMPBrEP1FNIQEhaA==} cpu: [arm64] os: [linux] - '@oxc-resolver/binding-linux-arm64-musl@11.13.2': - resolution: {integrity: sha512-dkGzOxo+I9lA4Er6qzFgkFevl3JvwyI9i0T/PkOJHva04rb1p9dz8GPogTO9uMK4lrwLWzm/piAu+tHYC7v7+w==} + '@oxc-resolver/binding-linux-arm64-musl@11.16.4': + resolution: {integrity: sha512-wEXSaEaYxGGoVSbw0i2etjDDWcqErKr8xSkTdwATP798efsZmodUAcLYJhN0Nd4W35Oq6qAvFGHpKwFrrhpTrA==} cpu: [arm64] os: [linux] - '@oxc-resolver/binding-linux-ppc64-gnu@11.13.2': - resolution: {integrity: sha512-53kWsjLkVFnoSA7COdps38pBssN48zI8LfsOvupsmQ0/4VeMYb+0Ao9O6r52PtmFZsGB3S1Qjqbjl/Pswj1a3g==} + '@oxc-resolver/binding-linux-ppc64-gnu@11.16.4': + resolution: {integrity: sha512-CUFOlpb07DVOFLoYiaTfbSBRPIhNgwc/MtlYeg3p6GJJw+kEm/vzc9lohPSjzF2MLPB5hzsJdk+L/GjrTT3UPw==} cpu: [ppc64] os: [linux] - '@oxc-resolver/binding-linux-riscv64-gnu@11.13.2': - resolution: {integrity: sha512-MfxN6DMpvmdCbGlheJ+ihy11oTcipqDfcEIQV9ah3FGXBRCZtBOHJpQDk8qI2Y+nCXVr3Nln7OSsOzoC4+rSYQ==} + '@oxc-resolver/binding-linux-riscv64-gnu@11.16.4': + resolution: {integrity: sha512-d8It4AH8cN9ReK1hW6ZO4x3rMT0hB2LYH0RNidGogV9xtnjLRU+Y3MrCeClLyOSGCibmweJJAjnwB7AQ31GEhg==} cpu: [riscv64] os: [linux] - '@oxc-resolver/binding-linux-riscv64-musl@11.13.2': - resolution: {integrity: sha512-WXrm4YiRU0ijqb72WHSjmfYaQZ7t6/kkQrFc4JtU+pUE4DZA/DEdxOuQEd4Q43VqmLvICTJWSaZMlCGQ4PSRUg==} + '@oxc-resolver/binding-linux-riscv64-musl@11.16.4': + resolution: {integrity: sha512-d09dOww9iKyEHSxuOQ/Iu2aYswl0j7ExBcyy14D6lJ5ijQSP9FXcJYJsJ3yvzboO/PDEFjvRuF41f8O1skiPVg==} cpu: [riscv64] os: [linux] - '@oxc-resolver/binding-linux-s390x-gnu@11.13.2': - resolution: {integrity: sha512-4pISWIlOFRUhWyvGCB3XUhtcwyvwGGhlXhHz7IXCXuGufaQtvR05trvw8U1ZnaPhsdPBkRhOMIedX11ayi5uXw==} + '@oxc-resolver/binding-linux-s390x-gnu@11.16.4': + resolution: {integrity: sha512-lhjyGmUzTWHduZF3MkdUSEPMRIdExnhsqv8u1upX3A15epVn6YVwv4msFQPJl1x1wszkACPeDHGOtzHsITXGdw==} cpu: [s390x] os: [linux] - '@oxc-resolver/binding-linux-x64-gnu@11.13.2': - resolution: {integrity: sha512-DVo6jS8n73yNAmCsUOOk2vBeC60j2RauDXQM8p7RDl0afsEaA2le22vD8tky7iNoM5tsxfBmE4sOJXEKgpwWRw==} + '@oxc-resolver/binding-linux-x64-gnu@11.16.4': + resolution: {integrity: sha512-ZtqqiI5rzlrYBm/IMMDIg3zvvVj4WO/90Dg/zX+iA8lWaLN7K5nroXb17MQ4WhI5RqlEAgrnYDXW+hok1D9Kaw==} cpu: [x64] os: [linux] - '@oxc-resolver/binding-linux-x64-musl@11.13.2': - resolution: {integrity: sha512-6WqrE+hQBFP35KdwQjWcZpldbTq6yJmuTVThISu+rY3+j6MaDp2ciLHTr1X68r2H/7ocOIl4k3NnOVIzeRJE3w==} + '@oxc-resolver/binding-linux-x64-musl@11.16.4': + resolution: {integrity: sha512-LM424h7aaKcMlqHnQWgTzO+GRNLyjcNnMpqm8SygEtFRVW693XS+XGXYvjORlmJtsyjo84ej1FMb3U2HE5eyjg==} cpu: [x64] os: [linux] - '@oxc-resolver/binding-wasm32-wasi@11.13.2': - resolution: {integrity: sha512-YpxvQmP2D+mNUkLQZbBjGz20g/pY8XoOBdPPoWMl9X68liFFjXxkPQTrZxWw4zzG/UkTM5z6dPRTyTePRsMcjw==} + '@oxc-resolver/binding-openharmony-arm64@11.16.4': + resolution: {integrity: sha512-8w8U6A5DDWTBv3OUxSD9fNk37liZuEC5jnAc9wQRv9DeYKAXvuUtBfT09aIZ58swaci0q1WS48/CoMVEO6jdCA==} + cpu: [arm64] + os: [openharmony] + + '@oxc-resolver/binding-wasm32-wasi@11.16.4': + resolution: {integrity: sha512-hnjb0mDVQOon6NdfNJ1EmNquonJUjoYkp7UyasjxVa4iiMcApziHP4czzzme6WZbp+vzakhVv2Yi5ACTon3Zlw==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-resolver/binding-win32-arm64-msvc@11.13.2': - resolution: {integrity: sha512-1SKBw6KcCmvPBdEw1/Qdpv6eSDf23lCXTWz9VxTe6QUQ/1wR+HZR2uS4q6C8W6jnIswMTQbxpTvVwdRXl+ufeA==} + '@oxc-resolver/binding-win32-arm64-msvc@11.16.4': + resolution: {integrity: sha512-+i0XtNfSP7cfnh1T8FMrMm4HxTeh0jxKP/VQCLWbjdUxaAQ4damho4gN9lF5dl0tZahtdszXLUboBFNloSJNOQ==} cpu: [arm64] os: [win32] - '@oxc-resolver/binding-win32-ia32-msvc@11.13.2': - resolution: {integrity: sha512-KEVV7wggDucxRn3vvyHnmTCPXoCT7vWpH18UVLTygibHJvNRP2zl5lBaQcCIdIaYYZjKt1aGI/yZqxZvHoiCdg==} + '@oxc-resolver/binding-win32-ia32-msvc@11.16.4': + resolution: {integrity: sha512-ePW1islJrv3lPnef/iWwrjrSpRH8kLlftdKf2auQNWvYLx6F0xvcnv9d+r/upnVuttoQY9amLnWJf+JnCRksTw==} cpu: [ia32] os: [win32] - '@oxc-resolver/binding-win32-x64-msvc@11.13.2': - resolution: {integrity: sha512-6AAdN9v/wO5c3td1yidgNLKYlzuNgfOtEqBq60WE469bJWR7gHgG/S5aLR2pH6/gyPLs9UXtItxi934D+0Estg==} + '@oxc-resolver/binding-win32-x64-msvc@11.16.4': + resolution: {integrity: sha512-qnjQhjHI4TDL3hkidZyEmQRK43w2NHl6TP5Rnt/0XxYuLdEgx/1yzShhYidyqWzdnhGhSPTM/WVP2mK66XLegA==} cpu: [x64] os: [win32] '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - '@pkgr/core@0.2.9': resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.56.1': - resolution: {integrity: sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==} + '@playwright/test@1.58.0': + resolution: {integrity: sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg==} engines: {node: '>=18'} hasBin: true @@ -1110,12 +962,12 @@ packages: resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} engines: {node: '>=12.22.0'} - '@pnpm/npm-conf@2.3.1': - resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} + '@pnpm/npm-conf@3.0.2': + resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} engines: {node: '>=12'} - '@publint/pack@0.1.2': - resolution: {integrity: sha512-S+9ANAvUmjutrshV4jZjaiG8XQyuJIZ8a4utWmN/vW1sgQ9IfBnPndwkmQYw53QmouOIytT874u65HEmu6H5jw==} + '@publint/pack@0.1.3': + resolution: {integrity: sha512-dHDWeutAerz+Z2wFYAce7Y51vd4rbLBfUh0BNnyul4xKoVsPUVJBrOAFsJvtvYBwGFJSqKsxyyHf/7evZ8+Q5Q==} engines: {node: '>=18'} '@rollup/plugin-node-resolve@15.3.1': @@ -1136,296 +988,136 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.40.1': - resolution: {integrity: sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==} + '@rollup/rollup-android-arm-eabi@4.57.0': + resolution: {integrity: sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.53.3': - resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.40.1': - resolution: {integrity: sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-android-arm64@4.53.3': - resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} + '@rollup/rollup-android-arm64@4.57.0': + resolution: {integrity: sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.40.1': - resolution: {integrity: sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==} + '@rollup/rollup-darwin-arm64@4.57.0': + resolution: {integrity: sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-arm64@4.53.3': - resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.40.1': - resolution: {integrity: sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==} + '@rollup/rollup-darwin-x64@4.57.0': + resolution: {integrity: sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA==} cpu: [x64] os: [darwin] - '@rollup/rollup-darwin-x64@4.53.3': - resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.40.1': - resolution: {integrity: sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-arm64@4.53.3': - resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + '@rollup/rollup-freebsd-arm64@4.57.0': + resolution: {integrity: sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.40.1': - resolution: {integrity: sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==} + '@rollup/rollup-freebsd-x64@4.57.0': + resolution: {integrity: sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.53.3': - resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.40.1': - resolution: {integrity: sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-gnueabihf@4.53.3': - resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.40.1': - resolution: {integrity: sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==} + '@rollup/rollup-linux-arm-gnueabihf@4.57.0': + resolution: {integrity: sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.53.3': - resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} + '@rollup/rollup-linux-arm-musleabihf@4.57.0': + resolution: {integrity: sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.40.1': - resolution: {integrity: sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==} + '@rollup/rollup-linux-arm64-gnu@4.57.0': + resolution: {integrity: sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.53.3': - resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} + '@rollup/rollup-linux-arm64-musl@4.57.0': + resolution: {integrity: sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.40.1': - resolution: {integrity: sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.53.3': - resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loong64-gnu@4.53.3': - resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + '@rollup/rollup-linux-loong64-gnu@4.57.0': + resolution: {integrity: sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.40.1': - resolution: {integrity: sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==} + '@rollup/rollup-linux-loong64-musl@4.57.0': + resolution: {integrity: sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.40.1': - resolution: {integrity: sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==} + '@rollup/rollup-linux-ppc64-gnu@4.57.0': + resolution: {integrity: sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.53.3': - resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + '@rollup/rollup-linux-ppc64-musl@4.57.0': + resolution: {integrity: sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.40.1': - resolution: {integrity: sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.53.3': - resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} + '@rollup/rollup-linux-riscv64-gnu@4.57.0': + resolution: {integrity: sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.40.1': - resolution: {integrity: sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==} + '@rollup/rollup-linux-riscv64-musl@4.57.0': + resolution: {integrity: sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.53.3': - resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.40.1': - resolution: {integrity: sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==} + '@rollup/rollup-linux-s390x-gnu@4.57.0': + resolution: {integrity: sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.53.3': - resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.40.1': - resolution: {integrity: sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.53.3': - resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} + '@rollup/rollup-linux-x64-gnu@4.57.0': + resolution: {integrity: sha512-OR5p5yG5OKSxHReWmwvM0P+VTPMwoBS45PXTMYaskKQqybkS3Kmugq1W+YbNWArF8/s7jQScgzXUhArzEQ7x0A==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.40.1': - resolution: {integrity: sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==} + '@rollup/rollup-linux-x64-musl@4.57.0': + resolution: {integrity: sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.53.3': - resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + '@rollup/rollup-openbsd-x64@4.57.0': + resolution: {integrity: sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw==} cpu: [x64] - os: [linux] + os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.53.3': - resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} + '@rollup/rollup-openharmony-arm64@4.57.0': + resolution: {integrity: sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.40.1': - resolution: {integrity: sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-arm64-msvc@4.53.3': - resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} + '@rollup/rollup-win32-arm64-msvc@4.57.0': + resolution: {integrity: sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.40.1': - resolution: {integrity: sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==} + '@rollup/rollup-win32-ia32-msvc@4.57.0': + resolution: {integrity: sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.53.3': - resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.53.3': - resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.40.1': - resolution: {integrity: sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.53.3': - resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} - cpu: [x64] - os: [win32] - - '@socket.io/component-emitter@3.1.0': - resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==} - - '@standard-schema/spec@1.0.0': - resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - - '@swc/core-darwin-arm64@1.13.5': - resolution: {integrity: sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - - '@swc/core-darwin-x64@1.13.5': - resolution: {integrity: sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - - '@swc/core-linux-arm-gnueabihf@1.13.5': - resolution: {integrity: sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - - '@swc/core-linux-arm64-gnu@1.13.5': - resolution: {integrity: sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - - '@swc/core-linux-arm64-musl@1.13.5': - resolution: {integrity: sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - - '@swc/core-linux-x64-gnu@1.13.5': - resolution: {integrity: sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==} - engines: {node: '>=10'} + '@rollup/rollup-win32-x64-gnu@4.57.0': + resolution: {integrity: sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA==} cpu: [x64] - os: [linux] - - '@swc/core-linux-x64-musl@1.13.5': - resolution: {integrity: sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - - '@swc/core-win32-arm64-msvc@1.13.5': - resolution: {integrity: sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==} - engines: {node: '>=10'} - cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.13.5': - resolution: {integrity: sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - - '@swc/core-win32-x64-msvc@1.13.5': - resolution: {integrity: sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==} - engines: {node: '>=10'} + '@rollup/rollup-win32-x64-msvc@4.57.0': + resolution: {integrity: sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ==} cpu: [x64] os: [win32] - '@swc/core@1.13.5': - resolution: {integrity: sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==} - engines: {node: '>=10'} - peerDependencies: - '@swc/helpers': '>=0.5.17' - peerDependenciesMeta: - '@swc/helpers': - optional: true - - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - '@swc/types@0.1.24': - resolution: {integrity: sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -1436,11 +1128,11 @@ packages: '@types/better-sqlite3@7.6.13': resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} - '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/command-line-args@5.2.3': resolution: {integrity: sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==} @@ -1448,23 +1140,17 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/content-disposition@0.5.8': - resolution: {integrity: sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==} - - '@types/conventional-commits-parser@5.0.0': - resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + '@types/content-disposition@0.5.9': + resolution: {integrity: sha512-8uYXI3Gw35MhiVYhG3s295oihrxRyytcRHjSjqnqZVDDy/xcGBRny7+Xj1Wgfhv5QzRtN2hB2dVRBUX9XW3UcQ==} - '@types/conventional-commits-parser@5.0.1': - resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} + '@types/conventional-commits-parser@5.0.2': + resolution: {integrity: sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==} - '@types/cookie@0.4.1': - resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} + '@types/cookies@0.9.2': + resolution: {integrity: sha512-1AvkDdZM2dbyFybL4fxpuNCaWyv//0AwsuUk2DWeXyM1/5ZKm6W3z6mQi24RZ4l2ucY+bkSHzbDVpySqPGuV8A==} - '@types/cookies@0.9.0': - resolution: {integrity: sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==} - - '@types/cors@2.8.17': - resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + '@types/cors@2.8.19': + resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -1475,35 +1161,29 @@ packages: '@types/eslint-scope@3.7.7': resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - '@types/eslint@8.56.7': - resolution: {integrity: sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==} - - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - - '@types/estree@1.0.7': - resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/express-serve-static-core@4.17.43': - resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==} + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} - '@types/express-serve-static-core@5.1.0': - resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} + '@types/express-serve-static-core@5.1.1': + resolution: {integrity: sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==} - '@types/express@4.17.21': - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} - '@types/express@5.0.5': - resolution: {integrity: sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==} + '@types/express@5.0.6': + resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} - '@types/http-assert@1.5.5': - resolution: {integrity: sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==} + '@types/http-assert@1.5.6': + resolution: {integrity: sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw==} - '@types/http-errors@2.0.4': - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} '@types/issue-parser@3.0.5': resolution: {integrity: sha512-fvOrnb7uS6qRme16tfyxy9SjOgx47Krkt/ilLS7axP3SWtJb9GZlduWX2bAsJOnr1HuCwJh88rCidzCZ1LwuZg==} @@ -1517,8 +1197,8 @@ packages: '@types/keygrip@1.0.6': resolution: {integrity: sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==} - '@types/koa-compose@3.2.8': - resolution: {integrity: sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==} + '@types/koa-compose@3.2.9': + resolution: {integrity: sha512-BroAZ9FTvPiCy0Pi8tjD1OfJ7bgU1gQf0eR6e1Vm+JJATy9eKOG3hQMFtMciMawiSOVnLMdmUOC46s7HBhSTsA==} '@types/koa@2.15.0': resolution: {integrity: sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==} @@ -1526,30 +1206,23 @@ packages: '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/mime@4.0.0': - resolution: {integrity: sha512-5eEkJZ/BLvTE3vXGKkWlyTSUVZuzj23Wj8PoyOq2lt5I3CYbiLBOPb3XmCW6QcuOibIUE6emHXHt9E/F/rCa6w==} - deprecated: This is a stub types definition. mime provides its own type definitions, so you do not need this installed. - - '@types/ms@0.7.34': - resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/mustache@4.2.5': - resolution: {integrity: sha512-PLwiVvTBg59tGFL/8VpcGvqOu3L4OuveNvPi0EYbWchRdEVP++yRUXJPFl+CApKEq13017/4Nf7aQ5lTtHUNsA==} + '@types/mustache@4.2.6': + resolution: {integrity: sha512-t+8/QWTAhOFlrF1IVZqKnMRJi84EgkIK5Kh0p2JV4OLywUvCwJPFxbJAl7XAow7DVIHsF+xW9f1MVzg0L6Szjw==} - '@types/node@18.19.28': - resolution: {integrity: sha512-J5cOGD9n4x3YGgVuaND6khm5x07MMdAKkRyXnjVR6KFhLMNh2yONGiP7Z+4+tBOt5mK+GvDTiacTOVGGpqiecw==} + '@types/node@20.19.30': + resolution: {integrity: sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==} - '@types/node@20.19.25': - resolution: {integrity: sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==} - - '@types/node@24.5.2': - resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + '@types/node@24.10.9': + resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==} '@types/parse5@6.0.3': resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} - '@types/qs@6.9.14': - resolution: {integrity: sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==} + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} @@ -1557,14 +1230,20 @@ packages: '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} - '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} - '@types/serve-static@1.15.5': - resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} + '@types/serve-static@2.2.0': + resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==} '@types/serviceworker@0.0.167': resolution: {integrity: sha512-Np7fMd3niW5oL4Jz1A1T7pX5ZYriQJ6mob2g476RN47RqObajLkPjhPc4cnRpbEftsJLiIA0f7emykckcDxMxA==} @@ -1584,73 +1263,73 @@ packages: '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@17.0.32': - resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@typescript-eslint/eslint-plugin@8.47.0': - resolution: {integrity: sha512-fe0rz9WJQ5t2iaLfdbDc9T80GJy0AeO453q8C3YCilnGozvOyCG5t+EZtg7j7D88+c3FipfP/x+wzGnh1xp8ZA==} + '@typescript-eslint/eslint-plugin@8.54.0': + resolution: {integrity: sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.47.0 + '@typescript-eslint/parser': ^8.54.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.47.0': - resolution: {integrity: sha512-lJi3PfxVmo0AkEY93ecfN+r8SofEqZNGByvHAI3GBLrvt1Cw6H5k1IM02nSzu0RfUafr2EvFSw0wAsZgubNplQ==} + '@typescript-eslint/parser@8.54.0': + resolution: {integrity: sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.47.0': - resolution: {integrity: sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA==} + '@typescript-eslint/project-service@8.54.0': + resolution: {integrity: sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.47.0': - resolution: {integrity: sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==} + '@typescript-eslint/scope-manager@8.54.0': + resolution: {integrity: sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.47.0': - resolution: {integrity: sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g==} + '@typescript-eslint/tsconfig-utils@8.54.0': + resolution: {integrity: sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.47.0': - resolution: {integrity: sha512-QC9RiCmZ2HmIdCEvhd1aJELBlD93ErziOXXlHEZyuBo3tBiAZieya0HLIxp+DoDWlsQqDawyKuNEhORyku+P8A==} + '@typescript-eslint/type-utils@8.54.0': + resolution: {integrity: sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.47.0': - resolution: {integrity: sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==} + '@typescript-eslint/types@8.54.0': + resolution: {integrity: sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.47.0': - resolution: {integrity: sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg==} + '@typescript-eslint/typescript-estree@8.54.0': + resolution: {integrity: sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.47.0': - resolution: {integrity: sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ==} + '@typescript-eslint/utils@8.54.0': + resolution: {integrity: sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.47.0': - resolution: {integrity: sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==} + '@typescript-eslint/visitor-keys@8.54.0': + resolution: {integrity: sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/expect@4.0.13': - resolution: {integrity: sha512-zYtcnNIBm6yS7Gpr7nFTmq8ncowlMdOJkWLqYvhr/zweY6tFbDkDi8BPPOeHxEtK1rSI69H7Fd4+1sqvEGli6w==} + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} - '@vitest/mocker@4.0.13': - resolution: {integrity: sha512-eNCwzrI5djoauklwP1fuslHBjrbR8rqIVbvNlAnkq1OTa6XT+lX68mrtPirNM9TnR69XUPt4puBCx2Wexseylg==} + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -1660,20 +1339,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.13': - resolution: {integrity: sha512-ooqfze8URWbI2ozOeLDMh8YZxWDpGXoeY3VOgcDnsUxN0jPyPWSUvjPQWqDGCBks+opWlN1E4oP1UYl3C/2EQA==} + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} - '@vitest/runner@4.0.13': - resolution: {integrity: sha512-9IKlAru58wcVaWy7hz6qWPb2QzJTKt+IOVKjAx5vb5rzEFPTL6H4/R9BMvjZ2ppkxKgTrFONEJFtzvnyEpiT+A==} + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} - '@vitest/snapshot@4.0.13': - resolution: {integrity: sha512-hb7Usvyika1huG6G6l191qu1urNPsq1iFc2hmdzQY3F5/rTgqQnwwplyf8zoYHkpt7H6rw5UfIw6i/3qf9oSxQ==} + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} - '@vitest/spy@4.0.13': - resolution: {integrity: sha512-hSu+m4se0lDV5yVIcNWqjuncrmBgwaXa2utFLIrBkQCQkt+pSwyZTPFQAZiiF/63j8jYa8uAeUZ3RSfcdWaYWw==} + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} - '@vitest/utils@4.0.13': - resolution: {integrity: sha512-ydozWyQ4LZuu8rLp47xFUWis5VOKMdHjXCWhs1LuJsTNKww+pTHQNK4e0assIB9K80TxFyskENL6vCu3j34EYA==} + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} '@web/config-loader@0.3.3': resolution: {integrity: sha512-ilzeQzrPpPLWZhzFCV+4doxKDGm7oKVfdKpW9wiUNVgive34NSzCw+WzXTvjE4Jgr5CkyTDIObEmMrqQEjhT0g==} @@ -1692,54 +1371,54 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - '@web/parse5-utils@2.1.0': - resolution: {integrity: sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==} + '@web/parse5-utils@2.1.1': + resolution: {integrity: sha512-7rBVZEMGfrq2iPcAEwJ0KSNSvmA2a6jT2CK8/gyIOHgn4reg7bSSRbzyWIEYWyIkeRoYEukX/aW+nAeCgSSqhQ==} engines: {node: '>=18.0.0'} - '@webassemblyjs/ast@1.12.1': - resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - '@webassemblyjs/floating-point-hex-parser@1.11.6': - resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - '@webassemblyjs/helper-api-error@1.11.6': - resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - '@webassemblyjs/helper-buffer@1.12.1': - resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - '@webassemblyjs/helper-numbers@1.11.6': - resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - '@webassemblyjs/helper-wasm-bytecode@1.11.6': - resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - '@webassemblyjs/helper-wasm-section@1.12.1': - resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - '@webassemblyjs/ieee754@1.11.6': - resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - '@webassemblyjs/leb128@1.11.6': - resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - '@webassemblyjs/utf8@1.11.6': - resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - '@webassemblyjs/wasm-edit@1.12.1': - resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - '@webassemblyjs/wasm-gen@1.12.1': - resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - '@webassemblyjs/wasm-opt@1.12.1': - resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - '@webassemblyjs/wasm-parser@1.12.1': - resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - '@webassemblyjs/wast-printer@1.12.1': - resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -1762,25 +1441,34 @@ packages: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} - engines: {node: '>=0.4.0'} - hasBin: true - acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true - agent-base@7.1.1: - resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv-formats@3.0.1: resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} peerDependencies: @@ -1794,6 +1482,11 @@ packages: peerDependencies: ajv: ^6.9.1 + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -1804,16 +1497,16 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - ansi-escapes@7.0.0: - resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + ansi-escapes@7.2.0: + resolution: {integrity: sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==} engines: {node: '>=18'} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-styles@3.2.1: @@ -1824,8 +1517,8 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} any-promise@1.3.0: @@ -1849,8 +1542,8 @@ packages: resolution: {integrity: sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==} engines: {node: '>=12.17'} - array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} array-flatten@1.1.1: @@ -1859,16 +1552,24 @@ packages: array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - array.prototype.reduce@1.0.7: - resolution: {integrity: sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==} + array.prototype.reduce@1.0.8: + resolution: {integrity: sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw==} engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} - async@2.6.4: - resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -1888,8 +1589,8 @@ packages: avvio@9.1.0: resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} - axios@1.13.2: - resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + axios@1.13.4: + resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} babel-helper-evaluate-path@0.5.0: resolution: {integrity: sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA==} @@ -1995,40 +1696,39 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} + hasBin: true + big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - bignumber.js@9.1.2: - resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.23.0: - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - browserslist@4.24.2: - resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2071,8 +1771,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} engines: {node: '>= 0.4'} call-bound@1.0.4: @@ -2095,14 +1795,11 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001605: - resolution: {integrity: sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==} - - caniuse-lite@1.0.30001684: - resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==} + caniuse-lite@1.0.30001766: + resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} - chai@6.2.1: - resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} chalk-template@0.4.0: @@ -2117,8 +1814,8 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} chardet@0.7.0: @@ -2128,8 +1825,8 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chrome-trace-event@1.0.3: - resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} cli-cursor@3.1.0: @@ -2204,12 +1901,12 @@ packages: resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} engines: {node: '>=4.0.0'} - command-line-usage@7.0.1: - resolution: {integrity: sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==} + command-line-usage@7.0.3: + resolution: {integrity: sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==} engines: {node: '>=12.20.0'} - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} commander@2.20.3: @@ -2244,9 +1941,9 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} - content-disposition@1.0.0: - resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} - engines: {node: '>= 0.6'} + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} @@ -2268,35 +1965,27 @@ packages: engines: {node: '>=16'} hasBin: true - conventional-commits-parser@6.2.0: - resolution: {integrity: sha512-uLnoLeIW4XaoFtH37qEcg/SXMJmKF4vi7V0H2rnPueg+VEtFGA/asSCNTcq4M/GQ6QmlzchAEtOoDTtKqWeHag==} + conventional-commits-parser@6.2.1: + resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==} engines: {node: '>=18'} hasBin: true convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} - cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} - - cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} - engines: {node: '>= 0.6'} - - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} cookies@0.9.1: @@ -2306,18 +1995,10 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} - cosmiconfig-typescript-loader@5.0.0: - resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} - engines: {node: '>=v16'} - peerDependencies: - '@types/node': '*' - cosmiconfig: '>=8.2' - typescript: '>=4' - cosmiconfig-typescript-loader@6.2.0: resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==} engines: {node: '>=v18'} @@ -2347,8 +2028,8 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - cssstyle@4.1.0: - resolution: {integrity: sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==} + cssstyle@4.6.0: + resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} engines: {node: '>=18'} cz-conventional-changelog@3.3.0: @@ -2363,16 +2044,16 @@ packages: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} - data-view-buffer@1.0.1: - resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} - data-view-byte-length@1.0.1: - resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} engines: {node: '>= 0.4'} - data-view-byte-offset@1.0.0: - resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} dateformat@4.6.3: @@ -2397,33 +2078,6 @@ packages: supports-color: optional: true - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -2433,8 +2087,8 @@ packages: supports-color: optional: true - decimal.js@10.4.3: - resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} @@ -2521,27 +2175,18 @@ packages: duplexify@4.1.3: resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.4.723: - resolution: {integrity: sha512-rxFVtrMGMFROr4qqU6n95rUi9IlfIm+lIAt+hOToy/9r6CDv0XiEcQdC3VP71y1pE5CFTzKV0RvxOGYCPWWHPw==} - - electron-to-chromium@1.5.67: - resolution: {integrity: sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==} + electron-to-chromium@1.5.279: + resolution: {integrity: sha512-0bblUU5UNdOt5G7XqGiJtpZMONma6WAfq9vsFmtn9x1+joAObr6x1chfqyxFSDCAFwFhCQDrqeAr6MYdpwJ9Hg==} - emoji-regex@10.3.0: - resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - emojis-list@3.0.0: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} @@ -2554,23 +2199,23 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - engine.io-parser@5.2.2: - resolution: {integrity: sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==} + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} engines: {node: '>=10.0.0'} - engine.io@6.5.4: - resolution: {integrity: sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==} + engine.io@6.6.5: + resolution: {integrity: sha512-2RZdgEbXmp5+dVbRm0P7HQUImZpICccJy7rN7Tv+SFa55pH+lxnuw6/K1ZxxBfHoYpSkHLAO92oa8O4SwFXA2A==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.17.1: - resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + enhanced-resolve@5.18.4: + resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} engines: {node: '>=10.13.0'} - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} env-paths@2.2.1: @@ -2581,20 +2226,16 @@ packages: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-abstract@1.23.3: - resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + es-abstract@1.24.1: + resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} engines: {node: '>= 0.4'} es-array-method-boxes-properly@1.0.0: resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} - es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} - es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -2603,51 +2244,34 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-module-lexer@1.5.0: - resolution: {integrity: sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==} - es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - es-object-atoms@1.0.0: - resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} - engines: {node: '>= 0.4'} + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} - es-set-tostringtag@2.0.3: - resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} - engines: {node: '>= 0.4'} - es-set-tostringtag@2.1.0: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild-loader@4.4.0: - resolution: {integrity: sha512-4J+hXTpTtEdzUNLoY8ReqDNJx2NoldfiljRCiKbeYUuZmVaiJeDqFgyAzz8uOopaekwRoCcqBFyEroGQLFVZ1g==} + esbuild-loader@4.4.2: + resolution: {integrity: sha512-8LdoT9sC7fzfvhxhsIAiWhzLJr9yT3ggmckXxsgvM07wgrRxhuT98XhLn3E7VczU5W5AFsPKv9DdWcZIubbWkQ==} peerDependencies: webpack: ^4.40.0 || ^5.0.0 - esbuild@0.25.3: - resolution: {integrity: sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==} - engines: {node: '>=18'} - hasBin: true - - esbuild@0.27.0: - resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==} + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} engines: {node: '>=18'} hasBin: true - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -2669,8 +2293,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-prettier@5.5.4: - resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} + eslint-plugin-prettier@5.5.5: + resolution: {integrity: sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -2699,8 +2323,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.39.1: - resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==} + eslint@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2713,8 +2337,8 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -2743,8 +2367,8 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} @@ -2766,16 +2390,16 @@ packages: resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} engines: {node: '>=0.10.0'} - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} - express@4.19.2: - resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} engines: {node: '>= 0.10.0'} - express@5.1.0: - resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} external-editor@3.1.0: @@ -2798,8 +2422,8 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - fast-json-stringify@6.1.1: - resolution: {integrity: sha512-DbgptncYEXZqDUOEl4krff4mUiVrTZZVI7BBrQR/T3BqMj/eM1flTC1Uk2uUoLcWCxjT95xKulV/Lc6hhOZsBQ==} + fast-json-stringify@6.2.0: + resolution: {integrity: sha512-Eaf/KNIDwHkzfyeQFNfLXJnQ7cl1XQI3+zRqmPlvtkMigbXnAcasTrvJQmquBSxKfFGeRA6PFog8t+hFmpDoWw==} fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -2820,11 +2444,11 @@ packages: fastify-plugin@5.1.0: resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==} - fastify@5.6.2: - resolution: {integrity: sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==} + fastify@5.7.2: + resolution: {integrity: sha512-dBJolW+hm6N/yJVf6J5E1BxOBNkuXNl405nrfeR8SpvGWG3aCC2XDHyiFBdow8Win1kj7sjawQc257JlYY6M/A==} - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} fd-package-json@2.0.0: resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} @@ -2850,16 +2474,16 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} - find-my-way@9.3.0: - resolution: {integrity: sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==} + find-my-way@9.4.0: + resolution: {integrity: sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==} engines: {node: '>=20'} find-node-modules@2.1.3: @@ -2895,11 +2519,11 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -2907,16 +2531,9 @@ packages: debug: optional: true - for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} form-data@4.0.5: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} @@ -2947,8 +2564,8 @@ packages: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} - fs-monkey@1.0.5: - resolution: {integrity: sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==} + fs-monkey@1.1.0: + resolution: {integrity: sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==} fs-readdir-recursive@1.1.0: resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} @@ -2972,13 +2589,17 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -2987,14 +2608,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.2.0: - resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + get-east-asian-width@1.4.0: + resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} engines: {node: '>=18'} - get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} - get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -3011,15 +2628,15 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} get-tsconfig@4.13.0: resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} - git-log-parser@1.2.0: - resolution: {integrity: sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==} + git-log-parser@1.2.1: + resolution: {integrity: sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==} git-raw-commits@4.0.0: resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} @@ -3037,11 +2654,6 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.3.12: - resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - glob@13.0.0: resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} engines: {node: 20 || >=22} @@ -3062,21 +2674,14 @@ packages: resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} engines: {node: '>=0.10.0'} - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -3087,15 +2692,13 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - graphql@16.12.0: resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} @@ -3108,12 +2711,8 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} - - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} engines: {node: '>= 0.4'} has-symbols@1.1.0: @@ -3138,8 +2737,8 @@ packages: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} - hono@4.10.4: - resolution: {integrity: sha512-YG/fo7zlU3KwrBL5vDpWKisLYiM+nVstBQqfr7gCPbSYURnNEP9BDxEMz8KfsDR9JX0lJWDRNc6nXX31v7ZEyg==} + hono@4.11.7: + resolution: {integrity: sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw==} engines: {node: '>=16.9.0'} html-encoding-sniffer@4.0.0: @@ -3153,8 +2752,8 @@ packages: resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} engines: {node: '>= 0.8'} - http-cache-semantics@4.1.1: - resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} http-errors@1.6.3: resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} @@ -3164,16 +2763,16 @@ packages: resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} engines: {node: '>= 0.6'} - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} - https-proxy-agent@7.0.5: - resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} human-signals@2.1.0: @@ -3196,23 +2795,27 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} ignore@7.0.5: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-meta-resolve@4.0.0: - resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} @@ -3243,8 +2846,8 @@ packages: resolution: {integrity: sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==} engines: {node: '>=10'} - internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} ip-regex@4.3.0: @@ -3255,37 +2858,43 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.2.0: - resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} engines: {node: '>= 10'} - is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} - is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} - is-data-view@1.0.1: - resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} engines: {node: '>= 0.4'} - is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} is-docker@2.2.1: @@ -3297,6 +2906,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -3305,12 +2918,12 @@ packages: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} - is-fullwidth-code-point@5.0.0: - resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} engines: {node: '>=18'} - is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -3325,6 +2938,10 @@ packages: resolution: {integrity: sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==} engines: {node: '>=8'} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} @@ -3335,8 +2952,8 @@ packages: is-node-process@1.2.0: resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} is-number@7.0.0: @@ -3357,12 +2974,16 @@ packages: is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} - is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} is-stream@2.0.1: @@ -3373,20 +2994,20 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} - is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} engines: {node: '>= 0.4'} is-text-path@2.0.0: resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} engines: {node: '>=8'} - is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} is-unicode-supported@0.1.0: @@ -3396,8 +3017,17 @@ packages: is-utf8@0.2.1: resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} - is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} @@ -3413,8 +3043,8 @@ packages: isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - isbinaryfile@5.0.2: - resolution: {integrity: sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==} + isbinaryfile@5.0.7: + resolution: {integrity: sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==} engines: {node: '>= 18.0.0'} isexe@2.0.0: @@ -3428,18 +3058,10 @@ packages: resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==} engines: {node: ^18.17 || >=20.6.1} - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} - jiti@1.21.0: - resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} - hasBin: true - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -3451,10 +3073,6 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true @@ -3468,9 +3086,9 @@ packages: canvas: optional: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} hasBin: true json-bigint@1.0.0: @@ -3499,8 +3117,8 @@ packages: engines: {node: '>=6'} hasBin: true - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} @@ -3522,8 +3140,8 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} - knip@5.70.1: - resolution: {integrity: sha512-tGRjOivkHPV+YoVVDz0oKSlvCAY6d009Mlhufs4Y+7VWl/Ky073+KURcrgMLzJVy4pkpZvoxYu3wmC0gK7XS5g==} + knip@5.82.1: + resolution: {integrity: sha512-1nQk+5AcnkqL40kGQXfouzAEXkTR+eSrgo/8m1d0BMei4eAzFwghoXC4gOKbACgBiCof7hE8wkBVDsEvznf85w==} engines: {node: '>=18.18.0'} hasBin: true peerDependencies: @@ -3548,8 +3166,8 @@ packages: resolution: {integrity: sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==} engines: {node: '>= 7.6.0'} - koa@2.15.2: - resolution: {integrity: sha512-MXTeZH3M6AJ8ukW2QZ8wqO3Dcdfh2WRRmjCBkEP+NhKNCiqlO5RDqHmSnsyNrbRJrdjyvIGSJho4vQiWgQJSVA==} + koa@2.16.3: + resolution: {integrity: sha512-zPPuIt+ku1iCpFBRwseMcPYQ1cJL8l60rSmKeOuGfOXyE6YnTBmf2aEFNL2HQGrD0cPcLO/t+v9RTgC+fwEh/g==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} leven@2.1.0: @@ -3563,28 +3181,28 @@ packages: light-my-request@6.6.0: resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} - lilconfig@3.1.2: - resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@15.2.10: - resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==} + lint-staged@15.5.2: + resolution: {integrity: sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==} engines: {node: '>=18.12.0'} hasBin: true - listr2@8.2.5: - resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} + listr2@8.3.3: + resolution: {integrity: sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==} engines: {node: '>=18.0.0'} load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - loader-runner@4.3.0: - resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} loader-utils@2.0.4: @@ -3599,9 +3217,6 @@ packages: resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lodash.assignwith@4.2.0: - resolution: {integrity: sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==} - lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -3647,6 +3262,9 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -3659,28 +3277,20 @@ packages: resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==} engines: {node: '>=0.10.0'} - lru-cache@10.2.0: - resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} - engines: {node: 14 || >=16.14} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.0.2: - resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} + lru-cache@11.2.5: + resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} engines: {node: 20 || >=22} lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - lru-cache@8.0.5: resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==} engines: {node: '>=16.14'} - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -3708,8 +3318,8 @@ packages: resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} engines: {node: '>=18'} - merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} merge-descriptors@2.0.0: resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} @@ -3737,10 +3347,6 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - mime-db@1.53.0: - resolution: {integrity: sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==} - engines: {node: '>= 0.6'} - mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} @@ -3749,10 +3355,6 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime-types@3.0.0: - resolution: {integrity: sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==} - engines: {node: '>= 0.6'} - mime-types@3.0.2: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} @@ -3762,11 +3364,6 @@ packages: engines: {node: '>=4'} hasBin: true - mime@4.0.1: - resolution: {integrity: sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA==} - engines: {node: '>=16'} - hasBin: true - mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -3786,8 +3383,8 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.7: @@ -3811,12 +3408,13 @@ packages: resolution: {integrity: sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==} engines: {node: '>=4'} + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3865,11 +3463,8 @@ packages: encoding: optional: true - node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - - node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} @@ -3882,16 +3477,13 @@ packages: npx-import@1.1.4: resolution: {integrity: sha512-3ShymTWOgqGyNlh5lMJAejLuIv3W1K3fbI5Ewc6YErZU3Sp0PqsNs8UIU1O8z5+KVl/Du5ag56Gza9vdorGEoA==} - nwsapi@2.2.16: - resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==} + nwsapi@2.2.23: + resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -3900,13 +3492,16 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} - object.getownpropertydescriptors@2.1.8: - resolution: {integrity: sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==} - engines: {node: '>= 0.8'} + object.getownpropertydescriptors@2.1.9: + resolution: {integrity: sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==} + engines: {node: '>= 0.4'} + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} on-exit-leak-free@0.2.0: resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} @@ -3941,8 +3536,8 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} ora@5.4.1: @@ -3956,8 +3551,12 @@ packages: outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - oxc-resolver@11.13.2: - resolution: {integrity: sha512-1SXVyYQ9bqMX3uZo8Px81EG7jhZkO9PvvR5X9roY5TLYVm4ZA7pbPDNlYaDBBeF9U+YO3OeMNoHde52hrcCu8w==} + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + oxc-resolver@11.16.4: + resolution: {integrity: sha512-nvJr3orFz1wNaBA4neRw7CAn0SsjgVaEw1UHpgO/lzVW12w+nsFnvU/S6vVX3kYyFaZdxZheTExi/fa8R8PrZA==} p-event@4.2.0: resolution: {integrity: sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==} @@ -3990,8 +3589,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@1.3.0: - resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} page-with@0.6.1: resolution: {integrity: sha512-5J58fSpc8CKonUWCPsh8b2LctFrNSOpXQ8O3tB+/iJvixOQf1qHp4+cDLiIVsl/WiuheXdZTzMcuR0KLQMaWcg==} @@ -4014,8 +3613,8 @@ packages: parse5@6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} @@ -4044,23 +3643,18 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.10.2: - resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} - engines: {node: '>=16 || 14 >=14.17'} - - path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} - path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - path-to-regexp@8.2.0: - resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} - engines: {node: '>=16'} + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -4084,8 +3678,8 @@ packages: pino-abstract-transport@0.5.0: resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} - pino-abstract-transport@2.0.0: - resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + pino-abstract-transport@3.0.0: + resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} pino-pretty@7.6.1: resolution: {integrity: sha512-H7N6ZYkiyrfwBGW9CSjx0uyO9Q2Lyt73881+OTYk8v3TiTdgN92QHrWlEq/LeWw5XtDP64jeSk3mnc6T+xX9/w==} @@ -4094,50 +3688,40 @@ packages: pino-std-serializers@4.0.0: resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} - pino-std-serializers@7.0.0: - resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + pino-std-serializers@7.1.0: + resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} - pino@10.1.0: - resolution: {integrity: sha512-0zZC2ygfdqvqK8zJIr1e+wT1T/L+LF6qvqvbzEQ6tiMAoTqEVK9a1K3YRu8HEUvGEvNqZyPJTtb2sNIoTkB83w==} + pino@10.3.0: + resolution: {integrity: sha512-0GNPNzHXBKw6U/InGe79A3Crzyk9bcSyObF9/Gfo9DLEf5qj5RF50RSjsu0W1rZ6ZqRGdzDFCRBQvi9/rSGPtA==} hasBin: true pino@7.11.0: resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} hasBin: true - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - playwright-core@1.42.1: - resolution: {integrity: sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==} - engines: {node: '>=16'} - hasBin: true - - playwright-core@1.56.1: - resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} + playwright-core@1.58.0: + resolution: {integrity: sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==} engines: {node: '>=18'} hasBin: true - playwright@1.42.1: - resolution: {integrity: sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==} - engines: {node: '>=16'} - hasBin: true - - playwright@1.56.1: - resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} + playwright@1.58.0: + resolution: {integrity: sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==} engines: {node: '>=18'} hasBin: true - portfinder@1.0.32: - resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} - engines: {node: '>= 0.12.0'} + portfinder@1.0.38: + resolution: {integrity: sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==} + engines: {node: '>= 10.12'} - possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} postcss-load-config@6.0.1: @@ -4166,12 +3750,12 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + prettier-linter-helpers@1.0.1: + resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} engines: {node: '>=6.0.0'} - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true @@ -4181,8 +3765,8 @@ packages: process-warning@1.0.0: resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} - process-warning@4.0.0: - resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==} + process-warning@4.0.1: + resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} @@ -4197,24 +3781,20 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - publint@0.3.15: - resolution: {integrity: sha512-xPbRAPW+vqdiaKy5sVVY0uFAu3LaviaPO3pZ9FaRx59l9+U/RKR1OEbLhkug87cwiVKxPXyB4txsv5cad67u+A==} + publint@0.3.17: + resolution: {integrity: sha512-Q3NLegA9XM6usW+dYQRG1g9uEHiYUzcCVBJDJ7yMcWRqVU9LYZUWdqbwMZfmTCFC5PZLQpLAmhvRcQRl3exqkw==} engines: {node: '>=18'} hasBin: true - pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + qs@6.14.1: + resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -4230,13 +3810,13 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} engines: {node: '>= 0.8'} - raw-body@3.0.0: - resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} - engines: {node: '>= 0.8'} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} @@ -4249,9 +3829,9 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - readdirp@4.0.2: - resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} - engines: {node: '>= 14.16.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} real-require@0.1.0: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} @@ -4261,15 +3841,19 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - registry-auth-token@5.1.0: - resolution: {integrity: sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==} + registry-auth-token@5.1.1: + resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==} engines: {node: '>=14'} require-directory@2.1.1: @@ -4299,8 +3883,9 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} hasBin: true restore-cursor@3.1.0: @@ -4318,8 +3903,8 @@ packages: rettime@0.9.1: resolution: {integrity: sha512-UszoaHy8mQkQZCbEYjw+J21ZZ+VhiTAYK47Tl+wm8VSbTRronhJiheSNlRo0ED/6zUG9vbIY7gRu7ZfColdVnw==} - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} rfdc@1.4.1: @@ -4330,13 +3915,8 @@ packages: engines: {node: 20 || >=22} hasBin: true - rollup@4.40.1: - resolution: {integrity: sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - rollup@4.53.3: - resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} + rollup@4.57.0: + resolution: {integrity: sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -4347,6 +3927,9 @@ packages: rrweb-cssom@0.7.1: resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -4354,15 +3937,15 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} - safe-array-concat@1.1.2: - resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} safe-buffer@5.1.2: @@ -4371,15 +3954,19 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-regex-test@1.0.3: - resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} safe-regex2@5.0.0: resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==} - safe-stable-stringify@2.4.3: - resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} engines: {node: '>=10'} safer-buffer@2.1.2: @@ -4393,6 +3980,10 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} @@ -4403,36 +3994,32 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true - send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} engines: {node: '>= 0.8.0'} - send@1.1.0: - resolution: {integrity: sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==} - engines: {node: '>= 18'} - - send@1.2.0: - resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} - serve-static@2.2.0: - resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} engines: {node: '>= 18'} - set-cookie-parser@2.6.0: - resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} @@ -4442,6 +4029,10 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + setprototypeof@1.1.0: resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} @@ -4472,10 +4063,6 @@ packages: resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} engines: {node: '>= 0.4'} - side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} - engines: {node: '>= 0.4'} - side-channel@1.1.0: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} @@ -4498,23 +4085,23 @@ packages: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} - slice-ansi@7.1.0: - resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + slice-ansi@7.1.2: + resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} - smol-toml@1.5.2: - resolution: {integrity: sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==} + smol-toml@1.6.0: + resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} engines: {node: '>= 18'} - socket.io-adapter@2.5.4: - resolution: {integrity: sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==} + socket.io-adapter@2.5.6: + resolution: {integrity: sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==} - socket.io-parser@4.2.4: - resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + socket.io-parser@4.2.5: + resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==} engines: {node: '>=10.0.0'} - socket.io@4.7.5: - resolution: {integrity: sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==} + socket.io@4.8.3: + resolution: {integrity: sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==} engines: {node: '>=10.2.0'} sonic-boom@2.8.0: @@ -4558,10 +4145,6 @@ packages: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - statuses@2.0.2: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} @@ -4569,13 +4152,13 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + stream-combiner2@1.1.1: resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} - stream-read-all@3.0.1: - resolution: {integrity: sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==} - engines: {node: '>=10'} - stream-shift@1.0.3: resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} @@ -4594,24 +4177,17 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string-width@7.1.0: - resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} - engines: {node: '>=18'} - string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string.prototype.trim@1.2.9: - resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} string.prototype.trimstart@1.0.8: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} @@ -4627,8 +4203,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} strip-bom@4.0.0: @@ -4655,8 +4231,8 @@ packages: resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} engines: {node: '>=14.16'} - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true @@ -4679,25 +4255,24 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - synckit@0.11.11: - resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + synckit@0.11.12: + resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} - table-layout@3.0.2: - resolution: {integrity: sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==} + table-layout@4.1.1: + resolution: {integrity: sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==} engines: {node: '>=12.17'} - hasBin: true tagged-tag@1.0.0: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} - terser-webpack-plugin@5.3.10: - resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + terser-webpack-plugin@5.3.16: + resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -4712,8 +4287,8 @@ packages: uglify-js: optional: true - terser@5.30.1: - resolution: {integrity: sha512-PJhOnRttZqqmIujxOQOMu4QuFGvh43lR7Youln3k6OJvmxwZ5FxK5rbCEh8XABRCpLf7ZnhrZuclCNCASsScnA==} + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} engines: {node: '>=10'} hasBin: true @@ -4731,8 +4306,9 @@ packages: thread-stream@0.15.2: resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} - thread-stream@3.1.0: - resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + thread-stream@4.0.0: + resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==} + engines: {node: '>=20'} through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} @@ -4758,28 +4334,24 @@ packages: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} - tldts-core@6.1.65: - resolution: {integrity: sha512-Uq5t0N0Oj4nQSbU8wFN1YYENvMthvwU13MQrMJRspYCGLSAZjAfoBOJki5IQpnBM/WFskxxC/gIOTwaedmHaSg==} + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.0.12: - resolution: {integrity: sha512-3K76aXywJFduGRsOYoY5JzINLs/WMlOkeDwPL+8OCPq2Rh39gkSDtWAxdJQlWjpun/xF/LHf29yqCi6VC/rHDA==} + tldts-core@7.0.19: + resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} - tldts@6.1.65: - resolution: {integrity: sha512-xU9gLTfAGsADQ2PcWee6Hg8RFAv0DnjMGVJmDnUmI8a9+nYmapMQix4afwrdaCtT+AqP4MaxEzu7cCrYmBPbzQ==} + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.0.12: - resolution: {integrity: sha512-M9ZQBPp6FyqhMcl233vHYyYRkxXOA1SKGlnq13S0mJdUhRSwr2w6I8rlchPL73wBwRlyIZpFvpu2VcdSMWLYXw==} + tldts@7.0.19: + resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==} hasBin: true tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -4792,8 +4364,8 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - tough-cookie@5.0.0: - resolution: {integrity: sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==} + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} tough-cookie@6.0.0: @@ -4803,8 +4375,8 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@5.0.0: - resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} traverse@0.6.8: @@ -4815,8 +4387,8 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -4824,8 +4396,8 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} tsscmp@1.0.6: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} @@ -4858,8 +4430,8 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@5.2.0: - resolution: {integrity: sha512-xxCJm+Bckc6kQBknN7i9fnP/xobQRsRQxR01CztFkp/h++yfVxUUcmMgfR2HttJx/dpWjS9ubVuyspJv24Q9DA==} + type-fest@5.4.2: + resolution: {integrity: sha512-FLEenlVYf7Zcd34ISMLo3ZzRE1gRjY1nMDTp+bQRBiPsaKyIW8K3Zr99ioHDUgA9OGuGGJPyYpNcffGmBhJfGg==} engines: {node: '>=20'} type-is@1.6.18: @@ -4870,24 +4442,24 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} - typed-array-buffer@1.0.2: - resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.1: - resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.2: - resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} engines: {node: '>= 0.4'} - typed-array-length@1.0.6: - resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.47.0: - resolution: {integrity: sha512-Lwe8i2XQ3WoMjua/r1PHrCTpkubPYJCAfOurtn+mtTzqB6jNd+14n9UN1bJ4s3F49x9ixAm0FLflB/JzQ57M8Q==} + typescript-eslint@8.54.0: + resolution: {integrity: sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4902,31 +4474,29 @@ packages: resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} engines: {node: '>=8'} - typical@7.1.1: - resolution: {integrity: sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==} + typical@7.3.0: + resolution: {integrity: sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==} engines: {node: '>=12.17'} - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.12.0: - resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} - undici@7.16.0: - resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} + undici@7.19.2: + resolution: {integrity: sha512-4VQSpGEGsWzk0VYxyB/wVX/Q7qf9t5znLRgs0dzszr9w9Fej/8RVNQ+S20vdXSAyra/bJ7ZQfGv6ZMj7UEbzSg==} engines: {node: '>=20.18.1'} unicorn-magic@0.1.0: @@ -4944,14 +4514,8 @@ packages: until-async@3.0.2: resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} - update-browserslist-db@1.0.13: - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - update-browserslist-db@1.1.1: - resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -4975,8 +4539,9 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - util.promisify@1.1.2: - resolution: {integrity: sha512-PBdZ03m1kBnQ5cjjO0ZvJMJS+QsbyIcFwi4hY4U76OQsCO9JrOYjbCFgIF76ccFg9xnJo7ZHPkqyj1GqmdS7MA==} + util.promisify@1.1.3: + resolution: {integrity: sha512-GIEaZ6o86fj09Wtf0VfZ5XP7tmd4t3jM5aZCgmBi231D0DB1AEBa3Aa6MP48DMsAIi96WkpWLimIWVwOjbDMOw==} + engines: {node: '>= 0.8'} utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} @@ -4994,8 +4559,8 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite@7.2.4: - resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==} + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -5041,19 +4606,18 @@ packages: peerDependencies: vitest: '>=0.23.0' - vitest@4.0.13: - resolution: {integrity: sha512-QSD4I0fN6uZQfftryIXuqvqgBxTvJ3ZNkF6RWECd82YGAYAfhcppBLFXzXJHQAAhVFyYEuFTrq6h0hQqjB7jIQ==} + vitest@4.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 - '@types/debug': ^4.1.12 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.13 - '@vitest/browser-preview': 4.0.13 - '@vitest/browser-webdriverio': 4.0.13 - '@vitest/ui': 4.0.13 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -5061,8 +4625,6 @@ packages: optional: true '@opentelemetry/api': optional: true - '@types/debug': - optional: true '@types/node': optional: true '@vitest/browser-playwright': @@ -5086,8 +4648,8 @@ packages: resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} engines: {node: 20 || >=22} - watchpack@2.4.1: - resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} engines: {node: '>=10.13.0'} wcwidth@1.0.1: @@ -5110,12 +4672,12 @@ packages: webpack-sources@1.4.3: resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} - webpack-sources@3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} engines: {node: '>=10.13.0'} - webpack@5.96.1: - resolution: {integrity: sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==} + webpack@5.104.1: + resolution: {integrity: sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -5127,23 +4689,33 @@ packages: whatwg-encoding@3.1.1: resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} - whatwg-url@14.0.0: - resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==} + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} - which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} which@1.3.1: @@ -5167,8 +4739,8 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - wordwrapjs@5.1.0: - resolution: {integrity: sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==} + wordwrapjs@5.1.1: + resolution: {integrity: sha512-0yweIbkINJodk27gX9LBGMzyQdBDan3s/dEAiwBOj+Mf0PPyWL6/rikalkv8EeD0E8jm4o5RXEOrFTP3NXbhJg==} engines: {node: '>=12.17'} wrap-ansi@6.2.0: @@ -5179,12 +4751,8 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrap-ansi@9.0.0: - resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} engines: {node: '>=18'} wrappy@1.0.2: @@ -5202,20 +4770,8 @@ packages: utf-8-validate: optional: true - ws@8.11.0: - resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - ws@8.18.0: - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -5226,8 +4782,8 @@ packages: utf-8-validate: optional: true - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -5256,12 +4812,9 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yaml@2.5.1: - resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} - engines: {node: '>= 14'} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} hasBin: true yargs-parser@10.1.0: @@ -5295,241 +4848,185 @@ packages: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} - yoctocolors-cjs@2.1.2: - resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} - zod@4.1.12: - resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} snapshots: - '@75lb/deep-merge@1.1.1': - dependencies: - lodash.assignwith: 4.2.0 - typical: 7.1.1 - - '@aashutoshrathi/word-wrap@1.2.6': {} - - '@ampproject/remapping@2.3.0': + '@asamuzakjp/css-color@3.2.0': dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 10.4.3 - '@babel/code-frame@7.24.2': + '@babel/code-frame@7.28.6': dependencies: - '@babel/highlight': 7.24.2 + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.24.1': {} + '@babel/compat-data@7.28.6': {} - '@babel/core@7.24.3': + '@babel/core@7.28.6': dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.1 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) - '@babel/helpers': 7.24.1 - '@babel/parser': 7.24.1 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.1 - '@babel/types': 7.24.0 + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.0 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.24.1': + '@babel/generator@7.28.6': dependencies: - '@babel/types': 7.24.0 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.23.6': + '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/compat-data': 7.24.1 - '@babel/helper-validator-option': 7.23.5 - browserslist: 4.23.0 + '@babel/compat-data': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-environment-visitor@7.22.20': {} - - '@babel/helper-function-name@7.23.0': - dependencies: - '@babel/template': 7.24.0 - '@babel/types': 7.24.0 - - '@babel/helper-hoist-variables@7.22.5': - dependencies: - '@babel/types': 7.24.0 - - '@babel/helper-module-imports@7.24.3': - dependencies: - '@babel/types': 7.24.0 - - '@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3)': - dependencies: - '@babel/core': 7.24.3 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.20 + '@babel/helper-globals@7.28.0': {} - '@babel/helper-simple-access@7.22.5': + '@babel/helper-module-imports@7.28.6': dependencies: - '@babel/types': 7.24.0 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 + transitivePeerDependencies: + - supports-color - '@babel/helper-split-export-declaration@7.22.6': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.6)': dependencies: - '@babel/types': 7.24.0 - - '@babel/helper-string-parser@7.24.1': {} + '@babel/core': 7.28.6 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color - '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-option@7.23.5': {} + '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helpers@7.24.1': - dependencies: - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.1 - '@babel/types': 7.24.0 - transitivePeerDependencies: - - supports-color + '@babel/helper-validator-option@7.27.1': {} - '@babel/highlight@7.24.2': + '@babel/helpers@7.28.6': dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.1.1 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 - '@babel/parser@7.24.1': + '@babel/parser@7.28.6': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.28.6 - '@babel/template@7.24.0': + '@babel/template@7.28.6': dependencies: - '@babel/code-frame': 7.24.2 - '@babel/parser': 7.24.1 - '@babel/types': 7.24.0 + '@babel/code-frame': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 - '@babel/traverse@7.24.1': + '@babel/traverse@7.28.6': dependencies: - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.1 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.24.1 - '@babel/types': 7.24.0 + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 debug: 4.4.3 - globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.24.0': + '@babel/types@7.28.6': dependencies: - '@babel/helper-string-parser': 7.24.1 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 - '@cloudflare/workers-types@4.20250430.0': {} + '@cloudflare/workers-types@4.20260128.0': {} - '@commitlint/cli@20.1.0(@types/node@20.19.25)(typescript@5.9.3)': + '@commitlint/cli@20.3.1(@types/node@20.19.30)(typescript@5.9.3)': dependencies: - '@commitlint/format': 20.0.0 - '@commitlint/lint': 20.0.0 - '@commitlint/load': 20.1.0(@types/node@20.19.25)(typescript@5.9.3) - '@commitlint/read': 20.0.0 - '@commitlint/types': 20.0.0 + '@commitlint/format': 20.3.1 + '@commitlint/lint': 20.3.1 + '@commitlint/load': 20.3.1(@types/node@20.19.30)(typescript@5.9.3) + '@commitlint/read': 20.3.1 + '@commitlint/types': 20.3.1 tinyexec: 1.0.2 yargs: 17.7.2 transitivePeerDependencies: - '@types/node' - typescript - '@commitlint/config-conventional@20.0.0': + '@commitlint/config-conventional@20.3.1': dependencies: - '@commitlint/types': 20.0.0 + '@commitlint/types': 20.3.1 conventional-changelog-conventionalcommits: 7.0.2 - '@commitlint/config-validator@19.0.3': - dependencies: - '@commitlint/types': 19.0.3 - ajv: 8.17.1 - optional: true - - '@commitlint/config-validator@20.0.0': + '@commitlint/config-validator@20.3.1': dependencies: - '@commitlint/types': 20.0.0 + '@commitlint/types': 20.3.1 ajv: 8.17.1 - '@commitlint/ensure@20.0.0': + '@commitlint/ensure@20.3.1': dependencies: - '@commitlint/types': 20.0.0 + '@commitlint/types': 20.3.1 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 lodash.snakecase: 4.1.1 lodash.startcase: 4.4.0 lodash.upperfirst: 4.3.1 - '@commitlint/execute-rule@19.0.0': - optional: true - '@commitlint/execute-rule@20.0.0': {} - '@commitlint/format@20.0.0': - dependencies: - '@commitlint/types': 20.0.0 - chalk: 5.3.0 - - '@commitlint/is-ignored@20.0.0': + '@commitlint/format@20.3.1': dependencies: - '@commitlint/types': 20.0.0 - semver: 7.6.0 + '@commitlint/types': 20.3.1 + chalk: 5.6.2 - '@commitlint/lint@20.0.0': + '@commitlint/is-ignored@20.3.1': dependencies: - '@commitlint/is-ignored': 20.0.0 - '@commitlint/parse': 20.0.0 - '@commitlint/rules': 20.0.0 - '@commitlint/types': 20.0.0 + '@commitlint/types': 20.3.1 + semver: 7.7.3 - '@commitlint/load@19.2.0(@types/node@20.19.25)(typescript@5.9.3)': + '@commitlint/lint@20.3.1': dependencies: - '@commitlint/config-validator': 19.0.3 - '@commitlint/execute-rule': 19.0.0 - '@commitlint/resolve-extends': 19.1.0 - '@commitlint/types': 19.0.3 - chalk: 5.3.0 - cosmiconfig: 9.0.0(typescript@5.9.3) - cosmiconfig-typescript-loader: 5.0.0(@types/node@20.19.25)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) - lodash.isplainobject: 4.0.6 - lodash.merge: 4.6.2 - lodash.uniq: 4.5.0 - transitivePeerDependencies: - - '@types/node' - - typescript - optional: true + '@commitlint/is-ignored': 20.3.1 + '@commitlint/parse': 20.3.1 + '@commitlint/rules': 20.3.1 + '@commitlint/types': 20.3.1 - '@commitlint/load@20.1.0(@types/node@20.19.25)(typescript@5.9.3)': + '@commitlint/load@20.3.1(@types/node@20.19.30)(typescript@5.9.3)': dependencies: - '@commitlint/config-validator': 20.0.0 + '@commitlint/config-validator': 20.3.1 '@commitlint/execute-rule': 20.0.0 - '@commitlint/resolve-extends': 20.1.0 - '@commitlint/types': 20.0.0 - chalk: 5.3.0 + '@commitlint/resolve-extends': 20.3.1 + '@commitlint/types': 20.3.1 + chalk: 5.6.2 cosmiconfig: 9.0.0(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.2.0(@types/node@20.19.25)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.2.0(@types/node@20.19.30)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -5539,45 +5036,35 @@ snapshots: '@commitlint/message@20.0.0': {} - '@commitlint/parse@20.0.0': + '@commitlint/parse@20.3.1': dependencies: - '@commitlint/types': 20.0.0 + '@commitlint/types': 20.3.1 conventional-changelog-angular: 7.0.0 conventional-commits-parser: 5.0.0 - '@commitlint/read@20.0.0': + '@commitlint/read@20.3.1': dependencies: '@commitlint/top-level': 20.0.0 - '@commitlint/types': 20.0.0 - git-raw-commits: 4.0.0 - minimist: 1.2.8 - tinyexec: 1.0.2 - - '@commitlint/resolve-extends@19.1.0': - dependencies: - '@commitlint/config-validator': 19.0.3 - '@commitlint/types': 19.0.3 - global-directory: 4.0.1 - import-meta-resolve: 4.0.0 - lodash.mergewith: 4.6.2 - resolve-from: 5.0.0 - optional: true + '@commitlint/types': 20.3.1 + git-raw-commits: 4.0.0 + minimist: 1.2.8 + tinyexec: 1.0.2 - '@commitlint/resolve-extends@20.1.0': + '@commitlint/resolve-extends@20.3.1': dependencies: - '@commitlint/config-validator': 20.0.0 - '@commitlint/types': 20.0.0 + '@commitlint/config-validator': 20.3.1 + '@commitlint/types': 20.3.1 global-directory: 4.0.1 - import-meta-resolve: 4.0.0 + import-meta-resolve: 4.2.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 - '@commitlint/rules@20.0.0': + '@commitlint/rules@20.3.1': dependencies: - '@commitlint/ensure': 20.0.0 + '@commitlint/ensure': 20.3.1 '@commitlint/message': 20.0.0 '@commitlint/to-lines': 20.0.0 - '@commitlint/types': 20.0.0 + '@commitlint/types': 20.3.1 '@commitlint/to-lines@20.0.0': {} @@ -5585,206 +5072,145 @@ snapshots: dependencies: find-up: 7.0.0 - '@commitlint/types@19.0.3': + '@commitlint/types@20.3.1': dependencies: - '@types/conventional-commits-parser': 5.0.0 - chalk: 5.3.0 - optional: true + '@types/conventional-commits-parser': 5.0.2 + chalk: 5.6.2 + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 - '@commitlint/types@20.0.0': + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': dependencies: - '@types/conventional-commits-parser': 5.0.1 - chalk: 5.3.0 + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} - '@emnapi/core@1.7.1': + '@emnapi/core@1.8.1': dependencies: '@emnapi/wasi-threads': 1.1.0 - tslib: 2.6.2 + tslib: 2.8.1 optional: true - '@emnapi/runtime@1.7.1': + '@emnapi/runtime@1.8.1': dependencies: - tslib: 2.6.2 + tslib: 2.8.1 optional: true '@emnapi/wasi-threads@1.1.0': dependencies: - tslib: 2.6.2 + tslib: 2.8.1 optional: true '@epic-web/invariant@1.0.0': {} '@epic-web/test-server@0.1.6': dependencies: - '@hono/node-server': 1.19.6(hono@4.10.4) - '@hono/node-ws': 1.2.0(@hono/node-server@1.19.6(hono@4.10.4))(hono@4.10.4) + '@hono/node-server': 1.19.9(hono@4.11.7) + '@hono/node-ws': 1.3.0(@hono/node-server@1.19.9(hono@4.11.7))(hono@4.11.7) '@open-draft/deferred-promise': 2.2.0 '@types/ws': 8.18.1 - hono: 4.10.4 - ws: 8.18.3 + hono: 4.11.7 + ws: 8.19.0 transitivePeerDependencies: - bufferutil - utf-8-validate - '@esbuild/aix-ppc64@0.25.3': - optional: true - - '@esbuild/aix-ppc64@0.27.0': - optional: true - - '@esbuild/android-arm64@0.25.3': - optional: true - - '@esbuild/android-arm64@0.27.0': - optional: true - - '@esbuild/android-arm@0.25.3': - optional: true - - '@esbuild/android-arm@0.27.0': - optional: true - - '@esbuild/android-x64@0.25.3': - optional: true - - '@esbuild/android-x64@0.27.0': - optional: true - - '@esbuild/darwin-arm64@0.25.3': - optional: true - - '@esbuild/darwin-arm64@0.27.0': - optional: true - - '@esbuild/darwin-x64@0.25.3': - optional: true - - '@esbuild/darwin-x64@0.27.0': - optional: true - - '@esbuild/freebsd-arm64@0.25.3': - optional: true - - '@esbuild/freebsd-arm64@0.27.0': - optional: true - - '@esbuild/freebsd-x64@0.25.3': - optional: true - - '@esbuild/freebsd-x64@0.27.0': - optional: true - - '@esbuild/linux-arm64@0.25.3': - optional: true - - '@esbuild/linux-arm64@0.27.0': - optional: true - - '@esbuild/linux-arm@0.25.3': - optional: true - - '@esbuild/linux-arm@0.27.0': - optional: true - - '@esbuild/linux-ia32@0.25.3': - optional: true - - '@esbuild/linux-ia32@0.27.0': - optional: true - - '@esbuild/linux-loong64@0.25.3': - optional: true - - '@esbuild/linux-loong64@0.27.0': - optional: true - - '@esbuild/linux-mips64el@0.25.3': - optional: true - - '@esbuild/linux-mips64el@0.27.0': + '@esbuild/aix-ppc64@0.27.2': optional: true - '@esbuild/linux-ppc64@0.25.3': + '@esbuild/android-arm64@0.27.2': optional: true - '@esbuild/linux-ppc64@0.27.0': + '@esbuild/android-arm@0.27.2': optional: true - '@esbuild/linux-riscv64@0.25.3': + '@esbuild/android-x64@0.27.2': optional: true - '@esbuild/linux-riscv64@0.27.0': + '@esbuild/darwin-arm64@0.27.2': optional: true - '@esbuild/linux-s390x@0.25.3': + '@esbuild/darwin-x64@0.27.2': optional: true - '@esbuild/linux-s390x@0.27.0': + '@esbuild/freebsd-arm64@0.27.2': optional: true - '@esbuild/linux-x64@0.25.3': + '@esbuild/freebsd-x64@0.27.2': optional: true - '@esbuild/linux-x64@0.27.0': + '@esbuild/linux-arm64@0.27.2': optional: true - '@esbuild/netbsd-arm64@0.25.3': + '@esbuild/linux-arm@0.27.2': optional: true - '@esbuild/netbsd-arm64@0.27.0': + '@esbuild/linux-ia32@0.27.2': optional: true - '@esbuild/netbsd-x64@0.25.3': + '@esbuild/linux-loong64@0.27.2': optional: true - '@esbuild/netbsd-x64@0.27.0': + '@esbuild/linux-mips64el@0.27.2': optional: true - '@esbuild/openbsd-arm64@0.25.3': + '@esbuild/linux-ppc64@0.27.2': optional: true - '@esbuild/openbsd-arm64@0.27.0': + '@esbuild/linux-riscv64@0.27.2': optional: true - '@esbuild/openbsd-x64@0.25.3': + '@esbuild/linux-s390x@0.27.2': optional: true - '@esbuild/openbsd-x64@0.27.0': + '@esbuild/linux-x64@0.27.2': optional: true - '@esbuild/openharmony-arm64@0.27.0': + '@esbuild/netbsd-arm64@0.27.2': optional: true - '@esbuild/sunos-x64@0.25.3': + '@esbuild/netbsd-x64@0.27.2': optional: true - '@esbuild/sunos-x64@0.27.0': + '@esbuild/openbsd-arm64@0.27.2': optional: true - '@esbuild/win32-arm64@0.25.3': + '@esbuild/openbsd-x64@0.27.2': optional: true - '@esbuild/win32-arm64@0.27.0': + '@esbuild/openharmony-arm64@0.27.2': optional: true - '@esbuild/win32-ia32@0.25.3': + '@esbuild/sunos-x64@0.27.2': optional: true - '@esbuild/win32-ia32@0.27.0': + '@esbuild/win32-arm64@0.27.2': optional: true - '@esbuild/win32-x64@0.25.3': + '@esbuild/win32-ia32@0.27.2': optional: true - '@esbuild/win32-x64@0.27.0': + '@esbuild/win32-x64@0.27.2': optional: true - '@eslint-community/eslint-utils@4.8.0(eslint@9.39.1(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))': dependencies: - eslint: 9.39.1(jiti@2.6.1) + eslint: 9.39.2(jiti@2.6.1) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} '@eslint/config-array@0.21.1': dependencies: @@ -5802,21 +5228,21 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.1': + '@eslint/eslintrc@3.3.3': dependencies: ajv: 6.12.6 - debug: 4.4.0 + debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.39.1': {} + '@eslint/js@9.39.2': {} '@eslint/object-schema@2.1.7': {} @@ -5837,7 +5263,7 @@ snapshots: '@fastify/fast-json-stringify-compiler@5.0.3': dependencies: - fast-json-stringify: 6.1.1 + fast-json-stringify: 6.2.0 '@fastify/forwarded@3.0.1': {} @@ -5848,13 +5274,13 @@ snapshots: '@fastify/proxy-addr@5.1.0': dependencies: '@fastify/forwarded': 3.0.1 - ipaddr.js: 2.2.0 + ipaddr.js: 2.3.0 '@fastify/websocket@11.2.0': dependencies: duplexify: 4.1.3 fastify-plugin: 5.1.0 - ws: 8.18.3 + ws: 8.19.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -5863,15 +5289,15 @@ snapshots: dependencies: graphql: 16.12.0 - '@hono/node-server@1.19.6(hono@4.10.4)': + '@hono/node-server@1.19.9(hono@4.11.7)': dependencies: - hono: 4.10.4 + hono: 4.11.7 - '@hono/node-ws@1.2.0(@hono/node-server@1.19.6(hono@4.10.4))(hono@4.10.4)': + '@hono/node-ws@1.3.0(@hono/node-server@1.19.9(hono@4.11.7))(hono@4.11.7)': dependencies: - '@hono/node-server': 1.19.6(hono@4.10.4) - hono: 4.10.4 - ws: 8.18.3 + '@hono/node-server': 1.19.9(hono@4.11.7) + hono: 4.11.7 + ws: 8.19.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -5889,31 +5315,33 @@ snapshots: '@iarna/toml@2.2.5': {} - '@inquirer/confirm@5.0.2(@types/node@20.19.25)': + '@inquirer/ansi@1.0.2': {} + + '@inquirer/confirm@5.1.21(@types/node@20.19.30)': dependencies: - '@inquirer/core': 10.1.0(@types/node@20.19.25) - '@inquirer/type': 3.0.1(@types/node@20.19.25) - '@types/node': 20.19.25 + '@inquirer/core': 10.3.2(@types/node@20.19.30) + '@inquirer/type': 3.0.10(@types/node@20.19.30) + optionalDependencies: + '@types/node': 20.19.30 - '@inquirer/core@10.1.0(@types/node@20.19.25)': + '@inquirer/core@10.3.2(@types/node@20.19.30)': dependencies: - '@inquirer/figures': 1.0.8 - '@inquirer/type': 3.0.1(@types/node@20.19.25) - ansi-escapes: 4.3.2 + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@20.19.30) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 - strip-ansi: 6.0.1 wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.2 - transitivePeerDependencies: - - '@types/node' + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 20.19.30 - '@inquirer/figures@1.0.8': {} + '@inquirer/figures@1.0.15': {} - '@inquirer/type@3.0.1(@types/node@20.19.25)': - dependencies: - '@types/node': 20.19.25 + '@inquirer/type@3.0.10(@types/node@20.19.30)': + optionalDependencies: + '@types/node': 20.19.30 '@isaacs/balanced-match@4.0.1': {} @@ -5921,44 +5349,35 @@ snapshots: dependencies: '@isaacs/balanced-match': 4.0.1 - '@isaacs/cliui@8.0.2': + '@jridgewell/gen-mapping@0.3.13': dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/gen-mapping@0.3.5': + '@jridgewell/remapping@2.3.5': dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/source-map@0.3.6': + '@jridgewell/source-map@0.3.11': dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.25': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@miniflare/cache@2.14.4': dependencies: '@miniflare/core': 2.14.4 '@miniflare/shared': 2.14.4 - http-cache-semantics: 4.1.1 + http-cache-semantics: 4.2.0 undici: 5.28.4 '@miniflare/core@2.14.4': @@ -5970,7 +5389,7 @@ snapshots: busboy: 1.6.0 dotenv: 10.0.0 kleur: 4.1.5 - set-cookie-parser: 2.6.0 + set-cookie-parser: 2.7.2 undici: 5.28.4 urlpattern-polyfill: 4.0.3 @@ -6013,7 +5432,7 @@ snapshots: '@miniflare/shared-test-environment@2.14.4': dependencies: - '@cloudflare/workers-types': 4.20250430.0 + '@cloudflare/workers-types': 4.20260128.0 '@miniflare/cache': 2.14.4 '@miniflare/core': 2.14.4 '@miniflare/d1': 2.14.4 @@ -6061,7 +5480,7 @@ snapshots: '@miniflare/core': 2.14.4 '@miniflare/shared': 2.14.4 undici: 5.28.4 - ws: 8.18.0 + ws: 8.19.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -6075,10 +5494,10 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@napi-rs/wasm-runtime@1.0.7': + '@napi-rs/wasm-runtime@1.1.1': dependencies: - '@emnapi/core': 1.7.1 - '@emnapi/runtime': 1.7.1 + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 '@tybys/wasm-util': 0.10.1 optional: true @@ -6092,7 +5511,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 + fastq: 1.20.1 '@open-draft/deferred-promise@2.2.0': {} @@ -6103,13 +5522,13 @@ snapshots: '@open-draft/test-server@0.4.2': dependencies: - '@types/body-parser': 1.19.5 - '@types/cors': 2.8.17 - '@types/express': 4.17.21 - cors: 2.8.5 - express: 4.19.2 + '@types/body-parser': 1.19.6 + '@types/cors': 2.8.19 + '@types/express': 4.17.25 + cors: 2.8.6 + express: 4.22.1 outvariant: 1.4.3 - socket.io: 4.7.5 + socket.io: 4.8.3 transitivePeerDependencies: - bufferutil - supports-color @@ -6117,98 +5536,98 @@ snapshots: '@open-draft/until@2.1.0': {} - '@ossjs/release@0.10.0': + '@ossjs/release@0.10.1': dependencies: '@open-draft/deferred-promise': 2.2.0 - '@types/conventional-commits-parser': 5.0.1 + '@types/conventional-commits-parser': 5.0.2 '@types/issue-parser': 3.0.5 - '@types/node': 24.5.2 - '@types/semver': 7.5.8 - '@types/yargs': 17.0.32 + '@types/node': 24.10.9 + '@types/semver': 7.7.1 + '@types/yargs': 17.0.35 ajv: 8.17.1 - conventional-commits-parser: 6.2.0 + conventional-commits-parser: 6.2.1 get-stream: 6.0.1 - git-log-parser: 1.2.0 + git-log-parser: 1.2.1 issue-parser: 7.0.1 outvariant: 1.4.3 pino: 7.11.0 pino-pretty: 7.6.1 - publint: 0.3.15 + publint: 0.3.17 rc: 1.2.8 - registry-auth-token: 5.1.0 - semver: 7.6.0 + registry-auth-token: 5.1.1 + semver: 7.7.3 until-async: 3.0.2 yargs: 18.0.0 - '@oxc-resolver/binding-android-arm-eabi@11.13.2': + '@oxc-resolver/binding-android-arm-eabi@11.16.4': + optional: true + + '@oxc-resolver/binding-android-arm64@11.16.4': optional: true - '@oxc-resolver/binding-android-arm64@11.13.2': + '@oxc-resolver/binding-darwin-arm64@11.16.4': optional: true - '@oxc-resolver/binding-darwin-arm64@11.13.2': + '@oxc-resolver/binding-darwin-x64@11.16.4': optional: true - '@oxc-resolver/binding-darwin-x64@11.13.2': + '@oxc-resolver/binding-freebsd-x64@11.16.4': optional: true - '@oxc-resolver/binding-freebsd-x64@11.13.2': + '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.4': optional: true - '@oxc-resolver/binding-linux-arm-gnueabihf@11.13.2': + '@oxc-resolver/binding-linux-arm-musleabihf@11.16.4': optional: true - '@oxc-resolver/binding-linux-arm-musleabihf@11.13.2': + '@oxc-resolver/binding-linux-arm64-gnu@11.16.4': optional: true - '@oxc-resolver/binding-linux-arm64-gnu@11.13.2': + '@oxc-resolver/binding-linux-arm64-musl@11.16.4': optional: true - '@oxc-resolver/binding-linux-arm64-musl@11.13.2': + '@oxc-resolver/binding-linux-ppc64-gnu@11.16.4': optional: true - '@oxc-resolver/binding-linux-ppc64-gnu@11.13.2': + '@oxc-resolver/binding-linux-riscv64-gnu@11.16.4': optional: true - '@oxc-resolver/binding-linux-riscv64-gnu@11.13.2': + '@oxc-resolver/binding-linux-riscv64-musl@11.16.4': optional: true - '@oxc-resolver/binding-linux-riscv64-musl@11.13.2': + '@oxc-resolver/binding-linux-s390x-gnu@11.16.4': optional: true - '@oxc-resolver/binding-linux-s390x-gnu@11.13.2': + '@oxc-resolver/binding-linux-x64-gnu@11.16.4': optional: true - '@oxc-resolver/binding-linux-x64-gnu@11.13.2': + '@oxc-resolver/binding-linux-x64-musl@11.16.4': optional: true - '@oxc-resolver/binding-linux-x64-musl@11.13.2': + '@oxc-resolver/binding-openharmony-arm64@11.16.4': optional: true - '@oxc-resolver/binding-wasm32-wasi@11.13.2': + '@oxc-resolver/binding-wasm32-wasi@11.16.4': dependencies: - '@napi-rs/wasm-runtime': 1.0.7 + '@napi-rs/wasm-runtime': 1.1.1 optional: true - '@oxc-resolver/binding-win32-arm64-msvc@11.13.2': + '@oxc-resolver/binding-win32-arm64-msvc@11.16.4': optional: true - '@oxc-resolver/binding-win32-ia32-msvc@11.13.2': + '@oxc-resolver/binding-win32-ia32-msvc@11.16.4': optional: true - '@oxc-resolver/binding-win32-x64-msvc@11.13.2': + '@oxc-resolver/binding-win32-x64-msvc@11.16.4': optional: true '@pinojs/redact@0.4.0': {} - '@pkgjs/parseargs@0.11.0': - optional: true - '@pkgr/core@0.2.9': {} - '@playwright/test@1.56.1': + '@playwright/test@1.58.0': dependencies: - playwright: 1.56.1 + playwright: 1.58.0 '@pnpm/config.env-replace@1.1.0': {} @@ -6216,321 +5635,205 @@ snapshots: dependencies: graceful-fs: 4.2.10 - '@pnpm/npm-conf@2.3.1': + '@pnpm/npm-conf@3.0.2': dependencies: '@pnpm/config.env-replace': 1.1.0 '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 - '@publint/pack@0.1.2': {} + '@publint/pack@0.1.3': {} - '@rollup/plugin-node-resolve@15.3.1(rollup@4.53.3)': + '@rollup/plugin-node-resolve@15.3.1(rollup@4.57.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + '@rollup/pluginutils': 5.3.0(rollup@4.57.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 - resolve: 1.22.8 + resolve: 1.22.11 optionalDependencies: - rollup: 4.53.3 + rollup: 4.57.0 - '@rollup/pluginutils@5.3.0(rollup@4.53.3)': + '@rollup/pluginutils@5.3.0(rollup@4.57.0)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.53.3 - - '@rollup/rollup-android-arm-eabi@4.40.1': - optional: true - - '@rollup/rollup-android-arm-eabi@4.53.3': - optional: true - - '@rollup/rollup-android-arm64@4.40.1': - optional: true - - '@rollup/rollup-android-arm64@4.53.3': - optional: true - - '@rollup/rollup-darwin-arm64@4.40.1': - optional: true - - '@rollup/rollup-darwin-arm64@4.53.3': - optional: true - - '@rollup/rollup-darwin-x64@4.40.1': - optional: true - - '@rollup/rollup-darwin-x64@4.53.3': - optional: true - - '@rollup/rollup-freebsd-arm64@4.40.1': - optional: true - - '@rollup/rollup-freebsd-arm64@4.53.3': - optional: true - - '@rollup/rollup-freebsd-x64@4.40.1': - optional: true - - '@rollup/rollup-freebsd-x64@4.53.3': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.40.1': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.53.3': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.40.1': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.53.3': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.40.1': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.53.3': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.40.1': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.53.3': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.53.3': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.40.1': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.40.1': - optional: true + rollup: 4.57.0 - '@rollup/rollup-linux-ppc64-gnu@4.53.3': + '@rollup/rollup-android-arm-eabi@4.57.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.40.1': + '@rollup/rollup-android-arm64@4.57.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.53.3': + '@rollup/rollup-darwin-arm64@4.57.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.40.1': + '@rollup/rollup-darwin-x64@4.57.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.53.3': + '@rollup/rollup-freebsd-arm64@4.57.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.40.1': + '@rollup/rollup-freebsd-x64@4.57.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.53.3': + '@rollup/rollup-linux-arm-gnueabihf@4.57.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.40.1': + '@rollup/rollup-linux-arm-musleabihf@4.57.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.53.3': + '@rollup/rollup-linux-arm64-gnu@4.57.0': optional: true - '@rollup/rollup-linux-x64-musl@4.40.1': + '@rollup/rollup-linux-arm64-musl@4.57.0': optional: true - '@rollup/rollup-linux-x64-musl@4.53.3': + '@rollup/rollup-linux-loong64-gnu@4.57.0': optional: true - '@rollup/rollup-openharmony-arm64@4.53.3': + '@rollup/rollup-linux-loong64-musl@4.57.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.40.1': + '@rollup/rollup-linux-ppc64-gnu@4.57.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.53.3': + '@rollup/rollup-linux-ppc64-musl@4.57.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.40.1': + '@rollup/rollup-linux-riscv64-gnu@4.57.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.53.3': + '@rollup/rollup-linux-riscv64-musl@4.57.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.53.3': + '@rollup/rollup-linux-s390x-gnu@4.57.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.40.1': + '@rollup/rollup-linux-x64-gnu@4.57.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.53.3': + '@rollup/rollup-linux-x64-musl@4.57.0': optional: true - '@socket.io/component-emitter@3.1.0': {} - - '@standard-schema/spec@1.0.0': {} - - '@swc/core-darwin-arm64@1.13.5': - optional: true - - '@swc/core-darwin-x64@1.13.5': - optional: true - - '@swc/core-linux-arm-gnueabihf@1.13.5': - optional: true - - '@swc/core-linux-arm64-gnu@1.13.5': + '@rollup/rollup-openbsd-x64@4.57.0': optional: true - '@swc/core-linux-arm64-musl@1.13.5': + '@rollup/rollup-openharmony-arm64@4.57.0': optional: true - '@swc/core-linux-x64-gnu@1.13.5': + '@rollup/rollup-win32-arm64-msvc@4.57.0': optional: true - '@swc/core-linux-x64-musl@1.13.5': + '@rollup/rollup-win32-ia32-msvc@4.57.0': optional: true - '@swc/core-win32-arm64-msvc@1.13.5': + '@rollup/rollup-win32-x64-gnu@4.57.0': optional: true - '@swc/core-win32-ia32-msvc@1.13.5': + '@rollup/rollup-win32-x64-msvc@4.57.0': optional: true - '@swc/core-win32-x64-msvc@1.13.5': - optional: true - - '@swc/core@1.13.5': - dependencies: - '@swc/counter': 0.1.3 - '@swc/types': 0.1.24 - optionalDependencies: - '@swc/core-darwin-arm64': 1.13.5 - '@swc/core-darwin-x64': 1.13.5 - '@swc/core-linux-arm-gnueabihf': 1.13.5 - '@swc/core-linux-arm64-gnu': 1.13.5 - '@swc/core-linux-arm64-musl': 1.13.5 - '@swc/core-linux-x64-gnu': 1.13.5 - '@swc/core-linux-x64-musl': 1.13.5 - '@swc/core-win32-arm64-msvc': 1.13.5 - '@swc/core-win32-ia32-msvc': 1.13.5 - '@swc/core-win32-x64-msvc': 1.13.5 - optional: true - - '@swc/counter@0.1.3': - optional: true + '@socket.io/component-emitter@3.1.2': {} - '@swc/types@0.1.24': - dependencies: - '@swc/counter': 0.1.3 - optional: true + '@standard-schema/spec@1.1.0': {} '@tybys/wasm-util@0.10.1': dependencies: - tslib: 2.6.2 + tslib: 2.8.1 optional: true '@types/accepts@1.3.7': dependencies: - '@types/node': 20.19.25 + '@types/node': 20.19.30 '@types/better-sqlite3@7.6.13': dependencies: - '@types/node': 18.19.28 + '@types/node': 20.19.30 - '@types/body-parser@1.19.5': + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 18.19.28 + '@types/node': 20.19.30 - '@types/chai@5.2.2': + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 '@types/command-line-args@5.2.3': {} '@types/connect@3.4.38': dependencies: - '@types/node': 18.19.28 - - '@types/content-disposition@0.5.8': {} + '@types/node': 20.19.30 - '@types/conventional-commits-parser@5.0.0': - dependencies: - '@types/node': 18.19.28 - optional: true + '@types/content-disposition@0.5.9': {} - '@types/conventional-commits-parser@5.0.1': + '@types/conventional-commits-parser@5.0.2': dependencies: - '@types/node': 18.19.28 + '@types/node': 20.19.30 - '@types/cookie@0.4.1': {} - - '@types/cookies@0.9.0': + '@types/cookies@0.9.2': dependencies: '@types/connect': 3.4.38 - '@types/express': 5.0.5 + '@types/express': 5.0.6 '@types/keygrip': 1.0.6 - '@types/node': 20.19.25 + '@types/node': 20.19.30 - '@types/cors@2.8.17': + '@types/cors@2.8.19': dependencies: - '@types/node': 18.19.28 + '@types/node': 20.19.30 '@types/debug@4.1.12': dependencies: - '@types/ms': 0.7.34 + '@types/ms': 2.1.0 '@types/deep-eql@4.0.2': {} '@types/eslint-scope@3.7.7': dependencies: - '@types/eslint': 8.56.7 - '@types/estree': 1.0.6 + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 - '@types/eslint@8.56.7': + '@types/eslint@9.6.1': dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 - '@types/estree@1.0.6': {} - - '@types/estree@1.0.7': {} - '@types/estree@1.0.8': {} - '@types/express-serve-static-core@4.17.43': + '@types/express-serve-static-core@4.19.8': dependencies: - '@types/node': 18.19.28 - '@types/qs': 6.9.14 + '@types/node': 20.19.30 + '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 + '@types/send': 1.2.1 - '@types/express-serve-static-core@5.1.0': + '@types/express-serve-static-core@5.1.1': dependencies: - '@types/node': 20.19.25 - '@types/qs': 6.9.14 + '@types/node': 20.19.30 + '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 + '@types/send': 1.2.1 - '@types/express@4.17.21': + '@types/express@4.17.25': dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.17.43 - '@types/qs': 6.9.14 - '@types/serve-static': 1.15.5 + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.14.0 + '@types/serve-static': 1.15.10 - '@types/express@5.0.5': + '@types/express@5.0.6': dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 5.1.0 - '@types/serve-static': 1.15.5 + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 5.1.1 + '@types/serve-static': 2.2.0 - '@types/http-assert@1.5.5': {} + '@types/http-assert@1.5.6': {} - '@types/http-errors@2.0.4': {} + '@types/http-errors@2.0.5': {} '@types/issue-parser@3.0.5': {} @@ -6540,63 +5843,64 @@ snapshots: '@types/keygrip@1.0.6': {} - '@types/koa-compose@3.2.8': + '@types/koa-compose@3.2.9': dependencies: '@types/koa': 2.15.0 '@types/koa@2.15.0': dependencies: '@types/accepts': 1.3.7 - '@types/content-disposition': 0.5.8 - '@types/cookies': 0.9.0 - '@types/http-assert': 1.5.5 - '@types/http-errors': 2.0.4 + '@types/content-disposition': 0.5.9 + '@types/cookies': 0.9.2 + '@types/http-assert': 1.5.6 + '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 - '@types/koa-compose': 3.2.8 - '@types/node': 20.19.25 + '@types/koa-compose': 3.2.9 + '@types/node': 20.19.30 '@types/mime@1.3.5': {} - '@types/mime@4.0.0': - dependencies: - mime: 4.0.1 - - '@types/ms@0.7.34': {} - - '@types/mustache@4.2.5': {} + '@types/ms@2.1.0': {} - '@types/node@18.19.28': - dependencies: - undici-types: 5.26.5 + '@types/mustache@4.2.6': {} - '@types/node@20.19.25': + '@types/node@20.19.30': dependencies: undici-types: 6.21.0 - '@types/node@24.5.2': + '@types/node@24.10.9': dependencies: - undici-types: 7.12.0 + undici-types: 7.16.0 '@types/parse5@6.0.3': {} - '@types/qs@6.9.14': {} + '@types/qs@6.14.0': {} '@types/range-parser@1.2.7': {} '@types/resolve@1.20.2': {} - '@types/semver@7.5.8': {} + '@types/semver@7.7.1': {} - '@types/send@0.17.4': + '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.19.25 + '@types/node': 20.19.30 + + '@types/send@1.2.1': + dependencies: + '@types/node': 20.19.30 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 20.19.30 + '@types/send': 0.17.6 - '@types/serve-static@1.15.5': + '@types/serve-static@2.2.0': dependencies: - '@types/http-errors': 2.0.4 - '@types/mime': 4.0.0 - '@types/node': 20.19.25 + '@types/http-errors': 2.0.5 + '@types/node': 20.19.30 '@types/serviceworker@0.0.167': {} @@ -6606,149 +5910,147 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 20.19.25 + '@types/node': 20.19.30 '@types/ws@8.18.1': dependencies: - '@types/node': 18.19.28 + '@types/node': 20.19.30 '@types/yargs-parser@21.0.3': {} - '@types/yargs@17.0.32': + '@types/yargs@17.0.35': dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.47.0 - '@typescript-eslint/type-utils': 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.47.0 - eslint: 9.39.1(jiti@2.6.1) - graphemer: 1.4.0 + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 + eslint: 9.39.2(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.47.0 - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.47.0 + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 - eslint: 9.39.1(jiti@2.6.1) + eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.47.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3) - '@typescript-eslint/types': 8.47.0 + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.47.0': + '@typescript-eslint/scope-manager@8.54.0': dependencies: - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/visitor-keys': 8.47.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 - '@typescript-eslint/tsconfig-utils@8.47.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.54.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 9.39.1(jiti@2.6.1) - ts-api-utils: 2.1.0(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.47.0': {} + '@typescript-eslint/types@8.54.0': {} - '@typescript-eslint/typescript-estree@8.47.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.47.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3) - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/visitor-keys': 8.47.0 + '@typescript-eslint/project-service': 8.54.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.0 - ts-api-utils: 2.1.0(typescript@5.9.3) + minimatch: 9.0.5 + semver: 7.7.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.8.0(eslint@9.39.1(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.47.0 - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) - eslint: 9.39.1(jiti@2.6.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.47.0': + '@typescript-eslint/visitor-keys@8.54.0': dependencies: - '@typescript-eslint/types': 8.47.0 + '@typescript-eslint/types': 8.54.0 eslint-visitor-keys: 4.2.1 - '@vitest/expect@4.0.13': + '@vitest/expect@4.0.18': dependencies: - '@standard-schema/spec': 1.0.0 - '@types/chai': 5.2.2 - '@vitest/spy': 4.0.13 - '@vitest/utils': 4.0.13 - chai: 6.2.1 + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.13(msw@)(vite@7.2.4(@types/node@20.19.25)(jiti@2.6.1)(terser@5.30.1)(yaml@2.5.1))': + '@vitest/mocker@4.0.18(msw@)(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2))': dependencies: - '@vitest/spy': 4.0.13 + '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 'link:' - vite: 7.2.4(@types/node@20.19.25)(jiti@2.6.1)(terser@5.30.1)(yaml@2.5.1) + vite: 7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2) - '@vitest/pretty-format@4.0.13': + '@vitest/pretty-format@4.0.18': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.13': + '@vitest/runner@4.0.18': dependencies: - '@vitest/utils': 4.0.13 + '@vitest/utils': 4.0.18 pathe: 2.0.3 - '@vitest/snapshot@4.0.13': + '@vitest/snapshot@4.0.18': dependencies: - '@vitest/pretty-format': 4.0.13 + '@vitest/pretty-format': 4.0.18 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.13': {} + '@vitest/spy@4.0.18': {} - '@vitest/utils@4.0.13': + '@vitest/utils@4.0.18': dependencies: - '@vitest/pretty-format': 4.0.13 + '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 '@web/config-loader@0.3.3': {} @@ -6757,14 +6059,14 @@ snapshots: dependencies: '@types/koa': 2.15.0 '@types/ws': 7.4.7 - '@web/parse5-utils': 2.1.0 + '@web/parse5-utils': 2.1.1 chokidar: 4.0.3 clone: 2.1.2 es-module-lexer: 1.7.0 get-stream: 6.0.1 is-stream: 2.0.1 - isbinaryfile: 5.0.2 - koa: 2.15.2 + isbinaryfile: 5.0.7 + koa: 2.16.3 koa-etag: 4.0.0 koa-send: 5.0.1 koa-static: 5.0.0 @@ -6780,12 +6082,12 @@ snapshots: '@web/dev-server-rollup@0.6.4': dependencies: - '@rollup/plugin-node-resolve': 15.3.1(rollup@4.53.3) + '@rollup/plugin-node-resolve': 15.3.1(rollup@4.57.0) '@web/dev-server-core': 0.7.5 nanocolors: 0.2.13 parse5: 6.0.1 - rollup: 4.53.3 - whatwg-url: 14.0.0 + rollup: 4.57.0 + whatwg-url: 14.2.0 transitivePeerDependencies: - bufferutil - supports-color @@ -6793,104 +6095,104 @@ snapshots: '@web/dev-server@0.4.6': dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.28.6 '@types/command-line-args': 5.2.3 '@web/config-loader': 0.3.3 '@web/dev-server-core': 0.7.5 '@web/dev-server-rollup': 0.6.4 camelcase: 6.3.0 command-line-args: 5.2.1 - command-line-usage: 7.0.1 + command-line-usage: 7.0.3 debounce: 1.2.1 deepmerge: 4.3.1 internal-ip: 6.2.0 nanocolors: 0.2.13 open: 8.4.2 - portfinder: 1.0.32 + portfinder: 1.0.38 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@web/parse5-utils@2.1.0': + '@web/parse5-utils@2.1.1': dependencies: '@types/parse5': 6.0.3 parse5: 6.0.1 - '@webassemblyjs/ast@1.12.1': + '@webassemblyjs/ast@1.14.1': dependencies: - '@webassemblyjs/helper-numbers': 1.11.6 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/floating-point-hex-parser@1.11.6': {} + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} - '@webassemblyjs/helper-api-error@1.11.6': {} + '@webassemblyjs/helper-api-error@1.13.2': {} - '@webassemblyjs/helper-buffer@1.12.1': {} + '@webassemblyjs/helper-buffer@1.14.1': {} - '@webassemblyjs/helper-numbers@1.11.6': + '@webassemblyjs/helper-numbers@1.13.2': dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.11.6 - '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 '@xtuc/long': 4.2.2 - '@webassemblyjs/helper-wasm-bytecode@1.11.6': {} + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} - '@webassemblyjs/helper-wasm-section@1.12.1': + '@webassemblyjs/helper-wasm-section@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/ieee754@1.11.6': + '@webassemblyjs/ieee754@1.13.2': dependencies: '@xtuc/ieee754': 1.2.0 - '@webassemblyjs/leb128@1.11.6': + '@webassemblyjs/leb128@1.13.2': dependencies: '@xtuc/long': 4.2.2 - '@webassemblyjs/utf8@1.11.6': {} + '@webassemblyjs/utf8@1.13.2': {} - '@webassemblyjs/wasm-edit@1.12.1': + '@webassemblyjs/wasm-edit@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/helper-wasm-section': 1.12.1 - '@webassemblyjs/wasm-gen': 1.12.1 - '@webassemblyjs/wasm-opt': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - '@webassemblyjs/wast-printer': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 - '@webassemblyjs/wasm-gen@1.12.1': + '@webassemblyjs/wasm-gen@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/ieee754': 1.11.6 - '@webassemblyjs/leb128': 1.11.6 - '@webassemblyjs/utf8': 1.11.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 - '@webassemblyjs/wasm-opt@1.12.1': + '@webassemblyjs/wasm-opt@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/wasm-gen': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 - '@webassemblyjs/wasm-parser@1.12.1': + '@webassemblyjs/wasm-parser@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-api-error': 1.11.6 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/ieee754': 1.11.6 - '@webassemblyjs/leb128': 1.11.6 - '@webassemblyjs/utf8': 1.11.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 - '@webassemblyjs/wast-printer@1.12.1': + '@webassemblyjs/wast-printer@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 '@xtuc/ieee754@1.2.0': {} @@ -6911,22 +6213,24 @@ snapshots: accepts@2.0.0: dependencies: - mime-types: 3.0.0 + mime-types: 3.0.2 negotiator: 1.0.0 - acorn-jsx@5.3.2(acorn@8.15.0): + acorn-import-phases@1.0.4(acorn@8.15.0): dependencies: acorn: 8.15.0 - acorn@8.14.0: {} + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 acorn@8.15.0: {} - agent-base@7.1.1: - dependencies: - debug: 4.4.3 - transitivePeerDependencies: - - supports-color + agent-base@7.1.4: {} + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: @@ -6936,6 +6240,11 @@ snapshots: dependencies: ajv: 6.12.6 + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -6954,13 +6263,13 @@ snapshots: dependencies: type-fest: 0.21.3 - ansi-escapes@7.0.0: + ansi-escapes@7.2.0: dependencies: environment: 1.1.0 ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} + ansi-regex@6.2.2: {} ansi-styles@3.2.1: dependencies: @@ -6970,7 +6279,7 @@ snapshots: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} any-promise@1.3.0: {} @@ -6989,39 +6298,41 @@ snapshots: array-back@6.2.2: {} - array-buffer-byte-length@1.0.1: + array-buffer-byte-length@1.0.2: dependencies: - call-bind: 1.0.7 - is-array-buffer: 3.0.4 + call-bound: 1.0.4 + is-array-buffer: 3.0.5 array-flatten@1.1.1: {} array-ify@1.0.0: {} - array.prototype.reduce@1.0.7: + array.prototype.reduce@1.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.1 es-array-method-boxes-properly: 1.0.0 es-errors: 1.3.0 - es-object-atoms: 1.0.0 - is-string: 1.0.7 + es-object-atoms: 1.1.1 + is-string: 1.1.1 - arraybuffer.prototype.slice@1.0.3: + arraybuffer.prototype.slice@1.0.4: dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.1 es-errors: 1.3.0 - get-intrinsic: 1.2.4 - is-array-buffer: 3.0.4 - is-shared-array-buffer: 1.0.3 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 - async@2.6.4: - dependencies: - lodash: 4.17.21 + assertion-error@2.0.1: {} + + async-function@1.0.0: {} + + async@3.2.6: {} asynckit@0.4.0: {} @@ -7031,16 +6342,16 @@ snapshots: available-typed-arrays@1.0.7: dependencies: - possible-typed-array-names: 1.0.0 + possible-typed-array-names: 1.1.0 avvio@9.1.0: dependencies: '@fastify/error': 4.2.0 - fastq: 1.17.1 + fastq: 1.20.1 - axios@1.13.2: + axios@1.13.4: dependencies: - follow-redirects: 1.15.6 + follow-redirects: 1.15.11 form-data: 4.0.5 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -7062,12 +6373,12 @@ snapshots: babel-minify@0.5.2: dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.28.6 babel-preset-minify: 0.5.2 fs-readdir-recursive: 1.1.0 - lodash: 4.17.21 + lodash: 4.17.23 mkdirp: 0.5.6 - util.promisify: 1.1.2 + util.promisify: 1.1.3 yargs-parser: 10.1.0 transitivePeerDependencies: - supports-color @@ -7083,7 +6394,7 @@ snapshots: babel-helper-evaluate-path: 0.5.0 babel-helper-mark-eval-scopes: 0.4.3 babel-helper-remove-or-void: 0.4.3 - lodash: 4.17.21 + lodash: 4.17.23 babel-plugin-minify-flip-comparisons@0.4.3: dependencies: @@ -7165,7 +6476,7 @@ snapshots: babel-plugin-transform-remove-undefined: 0.5.0 babel-plugin-transform-simplify-comparison-operators: 6.9.4 babel-plugin-transform-undefined-to-void: 6.9.4 - lodash: 4.17.21 + lodash: 4.17.23 balanced-match@1.0.2: {} @@ -7173,9 +6484,11 @@ snapshots: base64id@2.0.0: {} + baseline-browser-mapping@2.9.19: {} + big.js@5.2.2: {} - bignumber.js@9.1.2: {} + bignumber.js@9.3.1: {} bl@4.1.0: dependencies: @@ -7183,43 +6496,43 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - body-parser@1.20.2: + body-parser@1.20.4: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.2 + qs: 6.14.1 + raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 transitivePeerDependencies: - supports-color - body-parser@2.2.0: + body-parser@2.2.2: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 4.4.3 - http-errors: 2.0.0 - iconv-lite: 0.6.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 on-finished: 2.4.1 - qs: 6.14.0 - raw-body: 3.0.0 + qs: 6.14.1 + raw-body: 3.0.2 type-is: 2.0.1 transitivePeerDependencies: - supports-color - brace-expansion@1.1.11: + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.1: + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -7227,19 +6540,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.23.0: - dependencies: - caniuse-lite: 1.0.30001605 - electron-to-chromium: 1.4.723 - node-releases: 2.0.14 - update-browserslist-db: 1.0.13(browserslist@4.23.0) - - browserslist@4.24.2: + browserslist@4.28.1: dependencies: - caniuse-lite: 1.0.30001684 - electron-to-chromium: 1.5.67 - node-releases: 2.0.18 - update-browserslist-db: 1.1.1(browserslist@4.24.2) + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001766 + electron-to-chromium: 1.5.279 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) buffer-from@1.1.2: {} @@ -7250,11 +6557,11 @@ snapshots: builtins@5.1.0: dependencies: - semver: 7.6.0 + semver: 7.7.3 - bundle-require@5.1.0(esbuild@0.27.0): + bundle-require@5.1.0(esbuild@0.27.2): dependencies: - esbuild: 0.27.0 + esbuild: 0.27.2 load-tsconfig: 0.2.5 busboy@1.6.0: @@ -7277,12 +6584,11 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.7: + call-bind@1.0.8: dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 set-function-length: 1.2.2 call-bound@1.0.4: @@ -7298,11 +6604,9 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001605: {} + caniuse-lite@1.0.30001766: {} - caniuse-lite@1.0.30001684: {} - - chai@6.2.1: {} + chai@6.2.2: {} chalk-template@0.4.0: dependencies: @@ -7319,15 +6623,15 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.3.0: {} + chalk@5.6.2: {} chardet@0.7.0: {} chokidar@4.0.3: dependencies: - readdirp: 4.0.2 + readdirp: 4.1.2 - chrome-trace-event@1.0.3: {} + chrome-trace-event@1.0.4: {} cli-cursor@3.1.0: dependencies: @@ -7342,7 +6646,7 @@ snapshots: cli-truncate@4.0.0: dependencies: slice-ansi: 5.0.0 - string-width: 7.1.0 + string-width: 7.2.0 cli-width@3.0.0: {} @@ -7357,8 +6661,8 @@ snapshots: cliui@9.0.1: dependencies: string-width: 7.2.0 - strip-ansi: 7.1.0 - wrap-ansi: 9.0.0 + strip-ansi: 7.1.2 + wrap-ansi: 9.0.2 clone-deep@4.0.1: dependencies: @@ -7397,23 +6701,23 @@ snapshots: lodash.camelcase: 4.3.0 typical: 4.0.0 - command-line-usage@7.0.1: + command-line-usage@7.0.3: dependencies: array-back: 6.2.2 chalk-template: 0.4.0 - table-layout: 3.0.2 - typical: 7.1.1 + table-layout: 4.1.1 + typical: 7.3.0 - commander@12.1.0: {} + commander@13.1.0: {} commander@2.20.3: {} commander@4.1.1: {} - commitizen@4.3.1(@types/node@20.19.25)(typescript@5.9.3): + commitizen@4.3.1(@types/node@20.19.30)(typescript@5.9.3): dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@20.19.25)(typescript@5.9.3) + cz-conventional-changelog: 3.3.0(@types/node@20.19.30)(typescript@5.9.3) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -7450,9 +6754,7 @@ snapshots: dependencies: safe-buffer: 5.2.1 - content-disposition@1.0.0: - dependencies: - safe-buffer: 5.2.1 + content-disposition@1.0.1: {} content-type@1.0.5: {} @@ -7473,23 +6775,19 @@ snapshots: meow: 12.1.1 split2: 4.2.0 - conventional-commits-parser@6.2.0: + conventional-commits-parser@6.2.1: dependencies: meow: 13.2.0 convert-source-map@2.0.0: {} - cookie-signature@1.0.6: {} + cookie-signature@1.0.7: {} cookie-signature@1.2.2: {} - cookie@0.4.2: {} + cookie@0.7.2: {} - cookie@0.6.0: {} - - cookie@0.7.1: {} - - cookie@1.0.2: {} + cookie@1.1.1: {} cookies@0.9.1: dependencies: @@ -7498,22 +6796,14 @@ snapshots: core-util-is@1.0.3: {} - cors@2.8.5: + cors@2.8.6: dependencies: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig-typescript-loader@5.0.0(@types/node@20.19.25)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): - dependencies: - '@types/node': 20.19.25 - cosmiconfig: 9.0.0(typescript@5.9.3) - jiti: 1.21.0 - typescript: 5.9.3 - optional: true - - cosmiconfig-typescript-loader@6.2.0(@types/node@20.19.25)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.2.0(@types/node@20.19.30)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@types/node': 20.19.25 + '@types/node': 20.19.30 cosmiconfig: 9.0.0(typescript@5.9.3) jiti: 2.6.1 typescript: 5.9.3 @@ -7521,8 +6811,8 @@ snapshots: cosmiconfig@9.0.0(typescript@5.9.3): dependencies: env-paths: 2.2.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 + import-fresh: 3.3.1 + js-yaml: 4.1.1 parse-json: 5.2.0 optionalDependencies: typescript: 5.9.3 @@ -7544,20 +6834,21 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - cssstyle@4.1.0: + cssstyle@4.6.0: dependencies: - rrweb-cssom: 0.7.1 + '@asamuzakjp/css-color': 3.2.0 + rrweb-cssom: 0.8.0 - cz-conventional-changelog@3.3.0(@types/node@20.19.25)(typescript@5.9.3): + cz-conventional-changelog@3.3.0(@types/node@20.19.30)(typescript@5.9.3): dependencies: chalk: 2.4.2 - commitizen: 4.3.1(@types/node@20.19.25)(typescript@5.9.3) + commitizen: 4.3.1(@types/node@20.19.30)(typescript@5.9.3) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.5 optionalDependencies: - '@commitlint/load': 19.2.0(@types/node@20.19.25)(typescript@5.9.3) + '@commitlint/load': 20.3.1(@types/node@20.19.30)(typescript@5.9.3) transitivePeerDependencies: - '@types/node' - typescript @@ -7567,25 +6858,25 @@ snapshots: data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 + whatwg-url: 14.2.0 - data-view-buffer@1.0.1: + data-view-buffer@1.0.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 - data-view-byte-length@1.0.1: + data-view-byte-length@1.0.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 - data-view-byte-offset@1.0.0: + data-view-byte-offset@1.0.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 dateformat@4.6.3: {} @@ -7599,23 +6890,11 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.4: - dependencies: - ms: 2.1.2 - - debug@4.3.7: - dependencies: - ms: 2.1.3 - - debug@4.4.0: - dependencies: - ms: 2.1.3 - debug@4.4.3: dependencies: ms: 2.1.3 - decimal.js@10.4.3: {} + decimal.js@10.6.0: {} dedent@0.7.0: {} @@ -7637,9 +6916,9 @@ snapshots: define-data-property@1.1.4: dependencies: - es-define-property: 1.0.0 + es-define-property: 1.0.1 es-errors: 1.3.0 - gopd: 1.0.1 + gopd: 1.2.0 define-lazy-prop@2.0.0: {} @@ -7683,146 +6962,133 @@ snapshots: duplexify@4.1.3: dependencies: - end-of-stream: 1.4.4 + end-of-stream: 1.4.5 inherits: 2.0.4 readable-stream: 3.6.2 stream-shift: 1.0.3 - eastasianwidth@0.2.0: {} - ee-first@1.1.1: {} - electron-to-chromium@1.4.723: {} - - electron-to-chromium@1.5.67: {} + electron-to-chromium@1.5.279: {} - emoji-regex@10.3.0: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} - emoji-regex@9.2.2: {} - emojis-list@3.0.0: {} encodeurl@1.0.2: {} encodeurl@2.0.0: {} - end-of-stream@1.4.4: + end-of-stream@1.4.5: dependencies: once: 1.4.0 - engine.io-parser@5.2.2: {} + engine.io-parser@5.2.3: {} - engine.io@6.5.4: + engine.io@6.6.5: dependencies: - '@types/cookie': 0.4.1 - '@types/cors': 2.8.17 - '@types/node': 18.19.28 + '@types/cors': 2.8.19 + '@types/node': 20.19.30 accepts: 1.3.8 base64id: 2.0.0 - cookie: 0.4.2 - cors: 2.8.5 - debug: 4.3.7 - engine.io-parser: 5.2.2 - ws: 8.11.0 + cookie: 0.7.2 + cors: 2.8.6 + debug: 4.4.3 + engine.io-parser: 5.2.3 + ws: 8.18.3 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - enhanced-resolve@5.17.1: + enhanced-resolve@5.18.4: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.3.0 - entities@4.5.0: {} + entities@6.0.1: {} env-paths@2.2.1: {} environment@1.1.0: {} - error-ex@1.3.2: + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 - es-abstract@1.23.3: + es-abstract@1.24.1: dependencies: - array-buffer-byte-length: 1.0.1 - arraybuffer.prototype.slice: 1.0.3 + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - data-view-buffer: 1.0.1 - data-view-byte-length: 1.0.1 - data-view-byte-offset: 1.0.0 - es-define-property: 1.0.0 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.0.0 - es-set-tostringtag: 2.0.3 - es-to-primitive: 1.2.1 - function.prototype.name: 1.1.6 - get-intrinsic: 1.2.4 - get-symbol-description: 1.0.2 - globalthis: 1.0.3 - gopd: 1.0.1 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.2.0 + has-symbols: 1.1.0 hasown: 2.0.2 - internal-slot: 1.0.7 - is-array-buffer: 3.0.4 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 is-callable: 1.2.7 - is-data-view: 1.0.1 + is-data-view: 1.0.2 is-negative-zero: 2.0.3 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 - is-string: 1.0.7 - is-typed-array: 1.1.13 - is-weakref: 1.0.2 - object-inspect: 1.13.1 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - safe-array-concat: 1.1.2 - safe-regex-test: 1.0.3 - string.prototype.trim: 1.2.9 - string.prototype.trimend: 1.0.8 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.2 - typed-array-byte-length: 1.0.1 - typed-array-byte-offset: 1.0.2 - typed-array-length: 1.0.6 - unbox-primitive: 1.0.2 - which-typed-array: 1.1.15 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 es-array-method-boxes-properly@1.0.0: {} - es-define-property@1.0.0: - dependencies: - get-intrinsic: 1.2.4 - es-define-property@1.0.1: {} es-errors@1.3.0: {} - es-module-lexer@1.5.0: {} - es-module-lexer@1.7.0: {} - es-object-atoms@1.0.0: - dependencies: - es-errors: 1.3.0 + es-module-lexer@2.0.0: {} es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 - es-set-tostringtag@2.0.3: - dependencies: - get-intrinsic: 1.2.4 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - es-set-tostringtag@2.1.0: dependencies: es-errors: 1.3.0 @@ -7830,78 +7096,48 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - es-to-primitive@1.2.1: + es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 + is-date-object: 1.1.0 + is-symbol: 1.1.1 - esbuild-loader@4.4.0(webpack@5.96.1(@swc/core@1.13.5)(esbuild@0.27.0)): + esbuild-loader@4.4.2(webpack@5.104.1(esbuild@0.27.2)): dependencies: - esbuild: 0.25.3 + esbuild: 0.27.2 get-tsconfig: 4.13.0 loader-utils: 2.0.4 - webpack: 5.96.1(@swc/core@1.13.5)(esbuild@0.27.0) + webpack: 5.104.1(esbuild@0.27.2) webpack-sources: 1.4.3 - esbuild@0.25.3: + esbuild@0.27.2: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.3 - '@esbuild/android-arm': 0.25.3 - '@esbuild/android-arm64': 0.25.3 - '@esbuild/android-x64': 0.25.3 - '@esbuild/darwin-arm64': 0.25.3 - '@esbuild/darwin-x64': 0.25.3 - '@esbuild/freebsd-arm64': 0.25.3 - '@esbuild/freebsd-x64': 0.25.3 - '@esbuild/linux-arm': 0.25.3 - '@esbuild/linux-arm64': 0.25.3 - '@esbuild/linux-ia32': 0.25.3 - '@esbuild/linux-loong64': 0.25.3 - '@esbuild/linux-mips64el': 0.25.3 - '@esbuild/linux-ppc64': 0.25.3 - '@esbuild/linux-riscv64': 0.25.3 - '@esbuild/linux-s390x': 0.25.3 - '@esbuild/linux-x64': 0.25.3 - '@esbuild/netbsd-arm64': 0.25.3 - '@esbuild/netbsd-x64': 0.25.3 - '@esbuild/openbsd-arm64': 0.25.3 - '@esbuild/openbsd-x64': 0.25.3 - '@esbuild/sunos-x64': 0.25.3 - '@esbuild/win32-arm64': 0.25.3 - '@esbuild/win32-ia32': 0.25.3 - '@esbuild/win32-x64': 0.25.3 - - esbuild@0.27.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.0 - '@esbuild/android-arm': 0.27.0 - '@esbuild/android-arm64': 0.27.0 - '@esbuild/android-x64': 0.27.0 - '@esbuild/darwin-arm64': 0.27.0 - '@esbuild/darwin-x64': 0.27.0 - '@esbuild/freebsd-arm64': 0.27.0 - '@esbuild/freebsd-x64': 0.27.0 - '@esbuild/linux-arm': 0.27.0 - '@esbuild/linux-arm64': 0.27.0 - '@esbuild/linux-ia32': 0.27.0 - '@esbuild/linux-loong64': 0.27.0 - '@esbuild/linux-mips64el': 0.27.0 - '@esbuild/linux-ppc64': 0.27.0 - '@esbuild/linux-riscv64': 0.27.0 - '@esbuild/linux-s390x': 0.27.0 - '@esbuild/linux-x64': 0.27.0 - '@esbuild/netbsd-arm64': 0.27.0 - '@esbuild/netbsd-x64': 0.27.0 - '@esbuild/openbsd-arm64': 0.27.0 - '@esbuild/openbsd-x64': 0.27.0 - '@esbuild/openharmony-arm64': 0.27.0 - '@esbuild/sunos-x64': 0.27.0 - '@esbuild/win32-arm64': 0.27.0 - '@esbuild/win32-ia32': 0.27.0 - '@esbuild/win32-x64': 0.27.0 - - escalade@3.1.2: {} + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 escalade@3.2.0: {} @@ -7911,19 +7147,19 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)): dependencies: - eslint: 9.39.1(jiti@2.6.1) + eslint: 9.39.2(jiti@2.6.1) - eslint-plugin-prettier@5.5.4(@types/eslint@8.56.7)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2): + eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.8.1): dependencies: - eslint: 9.39.1(jiti@2.6.1) - prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 - synckit: 0.11.11 + eslint: 9.39.2(jiti@2.6.1) + prettier: 3.8.1 + prettier-linter-helpers: 1.0.1 + synckit: 0.11.12 optionalDependencies: - '@types/eslint': 8.56.7 - eslint-config-prettier: 10.1.8(eslint@9.39.1(jiti@2.6.1)) + '@types/eslint': 9.6.1 + eslint-config-prettier: 10.1.8(eslint@9.39.2(jiti@2.6.1)) eslint-scope@5.1.1: dependencies: @@ -7939,15 +7175,15 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.39.1(jiti@2.6.1): + eslint@9.39.2(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.8.0(eslint@9.39.1(jiti@2.6.1)) - '@eslint-community/regexpp': 4.12.1 + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.1 '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.39.1 + '@eslint/eslintrc': 3.3.3 + '@eslint/js': 9.39.2 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 @@ -7961,20 +7197,20 @@ snapshots: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - esquery: 1.5.0 + esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.3 + optionator: 0.9.4 optionalDependencies: jiti: 2.6.1 transitivePeerDependencies: @@ -7986,7 +7222,7 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 - esquery@1.5.0: + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -8002,13 +7238,13 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 esutils@2.0.3: {} etag@1.8.1: {} - eventemitter3@5.0.1: {} + eventemitter3@5.0.4: {} events@3.3.0: {} @@ -8052,70 +7288,71 @@ snapshots: dependencies: homedir-polyfill: 1.0.3 - expect-type@1.2.2: {} + expect-type@1.3.0: {} - express@4.19.2: + express@4.22.1: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.4 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.6.0 - cookie-signature: 1.0.6 + cookie: 0.7.2 + cookie-signature: 1.0.7 debug: 2.6.9 depd: 2.0.0 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.2 fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.12 proxy-addr: 2.0.7 - qs: 6.11.0 + qs: 6.14.1 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + send: 0.19.2 + serve-static: 1.16.3 setprototypeof: 1.2.0 - statuses: 2.0.1 + statuses: 2.0.2 type-is: 1.6.18 utils-merge: 1.0.1 vary: 1.1.2 transitivePeerDependencies: - supports-color - express@5.1.0: + express@5.2.1: dependencies: accepts: 2.0.0 - body-parser: 2.2.0 - content-disposition: 1.0.0 + body-parser: 2.2.2 + content-disposition: 1.0.1 content-type: 1.0.5 - cookie: 0.7.1 + cookie: 0.7.2 cookie-signature: 1.2.2 debug: 4.4.3 + depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.0 + finalhandler: 2.1.1 fresh: 2.0.0 - http-errors: 2.0.0 + http-errors: 2.0.1 merge-descriptors: 2.0.0 - mime-types: 3.0.0 + mime-types: 3.0.2 on-finished: 2.4.1 once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.14.0 + qs: 6.14.1 range-parser: 1.2.1 router: 2.2.0 - send: 1.1.0 - serve-static: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 statuses: 2.0.2 type-is: 2.0.1 vary: 1.1.2 @@ -8144,7 +7381,7 @@ snapshots: fast-json-stable-stringify@2.1.0: {} - fast-json-stringify@6.1.1: + fast-json-stringify@6.2.0: dependencies: '@fastify/merge-json-schemas': 0.2.1 ajv: 8.17.1 @@ -8167,7 +7404,7 @@ snapshots: fastify-plugin@5.1.0: {} - fastify@5.6.2: + fastify@5.7.2: dependencies: '@fastify/ajv-compiler': 4.0.5 '@fastify/error': 4.2.0 @@ -8175,19 +7412,19 @@ snapshots: '@fastify/proxy-addr': 5.1.0 abstract-logging: 2.0.1 avvio: 9.1.0 - fast-json-stringify: 6.1.1 - find-my-way: 9.3.0 + fast-json-stringify: 6.2.0 + find-my-way: 9.4.0 light-my-request: 6.6.0 - pino: 10.1.0 + pino: 10.3.0 process-warning: 5.0.0 rfdc: 1.4.1 secure-json-parse: 4.1.0 - semver: 7.6.0 + semver: 7.7.3 toad-cache: 3.7.0 - fastq@1.17.1: + fastq@1.20.1: dependencies: - reusify: 1.0.4 + reusify: 1.1.0 fd-package-json@2.0.0: dependencies: @@ -8209,19 +7446,19 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@1.2.0: + finalhandler@1.3.2: dependencies: debug: 2.6.9 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 - statuses: 2.0.1 + statuses: 2.0.2 unpipe: 1.0.0 transitivePeerDependencies: - supports-color - finalhandler@2.1.0: + finalhandler@2.1.1: dependencies: debug: 4.4.3 encodeurl: 2.0.0 @@ -8232,7 +7469,7 @@ snapshots: transitivePeerDependencies: - supports-color - find-my-way@9.3.0: + find-my-way@9.4.0: dependencies: fast-deep-equal: 3.1.3 fast-querystring: 1.1.2 @@ -8269,36 +7506,25 @@ snapshots: fix-dts-default-cjs-exports@1.0.1: dependencies: - magic-string: 0.30.17 + magic-string: 0.30.21 mlly: 1.8.0 - rollup: 4.40.1 + rollup: 4.57.0 flat-cache@4.0.1: dependencies: - flatted: 3.3.1 + flatted: 3.3.3 keyv: 4.5.4 flat@5.0.2: {} - flatted@3.3.1: {} + flatted@3.3.3: {} - follow-redirects@1.15.6: {} + follow-redirects@1.15.11: {} - for-each@0.3.3: + for-each@0.3.5: dependencies: is-callable: 1.2.7 - foreground-child@3.1.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - form-data@4.0.5: dependencies: asynckit: 0.4.0 @@ -8320,17 +7546,17 @@ snapshots: fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 - fs-monkey@1.0.5: {} + fs-monkey@1.1.0: {} fs-readdir-recursive@1.1.0: {} @@ -8349,28 +7575,24 @@ snapshots: function-bind@1.1.2: {} - function.prototype.name@1.1.6: + function.prototype.name@1.1.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.3 functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 functions-have-names@1.2.3: {} + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} - get-east-asian-width@1.2.0: {} - - get-intrinsic@1.2.4: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 - hasown: 2.0.2 + get-east-asian-width@1.4.0: {} get-intrinsic@1.3.0: dependencies: @@ -8394,17 +7616,17 @@ snapshots: get-stream@8.0.1: {} - get-symbol-description@1.0.2: + get-symbol-description@1.1.0: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 get-tsconfig@4.13.0: dependencies: resolve-pkg-maps: 1.0.0 - git-log-parser@1.2.0: + git-log-parser@1.2.1: dependencies: argv-formatter: 1.0.0 spawn-error-forwarder: 1.0.0 @@ -8429,19 +7651,11 @@ snapshots: glob-to-regexp@0.4.1: {} - glob@10.3.12: - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.4 - minipass: 7.1.2 - path-scurry: 1.10.2 - glob@13.0.0: dependencies: minimatch: 10.1.1 minipass: 7.1.2 - path-scurry: 2.0.0 + path-scurry: 2.0.1 glob@7.2.3: dependencies: @@ -8470,17 +7684,12 @@ snapshots: is-windows: 1.0.2 which: 1.3.1 - globals@11.12.0: {} - globals@14.0.0: {} - globalthis@1.0.3: + globalthis@1.0.4: dependencies: define-properties: 1.2.1 - - gopd@1.0.1: - dependencies: - get-intrinsic: 1.2.4 + gopd: 1.2.0 gopd@1.2.0: {} @@ -8488,11 +7697,9 @@ snapshots: graceful-fs@4.2.11: {} - graphemer@1.4.0: {} - graphql@16.12.0: {} - has-bigints@1.0.2: {} + has-bigints@1.1.0: {} has-flag@3.0.0: {} @@ -8500,17 +7707,17 @@ snapshots: has-property-descriptors@1.0.2: dependencies: - es-define-property: 1.0.0 - - has-proto@1.0.3: {} + es-define-property: 1.0.1 - has-symbols@1.0.3: {} + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 has-symbols@1.1.0: {} has-tostringtag@1.0.2: dependencies: - has-symbols: 1.0.3 + has-symbols: 1.1.0 hasown@2.0.2: dependencies: @@ -8524,7 +7731,7 @@ snapshots: dependencies: parse-passwd: 1.0.0 - hono@4.10.4: {} + hono@4.11.7: {} html-encoding-sniffer@4.0.0: dependencies: @@ -8537,7 +7744,7 @@ snapshots: deep-equal: 1.0.1 http-errors: 1.8.1 - http-cache-semantics@4.1.1: {} + http-cache-semantics@4.2.0: {} http-errors@1.6.3: dependencies: @@ -8554,25 +7761,25 @@ snapshots: statuses: 1.5.0 toidentifier: 1.0.1 - http-errors@2.0.0: + http-errors@2.0.1: dependencies: depd: 2.0.0 inherits: 2.0.4 setprototypeof: 1.2.0 - statuses: 2.0.1 + statuses: 2.0.2 toidentifier: 1.0.1 http-proxy-agent@7.0.2: dependencies: - agent-base: 7.1.1 - debug: 4.4.0 + agent-base: 7.1.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.5: + https-proxy-agent@7.0.6: dependencies: - agent-base: 7.1.1 - debug: 4.4.0 + agent-base: 7.1.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -8590,18 +7797,22 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} - ignore@5.3.1: {} + ignore@5.3.2: {} ignore@7.0.5: {} - import-fresh@3.3.0: + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - import-meta-resolve@4.0.0: {} + import-meta-resolve@4.2.0: {} imurmurhash@0.1.4: {} @@ -8630,7 +7841,7 @@ snapshots: mute-stream: 0.0.8 ora: 5.4.1 run-async: 2.4.1 - rxjs: 7.8.1 + rxjs: 7.8.2 string-width: 4.2.3 strip-ansi: 6.0.1 through: 2.3.8 @@ -8643,63 +7854,83 @@ snapshots: is-ip: 3.1.0 p-event: 4.2.0 - internal-slot@1.0.7: + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.2 - side-channel: 1.0.6 + side-channel: 1.1.0 ip-regex@4.3.0: {} ipaddr.js@1.9.1: {} - ipaddr.js@2.2.0: {} + ipaddr.js@2.3.0: {} - is-array-buffer@3.0.4: + is-array-buffer@3.0.5: dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 is-arrayish@0.2.1: {} - is-bigint@1.0.4: + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: dependencies: - has-bigints: 1.0.2 + has-bigints: 1.1.0 - is-boolean-object@1.1.2: + is-boolean-object@1.2.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 has-tostringtag: 1.0.2 is-callable@1.2.7: {} - is-core-module@2.13.1: + is-core-module@2.16.1: dependencies: hasown: 2.0.2 - is-data-view@1.0.1: + is-data-view@1.0.2: dependencies: - is-typed-array: 1.1.13 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 - is-date-object@1.0.5: + is-date-object@1.1.0: dependencies: + call-bound: 1.0.4 has-tostringtag: 1.0.2 is-docker@2.2.1: {} is-extglob@2.1.1: {} + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + is-fullwidth-code-point@3.0.0: {} is-fullwidth-code-point@4.0.0: {} - is-fullwidth-code-point@5.0.0: + is-fullwidth-code-point@5.1.0: dependencies: - get-east-asian-width: 1.2.0 + get-east-asian-width: 1.4.0 - is-generator-function@1.0.10: + is-generator-function@1.1.2: dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 is-glob@4.0.3: dependencies: @@ -8711,14 +7942,17 @@ snapshots: dependencies: ip-regex: 4.3.0 + is-map@2.0.3: {} + is-module@1.0.0: {} is-negative-zero@2.0.3: {} is-node-process@1.2.0: {} - is-number-object@1.0.7: + is-number-object@1.1.1: dependencies: + call-bound: 1.0.4 has-tostringtag: 1.0.2 is-number@7.0.0: {} @@ -8733,42 +7967,56 @@ snapshots: is-promise@4.0.0: {} - is-regex@1.1.4: + is-regex@1.2.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 + gopd: 1.2.0 has-tostringtag: 1.0.2 + hasown: 2.0.2 - is-shared-array-buffer@1.0.3: + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 is-stream@2.0.1: {} is-stream@3.0.0: {} - is-string@1.0.7: + is-string@1.1.1: dependencies: + call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-symbol@1.0.4: + is-symbol@1.1.1: dependencies: - has-symbols: 1.0.3 + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 is-text-path@2.0.0: dependencies: text-extensions: 2.4.0 - is-typed-array@1.1.13: + is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.15 + which-typed-array: 1.1.20 is-unicode-supported@0.1.0: {} is-utf8@0.2.1: {} - is-weakref@1.0.2: + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 is-windows@1.0.2: {} @@ -8780,7 +8028,7 @@ snapshots: isarray@2.0.5: {} - isbinaryfile@5.0.2: {} + isbinaryfile@5.0.7: {} isexe@2.0.0: {} @@ -8794,68 +8042,55 @@ snapshots: lodash.isstring: 4.0.1 lodash.uniqby: 4.7.0 - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - jest-worker@27.5.1: dependencies: - '@types/node': 18.19.28 + '@types/node': 20.19.30 merge-stream: 2.0.0 supports-color: 8.1.1 - jiti@1.21.0: - optional: true - jiti@2.6.1: {} joycon@3.1.1: {} js-tokens@4.0.0: {} - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - js-yaml@4.1.1: dependencies: argparse: 2.0.1 jsdom@25.0.1: dependencies: - cssstyle: 4.1.0 + cssstyle: 4.6.0 data-urls: 5.0.0 - decimal.js: 10.4.3 - form-data: 4.0.0 + decimal.js: 10.6.0 + form-data: 4.0.5 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.5 + https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.16 - parse5: 7.1.2 + nwsapi: 2.2.23 + parse5: 7.3.0 rrweb-cssom: 0.7.1 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 5.0.0 + tough-cookie: 5.1.2 w3c-xmlserializer: 5.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 - ws: 8.18.0 + whatwg-url: 14.2.0 + ws: 8.19.0 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - jsesc@2.5.2: {} + jsesc@3.1.0: {} json-bigint@1.0.0: dependencies: - bignumber.js: 9.1.2 + bignumber.js: 9.3.1 json-buffer@3.0.1: {} @@ -8873,7 +8108,7 @@ snapshots: json5@2.2.3: {} - jsonfile@6.1.0: + jsonfile@6.2.0: dependencies: universalify: 2.0.1 optionalDependencies: @@ -8893,22 +8128,22 @@ snapshots: kleur@4.1.5: {} - knip@5.70.1(@types/node@20.19.25)(typescript@5.9.3): + knip@5.82.1(@types/node@20.19.30)(typescript@5.9.3): dependencies: '@nodelib/fs.walk': 1.2.8 - '@types/node': 20.19.25 + '@types/node': 20.19.30 fast-glob: 3.3.3 formatly: 0.3.0 jiti: 2.6.1 js-yaml: 4.1.1 minimist: 1.2.8 - oxc-resolver: 11.13.2 + oxc-resolver: 11.16.4 picocolors: 1.1.1 picomatch: 4.0.3 - smol-toml: 1.5.2 + smol-toml: 1.6.0 strip-json-comments: 5.0.3 typescript: 5.9.3 - zod: 4.1.12 + zod: 4.3.6 koa-compose@4.1.0: {} @@ -8936,7 +8171,7 @@ snapshots: transitivePeerDependencies: - supports-color - koa@2.15.2: + koa@2.16.3: dependencies: accepts: 1.3.8 cache-content-type: 1.0.1 @@ -8952,7 +8187,7 @@ snapshots: fresh: 0.5.2 http-assert: 1.5.0 http-errors: 1.8.1 - is-generator-function: 1.0.10 + is-generator-function: 1.1.2 koa-compose: 4.1.0 koa-convert: 2.0.0 on-finished: 2.4.1 @@ -8973,41 +8208,41 @@ snapshots: light-my-request@6.6.0: dependencies: - cookie: 1.0.2 - process-warning: 4.0.0 - set-cookie-parser: 2.6.0 + cookie: 1.1.1 + process-warning: 4.0.1 + set-cookie-parser: 2.7.2 - lilconfig@3.1.2: {} + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} - lint-staged@15.2.10: + lint-staged@15.5.2: dependencies: - chalk: 5.3.0 - commander: 12.1.0 - debug: 4.3.7 + chalk: 5.6.2 + commander: 13.1.0 + debug: 4.4.3 execa: 8.0.1 - lilconfig: 3.1.2 - listr2: 8.2.5 + lilconfig: 3.1.3 + listr2: 8.3.3 micromatch: 4.0.8 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.5.1 + yaml: 2.8.2 transitivePeerDependencies: - supports-color - listr2@8.2.5: + listr2@8.3.3: dependencies: cli-truncate: 4.0.0 colorette: 2.0.20 - eventemitter3: 5.0.1 + eventemitter3: 5.0.4 log-update: 6.1.0 rfdc: 1.4.1 - wrap-ansi: 9.0.0 + wrap-ansi: 9.0.2 load-tsconfig@0.2.5: {} - loader-runner@4.3.0: {} + loader-runner@4.3.1: {} loader-utils@2.0.4: dependencies: @@ -9023,8 +8258,6 @@ snapshots: dependencies: p-locate: 6.0.0 - lodash.assignwith@4.2.0: {} - lodash.camelcase@4.3.0: {} lodash.capitalize@4.2.1: {} @@ -9055,6 +8288,8 @@ snapshots: lodash@4.17.21: {} + lodash@4.17.23: {} + log-symbols@4.1.0: dependencies: chalk: 4.1.2 @@ -9062,32 +8297,24 @@ snapshots: log-update@6.1.0: dependencies: - ansi-escapes: 7.0.0 + ansi-escapes: 7.2.0 cli-cursor: 5.0.0 - slice-ansi: 7.1.0 - strip-ansi: 7.1.0 - wrap-ansi: 9.0.0 + slice-ansi: 7.1.2 + strip-ansi: 7.1.2 + wrap-ansi: 9.0.2 longest@2.0.1: {} - lru-cache@10.2.0: {} + lru-cache@10.4.3: {} - lru-cache@11.0.2: {} + lru-cache@11.2.5: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - lru-cache@8.0.5: {} - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -9100,13 +8327,13 @@ snapshots: memfs@3.5.3: dependencies: - fs-monkey: 1.0.5 + fs-monkey: 1.1.0 meow@12.1.1: {} meow@13.2.0: {} - merge-descriptors@1.0.1: {} + merge-descriptors@1.0.3: {} merge-descriptors@2.0.0: {} @@ -9125,26 +8352,18 @@ snapshots: mime-db@1.52.0: {} - mime-db@1.53.0: {} - mime-db@1.54.0: {} mime-types@2.1.35: dependencies: mime-db: 1.52.0 - mime-types@3.0.0: - dependencies: - mime-db: 1.53.0 - mime-types@3.0.2: dependencies: mime-db: 1.54.0 mime@1.6.0: {} - mime@4.0.1: {} - mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} @@ -9157,11 +8376,11 @@ snapshots: minimatch@3.1.2: dependencies: - brace-expansion: 1.1.11 + brace-expansion: 1.1.12 - minimatch@9.0.4: + minimatch@9.0.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimist@1.2.7: {} @@ -9178,13 +8397,13 @@ snapshots: acorn: 8.15.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.6.1 + ufo: 1.6.3 mri@1.1.4: {} - ms@2.0.0: {} + mri@1.2.0: {} - ms@2.1.2: {} + ms@2.0.0: {} ms@2.1.3: {} @@ -9216,9 +8435,7 @@ snapshots: dependencies: whatwg-url: 5.0.0 - node-releases@2.0.14: {} - - node-releases@2.0.18: {} + node-releases@2.0.27: {} npm-run-path@4.0.1: dependencies: @@ -9232,35 +8449,37 @@ snapshots: dependencies: execa: 6.1.0 parse-package-name: 1.0.0 - semver: 7.6.0 + semver: 7.7.3 validate-npm-package-name: 4.0.0 - nwsapi@2.2.16: {} + nwsapi@2.2.23: {} object-assign@4.1.1: {} - object-inspect@1.13.1: {} - object-inspect@1.13.4: {} object-keys@1.1.1: {} - object.assign@4.1.5: + object.assign@4.1.7: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 define-properties: 1.2.1 - has-symbols: 1.0.3 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 object-keys: 1.1.1 - object.getownpropertydescriptors@2.1.8: + object.getownpropertydescriptors@2.1.9: dependencies: - array.prototype.reduce: 1.0.7 - call-bind: 1.0.7 + array.prototype.reduce: 1.0.8 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - gopd: 1.0.1 - safe-array-concat: 1.1.2 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + gopd: 1.2.0 + safe-array-concat: 1.1.3 + + obug@2.1.1: {} on-exit-leak-free@0.2.0: {} @@ -9294,14 +8513,14 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - optionator@0.9.3: + optionator@0.9.4: dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 + word-wrap: 1.2.5 ora@5.4.1: dependencies: @@ -9319,27 +8538,34 @@ snapshots: outvariant@1.4.3: {} - oxc-resolver@11.13.2: + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + oxc-resolver@11.16.4: optionalDependencies: - '@oxc-resolver/binding-android-arm-eabi': 11.13.2 - '@oxc-resolver/binding-android-arm64': 11.13.2 - '@oxc-resolver/binding-darwin-arm64': 11.13.2 - '@oxc-resolver/binding-darwin-x64': 11.13.2 - '@oxc-resolver/binding-freebsd-x64': 11.13.2 - '@oxc-resolver/binding-linux-arm-gnueabihf': 11.13.2 - '@oxc-resolver/binding-linux-arm-musleabihf': 11.13.2 - '@oxc-resolver/binding-linux-arm64-gnu': 11.13.2 - '@oxc-resolver/binding-linux-arm64-musl': 11.13.2 - '@oxc-resolver/binding-linux-ppc64-gnu': 11.13.2 - '@oxc-resolver/binding-linux-riscv64-gnu': 11.13.2 - '@oxc-resolver/binding-linux-riscv64-musl': 11.13.2 - '@oxc-resolver/binding-linux-s390x-gnu': 11.13.2 - '@oxc-resolver/binding-linux-x64-gnu': 11.13.2 - '@oxc-resolver/binding-linux-x64-musl': 11.13.2 - '@oxc-resolver/binding-wasm32-wasi': 11.13.2 - '@oxc-resolver/binding-win32-arm64-msvc': 11.13.2 - '@oxc-resolver/binding-win32-ia32-msvc': 11.13.2 - '@oxc-resolver/binding-win32-x64-msvc': 11.13.2 + '@oxc-resolver/binding-android-arm-eabi': 11.16.4 + '@oxc-resolver/binding-android-arm64': 11.16.4 + '@oxc-resolver/binding-darwin-arm64': 11.16.4 + '@oxc-resolver/binding-darwin-x64': 11.16.4 + '@oxc-resolver/binding-freebsd-x64': 11.16.4 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.16.4 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.16.4 + '@oxc-resolver/binding-linux-arm64-gnu': 11.16.4 + '@oxc-resolver/binding-linux-arm64-musl': 11.16.4 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.16.4 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.16.4 + '@oxc-resolver/binding-linux-riscv64-musl': 11.16.4 + '@oxc-resolver/binding-linux-s390x-gnu': 11.16.4 + '@oxc-resolver/binding-linux-x64-gnu': 11.16.4 + '@oxc-resolver/binding-linux-x64-musl': 11.16.4 + '@oxc-resolver/binding-openharmony-arm64': 11.16.4 + '@oxc-resolver/binding-wasm32-wasi': 11.16.4 + '@oxc-resolver/binding-win32-arm64-msvc': 11.16.4 + '@oxc-resolver/binding-win32-ia32-msvc': 11.16.4 + '@oxc-resolver/binding-win32-x64-msvc': 11.16.4 p-event@4.2.0: dependencies: @@ -9369,23 +8595,23 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@1.3.0: {} + package-manager-detector@1.6.0: {} - page-with@0.6.1(@swc/core@1.13.5)(esbuild@0.27.0): + page-with@0.6.1(esbuild@0.27.2): dependencies: '@open-draft/until': 2.1.0 '@types/debug': 4.1.12 - '@types/express': 4.17.21 - '@types/mustache': 4.2.5 + '@types/express': 4.17.25 + '@types/mustache': 4.2.6 '@types/uuid': 8.3.4 - debug: 4.3.4 - express: 4.19.2 + debug: 4.4.3 + express: 4.22.1 headers-polyfill: 3.3.0 memfs: 3.5.3 mustache: 4.2.0 - playwright: 1.42.1 + playwright: 1.58.0 uuid: 8.3.2 - webpack: 5.96.1(@swc/core@1.13.5)(esbuild@0.27.0) + webpack: 5.104.1(esbuild@0.27.2) webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' @@ -9400,8 +8626,8 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.2 - error-ex: 1.3.2 + '@babel/code-frame': 7.28.6 + error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -9411,9 +8637,9 @@ snapshots: parse5@6.0.1: {} - parse5@7.1.2: + parse5@7.3.0: dependencies: - entities: 4.5.0 + entities: 6.0.1 parseurl@1.3.3: {} @@ -9429,21 +8655,16 @@ snapshots: path-parse@1.0.7: {} - path-scurry@1.10.2: - dependencies: - lru-cache: 10.2.0 - minipass: 7.1.2 - - path-scurry@2.0.0: + path-scurry@2.0.1: dependencies: - lru-cache: 11.0.2 + lru-cache: 11.2.5 minipass: 7.1.2 - path-to-regexp@0.1.7: {} + path-to-regexp@0.1.12: {} path-to-regexp@6.3.0: {} - path-to-regexp@8.2.0: {} + path-to-regexp@8.3.0: {} pathe@2.0.3: {} @@ -9460,7 +8681,7 @@ snapshots: duplexify: 4.1.3 split2: 4.2.0 - pino-abstract-transport@2.0.0: + pino-abstract-transport@3.0.0: dependencies: split2: 4.2.0 @@ -9473,7 +8694,7 @@ snapshots: joycon: 3.1.1 on-exit-leak-free: 0.2.0 pino-abstract-transport: 0.5.0 - pump: 3.0.0 + pump: 3.0.3 readable-stream: 3.6.2 rfdc: 1.4.1 secure-json-parse: 2.7.0 @@ -9482,21 +8703,21 @@ snapshots: pino-std-serializers@4.0.0: {} - pino-std-serializers@7.0.0: {} + pino-std-serializers@7.1.0: {} - pino@10.1.0: + pino@10.3.0: dependencies: '@pinojs/redact': 0.4.0 atomic-sleep: 1.0.0 on-exit-leak-free: 2.1.2 - pino-abstract-transport: 2.0.0 - pino-std-serializers: 7.0.0 + pino-abstract-transport: 3.0.0 + pino-std-serializers: 7.1.0 process-warning: 5.0.0 quick-format-unescaped: 4.0.4 real-require: 0.2.0 - safe-stable-stringify: 2.4.3 + safe-stable-stringify: 2.5.0 sonic-boom: 4.2.0 - thread-stream: 3.1.0 + thread-stream: 4.0.0 pino@7.11.0: dependencies: @@ -9508,11 +8729,11 @@ snapshots: process-warning: 1.0.0 quick-format-unescaped: 4.0.4 real-require: 0.1.0 - safe-stable-stringify: 2.4.3 + safe-stable-stringify: 2.5.0 sonic-boom: 2.8.0 thread-stream: 0.15.2 - pirates@4.0.6: {} + pirates@4.0.7: {} pkg-types@1.3.1: dependencies: @@ -9520,39 +8741,30 @@ snapshots: mlly: 1.8.0 pathe: 2.0.3 - playwright-core@1.42.1: {} - - playwright-core@1.56.1: {} - - playwright@1.42.1: - dependencies: - playwright-core: 1.42.1 - optionalDependencies: - fsevents: 2.3.2 + playwright-core@1.58.0: {} - playwright@1.56.1: + playwright@1.58.0: dependencies: - playwright-core: 1.56.1 + playwright-core: 1.58.0 optionalDependencies: fsevents: 2.3.2 - portfinder@1.0.32: + portfinder@1.0.38: dependencies: - async: 2.6.4 - debug: 3.2.7 - mkdirp: 0.5.6 + async: 3.2.6 + debug: 4.4.3 transitivePeerDependencies: - supports-color - possible-typed-array-names@1.0.0: {} + possible-typed-array-names@1.1.0: {} - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(yaml@2.5.1): + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(yaml@2.8.2): dependencies: - lilconfig: 3.1.2 + lilconfig: 3.1.3 optionalDependencies: jiti: 2.6.1 postcss: 8.5.6 - yaml: 2.5.1 + yaml: 2.8.2 postcss@8.5.6: dependencies: @@ -9562,17 +8774,17 @@ snapshots: prelude-ls@1.2.1: {} - prettier-linter-helpers@1.0.0: + prettier-linter-helpers@1.0.1: dependencies: fast-diff: 1.3.0 - prettier@3.6.2: {} + prettier@3.8.1: {} process-nextick-args@2.0.1: {} process-warning@1.0.0: {} - process-warning@4.0.0: {} + process-warning@4.0.1: {} process-warning@5.0.0: {} @@ -9585,25 +8797,21 @@ snapshots: proxy-from-env@1.1.0: {} - publint@0.3.15: + publint@0.3.17: dependencies: - '@publint/pack': 0.1.2 - package-manager-detector: 1.3.0 + '@publint/pack': 0.1.3 + package-manager-detector: 1.6.0 picocolors: 1.1.1 sade: 1.8.1 - pump@3.0.0: + pump@3.0.3: dependencies: - end-of-stream: 1.4.4 + end-of-stream: 1.4.5 once: 1.4.0 punycode@2.3.1: {} - qs@6.11.0: - dependencies: - side-channel: 1.0.6 - - qs@6.14.0: + qs@6.14.1: dependencies: side-channel: 1.1.0 @@ -9617,18 +8825,18 @@ snapshots: range-parser@1.2.1: {} - raw-body@2.5.2: + raw-body@2.5.3: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.0: + raw-body@3.0.2: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.6.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 unpipe: 1.0.0 rc@1.2.8: @@ -9654,24 +8862,37 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - readdirp@4.0.2: {} + readdirp@4.1.2: {} real-require@0.1.0: {} real-require@0.2.0: {} + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + regenerator-runtime@0.14.1: {} - regexp.prototype.flags@1.5.2: + regexp.prototype.flags@1.5.4: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 set-function-name: 2.0.2 - registry-auth-token@5.1.0: + registry-auth-token@5.1.1: dependencies: - '@pnpm/npm-conf': 2.3.1 + '@pnpm/npm-conf': 3.0.2 require-directory@2.1.1: {} @@ -9693,9 +8914,9 @@ snapshots: resolve-pkg-maps@1.0.0: {} - resolve@1.22.8: + resolve@1.22.11: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -9713,7 +8934,7 @@ snapshots: rettime@0.9.1: {} - reusify@1.0.4: {} + reusify@1.1.0: {} rfdc@1.4.1: {} @@ -9722,58 +8943,35 @@ snapshots: glob: 13.0.0 package-json-from-dist: 1.0.1 - rollup@4.40.1: - dependencies: - '@types/estree': 1.0.7 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.40.1 - '@rollup/rollup-android-arm64': 4.40.1 - '@rollup/rollup-darwin-arm64': 4.40.1 - '@rollup/rollup-darwin-x64': 4.40.1 - '@rollup/rollup-freebsd-arm64': 4.40.1 - '@rollup/rollup-freebsd-x64': 4.40.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.40.1 - '@rollup/rollup-linux-arm-musleabihf': 4.40.1 - '@rollup/rollup-linux-arm64-gnu': 4.40.1 - '@rollup/rollup-linux-arm64-musl': 4.40.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.40.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.40.1 - '@rollup/rollup-linux-riscv64-gnu': 4.40.1 - '@rollup/rollup-linux-riscv64-musl': 4.40.1 - '@rollup/rollup-linux-s390x-gnu': 4.40.1 - '@rollup/rollup-linux-x64-gnu': 4.40.1 - '@rollup/rollup-linux-x64-musl': 4.40.1 - '@rollup/rollup-win32-arm64-msvc': 4.40.1 - '@rollup/rollup-win32-ia32-msvc': 4.40.1 - '@rollup/rollup-win32-x64-msvc': 4.40.1 - fsevents: 2.3.3 - - rollup@4.53.3: + rollup@4.57.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.53.3 - '@rollup/rollup-android-arm64': 4.53.3 - '@rollup/rollup-darwin-arm64': 4.53.3 - '@rollup/rollup-darwin-x64': 4.53.3 - '@rollup/rollup-freebsd-arm64': 4.53.3 - '@rollup/rollup-freebsd-x64': 4.53.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 - '@rollup/rollup-linux-arm-musleabihf': 4.53.3 - '@rollup/rollup-linux-arm64-gnu': 4.53.3 - '@rollup/rollup-linux-arm64-musl': 4.53.3 - '@rollup/rollup-linux-loong64-gnu': 4.53.3 - '@rollup/rollup-linux-ppc64-gnu': 4.53.3 - '@rollup/rollup-linux-riscv64-gnu': 4.53.3 - '@rollup/rollup-linux-riscv64-musl': 4.53.3 - '@rollup/rollup-linux-s390x-gnu': 4.53.3 - '@rollup/rollup-linux-x64-gnu': 4.53.3 - '@rollup/rollup-linux-x64-musl': 4.53.3 - '@rollup/rollup-openharmony-arm64': 4.53.3 - '@rollup/rollup-win32-arm64-msvc': 4.53.3 - '@rollup/rollup-win32-ia32-msvc': 4.53.3 - '@rollup/rollup-win32-x64-gnu': 4.53.3 - '@rollup/rollup-win32-x64-msvc': 4.53.3 + '@rollup/rollup-android-arm-eabi': 4.57.0 + '@rollup/rollup-android-arm64': 4.57.0 + '@rollup/rollup-darwin-arm64': 4.57.0 + '@rollup/rollup-darwin-x64': 4.57.0 + '@rollup/rollup-freebsd-arm64': 4.57.0 + '@rollup/rollup-freebsd-x64': 4.57.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.57.0 + '@rollup/rollup-linux-arm-musleabihf': 4.57.0 + '@rollup/rollup-linux-arm64-gnu': 4.57.0 + '@rollup/rollup-linux-arm64-musl': 4.57.0 + '@rollup/rollup-linux-loong64-gnu': 4.57.0 + '@rollup/rollup-linux-loong64-musl': 4.57.0 + '@rollup/rollup-linux-ppc64-gnu': 4.57.0 + '@rollup/rollup-linux-ppc64-musl': 4.57.0 + '@rollup/rollup-linux-riscv64-gnu': 4.57.0 + '@rollup/rollup-linux-riscv64-musl': 4.57.0 + '@rollup/rollup-linux-s390x-gnu': 4.57.0 + '@rollup/rollup-linux-x64-gnu': 4.57.0 + '@rollup/rollup-linux-x64-musl': 4.57.0 + '@rollup/rollup-openbsd-x64': 4.57.0 + '@rollup/rollup-openharmony-arm64': 4.57.0 + '@rollup/rollup-win32-arm64-msvc': 4.57.0 + '@rollup/rollup-win32-ia32-msvc': 4.57.0 + '@rollup/rollup-win32-x64-gnu': 4.57.0 + '@rollup/rollup-win32-x64-msvc': 4.57.0 fsevents: 2.3.3 router@2.2.0: @@ -9782,48 +8980,56 @@ snapshots: depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.2.0 + path-to-regexp: 8.3.0 transitivePeerDependencies: - supports-color rrweb-cssom@0.7.1: {} + rrweb-cssom@0.8.0: {} + run-async@2.4.1: {} run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - rxjs@7.8.1: + rxjs@7.8.2: dependencies: - tslib: 2.6.2 + tslib: 2.8.1 sade@1.8.1: dependencies: - mri: 1.1.4 + mri: 1.2.0 - safe-array-concat@1.1.2: + safe-array-concat@1.1.3: dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 isarray: 2.0.5 safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} - safe-regex-test@1.0.3: + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-regex: 1.1.4 + is-regex: 1.2.1 safe-regex2@5.0.0: dependencies: ret: 0.5.0 - safe-stable-stringify@2.4.3: {} + safe-stable-stringify@2.5.0: {} safer-buffer@2.1.2: {} @@ -9837,44 +9043,32 @@ snapshots: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + secure-json-parse@2.7.0: {} secure-json-parse@4.1.0: {} semver@6.3.1: {} - semver@7.6.0: - dependencies: - lru-cache: 6.0.0 + semver@7.7.3: {} - send@0.18.0: + send@0.19.2: dependencies: debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - - send@1.1.0: - dependencies: - debug: 4.4.3 - destroy: 1.2.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 fresh: 0.5.2 - http-errors: 2.0.0 - mime-types: 2.1.35 + http-errors: 2.0.1 + mime: 1.6.0 ms: 2.1.3 on-finished: 2.4.1 range-parser: 1.2.1 @@ -9882,14 +9076,14 @@ snapshots: transitivePeerDependencies: - supports-color - send@1.2.0: + send@1.2.1: dependencies: debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 fresh: 2.0.0 - http-errors: 2.0.0 + http-errors: 2.0.1 mime-types: 3.0.2 ms: 2.1.3 on-finished: 2.4.1 @@ -9902,33 +9096,33 @@ snapshots: dependencies: randombytes: 2.1.0 - serve-static@1.15.0: + serve-static@1.16.3: dependencies: - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 0.18.0 + send: 0.19.2 transitivePeerDependencies: - supports-color - serve-static@2.2.0: + serve-static@2.2.1: dependencies: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 1.2.0 + send: 1.2.1 transitivePeerDependencies: - supports-color - set-cookie-parser@2.6.0: {} + set-cookie-parser@2.7.2: {} set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 has-property-descriptors: 1.0.2 set-function-name@2.0.2: @@ -9938,6 +9132,12 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + setprototypeof@1.1.0: {} setprototypeof@1.2.0: {} @@ -9972,13 +9172,6 @@ snapshots: object-inspect: 1.13.4 side-channel-map: 1.0.1 - side-channel@1.0.6: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - object-inspect: 1.13.1 - side-channel@1.1.0: dependencies: es-errors: 1.3.0 @@ -9997,41 +9190,41 @@ snapshots: slice-ansi@5.0.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 is-fullwidth-code-point: 4.0.0 - slice-ansi@7.1.0: + slice-ansi@7.1.2: dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 5.0.0 + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 - smol-toml@1.5.2: {} + smol-toml@1.6.0: {} - socket.io-adapter@2.5.4: + socket.io-adapter@2.5.6: dependencies: - debug: 4.3.7 - ws: 8.11.0 + debug: 4.4.3 + ws: 8.18.3 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-parser@4.2.4: + socket.io-parser@4.2.5: dependencies: - '@socket.io/component-emitter': 3.1.0 - debug: 4.3.7 + '@socket.io/component-emitter': 3.1.2 + debug: 4.4.3 transitivePeerDependencies: - supports-color - socket.io@4.7.5: + socket.io@4.8.3: dependencies: accepts: 1.3.8 base64id: 2.0.0 - cors: 2.8.5 - debug: 4.3.7 - engine.io: 6.5.4 - socket.io-adapter: 2.5.4 - socket.io-parser: 4.2.4 + cors: 2.8.6 + debug: 4.4.3 + engine.io: 6.6.5 + socket.io-adapter: 2.5.6 + socket.io-parser: 4.2.5 transitivePeerDependencies: - bufferutil - supports-color @@ -10070,19 +9263,20 @@ snapshots: statuses@1.5.0: {} - statuses@2.0.1: {} - statuses@2.0.2: {} std-env@3.10.0: {} + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + stream-combiner2@1.1.1: dependencies: duplexer2: 0.1.4 readable-stream: 2.3.8 - stream-read-all@3.0.1: {} - stream-shift@1.0.3: {} streamsearch@1.1.0: {} @@ -10097,42 +9291,34 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string-width@7.1.0: - dependencies: - emoji-regex: 10.3.0 - get-east-asian-width: 1.2.0 - strip-ansi: 7.1.0 - string-width@7.2.0: dependencies: - emoji-regex: 10.3.0 - get-east-asian-width: 1.2.0 - strip-ansi: 7.1.0 + emoji-regex: 10.6.0 + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 - string.prototype.trim@1.2.9: + string.prototype.trim@1.2.10: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 - string.prototype.trimend@1.0.8: + string.prototype.trimend@1.0.9: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string_decoder@1.1.1: dependencies: @@ -10146,9 +9332,9 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.1.2: dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.2.2 strip-bom@4.0.0: {} @@ -10162,14 +9348,14 @@ snapshots: strip-json-comments@5.0.3: {} - sucrase@3.35.0: + sucrase@3.35.1: dependencies: - '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 - glob: 10.3.12 lines-and-columns: 1.2.4 mz: 2.7.0 - pirates: 4.0.6 + pirates: 4.0.7 + tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 supports-color@5.5.0: @@ -10188,40 +9374,34 @@ snapshots: symbol-tree@3.2.4: {} - synckit@0.11.11: + synckit@0.11.12: dependencies: '@pkgr/core': 0.2.9 - table-layout@3.0.2: + table-layout@4.1.1: dependencies: - '@75lb/deep-merge': 1.1.1 array-back: 6.2.2 - command-line-args: 5.2.1 - command-line-usage: 7.0.1 - stream-read-all: 3.0.1 - typical: 7.1.1 - wordwrapjs: 5.1.0 + wordwrapjs: 5.1.1 tagged-tag@1.0.0: {} - tapable@2.2.1: {} + tapable@2.3.0: {} - terser-webpack-plugin@5.3.10(@swc/core@1.13.5)(esbuild@0.27.0)(webpack@5.96.1(@swc/core@1.13.5)(esbuild@0.27.0)): + terser-webpack-plugin@5.3.16(esbuild@0.27.2)(webpack@5.104.1(esbuild@0.27.2)): dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 - schema-utils: 3.3.0 + schema-utils: 4.3.3 serialize-javascript: 6.0.2 - terser: 5.30.1 - webpack: 5.96.1(@swc/core@1.13.5)(esbuild@0.27.0) + terser: 5.46.0 + webpack: 5.104.1(esbuild@0.27.2) optionalDependencies: - '@swc/core': 1.13.5 - esbuild: 0.27.0 + esbuild: 0.27.2 - terser@5.30.1: + terser@5.46.0: dependencies: - '@jridgewell/source-map': 0.3.6 - acorn: 8.14.0 + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -10239,7 +9419,7 @@ snapshots: dependencies: real-require: 0.1.0 - thread-stream@3.1.0: + thread-stream@4.0.0: dependencies: real-require: 0.2.0 @@ -10263,24 +9443,22 @@ snapshots: tinyrainbow@3.0.3: {} - tldts-core@6.1.65: {} + tldts-core@6.1.86: {} - tldts-core@7.0.12: {} + tldts-core@7.0.19: {} - tldts@6.1.65: + tldts@6.1.86: dependencies: - tldts-core: 6.1.65 + tldts-core: 6.1.86 - tldts@7.0.12: + tldts@7.0.19: dependencies: - tldts-core: 7.0.12 + tldts-core: 7.0.19 tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 - to-fast-properties@2.0.0: {} - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -10289,17 +9467,17 @@ snapshots: toidentifier@1.0.1: {} - tough-cookie@5.0.0: + tough-cookie@5.1.2: dependencies: - tldts: 6.1.65 + tldts: 6.1.86 tough-cookie@6.0.0: dependencies: - tldts: 7.0.12 + tldts: 7.0.19 tr46@0.0.3: {} - tr46@5.0.0: + tr46@5.1.1: dependencies: punycode: 2.3.1 @@ -10307,37 +9485,36 @@ snapshots: tree-kill@1.2.2: {} - ts-api-utils@2.1.0(typescript@5.9.3): + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 ts-interface-checker@0.1.13: {} - tslib@2.6.2: {} + tslib@2.8.1: {} tsscmp@1.0.6: {} - tsup@8.5.1(@swc/core@1.13.5)(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.5.1): + tsup@8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.8.2): dependencies: - bundle-require: 5.1.0(esbuild@0.27.0) + bundle-require: 5.1.0(esbuild@0.27.2) cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 debug: 4.4.3 - esbuild: 0.27.0 + esbuild: 0.27.2 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(yaml@2.5.1) + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(yaml@2.8.2) resolve-from: 5.0.0 - rollup: 4.40.1 + rollup: 4.57.0 source-map: 0.7.6 - sucrase: 3.35.0 + sucrase: 3.35.1 tinyexec: 0.3.2 tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: - '@swc/core': 1.13.5 postcss: 8.5.6 typescript: 5.9.3 transitivePeerDependencies: @@ -10352,7 +9529,7 @@ snapshots: type-fest@0.21.3: {} - type-fest@5.2.0: + type-fest@5.4.2: dependencies: tagged-tag: 1.0.0 @@ -10365,47 +9542,48 @@ snapshots: dependencies: content-type: 1.0.5 media-typer: 1.1.0 - mime-types: 3.0.0 + mime-types: 3.0.2 - typed-array-buffer@1.0.2: + typed-array-buffer@1.0.3: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-typed-array: 1.1.13 + is-typed-array: 1.1.15 - typed-array-byte-length@1.0.1: + typed-array-byte-length@1.0.3: dependencies: - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 - is-typed-array: 1.1.13 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 - typed-array-byte-offset@1.0.2: + typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 - is-typed-array: 1.1.13 - - typed-array-length@1.0.6: - dependencies: - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 - is-typed-array: 1.1.13 - possible-typed-array-names: 1.0.0 - - typescript-eslint@8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@typescript-eslint/eslint-plugin': 8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.39.1(jiti@2.6.1) + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -10414,28 +9592,26 @@ snapshots: typical@4.0.0: {} - typical@7.1.1: {} + typical@7.3.0: {} - ufo@1.6.1: {} + ufo@1.6.3: {} - unbox-primitive@1.0.2: + unbox-primitive@1.1.0: dependencies: - call-bind: 1.0.7 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 - - undici-types@5.26.5: {} + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 undici-types@6.21.0: {} - undici-types@7.12.0: {} + undici-types@7.16.0: {} undici@5.28.4: dependencies: '@fastify/busboy': 2.1.1 - undici@7.16.0: {} + undici@7.19.2: {} unicorn-magic@0.1.0: {} @@ -10445,15 +9621,9 @@ snapshots: until-async@3.0.2: {} - update-browserslist-db@1.0.13(browserslist@4.23.0): + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: - browserslist: 4.23.0 - escalade: 3.1.2 - picocolors: 1.1.1 - - update-browserslist-db@1.1.1(browserslist@4.24.2): - dependencies: - browserslist: 4.24.2 + browserslist: 4.28.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -10461,26 +9631,31 @@ snapshots: dependencies: punycode: 2.3.1 - url-loader@4.1.1(webpack@5.96.1(@swc/core@1.13.5)(esbuild@0.27.0)): + url-loader@4.1.1(webpack@5.104.1(esbuild@0.27.2)): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.96.1(@swc/core@1.13.5)(esbuild@0.27.0) + webpack: 5.104.1(esbuild@0.27.2) urlpattern-polyfill@4.0.3: {} util-deprecate@1.0.2: {} - util.promisify@1.1.2: + util.promisify@1.1.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 define-properties: 1.2.1 - for-each: 0.3.3 - has-proto: 1.0.3 - has-symbols: 1.0.3 - object.getownpropertydescriptors: 2.1.8 - safe-array-concat: 1.1.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + for-each: 0.3.5 + get-intrinsic: 1.3.0 + has-proto: 1.2.0 + has-symbols: 1.1.0 + object.getownpropertydescriptors: 2.1.9 + safe-array-concat: 1.1.3 utils-merge@1.0.1: {} @@ -10492,58 +9667,57 @@ snapshots: vary@1.1.2: {} - vite@7.2.4(@types/node@20.19.25)(jiti@2.6.1)(terser@5.30.1)(yaml@2.5.1): + vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2): dependencies: - esbuild: 0.25.3 + esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.53.3 + rollup: 4.57.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.19.25 + '@types/node': 20.19.30 fsevents: 2.3.3 jiti: 2.6.1 - terser: 5.30.1 - yaml: 2.5.1 + terser: 5.46.0 + yaml: 2.8.2 - vitest-environment-miniflare@2.14.4(vitest@4.0.13(@types/debug@4.1.12)(@types/node@20.19.25)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.30.1)(yaml@2.5.1)): + vitest-environment-miniflare@2.14.4(vitest@4.0.18(@types/node@20.19.30)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.46.0)(yaml@2.8.2)): dependencies: '@miniflare/queues': 2.14.4 '@miniflare/runner-vm': 2.14.4 '@miniflare/shared': 2.14.4 '@miniflare/shared-test-environment': 2.14.4 undici: 5.28.4 - vitest: 4.0.13(@types/debug@4.1.12)(@types/node@20.19.25)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.30.1)(yaml@2.5.1) + vitest: 4.0.18(@types/node@20.19.30)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.46.0)(yaml@2.8.2) transitivePeerDependencies: - bufferutil - utf-8-validate - vitest@4.0.13(@types/debug@4.1.12)(@types/node@20.19.25)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.30.1)(yaml@2.5.1): + vitest@4.0.18(@types/node@20.19.30)(jiti@2.6.1)(jsdom@25.0.1)(msw@)(terser@5.46.0)(yaml@2.8.2): dependencies: - '@vitest/expect': 4.0.13 - '@vitest/mocker': 4.0.13(msw@)(vite@7.2.4(@types/node@20.19.25)(jiti@2.6.1)(terser@5.30.1)(yaml@2.5.1)) - '@vitest/pretty-format': 4.0.13 - '@vitest/runner': 4.0.13 - '@vitest/snapshot': 4.0.13 - '@vitest/spy': 4.0.13 - '@vitest/utils': 4.0.13 - debug: 4.4.3 + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(msw@)(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 es-module-lexer: 1.7.0 - expect-type: 1.2.2 + expect-type: 1.3.0 magic-string: 0.30.21 + obug: 2.1.1 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.10.0 tinybench: 2.9.0 - tinyexec: 0.3.2 + tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.2.4(@types/node@20.19.25)(jiti@2.6.1)(terser@5.30.1)(yaml@2.5.1) + vite: 7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/debug': 4.1.12 - '@types/node': 20.19.25 + '@types/node': 20.19.30 jsdom: 25.0.1 transitivePeerDependencies: - jiti @@ -10554,7 +9728,6 @@ snapshots: - sass-embedded - stylus - sugarss - - supports-color - terser - tsx - yaml @@ -10565,7 +9738,7 @@ snapshots: walk-up-path@4.0.0: {} - watchpack@2.4.1: + watchpack@2.5.1: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -10578,15 +9751,15 @@ snapshots: webidl-conversions@7.0.0: {} - webpack-http-server@0.5.0(@swc/core@1.13.5)(esbuild@0.27.0): + webpack-http-server@0.5.0(esbuild@0.27.2): dependencies: - '@types/express': 4.17.21 - '@types/mustache': 4.2.5 - express: 4.19.2 + '@types/express': 4.17.25 + '@types/mustache': 4.2.6 + express: 4.22.1 memfs: 3.5.3 mustache: 4.2.0 outvariant: 1.4.3 - webpack: 5.96.1(@swc/core@1.13.5)(esbuild@0.27.0) + webpack: 5.104.1(esbuild@0.27.2) transitivePeerDependencies: - '@swc/core' - esbuild @@ -10605,33 +9778,35 @@ snapshots: source-list-map: 2.0.1 source-map: 0.6.1 - webpack-sources@3.2.3: {} + webpack-sources@3.3.3: {} - webpack@5.96.1(@swc/core@1.13.5)(esbuild@0.27.0): + webpack@5.104.1(esbuild@0.27.2): dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.6 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.14.0 - browserslist: 4.24.2 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.17.1 - es-module-lexer: 1.5.0 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.28.1 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.4 + es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 + loader-runner: 4.3.1 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.13.5)(esbuild@0.27.0)(webpack@5.96.1(@swc/core@1.13.5)(esbuild@0.27.0)) - watchpack: 2.4.1 - webpack-sources: 3.2.3 + schema-utils: 4.3.3 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.16(esbuild@0.27.2)(webpack@5.104.1(esbuild@0.27.2)) + watchpack: 2.5.1 + webpack-sources: 3.3.3 transitivePeerDependencies: - '@swc/core' - esbuild @@ -10643,9 +9818,9 @@ snapshots: whatwg-mimetype@4.0.0: {} - whatwg-url@14.0.0: + whatwg-url@14.2.0: dependencies: - tr46: 5.0.0 + tr46: 5.1.1 webidl-conversions: 7.0.0 whatwg-url@5.0.0: @@ -10653,20 +9828,45 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 - which-boxed-primitive@1.0.2: + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 - which-typed-array@1.1.15: + which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.0.1 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 has-tostringtag: 1.0.2 which@1.3.1: @@ -10686,7 +9886,7 @@ snapshots: word-wrap@1.2.5: {} - wordwrapjs@5.1.0: {} + wordwrapjs@5.1.1: {} wrap-ansi@6.2.0: dependencies: @@ -10700,28 +9900,20 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@8.1.0: + wrap-ansi@9.0.2: dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrap-ansi@9.0.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 7.1.0 - strip-ansi: 7.1.0 + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.1.2 wrappy@1.0.2: {} ws@7.5.10: {} - ws@8.11.0: {} - - ws@8.18.0: {} - ws@8.18.3: {} + ws@8.19.0: {} + xml-name-validator@5.0.0: {} xmlchars@2.2.0: {} @@ -10732,9 +9924,7 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} - - yaml@2.5.1: {} + yaml@2.8.2: {} yargs-parser@10.1.0: dependencies: @@ -10747,7 +9937,7 @@ snapshots: yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -10769,6 +9959,6 @@ snapshots: yocto-queue@1.2.2: {} - yoctocolors-cjs@2.1.2: {} + yoctocolors-cjs@2.1.3: {} - zod@4.1.12: {} + zod@4.3.6: {} diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 404a9ef59..25211cfc2 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -1,11 +1,7 @@ import { invariant } from 'outvariant' import { isNodeProcess } from 'is-node-process' import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' -import { - defineNetwork, - NetworkApi, - NetworkHandlersApi, -} from '#core/new/define-network' +import { defineNetwork, NetworkHandlersApi } from '#core/new/define-network' import { type AnyHandler } from '#core/new/handlers-controller' import { InterceptorSource } from '#core/new/sources/interceptor-source' import { type UnhandledRequestStrategy } from '#core/utils/request/onUnhandledRequest' @@ -40,8 +36,6 @@ const DEFAULT_WORKER_URL = '/mockServiceWorker.js' * @see {@link https://mswjs.io/docs/api/setup-worker `setupWorker()` API reference} */ export function setupWorker(...handlers: Array): SetupWorkerApi { - let network: NetworkApi<[ServiceWorkerSource]> - invariant( !isNodeProcess(), devUtils.formatMessage( @@ -49,6 +43,13 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { ), ) + const network = defineNetwork< + Array + >({ + sources: [], + handlers, + }) + return { async start(options) { const httpSource = supportsServiceWorker() @@ -62,14 +63,13 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { }) : new FallbackHttpSource() - network = defineNetwork({ + network.configure({ sources: [ httpSource, new InterceptorSource({ interceptors: [new WebSocketInterceptor() as any], }), ], - handlers, onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { return options?.onUnhandledRequest || 'warn' }), diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index a94ce0e54..d3915cf7d 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -41,7 +41,7 @@ type ResponseEvent = Emitter.EventType< export class ServiceWorkerSource extends NetworkSource { #frames: Map #channel: WorkerChannel - #workerPromise: DeferredPromise + #workerPromise: DeferredPromise<[ServiceWorker, ServiceWorkerRegistration]> #keepAliveInterval?: number #stoppedAt?: number @@ -56,7 +56,7 @@ export class ServiceWorkerSource extends NetworkSource worker), }) } @@ -64,7 +64,11 @@ export class ServiceWorkerSource extends NetworkSource registration) } const [worker, registration] = await this.#startWorker() @@ -94,7 +98,6 @@ export class ServiceWorkerSource extends NetworkSource { await super.disable() - this.#frames.clear() this.#stoppedAt = Date.now() + this.#frames.clear() this.#channel.removeAllListeners() + this.#workerPromise = new DeferredPromise() this.#printStopMessage() } @@ -131,17 +135,17 @@ export class ServiceWorkerSource extends NetworkSource>> - extends NetworkHandlersApi { +export interface NetworkApi< + Sources extends Array>, +> extends NetworkHandlersApi { enable: () => Promise disable: () => Promise + configure: (options: Partial>) => void events: Emitter> } @@ -55,27 +57,37 @@ export function defineNetwork>>( ): NetworkApi { const events = new Emitter>() - const handlersController = - options.handlers instanceof HandlersController - ? options.handlers - : new InMemoryHandlersController(options.handlers || []) + let handlersController: HandlersController + + const deriveHandlersController = ( + handlers: DefineNetworkOptions['handlers'], + ) => { + return handlers instanceof HandlersController + ? handlers + : new InMemoryHandlersController(handlers || []) + } + + let resolvedOptions: DefineNetworkOptions = { + ...options, + } return { events, + configure(options) { + resolvedOptions = { + ...resolvedOptions, + ...options, + } + }, async enable() { + handlersController = deriveHandlersController(resolvedOptions.handlers) + await Promise.all( - options.sources.map(async (source) => { + resolvedOptions.sources.map(async (source) => { source.on( 'frame', async ({ data: frame }: { data: AnyNetworkFrame }) => { - /** - * @fixme This typeless listener makes it so all emits are treated as - * having a listener. That makes it hard for the library to know whether - * the user has actually defined any listeners. - */ - frame.events.on((event) => { - events.emit(event) - }) + frame.events.on('*', (event) => events.emit(event)) /** * @fixme Handler filtering on each frame is expensive. @@ -94,13 +106,13 @@ export function defineNetwork>>( const isHandledFrame = await frame.resolve( handlers, - options.context, + resolvedOptions.context, ) if (isHandledFrame === false) { await onUnhandledFrame( frame, - options.onUnhandledFrame || 'warn', + resolvedOptions.onUnhandledFrame || 'warn', ).catch((error) => { frame.errorWith(error) }) @@ -114,7 +126,7 @@ export function defineNetwork>>( }, async disable() { await Promise.all( - options.sources.map(async (source) => { + resolvedOptions.sources.map(async (source) => { await source.disable() }), ) diff --git a/src/core/new/frames/http-frame.ts b/src/core/new/frames/http-frame.ts index d26acd673..ada5eef66 100644 --- a/src/core/new/frames/http-frame.ts +++ b/src/core/new/frames/http-frame.ts @@ -160,7 +160,12 @@ export abstract class HttpNetworkFrame extends NetworkFrame< ) ) { // Surface the error to the developer since they haven't handled it. - devUtils.error('HAH!') + console.error(lookupError) + devUtils.error( + 'Encountered an unhandled exception during the handler lookup for "%s %s". Please see the original error above.', + request.method, + request.url, + ) } this.errorWith(lookupError) diff --git a/test/browser/msw-api/setup-worker/start/start.test.ts b/test/browser/msw-api/setup-worker/start/start.test.ts index bc3f90845..8ffb83691 100644 --- a/test/browser/msw-api/setup-worker/start/start.test.ts +++ b/test/browser/msw-api/setup-worker/start/start.test.ts @@ -93,7 +93,7 @@ test('prints the start message when the worker has been registered', async ({ ) }) -test('prints a warning if "worker.start()" is called multiple times', async ({ +test.only('prints a warning if "worker.start()" is called multiple times', async ({ loadExample, spyOnConsole, page, From 9ce2912f22ef9a5c73a688c129796429f202a93a Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 28 Jan 2026 17:31:37 +0100 Subject: [PATCH 26/68] chore: fix signature overload type error by updating `rettime` --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- test/typings/define-network.test-d.ts | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index d38638067..a02769a9a 100644 --- a/package.json +++ b/package.json @@ -248,7 +248,7 @@ "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", - "rettime": "^0.9.1", + "rettime": "^0.10.1", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 16ca44d07..bc5f80ff9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,8 +42,8 @@ importers: specifier: ^1.1.1 version: 1.1.1 rettime: - specifier: ^0.9.1 - version: 0.9.1 + specifier: ^0.10.1 + version: 0.10.1 statuses: specifier: ^2.0.2 version: 2.0.2 @@ -3900,8 +3900,8 @@ packages: resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} engines: {node: '>=10'} - rettime@0.9.1: - resolution: {integrity: sha512-UszoaHy8mQkQZCbEYjw+J21ZZ+VhiTAYK47Tl+wm8VSbTRronhJiheSNlRo0ED/6zUG9vbIY7gRu7ZfColdVnw==} + rettime@0.10.1: + resolution: {integrity: sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw==} reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} @@ -8932,7 +8932,7 @@ snapshots: ret@0.5.0: {} - rettime@0.9.1: {} + rettime@0.10.1: {} reusify@1.1.0: {} diff --git a/test/typings/define-network.test-d.ts b/test/typings/define-network.test-d.ts index 3113bd533..a9fa25af6 100644 --- a/test/typings/define-network.test-d.ts +++ b/test/typings/define-network.test-d.ts @@ -20,7 +20,7 @@ it('infers event map type from a single source', () => { defineNetwork({ sources: [new HttpSource()], - }).events.on((event) => { + }).events.on('*', (event) => { expectTypeOf(event.type).toExtend<'hello'>() expectTypeOf(event.data).toExtend<'world'>() expectTypeOf(event.data).not.toBeAny() @@ -40,7 +40,7 @@ it('combines event maps from different sources', () => { defineNetwork({ sources: [new HttpSource(), new SmtpSource()], - }).events.on((event) => { + }).events.on('*', (event) => { expectTypeOf(event.type).toExtend<'hello' | 'goodbye'>() expectTypeOf(event.data).toExtend<'world' | 'cosmos'>() expectTypeOf(event.data).not.toBeAny() From a5e09f2af185024590c82ea8c9a6bab5bc727c93 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 28 Jan 2026 17:36:00 +0100 Subject: [PATCH 27/68] chore: fix formatting issues --- src/browser/utils/workerChannel.ts | 27 +++++++++++++-------------- src/core/ws/WebSocketClientManager.ts | 4 +--- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/browser/utils/workerChannel.ts b/src/browser/utils/workerChannel.ts index 7b39f7114..c9987a459 100644 --- a/src/browser/utils/workerChannel.ts +++ b/src/browser/utils/workerChannel.ts @@ -27,20 +27,19 @@ export type WorkerChannelEventMap = { /** * Request representation received from the worker message event. */ -export interface IncomingWorkerRequest - extends Omit< - Request, - | 'text' - | 'body' - | 'json' - | 'blob' - | 'arrayBuffer' - | 'formData' - | 'clone' - | 'signal' - | 'isHistoryNavigation' - | 'isReloadNavigation' - > { +export interface IncomingWorkerRequest extends Omit< + Request, + | 'text' + | 'body' + | 'json' + | 'blob' + | 'arrayBuffer' + | 'formData' + | 'clone' + | 'signal' + | 'isHistoryNavigation' + | 'isReloadNavigation' +> { /** * Unique ID of the request generated once the request is * intercepted by the "fetch" event in the Service Worker. diff --git a/src/core/ws/WebSocketClientManager.ts b/src/core/ws/WebSocketClientManager.ts index 760e4a335..09d888b43 100644 --- a/src/core/ws/WebSocketClientManager.ts +++ b/src/core/ws/WebSocketClientManager.ts @@ -183,9 +183,7 @@ export class WebSocketClientManager { * on the given `BroadcastChannel` to communicate instructions * with the client connections from other runtimes. */ -export class WebSocketRemoteClientConnection - implements WebSocketClientConnectionProtocol -{ +export class WebSocketRemoteClientConnection implements WebSocketClientConnectionProtocol { constructor( public readonly id: string, public readonly url: URL, From e289a7b020ef9dbf83591acade844cc2be6f4c81 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 28 Jan 2026 17:39:51 +0100 Subject: [PATCH 28/68] fix(defineNetwork): create handlers controller immediately --- src/core/new/define-network.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index dce7deb24..61efa3867 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -57,8 +57,6 @@ export function defineNetwork>>( ): NetworkApi { const events = new Emitter>() - let handlersController: HandlersController - const deriveHandlersController = ( handlers: DefineNetworkOptions['handlers'], ) => { @@ -71,17 +69,28 @@ export function defineNetwork>>( ...options, } + /** + * @note Create the handlers controller immediately because + * certain setup API, like `setupServer`, don't await `.enable` (`.listen`). + */ + let handlersController = deriveHandlersController(resolvedOptions.handlers) + return { events, configure(options) { + if ( + options.handlers && + !Object.is(options.handlers, resolvedOptions.handlers) + ) { + handlersController = deriveHandlersController(options.handlers) + } + resolvedOptions = { ...resolvedOptions, ...options, } }, async enable() { - handlersController = deriveHandlersController(resolvedOptions.handlers) - await Promise.all( resolvedOptions.sources.map(async (source) => { source.on( From 4b26dbf4b6a70aea1b3dece79ad030b1e5d40d1b Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 28 Jan 2026 17:58:25 +0100 Subject: [PATCH 29/68] fix(setupWorker): print start message in `start`, add redundant start check --- src/browser/setup-worker.ts | 14 ++++++++++ src/browser/sources/fallback-http-source.ts | 7 +---- src/browser/sources/service-worker-source.ts | 27 +++++++++++-------- .../msw-api/setup-worker/start/start.test.ts | 2 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 25211cfc2..dc144d594 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -43,6 +43,7 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { ), ) + let hasStarted = false const network = defineNetwork< Array >({ @@ -52,6 +53,17 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { return { async start(options) { + /** + * @todo @fixme + * This is kept for backward-compatibility reasons. We don't really need this check anymore. + */ + if (hasStarted) { + devUtils.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 + } + const httpSource = supportsServiceWorker() ? new ServiceWorkerSource({ serviceWorker: { @@ -79,6 +91,8 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { }) await network.enable() + await httpSource.printStartMessage() + hasStarted = true }, stop() { network.disable() diff --git a/src/browser/sources/fallback-http-source.ts b/src/browser/sources/fallback-http-source.ts index 3dc11791d..c469e709a 100644 --- a/src/browser/sources/fallback-http-source.ts +++ b/src/browser/sources/fallback-http-source.ts @@ -10,12 +10,7 @@ export class FallbackHttpSource extends InterceptorSource { }) } - public async enable(): Promise { - await super.enable() - this.#printStartMessage() - } - - #printStartMessage(): void { + public printStartMessage(): void { console.groupCollapsed( `%c${devUtils.formatMessage('Mocking enabled (fallback mode).')}`, 'color:orangered;font-weight:bold;', diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index d3915cf7d..8f9574732 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -38,10 +38,14 @@ type ResponseEvent = Emitter.EventType< WorkerChannelEventMap > +type WorkerChannelClient = + WorkerChannelEventMap['MOCKING_ENABLED']['data']['client'] + export class ServiceWorkerSource extends NetworkSource { #frames: Map #channel: WorkerChannel #workerPromise: DeferredPromise<[ServiceWorker, ServiceWorkerRegistration]> + #clientPromise?: Promise #keepAliveInterval?: number #stoppedAt?: number @@ -93,15 +97,13 @@ export class ServiceWorkerSource extends NetworkSource() - this.#channel.once('MOCKING_ENABLED', async (event) => { - confirmationPromise.resolve() + const clientConfirmationPromise = new DeferredPromise() + this.#clientPromise = clientConfirmationPromise - this.#printStartMessage({ - client: event.data.client, - }) + this.#channel.once('MOCKING_ENABLED', (event) => { + clientConfirmationPromise.resolve(event.data.client) }) - await confirmationPromise + await clientConfirmationPromise return registration } @@ -277,14 +279,17 @@ Please consider using a custom "serviceWorker.url" option to point to the actual return integrityCheckPromise } - async #printStartMessage(args: { - client: WorkerChannelEventMap['MOCKING_ENABLED']['data']['client'] - }) { + public async printStartMessage() { if (this.options.quiet || this.#workerPromise.state === 'rejected') { return } - const { client } = args + invariant( + this.#clientPromise != null, + '[ServiceWorkerSource] Failed to print a start message: client confirmation not received', + ) + + const client = await this.#clientPromise const [worker, registration] = await this.#workerPromise console.groupCollapsed( diff --git a/test/browser/msw-api/setup-worker/start/start.test.ts b/test/browser/msw-api/setup-worker/start/start.test.ts index 8ffb83691..bc3f90845 100644 --- a/test/browser/msw-api/setup-worker/start/start.test.ts +++ b/test/browser/msw-api/setup-worker/start/start.test.ts @@ -93,7 +93,7 @@ test('prints the start message when the worker has been registered', async ({ ) }) -test.only('prints a warning if "worker.start()" is called multiple times', async ({ +test('prints a warning if "worker.start()" is called multiple times', async ({ loadExample, spyOnConsole, page, From 8a8c12119f0015b64b9a08dc30bb7564087c4e64 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 2 Feb 2026 11:36:10 +0100 Subject: [PATCH 30/68] fix(setupWorker): skip the start message in quiet mode --- src/browser/setup-worker.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index dc144d594..3492566cf 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -91,8 +91,11 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { }) await network.enable() - await httpSource.printStartMessage() hasStarted = true + + if (!options?.quiet) { + await httpSource.printStartMessage() + } }, stop() { network.disable() From 4255969ca2e396077bfbf1c7ad3e6151e4d033dc Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 4 Feb 2026 16:56:36 +0100 Subject: [PATCH 31/68] test: remove `not.toBeAny` assertions from `define-network` tests --- test/typings/define-network.test-d.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/typings/define-network.test-d.ts b/test/typings/define-network.test-d.ts index a9fa25af6..7cf8768a7 100644 --- a/test/typings/define-network.test-d.ts +++ b/test/typings/define-network.test-d.ts @@ -23,7 +23,6 @@ it('infers event map type from a single source', () => { }).events.on('*', (event) => { expectTypeOf(event.type).toExtend<'hello'>() expectTypeOf(event.data).toExtend<'world'>() - expectTypeOf(event.data).not.toBeAny() }) }) @@ -43,6 +42,5 @@ it('combines event maps from different sources', () => { }).events.on('*', (event) => { expectTypeOf(event.type).toExtend<'hello' | 'goodbye'>() expectTypeOf(event.data).toExtend<'world' | 'cosmos'>() - expectTypeOf(event.data).not.toBeAny() }) }) From 29032f36c4b0bfa09218975cca8a1c852725280e Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 4 Feb 2026 19:14:21 +0100 Subject: [PATCH 32/68] feat(handlers): store handlers as a kind-based map --- src/core/handlers/RequestHandler.ts | 19 +- src/core/handlers/WebSocketHandler.ts | 5 +- src/core/handlers/common.ts | 1 - src/core/new/define-network.ts | 30 +-- src/core/new/frames/network-frame.ts | 2 +- src/core/new/handlers-controller.test.ts | 178 ++++++++++++++++++ src/core/new/handlers-controller.ts | 120 +++++++++--- src/core/new/sources/network-source.ts | 23 +++ src/core/utils/internal/isHandlerKind.test.ts | 42 ++--- src/core/utils/internal/isHandlerKind.ts | 14 +- src/core/ws/handleWebSocketEvent.ts | 6 +- src/node/async-handlers-controller.ts | 62 ++++-- src/node/setup-server.ts | 13 +- .../setup-server/listHandlers.node.test.ts | 2 +- .../msw-api/setup-server/use.node.test.ts | 2 + 15 files changed, 404 insertions(+), 115 deletions(-) delete mode 100644 src/core/handlers/common.ts create mode 100644 src/core/new/handlers-controller.test.ts diff --git a/src/core/handlers/RequestHandler.ts b/src/core/handlers/RequestHandler.ts index bc240ebbc..400c4c691 100644 --- a/src/core/handlers/RequestHandler.ts +++ b/src/core/handlers/RequestHandler.ts @@ -11,7 +11,6 @@ import { HttpResponse, DefaultUnsafeFetchResponse, } from '../HttpResponse' -import type { HandlerKind } from './common' import type { GraphQLRequestBody } from './GraphQLHandler' export type DefaultRequestMultipartBody = Record< @@ -133,14 +132,7 @@ export abstract class RequestHandler< StrictRequest >() - private readonly __kind: HandlerKind - - public info: HandlerInfo & RequestHandlerInternalInfo - /** - * Indicates whether this request handler has been used - * (its resolver has successfully executed). - */ - public isUsed: boolean + public kind = 'request' as const protected resolver: ResponseResolver private resolverIterator?: @@ -157,6 +149,14 @@ export abstract class RequestHandler< private resolverIteratorResult?: Response | HttpResponse private options?: HandlerOptions + public info: HandlerInfo & RequestHandlerInternalInfo + + /** + * Indicates whether this request handler has been used + * (its resolver has successfully executed). + */ + public isUsed: boolean + constructor(args: RequestHandlerArgs) { this.resolver = args.resolver this.options = args.options @@ -169,7 +169,6 @@ export abstract class RequestHandler< } this.isUsed = false - this.__kind = 'RequestHandler' } /** diff --git a/src/core/handlers/WebSocketHandler.ts b/src/core/handlers/WebSocketHandler.ts index ebceda3b7..2b4398595 100644 --- a/src/core/handlers/WebSocketHandler.ts +++ b/src/core/handlers/WebSocketHandler.ts @@ -12,7 +12,6 @@ import { matchRequestUrl, } from '../utils/matching/matchRequestUrl' import { getCallFrame } from '../utils/internal/getCallFrame' -import type { HandlerKind } from './common' import { attachWebSocketLogger } from '../ws/utils/attachWebSocketLogger' type WebSocketHandlerParsedResult = { @@ -40,10 +39,9 @@ const kStopPropagationPatched = Symbol('kStopPropagationPatched') const KOnStopPropagation = Symbol('KOnStopPropagation') export class WebSocketHandler { - private readonly __kind: HandlerKind - public id: string public callFrame?: string + public kind = 'websocket' as const protected [kEmitter]: Emitter @@ -52,7 +50,6 @@ export class WebSocketHandler { this[kEmitter] = new Emitter() this.callFrame = getCallFrame(new Error()) - this.__kind = 'EventHandler' } public parse(args: { diff --git a/src/core/handlers/common.ts b/src/core/handlers/common.ts deleted file mode 100644 index ef0d1018a..000000000 --- a/src/core/handlers/common.ts +++ /dev/null @@ -1 +0,0 @@ -export type HandlerKind = 'RequestHandler' | 'EventHandler' diff --git a/src/core/new/define-network.ts b/src/core/new/define-network.ts index 61efa3867..9669c5fd4 100644 --- a/src/core/new/define-network.ts +++ b/src/core/new/define-network.ts @@ -3,10 +3,10 @@ import { type NetworkSource, type ExtractSourceEvents, type AnyNetworkFrame, + getHandlerKindByFrame, } from './sources/network-source' import { type NetworkFrameResolutionContext } from './frames/network-frame' import { onUnhandledFrame, UnhandledFrameHandle } from './on-unhandled-frame' -import { isHandlerKind } from '../utils/internal/isHandlerKind' import { AnyHandler, HandlersController, @@ -36,9 +36,8 @@ export interface DefineNetworkOptions< onUnhandledFrame?: UnhandledFrameHandle } -export interface NetworkApi< - Sources extends Array>, -> extends NetworkHandlersApi { +export interface NetworkApi>> + extends NetworkHandlersApi { enable: () => Promise disable: () => Promise configure: (options: Partial>) => void @@ -98,23 +97,12 @@ export function defineNetwork>>( async ({ data: frame }: { data: AnyNetworkFrame }) => { frame.events.on('*', (event) => events.emit(event)) - /** - * @fixme Handler filtering on each frame is expensive. - * Refactor the way we store handlers into a Map>. - */ - const handlerPredicate = - frame.protocol === 'http' - ? isHandlerKind('RequestHandler') - : frame.protocol === 'ws' - ? isHandlerKind('EventHandler') - : () => false - - const handlers = - handlersController.currentHandlers.filter(handlerPredicate) || - [] + const matchingHandlers = handlersController.getHandlersByKind( + getHandlerKindByFrame(frame), + ) const isHandledFrame = await frame.resolve( - handlers, + matchingHandlers, resolvedOptions.context, ) @@ -135,9 +123,7 @@ export function defineNetwork>>( }, async disable() { await Promise.all( - resolvedOptions.sources.map(async (source) => { - await source.disable() - }), + resolvedOptions.sources.map((source) => source.disable()), ) }, use(...handlers) { diff --git a/src/core/new/frames/network-frame.ts b/src/core/new/frames/network-frame.ts index 73cd9bf6a..878deb06f 100644 --- a/src/core/new/frames/network-frame.ts +++ b/src/core/new/frames/network-frame.ts @@ -1,5 +1,5 @@ import { Emitter, type DefaultEventMap } from 'rettime' -import { type AnyHandler } from '../handlers-controller' +import type { AnyHandler } from '../handlers-controller' export type ExtractFrameEvents = Frame extends NetworkFrame ? Events : never diff --git a/src/core/new/handlers-controller.test.ts b/src/core/new/handlers-controller.test.ts new file mode 100644 index 000000000..2da78ed7f --- /dev/null +++ b/src/core/new/handlers-controller.test.ts @@ -0,0 +1,178 @@ +import { http } from '../http' +import { graphql } from '../graphql' +import { ws } from '../ws' +import { InMemoryHandlersController } from './handlers-controller' + +describe(InMemoryHandlersController.prototype.use, () => { + it('prepends a handler to an empty controller', () => { + const controller = new InMemoryHandlersController([]) + const httpHandler = http.get('/', () => {}) + controller.use([httpHandler]) + + expect(controller.currentHandlers).toEqual([httpHandler]) + expect(controller.getHandlersByKind('request')).toEqual([httpHandler]) + }) + + it('prepends a single handler', () => { + const httpOne = http.get('/', () => {}) + const httpTwo = http.get('/', () => {}) + + const controller = new InMemoryHandlersController([httpOne]) + controller.use([httpTwo]) + + expect(controller.currentHandlers).toEqual([httpTwo, httpOne]) + expect(controller.getHandlersByKind('request')).toEqual([httpTwo, httpOne]) + }) + + it('prepends multiple handlers', () => { + const httpOne = http.get('/', () => {}) + const httpTwo = http.get('/', () => {}) + const httpThree = http.get('/', () => {}) + + const controller = new InMemoryHandlersController([httpOne]) + + controller.use([httpTwo, httpThree]) + + expect(controller.currentHandlers).toEqual([httpTwo, httpThree, httpOne]) + expect(controller.getHandlersByKind('request')).toEqual([ + httpTwo, + httpThree, + httpOne, + ]) + }) + + it('preserves order of handlers', () => { + const httpOne = http.get('/', () => {}) + const graphqlOne = graphql.query('', () => {}) + const httpTwo = http.get('/', () => {}) + + const controller = new InMemoryHandlersController([httpOne]) + controller.use([graphqlOne, httpTwo]) + + expect(controller.currentHandlers).toEqual([graphqlOne, httpTwo, httpOne]) + }) +}) + +describe(InMemoryHandlersController.prototype.reset, () => { + it('resets to the initial handlers if called with an empty list', () => { + { + const controller = new InMemoryHandlersController([]) + controller.reset([]) + expect(controller.currentHandlers).toEqual([]) + } + + { + const httpHandler = http.get('/', () => {}) + const controller = new InMemoryHandlersController([httpHandler]) + controller.reset([]) + expect(controller.currentHandlers).toEqual([httpHandler]) + } + }) + + it('replaces the initial handlers if called with a list of handlers', () => { + const httpOne = http.get('/', () => {}) + const httpTwo = http.get('/', () => {}) + const controller = new InMemoryHandlersController([httpOne]) + controller.reset([httpTwo]) + expect(controller.currentHandlers).toEqual([httpTwo]) + }) +}) + +describe(InMemoryHandlersController.prototype.getHandlersByKind, () => { + it('returns an empty array given an empty controller', () => { + const controller = new InMemoryHandlersController([]) + expect(controller.getHandlersByKind('request')).toEqual([]) + }) + + it('returns an empty array given no handlers by the given kind', () => { + expect( + new InMemoryHandlersController([ + http.get('/', () => {}), + graphql.query('', () => {}), + ]).getHandlersByKind('websocket'), + ).toEqual([]) + + expect( + new InMemoryHandlersController([ + ws.link('*').addEventListener('connection', () => {}), + ]).getHandlersByKind('request'), + ).toEqual([]) + }) + + it('returns all handlers if they all match', () => { + const httpHandler = http.get('/', () => {}) + const graphqlHandler = graphql.query('', () => {}) + const wsHandler = ws.link('*').addEventListener('connection', () => {}) + + expect( + new InMemoryHandlersController([ + httpHandler, + graphqlHandler, + ]).getHandlersByKind('request'), + ).toEqual([httpHandler, graphqlHandler]) + + expect( + new InMemoryHandlersController([wsHandler]).getHandlersByKind( + 'websocket', + ), + ).toEqual([wsHandler]) + }) + + it('returns only the matching handlers', () => { + const httpHandler = http.get('/', () => {}) + const graphqlHandler = graphql.query('', () => {}) + const wsHandler = ws.link('*').addEventListener('connection', () => {}) + + expect( + new InMemoryHandlersController([ + httpHandler, + graphqlHandler, + wsHandler, + ]).getHandlersByKind('request'), + ).toEqual([httpHandler, graphqlHandler]) + + expect( + new InMemoryHandlersController([ + httpHandler, + graphqlHandler, + wsHandler, + ]).getHandlersByKind('websocket'), + ).toEqual([wsHandler]) + }) + + it('preserves the order of returned handlers', () => { + const httpOne = http.get('/', () => {}) + const httpTwo = http.get('/', () => {}) + const httpThree = http.get('/', () => {}) + + expect( + new InMemoryHandlersController([ + httpOne, + httpTwo, + httpThree, + ]).getHandlersByKind('request'), + ).toEqual([httpOne, httpTwo, httpThree]) + + const graphqlOne = graphql.query('', () => {}) + const graphqlTwo = graphql.query('', () => {}) + const graphqlThree = graphql.query('', () => {}) + + expect( + new InMemoryHandlersController([ + graphqlOne, + graphqlTwo, + graphqlThree, + ]).getHandlersByKind('request'), + ).toEqual([graphqlOne, graphqlTwo, graphqlThree]) + + const wsOne = ws.link('*').addEventListener('connection', () => {}) + const wsTwo = ws.link('*').addEventListener('connection', () => {}) + const wsThree = ws.link('*').addEventListener('connection', () => {}) + + expect( + new InMemoryHandlersController([wsOne, wsTwo, wsThree]).getHandlersByKind( + 'websocket', + ), + ).toEqual([wsOne, wsTwo, wsThree]) + }) +}) diff --git a/src/core/new/handlers-controller.ts b/src/core/new/handlers-controller.ts index 41b006022..0176b31fc 100644 --- a/src/core/new/handlers-controller.ts +++ b/src/core/new/handlers-controller.ts @@ -5,65 +5,141 @@ import { type WebSocketHandler } from '../handlers/WebSocketHandler' import { devUtils } from '../utils/internal/devUtils' export type AnyHandler = HttpHandler | GraphQLHandler | WebSocketHandler +export type HandlersMap = Partial>> -function validateHandlers(handlers: Array): boolean { - return handlers.every((handler) => !Array.isArray(handler)) +export function groupHandlersByKind(handlers: Array): HandlersMap { + const groups: HandlersMap = {} + + /** + * @note `Object.groupBy` is not implemented in Node.js v20. + */ + for (const handler of handlers) { + ;(groups[handler.kind] ||= []).push(handler) + } + + return groups +} + +export interface HandlersControllerState { + initialHandlers: HandlersMap + handlers: HandlersMap } export abstract class HandlersController { - constructor(initialHandlers: Array) { + protected getInitialState( + initialHandlers: Array, + ): HandlersControllerState { invariant( - validateHandlers(initialHandlers), + this.#validateHandlers(initialHandlers), devUtils.formatMessage( '[MSW] Failed to apply given request handlers: invalid input. Did you forget to spread the request handlers Array?', ), ) + + const normalizedInitialHandlers = groupHandlersByKind(initialHandlers) + + return { + initialHandlers: normalizedInitialHandlers, + handlers: { ...normalizedInitialHandlers }, + } + } + + protected abstract getState(): HandlersControllerState + protected abstract setState(nextState: Partial): void + + public get currentHandlers(): Array { + return Object.values(this.getState().handlers) + .flat() + .filter((handler) => handler != null) } - public abstract get currentHandlers(): Array + public getHandlersByKind(kind: AnyHandler['kind']): Array { + return this.getState().handlers[kind] || [] + } public use(nextHandlers: Array): void { invariant( - validateHandlers(nextHandlers), + this.#validateHandlers(nextHandlers), devUtils.formatMessage( '[MSW] Failed to call "use()" with the given request handlers: invalid input. Did you forget to spread the array of request handlers?', ), ) + + if (nextHandlers.length === 0) { + return + } + + const { handlers } = this.getState() + + // Iterate over next handlers and prepend them to their respective lists. + // Iterate in a reverse order to the keep the order of the runtime handlers as provided. + for (let i = nextHandlers.length - 1; i >= 0; i--) { + const handler = nextHandlers[i] + handlers[handler.kind] = handlers[handler.kind] + ? [handler, ...handlers[handler.kind]!] + : [handler] + } } public reset(nextHandlers: Array): void { invariant( - nextHandlers.length > 0 ? validateHandlers(nextHandlers) : true, + nextHandlers.length > 0 ? this.#validateHandlers(nextHandlers) : true, devUtils.formatMessage( 'Failed to replace initial handlers during reset: invalid handlers. Did you forget to spread the handlers array?', ), ) + + const { initialHandlers } = this.getState() + + if (nextHandlers.length === 0) { + this.setState({ + handlers: { ...initialHandlers }, + }) + + return + } + + const normalizedNextHandlers = groupHandlersByKind(nextHandlers) + + this.setState({ + initialHandlers: + nextHandlers.length > 0 ? normalizedNextHandlers : undefined, + handlers: { ...normalizedNextHandlers }, + }) + } + + #validateHandlers(handlers: Array): boolean { + return handlers.every((handler) => !Array.isArray(handler)) } } export class InMemoryHandlersController extends HandlersController { - #handlers: Array - #initialHandlers: Array + #handlers: HandlersMap + #initialHandlers: HandlersMap constructor(initialHandlers: Array) { - super(initialHandlers) + super() - this.#initialHandlers = initialHandlers - this.#handlers = [...initialHandlers] - } + const initialState = this.getInitialState(initialHandlers) - get currentHandlers() { - return this.#handlers + this.#initialHandlers = initialState.initialHandlers + this.#handlers = initialState.handlers } - public use(nextHandlers: Array): void { - super.use(nextHandlers) - this.#handlers.unshift(...nextHandlers) + protected getState(): HandlersControllerState { + return { + initialHandlers: this.#initialHandlers, + handlers: this.#handlers, + } } - public reset(nextHandlers: Array): void { - super.reset(nextHandlers) - this.#handlers = - nextHandlers.length > 0 ? [...nextHandlers] : [...this.#initialHandlers] + protected setState(nextState: Partial): void { + if (nextState.initialHandlers) { + this.#initialHandlers = nextState.initialHandlers + } + + if (nextState.handlers) { + this.#handlers = nextState.handlers + } } } diff --git a/src/core/new/sources/network-source.ts b/src/core/new/sources/network-source.ts index 2be5177c9..6ba123fbd 100644 --- a/src/core/new/sources/network-source.ts +++ b/src/core/new/sources/network-source.ts @@ -1,8 +1,10 @@ +import { InvariantError } from 'outvariant' import { Emitter, TypedEvent } from 'rettime' import { type NetworkFrame, type ExtractFrameEvents, } from '../frames/network-frame' +import { AnyHandler } from '../handlers-controller' export type AnyNetworkFrame = NetworkFrame @@ -45,3 +47,24 @@ export abstract class NetworkSource< this.emitter.removeAllListeners() } } + +export function getHandlerKindByFrame( + frame: AnyNetworkFrame, +): AnyHandler['kind'] { + switch (frame.protocol) { + case 'http': { + return 'request' + } + + case 'ws': { + return 'websocket' + } + + default: { + throw new InvariantError( + 'Failed to get handler kind by frame: unknown frame protocol "%s"', + frame.protocol, + ) + } + } +} diff --git a/src/core/utils/internal/isHandlerKind.test.ts b/src/core/utils/internal/isHandlerKind.test.ts index 84486fbe9..ae78f5f0a 100644 --- a/src/core/utils/internal/isHandlerKind.test.ts +++ b/src/core/utils/internal/isHandlerKind.test.ts @@ -5,14 +5,12 @@ import { WebSocketHandler } from '../../handlers/WebSocketHandler' import { isHandlerKind } from './isHandlerKind' it('returns true if expected a request handler and given a request handler', () => { - expect( - isHandlerKind('RequestHandler')(new HttpHandler('*', '*', () => {})), - ).toBe(true) + expect(isHandlerKind('request')(new HttpHandler('*', '*', () => {}))).toBe( + true, + ) expect( - isHandlerKind('RequestHandler')( - new GraphQLHandler('all', '*', '*', () => {}), - ), + isHandlerKind('request')(new GraphQLHandler('all', '*', '*', () => {})), ).toBe(true) }) @@ -25,24 +23,24 @@ it('returns true if expected a request handler and given a custom request handle log() {} } - expect(isHandlerKind('RequestHandler')(new MyHandler())).toBe(true) + expect(isHandlerKind('request')(new MyHandler())).toBe(true) }) it('returns false if expected a request handler but given event handler', () => { - expect(isHandlerKind('RequestHandler')(new WebSocketHandler('*'))).toBe(false) + expect(isHandlerKind('request')(new WebSocketHandler('*'))).toBe(false) }) it('returns false if expected a request handler but given arbitrary object', () => { - expect(isHandlerKind('RequestHandler')(undefined)).toBe(false) - expect(isHandlerKind('RequestHandler')(null)).toBe(false) - expect(isHandlerKind('RequestHandler')({})).toBe(false) - expect(isHandlerKind('RequestHandler')([])).toBe(false) - expect(isHandlerKind('RequestHandler')(123)).toBe(false) - expect(isHandlerKind('RequestHandler')('hello')).toBe(false) + expect(isHandlerKind('request')(undefined)).toBe(false) + expect(isHandlerKind('request')(null)).toBe(false) + expect(isHandlerKind('request')({})).toBe(false) + expect(isHandlerKind('request')([])).toBe(false) + expect(isHandlerKind('request')(123)).toBe(false) + expect(isHandlerKind('request')('hello')).toBe(false) }) it('returns true if expected an event handler and given an event handler', () => { - expect(isHandlerKind('EventHandler')(new WebSocketHandler('*'))).toBe(true) + expect(isHandlerKind('websocket')(new WebSocketHandler('*'))).toBe(true) }) it('returns true if expected an event handler and given a custom event handler', () => { @@ -51,14 +49,14 @@ it('returns true if expected an event handler and given a custom event handler', super('*') } } - expect(isHandlerKind('EventHandler')(new MyEventHandler())).toBe(true) + expect(isHandlerKind('websocket')(new MyEventHandler())).toBe(true) }) it('returns false if expected an event handler but given arbitrary object', () => { - expect(isHandlerKind('EventHandler')(undefined)).toBe(false) - expect(isHandlerKind('EventHandler')(null)).toBe(false) - expect(isHandlerKind('EventHandler')({})).toBe(false) - expect(isHandlerKind('EventHandler')([])).toBe(false) - expect(isHandlerKind('EventHandler')(123)).toBe(false) - expect(isHandlerKind('EventHandler')('hello')).toBe(false) + expect(isHandlerKind('websocket')(undefined)).toBe(false) + expect(isHandlerKind('websocket')(null)).toBe(false) + expect(isHandlerKind('websocket')({})).toBe(false) + expect(isHandlerKind('websocket')([])).toBe(false) + expect(isHandlerKind('websocket')(123)).toBe(false) + expect(isHandlerKind('websocket')('hello')).toBe(false) }) diff --git a/src/core/utils/internal/isHandlerKind.ts b/src/core/utils/internal/isHandlerKind.ts index d877bc847..11a98967a 100644 --- a/src/core/utils/internal/isHandlerKind.ts +++ b/src/core/utils/internal/isHandlerKind.ts @@ -1,21 +1,17 @@ -import type { HandlerKind } from '../../handlers/common' +import type { AnyHandler } from '../../new/handlers-controller' import type { RequestHandler } from '../../handlers/RequestHandler' import type { WebSocketHandler } from '../../handlers/WebSocketHandler' +import { isObject } from './isObject' /** * A filter function that ensures that the provided argument * is a handler of the given kind. This helps differentiate * between different kinds of handlers, e.g. request and event handlers. */ -export function isHandlerKind(kind: K) { +export function isHandlerKind(kind: K) { return ( input: unknown, - ): input is K extends 'EventHandler' ? WebSocketHandler : RequestHandler => { - return ( - input != null && - typeof input === 'object' && - '__kind' in input && - input.__kind === kind - ) + ): input is K extends 'websocket' ? WebSocketHandler : RequestHandler => { + return isObject(input) && 'kind' in input && input.kind === kind } } diff --git a/src/core/ws/handleWebSocketEvent.ts b/src/core/ws/handleWebSocketEvent.ts index f67a17805..8ffd77b1f 100644 --- a/src/core/ws/handleWebSocketEvent.ts +++ b/src/core/ws/handleWebSocketEvent.ts @@ -17,7 +17,11 @@ interface HandleWebSocketEventOptions { export function handleWebSocketEvent(options: HandleWebSocketEventOptions) { webSocketInterceptor.on('connection', async (connection) => { - const handlers = options.getHandlers().filter(isHandlerKind('EventHandler')) + /** + * @todo @fixme Reference the handlers controller here and use `.getHandlersByKind`. + * That one relies on the pre-grouped handlers map and will be more performant. + */ + const handlers = options.getHandlers().filter(isHandlerKind('websocket')) // Ignore this connection if the user hasn't defined any handlers. if (handlers.length > 0) { diff --git a/src/node/async-handlers-controller.ts b/src/node/async-handlers-controller.ts index 678c4cc19..e0e40018d 100644 --- a/src/node/async-handlers-controller.ts +++ b/src/node/async-handlers-controller.ts @@ -1,12 +1,14 @@ import { AsyncLocalStorage } from 'node:async_hooks' import { type AnyHandler, + type HandlersMap, HandlersController, + HandlersControllerState, } from '#core/new/handlers-controller' export interface AsyncHandlersControllerContext { - initialHandlers: Array - handlers: Array + initialHandlers: HandlersMap + handlers: HandlersMap } export class AsyncHandlersController extends HandlersController { @@ -15,37 +17,59 @@ export class AsyncHandlersController extends HandlersController { public context: AsyncLocalStorage constructor(initialHandlers: Array) { - super(initialHandlers) + super() + + const initialState = this.getInitialState(initialHandlers) this.context = new AsyncLocalStorage() + this.#fallbackContext = { - initialHandlers: [...initialHandlers], - handlers: [], + initialHandlers: initialState.initialHandlers, + handlers: initialState.handlers, } } - get currentHandlers() { - const { initialHandlers, handlers } = this.#getContext() - return [...handlers, ...initialHandlers] - } - - public use(nextHandlers: Array): void { - super.use(nextHandlers) + protected getState() { + const context = this.#getContext() - this.#getContext().handlers.unshift(...nextHandlers) + return { + initialHandlers: context.initialHandlers, + handlers: context.handlers, + } } - public reset(nextHandlers: Array): void { - super.reset(nextHandlers) - + protected setState(nextState: HandlersControllerState): void { const context = this.#getContext() - context.handlers = [] - if (nextHandlers.length > 0) { - context.initialHandlers = [...nextHandlers] + if (nextState.initialHandlers) { + context.initialHandlers = nextState.initialHandlers + } + + if (nextState.handlers) { + context.handlers = nextState.handlers } } + // public get currentHandlers() { + // const { initialHandlers, handlers } = this.getState() + + // This looks terribly incorrect. + // return [...Object.values(handlers), ...Object.values(initialHandlers)] + // .flat() + // .filter((handler) => handler != null) + // } + + // public reset(nextHandlers: Array): void { + // super.reset(nextHandlers) + + // const context = this.#getContext() + // context.handlers = [...initialHandlers] + + // if (nextHandlers.length > 0) { + // context.initialHandlers = [...nextHandlers] + // } + // } + #getContext() { return this.context.getStore() || this.#fallbackContext } diff --git a/src/node/setup-server.ts b/src/node/setup-server.ts index a5f2a0f29..0f28f4b04 100644 --- a/src/node/setup-server.ts +++ b/src/node/setup-server.ts @@ -3,8 +3,11 @@ import { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' +import { + type AnyHandler, + groupHandlersByKind, +} from '#core/new/handlers-controller' import { SetupServer } from './glossary' -import { type AnyHandler } from '#core/new/handlers-controller' import { AsyncHandlersController } from './async-handlers-controller' import { SetupServerCommonApi } from './setup-server-common' @@ -47,10 +50,14 @@ export class SetupServerApi callback: (...args: Args) => ReturnType, ): (...args: Args) => ReturnType { return (...args: Args): ReturnType => { + const normalizedInitialHandlers = groupHandlersByKind( + this.#handlersController.currentHandlers, + ) + return this.#handlersController.context.run( { - initialHandlers: this.#handlersController.currentHandlers, - handlers: [], + initialHandlers: normalizedInitialHandlers, + handlers: { ...normalizedInitialHandlers }, }, callback, ...args, diff --git a/test/node/msw-api/setup-server/listHandlers.node.test.ts b/test/node/msw-api/setup-server/listHandlers.node.test.ts index 6245f9463..674ffbcda 100644 --- a/test/node/msw-api/setup-server/listHandlers.node.test.ts +++ b/test/node/msw-api/setup-server/listHandlers.node.test.ts @@ -4,7 +4,7 @@ import { http, graphql } from 'msw' import { setupServer } from 'msw/node' -const resolver = () => null +const resolver = () => {} const github = graphql.link('https://api.github.com') const server = setupServer( diff --git a/test/node/msw-api/setup-server/use.node.test.ts b/test/node/msw-api/setup-server/use.node.test.ts index 22dcc189c..2b85d50b3 100644 --- a/test/node/msw-api/setup-server/use.node.test.ts +++ b/test/node/msw-api/setup-server/use.node.test.ts @@ -44,6 +44,8 @@ test('returns a mocked response from a runtime request handler upon match', asyn }), ) + console.log('AFTER USE:', server.listHandlers()) + // Request handlers added on runtime affect network communication as usual. const loginResponse = await fetch(httpServer.http.url('/login'), { method: 'POST', From 5534df77a368a7af59f2707b5e199ce0ea9e66eb Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 4 Feb 2026 19:47:04 +0100 Subject: [PATCH 33/68] fix: export `defaultNetworkOptions` from `/node` and `/native` --- src/native/index.ts | 38 +++++++++++---- src/node/glossary.ts | 16 +++--- src/node/index.ts | 6 ++- src/node/setup-server-common.ts | 43 ++++++++++++----- src/node/setup-server.ts | 86 +++++++++++++++++++++++++++------ 5 files changed, 145 insertions(+), 44 deletions(-) diff --git a/src/native/index.ts b/src/native/index.ts index 9cb053045..56a6cb0d0 100644 --- a/src/native/index.ts +++ b/src/native/index.ts @@ -1,7 +1,29 @@ +import type { Interceptor } from '@mswjs/interceptors' import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' import { type AnyHandler } from '#core/new/handlers-controller' -import { SetupServerCommonApi } from '../node/setup-server-common' +import { defineNetwork, DefineNetworkOptions } from '#core/new/define-network' +import { InterceptorSource } from '#core/new/sources/interceptor-source' +import { type SetupServerCommon } from '../node/glossary' +import { createSetupServerCommonApi } from '../node/setup-server-common' + +const defaultInterceptors: Array> = [ + new FetchInterceptor(), + new XMLHttpRequestInterceptor(), +] + +export const defaultNetworkOptions: DefineNetworkOptions<[InterceptorSource]> = + { + sources: [ + new InterceptorSource({ + interceptors: defaultInterceptors, + }), + ], + onUnhandledFrame: 'warn', + context: { + quiet: true, + }, + } /** * Sets up a requests interception in React Native with the given request handlers. @@ -9,13 +31,11 @@ import { SetupServerCommonApi } from '../node/setup-server-common' * * @see {@link https://mswjs.io/docs/api/setup-server `setupServer()` API reference} */ -export function setupServer( - ...handlers: Array -): SetupServerCommonApi { - // Provision request interception via patching the `XMLHttpRequest` class only - // in React Native. There is no `http`/`https` modules in that environment. - return new SetupServerCommonApi( - [new FetchInterceptor(), new XMLHttpRequestInterceptor()], +export function setupServer(...handlers: Array): SetupServerCommon { + const network = defineNetwork({ + ...defaultNetworkOptions, handlers, - ) + }) + + return createSetupServerCommonApi(network) } diff --git a/src/node/glossary.ts b/src/node/glossary.ts index b1be5b3d1..7e7bd4991 100644 --- a/src/node/glossary.ts +++ b/src/node/glossary.ts @@ -12,42 +12,42 @@ export interface SetupServerCommon { * * @see {@link https://mswjs.io/docs/api/setup-server/listen `server.listen()` API reference} */ - listen(options?: PartialDeep): void + listen: (options?: PartialDeep) => void /** * Stops requests interception by restoring all augmented modules. * * @see {@link https://mswjs.io/docs/api/setup-server/close `server.close()` API reference} */ - close(): void + close: () => void /** * Prepends given request handlers to the list of existing handlers. * * @see {@link https://mswjs.io/docs/api/setup-server/use `server.use()` API reference} */ - use(...handlers: Array): void + use: (...handlers: Array) => void /** * Marks all request handlers that respond using `res.once()` as unused. * * @see {@link https://mswjs.io/docs/api/setup-server/restore-handlers `server.restore-handlers()` API reference} */ - restoreHandlers(): void + restoreHandlers: () => void /** * Resets request handlers to the initial list given to the `setupServer` call, or to the explicit next request handlers list, if given. * * @see {@link https://mswjs.io/docs/api/setup-server/reset-handlers `server.reset-handlers()` API reference} */ - resetHandlers(...nextHandlers: Array): void + resetHandlers: (...nextHandlers: Array) => void /** * Returns a readonly list of currently active request handlers. * * @see {@link https://mswjs.io/docs/api/setup-server/list-handlers `server.listHandlers()` API reference} */ - listHandlers(): ReadonlyArray + listHandlers: () => ReadonlyArray /** * Life-cycle events. @@ -69,7 +69,7 @@ export interface SetupServer extends SetupServerCommon { * * @see {@link https://mswjs.io/docs/api/setup-server/boundary `server.boundary()` API reference} */ - boundary, R>( + boundary: , R>( callback: (...args: Args) => R, - ): (...args: Args) => R + ) => (...args: Args) => R } diff --git a/src/node/index.ts b/src/node/index.ts index 8ccac8652..e8e63f7e5 100644 --- a/src/node/index.ts +++ b/src/node/index.ts @@ -1,3 +1,7 @@ export type { SetupServer } from './glossary' -export { setupServer, SetupServerApi } from './setup-server' +export { + setupServer, + SetupServerApi, + defaultNetworkOptions, +} from './setup-server' export { SetupServerCommonApi } from './setup-server-common' diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts index bfbcc0eb2..0ef424e8d 100644 --- a/src/node/setup-server-common.ts +++ b/src/node/setup-server-common.ts @@ -1,16 +1,38 @@ import type { PartialDeep } from 'type-fest' import { Interceptor } from '@mswjs/interceptors' -import type { ListenOptions, SetupServerCommon } from './glossary' import { type NetworkApi, defineNetwork } from '#core/new/define-network' import { type AnyHandler } from '#core/new/handlers-controller' import { HandlersController } from '#core/new/handlers-controller' import { InterceptorSource } from '#core/new/sources/interceptor-source' import { fromLegacyOnUnhandledRequest } from '#core/new/compat' +import type { ListenOptions, SetupServerCommon } from './glossary' -export class SetupServerCommonApi implements SetupServerCommon { - #listenOptions?: PartialDeep +export function createSetupServerCommonApi( + network: NetworkApi, +): SetupServerCommon { + return { + events: network.events, + listen(options) { + network.configure({ + onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { + return options?.onUnhandledRequest || 'warn' + }), + }) - protected network: NetworkApi + network.enable() + }, + use: network.use.bind(network), + resetHandlers: network.resetHandlers.bind(network), + restoreHandlers: network.restoreHandlers.bind(network), + listHandlers: network.listHandlers.bind(network), + close() { + network.disable() + }, + } +} + +export class SetupServerCommonApi implements SetupServerCommon { + protected network: NetworkApi<[InterceptorSource]> constructor( interceptors: Array>, @@ -19,12 +41,6 @@ export class SetupServerCommonApi implements SetupServerCommon { this.network = defineNetwork({ sources: [new InterceptorSource({ interceptors })], handlers, - onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { - return this.#listenOptions?.onUnhandledRequest || 'warn' - }), - context: { - quiet: true, - }, }) } @@ -33,7 +49,12 @@ export class SetupServerCommonApi implements SetupServerCommon { } public listen(options?: PartialDeep): void { - this.#listenOptions = options + this.network.configure({ + onUnhandledFrame: fromLegacyOnUnhandledRequest(() => { + return options?.onUnhandledRequest || 'warn' + }), + }) + this.network.enable() } diff --git a/src/node/setup-server.ts b/src/node/setup-server.ts index 0f28f4b04..62fa3eb1d 100644 --- a/src/node/setup-server.ts +++ b/src/node/setup-server.ts @@ -1,35 +1,88 @@ -import { Interceptor } from '@mswjs/interceptors' +import type { Interceptor } from '@mswjs/interceptors' import { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' +import { + defineNetwork, + type DefineNetworkOptions, +} from '#core/new/define-network' import { type AnyHandler, groupHandlersByKind, } from '#core/new/handlers-controller' +import { InterceptorSource } from '#core/new/sources/interceptor-source' import { SetupServer } from './glossary' import { AsyncHandlersController } from './async-handlers-controller' -import { SetupServerCommonApi } from './setup-server-common' +import { + createSetupServerCommonApi, + SetupServerCommonApi, +} from './setup-server-common' + +const defaultInterceptors: Array> = [ + new ClientRequestInterceptor(), + new XMLHttpRequestInterceptor(), + new FetchInterceptor(), + /** + * @fixme WebSocketInterceptor is in a browser-only export of Interceptors + * while the Interceptor class imported from the root module points to `lib/node`. + * An absolute madness to solve as it requires to duplicate the build config we have + * in MSW: shared core, CJS/ESM patching, .d.ts patching... + */ + new WebSocketInterceptor() as any, +] + +export const defaultNetworkOptions: DefineNetworkOptions<[InterceptorSource]> = + { + sources: [ + new InterceptorSource({ + interceptors: defaultInterceptors, + }), + ], + onUnhandledFrame: 'warn', + context: { + quiet: true, + }, + } /** * Enables request interception in Node.js with the given request handlers. * @see {@link https://mswjs.io/docs/api/setup-server `setupServer()` API reference} */ -export function setupServer(...handlers: Array): SetupServerApi { - return new SetupServerApi(handlers, [ - new ClientRequestInterceptor(), - new XMLHttpRequestInterceptor(), - new FetchInterceptor(), - /** - * @fixme WebSocketInterceptor is in a browser-only export of Interceptors - * while the Interceptor class imported from the root module points to `lib/node`. - * An absolute madness to solve as it requires to duplicate the build config we have - * in MSW: shared core, CJS/ESM patching, .d.ts patching... - */ - new WebSocketInterceptor() as any, - ]) +export function setupServer(...handlers: Array): SetupServer { + const handlersController = new AsyncHandlersController(handlers) + const network = defineNetwork({ + ...defaultNetworkOptions, + handlers: handlersController, + }) + + const commonApi = createSetupServerCommonApi(network) + + return { + ...commonApi, + boundary(callback) { + return (...args) => { + const normalizedInitialHandlers = groupHandlersByKind( + handlersController.currentHandlers, + ) + + return handlersController.context.run( + { + initialHandlers: normalizedInitialHandlers, + handlers: { ...normalizedInitialHandlers }, + }, + callback, + ...args, + ) + } + }, + } } +/** + * @deprecated + * Please use the `defineNetwork` API instead. + */ export class SetupServerApi extends SetupServerCommonApi implements SetupServer @@ -43,6 +96,9 @@ export class SetupServerApi const controller = new AsyncHandlersController(handlers) super(interceptors, controller) + const { sources: _, ...networkOptions } = defaultNetworkOptions + this.network.configure(networkOptions) + this.#handlersController = controller } From 87239cf58fa240bbd385d38d011fd0a8c331eeb5 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 4 Feb 2026 20:24:58 +0100 Subject: [PATCH 34/68] chore: fix formatting linting errors --- src/browser/utils/workerChannel.ts | 27 ++++++++++++++------------- src/core/ws/WebSocketClientManager.ts | 4 +++- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/browser/utils/workerChannel.ts b/src/browser/utils/workerChannel.ts index c9987a459..7b39f7114 100644 --- a/src/browser/utils/workerChannel.ts +++ b/src/browser/utils/workerChannel.ts @@ -27,19 +27,20 @@ export type WorkerChannelEventMap = { /** * Request representation received from the worker message event. */ -export interface IncomingWorkerRequest extends Omit< - Request, - | 'text' - | 'body' - | 'json' - | 'blob' - | 'arrayBuffer' - | 'formData' - | 'clone' - | 'signal' - | 'isHistoryNavigation' - | 'isReloadNavigation' -> { +export interface IncomingWorkerRequest + extends Omit< + Request, + | 'text' + | 'body' + | 'json' + | 'blob' + | 'arrayBuffer' + | 'formData' + | 'clone' + | 'signal' + | 'isHistoryNavigation' + | 'isReloadNavigation' + > { /** * Unique ID of the request generated once the request is * intercepted by the "fetch" event in the Service Worker. diff --git a/src/core/ws/WebSocketClientManager.ts b/src/core/ws/WebSocketClientManager.ts index 09d888b43..760e4a335 100644 --- a/src/core/ws/WebSocketClientManager.ts +++ b/src/core/ws/WebSocketClientManager.ts @@ -183,7 +183,9 @@ export class WebSocketClientManager { * on the given `BroadcastChannel` to communicate instructions * with the client connections from other runtimes. */ -export class WebSocketRemoteClientConnection implements WebSocketClientConnectionProtocol { +export class WebSocketRemoteClientConnection + implements WebSocketClientConnectionProtocol +{ constructor( public readonly id: string, public readonly url: URL, From 9bc12232f6cbf4d8a36b0eebc1ed1bea537b16e3 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 4 Feb 2026 22:27:51 +0100 Subject: [PATCH 35/68] fix: export new apis under `msw/future` --- package.json | 10 ++++++++++ src/core/future.ts | 6 ++++++ test/typings/define-network.test-d.ts | 4 +--- 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/core/future.ts diff --git a/package.json b/package.json index 3e6b67782..a206b3835 100644 --- a/package.json +++ b/package.json @@ -159,6 +159,16 @@ "default": "./lib/core/ws.js" } }, + "./future": { + "import": { + "types": "./lib/core/future.d.mts", + "default": "./lib/core/future.mjs" + }, + "default": { + "types": "./lib/core/future.d.ts", + "default": "./lib/core/future.js" + } + }, "./mockServiceWorker.js": "./lib/mockServiceWorker.js", "./package.json": "./package.json" }, diff --git a/src/core/future.ts b/src/core/future.ts new file mode 100644 index 000000000..3ea60ec24 --- /dev/null +++ b/src/core/future.ts @@ -0,0 +1,6 @@ +export { NetworkFrame } from './new/frames/network-frame' +export { HttpNetworkFrame } from './new/frames/http-frame' +export { WebSocketNetworkFrame } from './new/frames/websocket-frame' +export { NetworkSource } from './new/sources/network-source' +export { InterceptorSource } from './new/sources/interceptor-source' +export { defineNetwork, DefineNetworkOptions } from './new/define-network' diff --git a/test/typings/define-network.test-d.ts b/test/typings/define-network.test-d.ts index 7cf8768a7..d02d2f725 100644 --- a/test/typings/define-network.test-d.ts +++ b/test/typings/define-network.test-d.ts @@ -1,7 +1,5 @@ import { DefaultEventMap, Emitter, TypedEvent } from 'rettime' -import { defineNetwork } from '../../src/core/new/define-network' -import { NetworkSource } from '../../src/core/new/sources/network-source' -import { NetworkFrame } from '../../src/core/new/frames/network-frame' +import { defineNetwork, NetworkSource, NetworkFrame } from 'msw/future' it('uses an empty event map when no sources were provided', () => { expectTypeOf( From c85308b0b7368dd720a81255ff344cfc850077b6 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Wed, 4 Feb 2026 22:34:29 +0100 Subject: [PATCH 36/68] chore: rename `new` to `future` --- package.json | 8 +++---- src/browser/glossary.ts | 6 ++--- src/browser/setup-worker.ts | 8 +++---- src/browser/sources/fallback-http-source.ts | 2 +- src/browser/sources/service-worker-source.ts | 4 ++-- src/core/future.ts | 6 ----- src/core/{new => future}/compat.ts | 0 src/core/{new => future}/define-network.ts | 0 src/core/{new => future}/frames/http-frame.ts | 0 .../{new => future}/frames/network-frame.ts | 0 .../{new => future}/frames/websocket-frame.ts | 0 .../handlers-controller.test.ts | 0 .../{new => future}/handlers-controller.ts | 0 src/core/future/index.ts | 6 +++++ .../{new => future}/on-unhandled-frame.ts | 0 src/core/{new => future}/request-utils.ts | 0 src/core/{new => future}/setup-api.ts | 0 .../sources/interceptor-source.ts | 0 .../{new => future}/sources/network-source.ts | 0 src/core/index.ts | 2 +- src/core/utils/internal/isHandlerKind.ts | 2 +- src/native/index.ts | 9 +++++--- src/node/async-handlers-controller.ts | 22 +------------------ src/node/glossary.ts | 6 ++--- src/node/setup-server-common.ts | 10 ++++----- src/node/setup-server.ts | 6 ++--- .../msw-api/setup-server/use.node.test.ts | 2 -- 27 files changed, 40 insertions(+), 59 deletions(-) delete mode 100644 src/core/future.ts rename src/core/{new => future}/compat.ts (100%) rename src/core/{new => future}/define-network.ts (100%) rename src/core/{new => future}/frames/http-frame.ts (100%) rename src/core/{new => future}/frames/network-frame.ts (100%) rename src/core/{new => future}/frames/websocket-frame.ts (100%) rename src/core/{new => future}/handlers-controller.test.ts (100%) rename src/core/{new => future}/handlers-controller.ts (100%) create mode 100644 src/core/future/index.ts rename src/core/{new => future}/on-unhandled-frame.ts (100%) rename src/core/{new => future}/request-utils.ts (100%) rename src/core/{new => future}/setup-api.ts (100%) rename src/core/{new => future}/sources/interceptor-source.ts (100%) rename src/core/{new => future}/sources/network-source.ts (100%) diff --git a/package.json b/package.json index a206b3835..df060c956 100644 --- a/package.json +++ b/package.json @@ -161,12 +161,12 @@ }, "./future": { "import": { - "types": "./lib/core/future.d.mts", - "default": "./lib/core/future.mjs" + "types": "./lib/core/future/index.d.mts", + "default": "./lib/core/future/index.mjs" }, "default": { - "types": "./lib/core/future.d.ts", - "default": "./lib/core/future.js" + "types": "./lib/core/future/index.d.ts", + "default": "./lib/core/future/index.js" } }, "./mockServiceWorker.js": "./lib/mockServiceWorker.js", diff --git a/src/browser/glossary.ts b/src/browser/glossary.ts index f7b45b70f..cfac396d1 100644 --- a/src/browser/glossary.ts +++ b/src/browser/glossary.ts @@ -1,8 +1,8 @@ import type { LifeCycleEventEmitter, SharedOptions } from '#core/sharedOptions' import type { RequiredDeep } from '#core/typeUtils' -import type { HttpNetworkFrameEventMap } from '#core/new/frames/http-frame' -import type { WebSocketNetworkFrameEventMap } from '#core/new/frames/websocket-frame' -import { AnyHandler } from '#core/new/handlers-controller' +import type { HttpNetworkFrameEventMap } from '#core/future/frames/http-frame' +import type { WebSocketNetworkFrameEventMap } from '#core/future/frames/websocket-frame' +import { AnyHandler } from '#core/future/handlers-controller' export interface StringifiedResponse extends ResponseInit { body: string | ArrayBuffer | ReadableStream | null diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 3492566cf..eca66f53e 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -1,11 +1,11 @@ import { invariant } from 'outvariant' import { isNodeProcess } from 'is-node-process' import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' -import { defineNetwork, NetworkHandlersApi } from '#core/new/define-network' -import { type AnyHandler } from '#core/new/handlers-controller' -import { InterceptorSource } from '#core/new/sources/interceptor-source' +import { defineNetwork, NetworkHandlersApi } from '#core/future/define-network' +import { type AnyHandler } from '#core/future/handlers-controller' +import { InterceptorSource } from '#core/future/sources/interceptor-source' import { type UnhandledRequestStrategy } from '#core/utils/request/onUnhandledRequest' -import { fromLegacyOnUnhandledRequest } from '#core/new/compat' +import { fromLegacyOnUnhandledRequest } from '#core/future/compat' import { devUtils } from '#core/utils/internal/devUtils' import { supportsServiceWorker } from './utils/supports' import { ServiceWorkerSource } from './sources/service-worker-source' diff --git a/src/browser/sources/fallback-http-source.ts b/src/browser/sources/fallback-http-source.ts index c469e709a..6cbdf67dd 100644 --- a/src/browser/sources/fallback-http-source.ts +++ b/src/browser/sources/fallback-http-source.ts @@ -1,6 +1,6 @@ import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' -import { InterceptorSource } from '#core/new/sources/interceptor-source' +import { InterceptorSource } from '#core/future/sources/interceptor-source' import { devUtils } from '#core/utils/internal/devUtils' export class FallbackHttpSource extends InterceptorSource { diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index 8f9574732..f19c8cc14 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -2,9 +2,9 @@ import { invariant } from 'outvariant' import { Emitter, TypedEvent } from 'rettime' import { DeferredPromise } from '@open-draft/deferred-promise' import { FetchResponse } from '@mswjs/interceptors' -import { NetworkSource } from '#core/new/sources/network-source' +import { NetworkSource } from '#core/future/sources/network-source' import { RequestHandler } from '#core/handlers/RequestHandler' -import { HttpNetworkFrame } from '#core/new/frames/http-frame' +import { HttpNetworkFrame } from '#core/future/frames/http-frame' import { HttpResponse } from '#core/HttpResponse' import { toResponseInit } from '#core/utils/toResponseInit' import { devUtils } from '#core/utils/internal/devUtils' diff --git a/src/core/future.ts b/src/core/future.ts deleted file mode 100644 index 3ea60ec24..000000000 --- a/src/core/future.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { NetworkFrame } from './new/frames/network-frame' -export { HttpNetworkFrame } from './new/frames/http-frame' -export { WebSocketNetworkFrame } from './new/frames/websocket-frame' -export { NetworkSource } from './new/sources/network-source' -export { InterceptorSource } from './new/sources/interceptor-source' -export { defineNetwork, DefineNetworkOptions } from './new/define-network' diff --git a/src/core/new/compat.ts b/src/core/future/compat.ts similarity index 100% rename from src/core/new/compat.ts rename to src/core/future/compat.ts diff --git a/src/core/new/define-network.ts b/src/core/future/define-network.ts similarity index 100% rename from src/core/new/define-network.ts rename to src/core/future/define-network.ts diff --git a/src/core/new/frames/http-frame.ts b/src/core/future/frames/http-frame.ts similarity index 100% rename from src/core/new/frames/http-frame.ts rename to src/core/future/frames/http-frame.ts diff --git a/src/core/new/frames/network-frame.ts b/src/core/future/frames/network-frame.ts similarity index 100% rename from src/core/new/frames/network-frame.ts rename to src/core/future/frames/network-frame.ts diff --git a/src/core/new/frames/websocket-frame.ts b/src/core/future/frames/websocket-frame.ts similarity index 100% rename from src/core/new/frames/websocket-frame.ts rename to src/core/future/frames/websocket-frame.ts diff --git a/src/core/new/handlers-controller.test.ts b/src/core/future/handlers-controller.test.ts similarity index 100% rename from src/core/new/handlers-controller.test.ts rename to src/core/future/handlers-controller.test.ts diff --git a/src/core/new/handlers-controller.ts b/src/core/future/handlers-controller.ts similarity index 100% rename from src/core/new/handlers-controller.ts rename to src/core/future/handlers-controller.ts diff --git a/src/core/future/index.ts b/src/core/future/index.ts new file mode 100644 index 000000000..f42711ba2 --- /dev/null +++ b/src/core/future/index.ts @@ -0,0 +1,6 @@ +export { NetworkFrame } from './frames/network-frame' +export { HttpNetworkFrame } from './frames/http-frame' +export { WebSocketNetworkFrame } from './frames/websocket-frame' +export { NetworkSource } from './sources/network-source' +export { InterceptorSource } from './sources/interceptor-source' +export { defineNetwork, DefineNetworkOptions } from './define-network' diff --git a/src/core/new/on-unhandled-frame.ts b/src/core/future/on-unhandled-frame.ts similarity index 100% rename from src/core/new/on-unhandled-frame.ts rename to src/core/future/on-unhandled-frame.ts diff --git a/src/core/new/request-utils.ts b/src/core/future/request-utils.ts similarity index 100% rename from src/core/new/request-utils.ts rename to src/core/future/request-utils.ts diff --git a/src/core/new/setup-api.ts b/src/core/future/setup-api.ts similarity index 100% rename from src/core/new/setup-api.ts rename to src/core/future/setup-api.ts diff --git a/src/core/new/sources/interceptor-source.ts b/src/core/future/sources/interceptor-source.ts similarity index 100% rename from src/core/new/sources/interceptor-source.ts rename to src/core/future/sources/interceptor-source.ts diff --git a/src/core/new/sources/network-source.ts b/src/core/future/sources/network-source.ts similarity index 100% rename from src/core/new/sources/network-source.ts rename to src/core/future/sources/network-source.ts diff --git a/src/core/index.ts b/src/core/index.ts index 2ed43a40d..866d7d0b8 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,6 +1,6 @@ import { checkGlobals } from './utils/internal/checkGlobals' -export { SetupApi } from './new/setup-api' +export { SetupApi } from './future/setup-api' /* HTTP handlers */ export { RequestHandler } from './handlers/RequestHandler' diff --git a/src/core/utils/internal/isHandlerKind.ts b/src/core/utils/internal/isHandlerKind.ts index 11a98967a..aff11d02a 100644 --- a/src/core/utils/internal/isHandlerKind.ts +++ b/src/core/utils/internal/isHandlerKind.ts @@ -1,4 +1,4 @@ -import type { AnyHandler } from '../../new/handlers-controller' +import type { AnyHandler } from '../../future/handlers-controller' import type { RequestHandler } from '../../handlers/RequestHandler' import type { WebSocketHandler } from '../../handlers/WebSocketHandler' import { isObject } from './isObject' diff --git a/src/native/index.ts b/src/native/index.ts index 56a6cb0d0..f7c5c42a2 100644 --- a/src/native/index.ts +++ b/src/native/index.ts @@ -1,9 +1,12 @@ import type { Interceptor } from '@mswjs/interceptors' import { FetchInterceptor } from '@mswjs/interceptors/fetch' import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' -import { type AnyHandler } from '#core/new/handlers-controller' -import { defineNetwork, DefineNetworkOptions } from '#core/new/define-network' -import { InterceptorSource } from '#core/new/sources/interceptor-source' +import { type AnyHandler } from '#core/future/handlers-controller' +import { + defineNetwork, + DefineNetworkOptions, +} from '#core/future/define-network' +import { InterceptorSource } from '#core/future/sources/interceptor-source' import { type SetupServerCommon } from '../node/glossary' import { createSetupServerCommonApi } from '../node/setup-server-common' diff --git a/src/node/async-handlers-controller.ts b/src/node/async-handlers-controller.ts index e0e40018d..e402ac8c7 100644 --- a/src/node/async-handlers-controller.ts +++ b/src/node/async-handlers-controller.ts @@ -4,7 +4,7 @@ import { type HandlersMap, HandlersController, HandlersControllerState, -} from '#core/new/handlers-controller' +} from '#core/future/handlers-controller' export interface AsyncHandlersControllerContext { initialHandlers: HandlersMap @@ -50,26 +50,6 @@ export class AsyncHandlersController extends HandlersController { } } - // public get currentHandlers() { - // const { initialHandlers, handlers } = this.getState() - - // This looks terribly incorrect. - // return [...Object.values(handlers), ...Object.values(initialHandlers)] - // .flat() - // .filter((handler) => handler != null) - // } - - // public reset(nextHandlers: Array): void { - // super.reset(nextHandlers) - - // const context = this.#getContext() - // context.handlers = [...initialHandlers] - - // if (nextHandlers.length > 0) { - // context.initialHandlers = [...nextHandlers] - // } - // } - #getContext() { return this.context.getStore() || this.#fallbackContext } diff --git a/src/node/glossary.ts b/src/node/glossary.ts index 7e7bd4991..d8aca3881 100644 --- a/src/node/glossary.ts +++ b/src/node/glossary.ts @@ -1,7 +1,7 @@ import type { PartialDeep } from 'type-fest' -import type { HttpNetworkFrameEventMap } from '#core/new/frames/http-frame' -import type { WebSocketNetworkFrameEventMap } from '#core/new/frames/websocket-frame' -import type { AnyHandler } from '#core/new/handlers-controller' +import type { HttpNetworkFrameEventMap } from '#core/future/frames/http-frame' +import type { WebSocketNetworkFrameEventMap } from '#core/future/frames/websocket-frame' +import type { AnyHandler } from '#core/future/handlers-controller' import type { LifeCycleEventEmitter, SharedOptions } from '#core/sharedOptions' export interface ListenOptions extends SharedOptions {} diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts index 0ef424e8d..e092e3ef2 100644 --- a/src/node/setup-server-common.ts +++ b/src/node/setup-server-common.ts @@ -1,10 +1,10 @@ import type { PartialDeep } from 'type-fest' import { Interceptor } from '@mswjs/interceptors' -import { type NetworkApi, defineNetwork } from '#core/new/define-network' -import { type AnyHandler } from '#core/new/handlers-controller' -import { HandlersController } from '#core/new/handlers-controller' -import { InterceptorSource } from '#core/new/sources/interceptor-source' -import { fromLegacyOnUnhandledRequest } from '#core/new/compat' +import { type NetworkApi, defineNetwork } from '#core/future/define-network' +import { type AnyHandler } from '#core/future/handlers-controller' +import { HandlersController } from '#core/future/handlers-controller' +import { InterceptorSource } from '#core/future/sources/interceptor-source' +import { fromLegacyOnUnhandledRequest } from '#core/future/compat' import type { ListenOptions, SetupServerCommon } from './glossary' export function createSetupServerCommonApi( diff --git a/src/node/setup-server.ts b/src/node/setup-server.ts index 62fa3eb1d..065ca1716 100644 --- a/src/node/setup-server.ts +++ b/src/node/setup-server.ts @@ -6,12 +6,12 @@ import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket' import { defineNetwork, type DefineNetworkOptions, -} from '#core/new/define-network' +} from '#core/future/define-network' import { type AnyHandler, groupHandlersByKind, -} from '#core/new/handlers-controller' -import { InterceptorSource } from '#core/new/sources/interceptor-source' +} from '#core/future/handlers-controller' +import { InterceptorSource } from '#core/future/sources/interceptor-source' import { SetupServer } from './glossary' import { AsyncHandlersController } from './async-handlers-controller' import { diff --git a/test/node/msw-api/setup-server/use.node.test.ts b/test/node/msw-api/setup-server/use.node.test.ts index 2b85d50b3..22dcc189c 100644 --- a/test/node/msw-api/setup-server/use.node.test.ts +++ b/test/node/msw-api/setup-server/use.node.test.ts @@ -44,8 +44,6 @@ test('returns a mocked response from a runtime request handler upon match', asyn }), ) - console.log('AFTER USE:', server.listHandlers()) - // Request handlers added on runtime affect network communication as usual. const loginResponse = await fetch(httpServer.http.url('/login'), { method: 'POST', From 4c8dd58c7caebec174afca64ebc7b9620e2abf72 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 6 Feb 2026 11:07:37 +0100 Subject: [PATCH 37/68] fix(worker): formatting of the integrity check --- src/browser/sources/service-worker-source.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index f19c8cc14..8864d640d 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -265,11 +265,11 @@ Please consider using a custom "serviceWorker.url" option to point to the actual devUtils.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: +It's recommended you update your worker script by running this command: - \u2022 npx msw init + \u2022 npx msw init - 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.`, +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.`, ) } From 0c77bfbd9afefe27b21974daf58794f84c02a2ff Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 6 Feb 2026 11:18:49 +0100 Subject: [PATCH 38/68] fix(worker): use `ResponseEvent` for life-cycle events --- src/browser/setup-worker.ts | 29 ++++++++++---------- src/browser/sources/service-worker-source.ts | 23 ++++++++-------- src/core/future/frames/network-frame.ts | 3 ++ src/node/setup-server-common.ts | 4 +-- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index eca66f53e..c0ef3606b 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -6,6 +6,9 @@ import { type AnyHandler } from '#core/future/handlers-controller' import { InterceptorSource } from '#core/future/sources/interceptor-source' import { type UnhandledRequestStrategy } from '#core/utils/request/onUnhandledRequest' import { fromLegacyOnUnhandledRequest } from '#core/future/compat' +import type { LifeCycleEventEmitter } from '#core/sharedOptions' +import type { HttpNetworkFrameEventMap } from '#core/future/frames/http-frame' +import type { WebSocketNetworkFrameEventMap } from '#core/future/frames/websocket-frame' import { devUtils } from '#core/utils/internal/devUtils' import { supportsServiceWorker } from './utils/supports' import { ServiceWorkerSource } from './sources/service-worker-source' @@ -15,6 +18,9 @@ import { type FindWorker } from './glossary' export interface SetupWorkerApi extends NetworkHandlersApi { start: (options?: SetupWorkerStartOptions) => Promise stop: () => void + events: LifeCycleEventEmitter< + HttpNetworkFrameEventMap | WebSocketNetworkFrameEventMap + > } interface SetupWorkerStartOptions { @@ -43,7 +49,7 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { ), ) - let hasStarted = false + let isStarted = false const network = defineNetwork< Array >({ @@ -57,7 +63,7 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { * @todo @fixme * This is kept for backward-compatibility reasons. We don't really need this check anymore. */ - if (hasStarted) { + if (isStarted) { devUtils.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.', ) @@ -91,7 +97,7 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { }) await network.enable() - hasStarted = true + isStarted = true if (!options?.quiet) { await httpSource.printStartMessage() @@ -100,17 +106,10 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { stop() { network.disable() }, - use(...handlers) { - return network.use(...handlers) - }, - resetHandlers(...handlers) { - return network.resetHandlers(...handlers) - }, - restoreHandlers() { - return network.restoreHandlers() - }, - listHandlers() { - return network.listHandlers() - }, + events: network.events, + use: network.use.bind(network), + resetHandlers: network.resetHandlers.bind(network), + restoreHandlers: network.restoreHandlers.bind(network), + listHandlers: network.listHandlers.bind(network), } } diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index 8864d640d..4ea010bf2 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -1,10 +1,10 @@ import { invariant } from 'outvariant' -import { Emitter, TypedEvent } from 'rettime' +import { Emitter } from 'rettime' import { DeferredPromise } from '@open-draft/deferred-promise' import { FetchResponse } from '@mswjs/interceptors' import { NetworkSource } from '#core/future/sources/network-source' import { RequestHandler } from '#core/handlers/RequestHandler' -import { HttpNetworkFrame } from '#core/future/frames/http-frame' +import { HttpNetworkFrame, ResponseEvent } from '#core/future/frames/http-frame' import { HttpResponse } from '#core/HttpResponse' import { toResponseInit } from '#core/utils/toResponseInit' import { devUtils } from '#core/utils/internal/devUtils' @@ -26,13 +26,13 @@ export interface ServiceWorkerSourceOptions { findWorker?: FindWorker } -type RequestEvent = Emitter.EventType< +type WorkerChannelRequestEvent = Emitter.EventType< WorkerChannel, 'REQUEST', WorkerChannelEventMap > -type ResponseEvent = Emitter.EventType< +type WorkerChannelResponseEvent = Emitter.EventType< WorkerChannel, 'RESPONSE', WorkerChannelEventMap @@ -184,7 +184,7 @@ Please consider using a custom "serviceWorker.url" option to point to the actual return [worker, registration] as const } - async #handleRequest(event: RequestEvent): Promise { + async #handleRequest(event: WorkerChannelRequestEvent): Promise { // Passthrough any requests performed after the interception was stopped. if (this.#stoppedAt && event.data.interceptedAt > this.#stoppedAt) { return event.postMessage('PASSTHROUGH') @@ -202,7 +202,7 @@ Please consider using a custom "serviceWorker.url" option to point to the actual await this.queue(frame) } - async #handleResponse(event: ResponseEvent): Promise { + async #handleResponse(event: WorkerChannelResponseEvent): Promise { const { request, response, isMockedResponse } = event.data /** @@ -233,14 +233,15 @@ Please consider using a custom "serviceWorker.url" option to point to the actual : new FetchResponse(response.body, response) frame.events.emit( - new TypedEvent(isMockedResponse ? 'response:mocked' : 'response:bypass', { - data: { + new ResponseEvent( + isMockedResponse ? 'response:mocked' : 'response:bypass', + { requestId: request.id, request: fetchRequest, response: fetchResponse, isMockedResponse, }, - }), + ), ) } @@ -333,9 +334,9 @@ You can also automate this process and make the worker script update automatical } class ServiceWorkerHttpNetworkFrame extends HttpNetworkFrame { - #event: RequestEvent + #event: WorkerChannelRequestEvent - constructor(options: { event: RequestEvent; request: Request }) { + constructor(options: { event: WorkerChannelRequestEvent; request: Request }) { super({ request: options.request }) this.#event = options.event } diff --git a/src/core/future/frames/network-frame.ts b/src/core/future/frames/network-frame.ts index 878deb06f..660a9f972 100644 --- a/src/core/future/frames/network-frame.ts +++ b/src/core/future/frames/network-frame.ts @@ -27,6 +27,9 @@ export abstract class NetworkFrame< * Resolve the current frame against the given list of handlers. * Optionally, use a custom resolution context to control behaviors * like `baseUrl`. + * + * Returns `true` if the frame was handled, `false` if it wasn't, and `null` + * if its handling was skipped (e.g. the frame was bypassed). */ public abstract resolve( handlers: Array, diff --git a/src/node/setup-server-common.ts b/src/node/setup-server-common.ts index e092e3ef2..efb3b8faa 100644 --- a/src/node/setup-server-common.ts +++ b/src/node/setup-server-common.ts @@ -2,7 +2,7 @@ import type { PartialDeep } from 'type-fest' import { Interceptor } from '@mswjs/interceptors' import { type NetworkApi, defineNetwork } from '#core/future/define-network' import { type AnyHandler } from '#core/future/handlers-controller' -import { HandlersController } from '#core/future/handlers-controller' +import { type HandlersController } from '#core/future/handlers-controller' import { InterceptorSource } from '#core/future/sources/interceptor-source' import { fromLegacyOnUnhandledRequest } from '#core/future/compat' import type { ListenOptions, SetupServerCommon } from './glossary' @@ -45,7 +45,7 @@ export class SetupServerCommonApi implements SetupServerCommon { } get events() { - return this.network.events as any + return this.network.events } public listen(options?: PartialDeep): void { From a5b7c21328b668eab9d7fed0a23abc22693a9b52 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 6 Feb 2026 11:28:44 +0100 Subject: [PATCH 39/68] fix(WebSocketFrame): implement custom `WebSocketConnectionEvent` --- src/core/future/frames/websocket-frame.ts | 27 +++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/core/future/frames/websocket-frame.ts b/src/core/future/frames/websocket-frame.ts index ce66d789c..2045a4a75 100644 --- a/src/core/future/frames/websocket-frame.ts +++ b/src/core/future/frames/websocket-frame.ts @@ -11,10 +11,25 @@ export interface WebSocketNetworkFrameOptions { } export type WebSocketNetworkFrameEventMap = { - connection: TypedEvent<{ + connection: WebSocketConnectionEvent +} + +class WebSocketConnectionEvent< + DataType extends { url: URL protocols: string | Array | undefined - }> + } = { url: URL; protocols: string | Array | undefined }, + ReturnType = void, + EventType extends string = string, +> extends TypedEvent { + public readonly url: URL + public readonly protocols: string | Array | undefined + + constructor(type: EventType, data: DataType) { + super(...([type, {}] as any)) + this.url = data.url + this.protocols = data.protocols + } } export abstract class WebSocketNetworkFrame extends NetworkFrame< @@ -37,11 +52,9 @@ export abstract class WebSocketNetworkFrame extends NetworkFrame< const { connection } = this.data this.events.emit( - new TypedEvent('connection', { - data: { - url: connection.client.url, - protocols: connection.info.protocols, - }, + new WebSocketConnectionEvent('connection', { + url: connection.client.url, + protocols: connection.info.protocols, }), ) From 61e54432b678cbb4d004a2e50f8b9dd7f6d5ed51 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 6 Feb 2026 11:40:28 +0100 Subject: [PATCH 40/68] fix(worker): return worker registration from `start` --- src/browser/glossary.ts | 3 +++ src/browser/setup-worker.ts | 12 ++++++++--- src/browser/sources/service-worker-source.ts | 21 +++++++++++--------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/browser/glossary.ts b/src/browser/glossary.ts index cfac396d1..c3e7e637c 100644 --- a/src/browser/glossary.ts +++ b/src/browser/glossary.ts @@ -62,6 +62,9 @@ export type StartHandler = ( export type StopHandler = () => void +/** + * @deprecated Use the `SetupWorkerApi` type instead. + */ export interface SetupWorker { /** * Registers and activates the mock Service Worker. diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index c0ef3606b..2ba6d5a3f 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -13,10 +13,10 @@ import { devUtils } from '#core/utils/internal/devUtils' import { supportsServiceWorker } from './utils/supports' import { ServiceWorkerSource } from './sources/service-worker-source' import { FallbackHttpSource } from './sources/fallback-http-source' -import { type FindWorker } from './glossary' +import type { FindWorker, StartReturnType } from './glossary' export interface SetupWorkerApi extends NetworkHandlersApi { - start: (options?: SetupWorkerStartOptions) => Promise + start: (options?: SetupWorkerStartOptions) => StartReturnType stop: () => void events: LifeCycleEventEmitter< HttpNetworkFrameEventMap | WebSocketNetworkFrameEventMap @@ -49,7 +49,6 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { ), ) - let isStarted = false const network = defineNetwork< Array >({ @@ -57,6 +56,8 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { handlers, }) + let isStarted = false + return { async start(options) { /** @@ -102,6 +103,11 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { if (!options?.quiet) { await httpSource.printStartMessage() } + + if (httpSource instanceof ServiceWorkerSource) { + const [, registration] = await httpSource.workerPromise + return registration + } }, stop() { network.disable() diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index 4ea010bf2..12d735755 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -44,11 +44,14 @@ type WorkerChannelClient = export class ServiceWorkerSource extends NetworkSource { #frames: Map #channel: WorkerChannel - #workerPromise: DeferredPromise<[ServiceWorker, ServiceWorkerRegistration]> #clientPromise?: Promise #keepAliveInterval?: number #stoppedAt?: number + public workerPromise: DeferredPromise< + [ServiceWorker, ServiceWorkerRegistration] + > + constructor(private readonly options: ServiceWorkerSourceOptions) { super() @@ -58,21 +61,21 @@ export class ServiceWorkerSource extends NetworkSource worker), + worker: this.workerPromise.then(([worker]) => worker), }) } public async enable(): Promise { this.#stoppedAt = undefined - if (this.#workerPromise.state !== 'pending') { + if (this.workerPromise.state !== 'pending') { devUtils.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.#workerPromise.then(([, registration]) => registration) + return this.workerPromise.then(([, registration]) => registration) } const [worker, registration] = await this.#startWorker() @@ -114,7 +117,7 @@ export class ServiceWorkerSource extends NetworkSource Date: Fri, 6 Feb 2026 11:47:29 +0100 Subject: [PATCH 41/68] fix(worker): dispatch "msw:worker/stop" on `stop` --- src/browser/setup-worker.ts | 1 + src/core/ws.ts | 12 ++++++------ test/browser/ws-api/ws.clients.browser.test.ts | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 2ba6d5a3f..fae3a14cc 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -110,6 +110,7 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { } }, stop() { + window.postMessage({ type: 'msw/worker:stop' }) network.disable() }, events: network.events, diff --git a/src/core/ws.ts b/src/core/ws.ts index 745615951..376dbe195 100644 --- a/src/core/ws.ts +++ b/src/core/ws.ts @@ -8,7 +8,7 @@ import { kEmitter, type WebSocketHandlerEventMap, } from './handlers/WebSocketHandler' -import { Path, isPath } from './utils/matching/matchRequestUrl' +import { type Path, isPath } from './utils/matching/matchRequestUrl' import { WebSocketClientManager } from './ws/WebSocketClientManager' function isBroadcastChannelWithUnref( @@ -47,10 +47,10 @@ export type WebSocketLink = { * * @see {@link https://mswjs.io/docs/api/ws#onevent-listener `on()` API reference} */ - addEventListener( + addEventListener: ( event: EventType, listener: WebSocketEventListener, - ): WebSocketHandler + ) => WebSocketHandler /** * Broadcasts the given data to all WebSocket clients. @@ -63,7 +63,7 @@ export type WebSocketLink = { * * @see {@link https://mswjs.io/docs/api/ws#broadcastdata `broadcast()` API reference} */ - broadcast(data: WebSocketData): void + broadcast: (data: WebSocketData) => void /** * Broadcasts the given data to all WebSocket clients @@ -77,12 +77,12 @@ export type WebSocketLink = { * * @see {@link https://mswjs.io/docs/api/ws#broadcastexceptclients-data `broadcast()` API reference} */ - broadcastExcept( + broadcastExcept: ( clients: | WebSocketClientConnectionProtocol | Array, data: WebSocketData, - ): void + ) => void } /** diff --git a/test/browser/ws-api/ws.clients.browser.test.ts b/test/browser/ws-api/ws.clients.browser.test.ts index 6b3e8c345..df53c86ca 100644 --- a/test/browser/ws-api/ws.clients.browser.test.ts +++ b/test/browser/ws-api/ws.clients.browser.test.ts @@ -207,7 +207,7 @@ test('clears the list of clients when the worker is stopped', async ({ // Must purge the local storage on reload. // The worker has been started as a part of the test, not runtime, // so it will start with empty clients. - expect(await page.evaluate(() => window.link.clients.size)).toBe(0) + await expect(page.evaluate(() => window.link.clients.size)).resolves.toBe(0) }) test('clears the list of clients when the page is reloaded', async ({ From d676202110191c437660c9024fd76350e57871b5 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 6 Feb 2026 11:53:42 +0100 Subject: [PATCH 42/68] fix: forward `quiet` onto handled resolution context --- src/browser/setup-worker.ts | 1 + src/core/future/frames/http-frame.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index fae3a14cc..5407ed1c7 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -79,6 +79,7 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { options: options?.serviceWorker?.options, }, findWorker: options?.findWorker, + quiet: options?.quiet, }) : new FallbackHttpSource() diff --git a/src/core/future/frames/http-frame.ts b/src/core/future/frames/http-frame.ts index ada5eef66..78f6b337c 100644 --- a/src/core/future/frames/http-frame.ts +++ b/src/core/future/frames/http-frame.ts @@ -145,6 +145,7 @@ export abstract class HttpNetworkFrame extends NetworkFrame< handlers, resolutionContext: { baseUrl: resolutionContext?.baseUrl?.toString(), + quiet: resolutionContext?.quiet, }, }) }) From 061c3a67f3bdea57d61decf75ec916bfe6170c66 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 9 Feb 2026 18:14:27 +0100 Subject: [PATCH 43/68] chore: implement print start/stop messages as methods of sources --- src/browser/setup-worker.ts | 8 ++--- src/browser/sources/fallback-http-source.ts | 32 ++++++++++++++++++-- src/browser/sources/service-worker-source.ts | 6 +++- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 5407ed1c7..b2f9da1b1 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -81,7 +81,9 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { findWorker: options?.findWorker, quiet: options?.quiet, }) - : new FallbackHttpSource() + : new FallbackHttpSource({ + quiet: options?.quiet, + }) network.configure({ sources: [ @@ -101,10 +103,6 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { await network.enable() isStarted = true - if (!options?.quiet) { - await httpSource.printStartMessage() - } - if (httpSource instanceof ServiceWorkerSource) { const [, registration] = await httpSource.workerPromise return registration diff --git a/src/browser/sources/fallback-http-source.ts b/src/browser/sources/fallback-http-source.ts index 6cbdf67dd..8fae84169 100644 --- a/src/browser/sources/fallback-http-source.ts +++ b/src/browser/sources/fallback-http-source.ts @@ -3,14 +3,34 @@ import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' import { InterceptorSource } from '#core/future/sources/interceptor-source' import { devUtils } from '#core/utils/internal/devUtils' +interface FallbackHttpSourceOptions { + quiet?: boolean +} + export class FallbackHttpSource extends InterceptorSource { - constructor() { + constructor(private readonly options: FallbackHttpSourceOptions) { super({ interceptors: [new XMLHttpRequestInterceptor(), new FetchInterceptor()], }) } - public printStartMessage(): void { + public async enable(): Promise { + await super.enable() + + if (!this.options.quiet) { + this.#printStartMessage() + } + } + + public async disable(): Promise { + await super.disable() + + if (!this.options.quiet) { + this.#printStopMessage() + } + } + + #printStartMessage(): void { console.groupCollapsed( `%c${devUtils.formatMessage('Mocking enabled (fallback mode).')}`, 'color:orangered;font-weight:bold;', @@ -25,4 +45,12 @@ export class FallbackHttpSource extends InterceptorSource { console.log('Found an issue? https://github.com/mswjs/msw/issues') console.groupEnd() } + + #printStopMessage(): void { + // eslint-disable-next-line no-console + console.log( + `%c${devUtils.formatMessage('Mocking disabled.')}`, + 'color:orangered;font-weight:bold;', + ) + } } diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index 12d735755..12a273c1e 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -108,6 +108,10 @@ export class ServiceWorkerSource extends NetworkSource Date: Mon, 9 Feb 2026 18:30:35 +0100 Subject: [PATCH 44/68] fix(http-frame): emit `request:end` for bypassed requests --- src/core/future/frames/http-frame.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/future/frames/http-frame.ts b/src/core/future/frames/http-frame.ts index 78f6b337c..2a6f86d19 100644 --- a/src/core/future/frames/http-frame.ts +++ b/src/core/future/frames/http-frame.ts @@ -134,6 +134,7 @@ export abstract class HttpNetworkFrame extends NetworkFrame< // Requests wrapped in explicit `bypass(request)`. if (shouldBypassRequest(request)) { + this.events.emit(new RequestEvent('request:end', { requestId, request })) this.passthrough() return null } From 847c837a45be5b329fa8904bedad063e75297ce9 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 9 Feb 2026 18:31:05 +0100 Subject: [PATCH 45/68] fix(sw-source): set `url` on the response instance --- src/browser/sources/service-worker-source.ts | 23 ++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index 12a273c1e..c81ad2c52 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -237,13 +237,32 @@ Please consider using a custom "serviceWorker.url" option to point to the actual const fetchResponse = response.status === 0 ? Response.error() - : new FetchResponse(response.body, response) + : 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(response.status) + ? response.body + : null, + { + ...response, + /** + * 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, + }, + ) frame.events.emit( new ResponseEvent( isMockedResponse ? 'response:mocked' : 'response:bypass', { - requestId: request.id, + requestId: frame.data.id, request: fetchRequest, response: fetchResponse, isMockedResponse, From 4985c5f1bf9735b5d47a3141abe36bd5e01dc65e Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 9 Feb 2026 18:31:30 +0100 Subject: [PATCH 46/68] fix(setupWorker): dispatch `msw/worker:stop` after disabling network --- src/browser/setup-worker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index b2f9da1b1..6ded1790a 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -109,8 +109,8 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { } }, stop() { - window.postMessage({ type: 'msw/worker:stop' }) network.disable() + window.postMessage({ type: 'msw/worker:stop' }) }, events: network.events, use: network.use.bind(network), From d6b6cb30b61bad165e5cc0aa886e3b324d2ca322 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 9 Feb 2026 18:57:21 +0100 Subject: [PATCH 47/68] fix(setupWorker): support passthrough after stop --- src/browser/setup-worker.ts | 5 +- src/browser/sources/service-worker-source.ts | 25 +++---- .../setup-worker/life-cycle-events/on.test.ts | 74 ++++++++----------- 3 files changed, 47 insertions(+), 57 deletions(-) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index 6ded1790a..a5531df86 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -109,8 +109,9 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { } }, stop() { - network.disable() - window.postMessage({ type: 'msw/worker:stop' }) + network.disable().then(() => { + window.postMessage({ type: 'msw/worker:stop' }) + }) }, events: network.events, use: network.use.bind(network), diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index c81ad2c52..80ae172a1 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -78,6 +78,7 @@ export class ServiceWorkerSource extends NetworkSource registration) } + this.#channel.removeAllListeners() const [worker, registration] = await this.#startWorker() if (worker.state !== 'activated') { @@ -120,10 +121,11 @@ export class ServiceWorkerSource extends NetworkSource { const consoleSpy = spyOnConsole() await loadExample(ON_EXAMPLE) @@ -55,11 +54,9 @@ test('emits events for a handled request and mocked response', async ({ await fetch(url) const requestId = getRequestId(consoleSpy) - await waitFor(() => { - expect(consoleSpy.get('warning')).toContainEqual( - expect.stringContaining('[response:mocked]'), - ) - }) + await expect + .poll(() => consoleSpy.get('warning')) + .toContainEqual(expect.stringContaining('[response:mocked]')) expect(consoleSpy.get('warning')).toEqual([ `[request:start] GET ${url} ${requestId}`, @@ -73,7 +70,6 @@ test('emits events for a handled request with no response', async ({ loadExample, spyOnConsole, fetch, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(ON_EXAMPLE) @@ -82,11 +78,9 @@ test('emits events for a handled request with no response', async ({ await fetch(url, { method: 'POST' }) const requestId = getRequestId(consoleSpy) - await waitFor(() => { - expect(consoleSpy.get('warning')).toContainEqual( - expect.stringContaining('[response:bypass]'), - ) - }) + await expect + .poll(() => consoleSpy.get('warning')) + .toContainEqual(expect.stringContaining('[response:bypass]')) expect(consoleSpy.get('warning')).toEqual([ `[request:start] POST ${url} ${requestId}`, @@ -99,7 +93,6 @@ test('emits events for an unhandled request', async ({ loadExample, spyOnConsole, fetch, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(ON_EXAMPLE) @@ -108,11 +101,9 @@ test('emits events for an unhandled request', async ({ await fetch(url) const requestId = getRequestId(consoleSpy) - await waitFor(() => { - expect(consoleSpy.get('warning')).toContainEqual( - expect.stringContaining('[response:bypass]'), - ) - }) + await expect + .poll(() => consoleSpy.get('warning')) + .toContainEqual(expect.stringContaining('[response:bypass]')) expect(consoleSpy.get('warning')).toEqual([ `[request:start] GET ${url} ${requestId}`, @@ -126,7 +117,6 @@ test('emits events for a passthrough request', async ({ loadExample, spyOnConsole, fetch, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(ON_EXAMPLE) @@ -138,20 +128,19 @@ test('emits events for a passthrough request', async ({ await fetch(url) const requestId = getRequestId(consoleSpy) - await waitFor(() => { - expect(consoleSpy.get('warning')).toEqual([ + await expect + .poll(() => consoleSpy.get('warning')) + .toEqual([ `[request:start] GET ${url} ${requestId}`, `[request:end] GET ${url} ${requestId}`, `[response:bypass] 200 ${url} passthrough-response GET ${url} ${requestId}`, ]) - }) }) test('emits events for a bypassed request', async ({ loadExample, spyOnConsole, fetch, - waitFor, page, }) => { const consoleSpy = spyOnConsole() @@ -163,9 +152,10 @@ test('emits events for a bypassed request', async ({ const url = server.http.url('/bypass') await fetch(url) - await waitFor(() => { - // First, must print the events for the original (mocked) request. - expect(consoleSpy.get('warning')).toEqual( + // First, must print the events for the original (mocked) request. + await expect + .poll(() => consoleSpy.get('warning')) + .toEqual( expect.arrayContaining([ expect.stringContaining(`[request:start] GET ${url}`), expect.stringContaining(`[request:end] GET ${url}`), @@ -175,19 +165,18 @@ test('emits events for a bypassed request', async ({ ]), ) - // Then, must also print events for the bypassed request. - expect(consoleSpy.get('warning')).toEqual( - expect.arrayContaining([ - expect.stringContaining(`[request:start] POST ${url}`), - expect.stringContaining(`[request:end] POST ${url}`), - expect.stringContaining( - `[response:bypass] 200 ${url} bypassed-response POST ${url}`, - ), - ]), - ) + // Then, must also print events for the bypassed request. + expect(consoleSpy.get('warning')).toEqual( + expect.arrayContaining([ + expect.stringContaining(`[request:start] POST ${url}`), + expect.stringContaining(`[request:end] POST ${url}`), + expect.stringContaining( + `[response:bypass] 200 ${url} bypassed-response POST ${url}`, + ), + ]), + ) - expect(pageErrors).toEqual([]) - }) + expect(pageErrors).toEqual([]) }) test('emits unhandled exceptions in the request handler', async ({ @@ -210,7 +199,6 @@ test('emits unhandled exceptions in the request handler', async ({ test('stops emitting events once the worker is stopped', async ({ loadExample, spyOnConsole, - fetch, page, }) => { const consoleSpy = spyOnConsole() @@ -219,7 +207,9 @@ test('stops emitting events once the worker is stopped', async ({ await page.evaluate(() => { return window.msw.worker.stop() }) - await fetch('/unknown-route') + + const url = server.http.url('/passthrough') + await page.evaluate((url) => fetch(url), url) expect(consoleSpy.get('warning')).toBeUndefined() }) From 56d48b73b45a360927ccb5945355a83660ac200e Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 9 Feb 2026 22:07:50 +0100 Subject: [PATCH 48/68] test: refactor ws.clients test --- test/browser/ws-api/ws.clients.browser.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/browser/ws-api/ws.clients.browser.test.ts b/test/browser/ws-api/ws.clients.browser.test.ts index df53c86ca..10a3225b4 100644 --- a/test/browser/ws-api/ws.clients.browser.test.ts +++ b/test/browser/ws-api/ws.clients.browser.test.ts @@ -231,7 +231,7 @@ test('clears the list of clients when the page is reloaded', async ({ await enableMocking() - expect(await page.evaluate(() => window.link.clients.size)).toBe(0) + await expect(page.evaluate(() => window.link.clients.size)).resolves.toBe(0) await page.evaluate(async () => { const ws = new WebSocket('wss://example.com') @@ -239,7 +239,7 @@ test('clears the list of clients when the page is reloaded', async ({ }) // Must return the number of joined clients. - expect(await page.evaluate(() => window.link.clients.size)).toBe(1) + await expect(page.evaluate(() => window.link.clients.size)).resolves.toBe(1) await page.reload() await enableMocking() @@ -247,5 +247,5 @@ test('clears the list of clients when the page is reloaded', async ({ // Must purge the local storage on reload. // The worker has been started as a part of the test, not runtime, // so it will start with empty clients. - expect(await page.evaluate(() => window.link.clients.size)).toBe(0) + await expect(page.evaluate(() => window.link.clients.size)).resolves.toBe(0) }) From e2af5aa5404c92c0f7e5e88b7dfb4373c3f4e759 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 9 Feb 2026 22:25:18 +0100 Subject: [PATCH 49/68] fix(setupWorker): simplify the handler exception error message --- src/browser/sources/service-worker-source.ts | 9 ++----- .../scenarios/errors/internal-error.test.ts | 25 ++++++++----------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index 80ae172a1..25cba1ea8 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -382,15 +382,10 @@ class ServiceWorkerHttpNetworkFrame extends HttpNetworkFrame { } if (reason instanceof Error) { - devUtils.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`, + devUtils.warn( + `Uncaught exception in the request handler for "%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`, this.data.request.method, this.data.request.url, - reason.stack ?? reason, ) // Treat exceptions during the request handling as 500 responses. diff --git a/test/browser/msw-api/setup-worker/scenarios/errors/internal-error.test.ts b/test/browser/msw-api/setup-worker/scenarios/errors/internal-error.test.ts index 0a4735fb2..f60c4460a 100644 --- a/test/browser/msw-api/setup-worker/scenarios/errors/internal-error.test.ts +++ b/test/browser/msw-api/setup-worker/scenarios/errors/internal-error.test.ts @@ -4,42 +4,39 @@ test('propagates the exception originating from a handled request', async ({ loadExample, spyOnConsole, fetch, - waitFor, makeUrl, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./internal-error.mocks.ts', import.meta.url)) const endpointUrl = makeUrl('/user') - const res = await fetch(endpointUrl) + const response = await fetch(endpointUrl) // Expect the exception to be handled as a 500 error response. - expect(res.status()).toBe(500) - expect(res.statusText()).toBe('Request Handler Error') - expect(await res.json()).toEqual({ + expect.soft(response.status()).toBe(500) + expect.soft(response.statusText()).toBe('Request Handler Error') + await expect(response.json()).resolves.toEqual({ name: 'Error', message: 'Custom error message', stack: expect.stringContaining('Error: Custom error message'), }) // Expect standard request failure message from the browser. - await waitFor(() => { - expect(consoleSpy.get('error')).toEqual( + await expect + .poll(() => consoleSpy.get('error')) + .toEqual( expect.arrayContaining([ expect.stringContaining( 'Failed to load resource: the server responded with a status of 500', ), ]), ) - }) - expect(consoleSpy.get('error')).toEqual( + expect(consoleSpy.get('warning')).toEqual( expect.arrayContaining([ - expect.stringContaining(`\ -[MSW] Uncaught exception in the request handler for "GET ${endpointUrl}": - -Error: Custom error message -`), + expect.stringContaining( + `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`, + ), ]), ) }) From ea91f997bbe48a83742a29bf551ab27c8d5f1404 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Mon, 9 Feb 2026 22:27:49 +0100 Subject: [PATCH 50/68] fix(setupWorker): add redundant `worker.stop()` warning --- src/browser/sources/service-worker-source.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index 25cba1ea8..02b540a4e 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -119,6 +119,14 @@ export class ServiceWorkerSource extends NetworkSource { await super.disable() + if (typeof this.#stoppedAt !== 'undefined') { + devUtils.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.#stoppedAt = Date.now() this.#frames.clear() this.workerPromise = new DeferredPromise() From 96719b9272f73f5b41603d79b135b8b6050b3ba7 Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 13 Feb 2026 13:13:09 +0100 Subject: [PATCH 51/68] fix(setupWorker): add deprecated `waitUntilReady` start option --- src/browser/setup-worker.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/browser/setup-worker.ts b/src/browser/setup-worker.ts index a5531df86..e10055889 100644 --- a/src/browser/setup-worker.ts +++ b/src/browser/setup-worker.ts @@ -31,6 +31,13 @@ interface SetupWorkerStartOptions { } findWorker?: FindWorker onUnhandledRequest?: UnhandledRequestStrategy + + /** + * @deprecated + * Please use a proper browser integration instead. + * @see https://mswjs.io/docs/integrations/browser + */ + waitUntilReady?: boolean } const DEFAULT_WORKER_URL = '/mockServiceWorker.js' @@ -60,6 +67,12 @@ export function setupWorker(...handlers: Array): SetupWorkerApi { return { async start(options) { + if (options?.waitUntilReady != null) { + devUtils.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.`, + ) + } + /** * @todo @fixme * This is kept for backward-compatibility reasons. We don't really need this check anymore. From 56e59ab6626ad272878afb3e02433de99af30b8a Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 13 Feb 2026 15:09:58 +0100 Subject: [PATCH 52/68] fix(ws): attach logger before `connection` is emitted --- src/core/future/frames/websocket-frame.ts | 39 ++++- src/core/handlers/WebSocketHandler.ts | 28 ++- src/core/ws/utils/attachWebSocketLogger.ts | 54 ++++-- .../browser/ws-api/ws.logging.browser.test.ts | 160 ++++++++++-------- 4 files changed, 184 insertions(+), 97 deletions(-) diff --git a/src/core/future/frames/websocket-frame.ts b/src/core/future/frames/websocket-frame.ts index 2045a4a75..ddc455475 100644 --- a/src/core/future/frames/websocket-frame.ts +++ b/src/core/future/frames/websocket-frame.ts @@ -1,6 +1,10 @@ import { TypedEvent } from 'rettime' import { type WebSocketConnectionData } from '@mswjs/interceptors/WebSocket' -import { type WebSocketHandler } from '../../handlers/WebSocketHandler' +import { + kConnect, + kAutoConnect, + type WebSocketHandler, +} from '../../handlers/WebSocketHandler' import { NetworkFrame, type NetworkFrameResolutionContext, @@ -58,29 +62,46 @@ export abstract class WebSocketNetworkFrame extends NetworkFrame< }), ) + // No WebSocket handlers defined. if (handlers.length === 0) { return false } const matchingHandlers = await Promise.all( - handlers.map(async (handler) => { - const matches = await handler.run(connection, { + handlers.filter(async (handler) => { + const handlerConnection = await handler.run(connection, { baseUrl: resolutionContext?.baseUrl?.toString(), + /** + * @note Do not emit the "connection" event when running the handler. + * Use the run only to get the resolved connection object. + */ + [kAutoConnect]: false, }) - if (!matches) { - return null + if (!handlerConnection) { + return false } - if (!resolutionContext?.quiet) { - handler.log(connection) + /** + * @note Attach the WebSocket logger *before* emitting the "connection" event. + * Connection event listeners may perform actions that should be reflected in the logs + * (e.g. closing the connection immediately). If the logger is attached after the connection, + * those actions cannot be properly logged. + */ + const removeLogger = !resolutionContext?.quiet + ? handler.log(connection) + : undefined + + if (!handler[kConnect](handlerConnection)) { + removeLogger?.() } - return handler + return true }), ) - if (matchingHandlers.every((handler) => handler == null)) { + // No matching WebSocket handlers found. + if (matchingHandlers.length === 0) { this.passthrough() return null } diff --git a/src/core/handlers/WebSocketHandler.ts b/src/core/handlers/WebSocketHandler.ts index b3274198d..8edca8299 100644 --- a/src/core/handlers/WebSocketHandler.ts +++ b/src/core/handlers/WebSocketHandler.ts @@ -31,10 +31,14 @@ export interface WebSocketHandlerConnection { export interface WebSocketResolutionContext { baseUrl?: string + [kAutoConnect]?: boolean } export const kEmitter = Symbol('kEmitter') export const kSender = Symbol('kSender') +export const kConnect = Symbol('kConnect') +export const kAutoConnect = Symbol('kAutoConnect') + const kStopPropagationPatched = Symbol('kStopPropagationPatched') const KOnStopPropagation = Symbol('KOnStopPropagation') @@ -93,16 +97,16 @@ export class WebSocketHandler { } public async run( - connection: Omit, + connection: WebSocketConnectionData, resolutionContext?: WebSocketResolutionContext, - ): Promise { + ): Promise { const parsedResult = this.parse({ url: connection.client.url, resolutionContext, }) if (!this.predicate({ url: connection.client.url, parsedResult })) { - return false + return null } const resolvedConnection: WebSocketHandlerConnection = { @@ -110,10 +114,18 @@ export class WebSocketHandler { params: parsedResult.match.params || {}, } - return this.connect(resolvedConnection) + if (resolutionContext?.[kAutoConnect]) { + if (this[kConnect](resolvedConnection)) { + return resolvedConnection + } + + return null + } + + return resolvedConnection } - protected connect(connection: WebSocketHandlerConnection): boolean { + protected [kConnect](connection: WebSocketHandlerConnection): boolean { // Support `event.stopPropagation()` for various client/server events. connection.client.addEventListener( 'message', @@ -141,13 +153,11 @@ export class WebSocketHandler { createStopPropagationListener(this), ) - // Emit the connection event on the handler. - // This is what the developer adds listeners for. return this[kEmitter].emit('connection', connection) } - public log(connection: WebSocketConnectionData): void { - attachWebSocketLogger(connection) + public log(connection: WebSocketConnectionData): () => void { + return attachWebSocketLogger(connection) } #resolveWebSocketUrl(url: string, baseUrl?: string): string { diff --git a/src/core/ws/utils/attachWebSocketLogger.ts b/src/core/ws/utils/attachWebSocketLogger.ts index 91ecd92f5..0afba3298 100644 --- a/src/core/ws/utils/attachWebSocketLogger.ts +++ b/src/core/ws/utils/attachWebSocketLogger.ts @@ -18,8 +18,9 @@ export const colors = { export function attachWebSocketLogger( connection: WebSocketConnectionData, -): void { +): () => void { const { client, server } = connection + const controller = new AbortController() logConnectionOpen(client) @@ -30,19 +31,32 @@ export function attachWebSocketLogger( * @todo Provide the reference to the exact event handler * that called this `client.send()`. */ - client.addEventListener('message', (event) => { - logOutgoingClientMessage(event) - }) + client.addEventListener( + 'message', + (event) => { + logOutgoingClientMessage(event) + }, + { signal: controller.signal }, + ) - client.addEventListener('close', (event) => { - logConnectionClose(event) - }) + client.addEventListener( + 'close', + (event) => { + logConnectionClose(event) + }, + { signal: controller.signal }, + ) // Log client errors (connection closures due to errors). - client.socket.addEventListener('error', (event) => { - logClientError(event) - }) + client.socket.addEventListener( + 'error', + (event) => { + logClientError(event) + }, + { signal: controller.signal }, + ) + const { send: originalClientSend } = client client.send = new Proxy(client.send, { apply(target, thisArg, args) { const [data] = args @@ -75,11 +89,15 @@ export function attachWebSocketLogger( logIncomingServerMessage(event) }) }, - { once: true }, + { + once: true, + signal: controller.signal, + }, ) // Log outgoing client events initiated by the event handler. // The actual client never sent these but the handler did. + const { send: originalServerSend } = server server.send = new Proxy(server.send, { apply(target, thisArg, args) { const [data] = args @@ -102,6 +120,20 @@ export function attachWebSocketLogger( return Reflect.apply(target, thisArg, args) }, }) + + // Undo method proxies. + controller.signal.addEventListener( + 'abort', + () => { + client.send = originalClientSend + server.send = originalServerSend + }, + { once: true }, + ) + + return () => { + controller.abort() + } } /** diff --git a/test/browser/ws-api/ws.logging.browser.test.ts b/test/browser/ws-api/ws.logging.browser.test.ts index 78a00ea17..c8b880078 100644 --- a/test/browser/ws-api/ws.logging.browser.test.ts +++ b/test/browser/ws-api/ws.logging.browser.test.ts @@ -45,12 +45,45 @@ test('does not log anything if "quiet" was set to "true"', async ({ expect(consoleSpy.get('startGroupCollapsed')).toBeUndefined() }) -test('logs the open event', async ({ +test('does not log anything if there are no matching event handlers', async ({ loadExample, page, spyOnConsole, - waitFor, + defineWebSocketServer, }) => { + const server = await defineWebSocketServer() + const consoleSpy = spyOnConsole() + await loadExample(new URL('./ws.runtime.js', import.meta.url), { + skipActivation: true, + }) + + server.once('connection', (client) => { + client.close() + }) + + await page.evaluate(async () => { + const { setupWorker, ws } = window.msw + // Create an event handler that doesn't match the WebSocket connection. + const api = ws.link('wss://localhost/one') + const worker = setupWorker(api.addEventListener('connection', () => {})) + await worker.start() + }) + + await page.evaluate((serverUrl) => { + const ws = new WebSocket(serverUrl) + + return new Promise((resolve, reject) => { + ws.onopen = () => resolve() + ws.onerror = () => reject(new Error('Client connection errored')) + }) + }, server.url) + + expect(consoleSpy.get('startGroupCollapsed')).not.toEqual( + expect.arrayContaining([expect.stringContaining(server.url)]), + ) +}) + +test('logs the open event', async ({ loadExample, page, spyOnConsole }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { skipActivation: true, @@ -67,22 +100,21 @@ test('logs the open event', async ({ new WebSocket('wss://localhost/path') }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2} %c▶%c wss:\/\/localhost\/path color:#3b82f6 color:inherit$/, ), ]), ) - }) }) test('logs the close event initiated by the client', async ({ loadExample, page, spyOnConsole, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { @@ -101,22 +133,22 @@ test('logs the close event initiated by the client', async ({ ws.onopen = () => ws.close() }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c■%c wss:\/\/localhost\/path color:#3b82f6 color:inherit$/, ), ]), ) - }) }) test('logs the close event initiated by the original server', async ({ loadExample, spyOnConsole, page, - waitFor, + defineWebSocketServer, }) => { const server = await defineWebSocketServer() @@ -144,22 +176,21 @@ test('logs the close event initiated by the original server', async ({ new WebSocket(url) }, server.url) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c■%c ws:\/\/(.+):\d{4,}\/ color:#3b82f6 color:inherit$/, ), ]), ) - }) }) test('logs the close event initiated by the event handler', async ({ loadExample, page, spyOnConsole, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { @@ -181,22 +212,21 @@ test('logs the close event initiated by the event handler', async ({ new WebSocket('wss://localhost/path') }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c■%c wss:\/\/localhost\/path color:#3b82f6 color:inherit$/, ), ]), ) - }) }) test('logs outgoing client message sending text', async ({ loadExample, page, spyOnConsole, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { @@ -215,22 +245,21 @@ test('logs outgoing client message sending text', async ({ ws.onopen = () => ws.send('hello world') }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬆%c hello world %c11%c color:#22c55e color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('logs outgoing client message sending long text', async ({ loadExample, page, spyOnConsole, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { @@ -249,22 +278,21 @@ test('logs outgoing client message sending long text', async ({ ws.onopen = () => ws.send('this is an extremely long sentence to log out') }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬆%c this is an extremely lon… %c45%c color:#22c55e color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('logs outgoing client message sending Blob', async ({ loadExample, page, spyOnConsole, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { @@ -283,22 +311,21 @@ test('logs outgoing client message sending Blob', async ({ ws.onopen = () => ws.send(new Blob(['hello world'])) }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬆%c Blob\(hello world\) %c11%c color:#22c55e color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('logs outgoing client message sending long Blob', async ({ loadExample, page, spyOnConsole, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { @@ -318,22 +345,21 @@ test('logs outgoing client message sending long Blob', async ({ ws.send(new Blob(['this is an extremely long sentence to log out'])) }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬆%c Blob\(this is an extremely lon…\) %c45%c color:#22c55e color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('logs outgoing client message sending ArrayBuffer data', async ({ loadExample, page, spyOnConsole, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { @@ -352,22 +378,21 @@ test('logs outgoing client message sending ArrayBuffer data', async ({ ws.onopen = () => ws.send(new TextEncoder().encode('hello world')) }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬆%c ArrayBuffer\(hello world\) %c11%c color:#22c55e color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('logs outgoing client message sending long ArrayBuffer', async ({ loadExample, page, spyOnConsole, - waitFor, }) => { const consoleSpy = spyOnConsole() await loadExample(new URL('./ws.runtime.js', import.meta.url), { @@ -391,22 +416,21 @@ test('logs outgoing client message sending long ArrayBuffer', async ({ ) }) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬆%c ArrayBuffer\(this is an extremely lon…\) %c45%c color:#22c55e color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('logs incoming server messages', async ({ loadExample, page, spyOnConsole, - waitFor, defineWebSocketServer, }) => { const server = await defineWebSocketServer() @@ -446,33 +470,33 @@ test('logs incoming server messages', async ({ }, server.url) // Initial message sent to every connected client. - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬇%c hello from server %c17%c color:#ef4444 color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) // Message sent in response to a client message. - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬇%c thanks, not bad %c15%c color:#ef4444 color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('logs raw incoming server events', async ({ loadExample, page, spyOnConsole, - waitFor, + defineWebSocketServer, }) => { const server = await defineWebSocketServer() @@ -507,8 +531,9 @@ test('logs raw incoming server events', async ({ new WebSocket(url) }, server.url) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ // The actual (raw) message received from the server. // The arrow is dotted because the message's default has been prevented. @@ -522,14 +547,13 @@ test('logs raw incoming server events', async ({ ), ]), ) - }) }) test('logs mocked outgoing client message (server.send)', async ({ loadExample, page, spyOnConsole, - waitFor, + defineWebSocketServer, }) => { const server = await defineWebSocketServer() @@ -554,22 +578,22 @@ test('logs mocked outgoing client message (server.send)', async ({ new WebSocket(url) }, server.url) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬆%c hello from handler %c18%c color:#ff6a33 color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('logs mocked incoming server message (client.send)', async ({ loadExample, page, spyOnConsole, - waitFor, + defineWebSocketServer, }) => { const server = await defineWebSocketServer() @@ -593,22 +617,22 @@ test('logs mocked incoming server message (client.send)', async ({ new WebSocket(url) }, server.url) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⬇%c hello from handler %c18%c color:#ff6a33 color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('marks the prevented outgoing client event as dashed', async ({ loadExample, page, spyOnConsole, - waitFor, + defineWebSocketServer, }) => { const server = await defineWebSocketServer() @@ -635,22 +659,22 @@ test('marks the prevented outgoing client event as dashed', async ({ socket.onopen = () => socket.send('hello world') }, server.url) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⇡%c hello world %c11%c color:#22c55e color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) test('marks the prevented incoming server event as dashed', async ({ loadExample, page, spyOnConsole, - waitFor, + defineWebSocketServer, }) => { const server = await defineWebSocketServer() @@ -681,13 +705,13 @@ test('marks the prevented incoming server event as dashed', async ({ new WebSocket(url) }, server.url) - await waitFor(() => { - expect(consoleSpy.get('raw')!.get('startGroupCollapsed')).toEqual( + await expect + .poll(() => consoleSpy.get('raw')!.get('startGroupCollapsed')) + .toEqual( expect.arrayContaining([ expect.stringMatching( /^\[MSW\] \d{2}:\d{2}:\d{2}\.\d{3} %c⇣%c hello from server %c17%c color:#ef4444 color:inherit color:gray;font-weight:normal color:inherit;font-weight:inherit$/, ), ]), ) - }) }) From ed5e2ff12b7dddc52c632c9b90160a1b41cd49ca Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 13 Feb 2026 21:13:48 +0100 Subject: [PATCH 53/68] fix: execute unhandled frame handle as a part of `frame.resolve` --- src/core/future/compat.ts | 6 +- src/core/future/define-network.ts | 14 +- src/core/future/frames/http-frame.ts | 15 +- src/core/future/frames/network-frame.ts | 2 + src/core/future/frames/websocket-frame.ts | 18 ++- src/core/future/on-unhandled-frame.ts | 60 +++++--- src/core/utils/request/onUnhandledRequest.ts | 4 +- .../callback-print.mocks.ts | 21 +-- .../callback-print.test.ts | 129 ++++++++++++++---- test/browser/playwright.extend.ts | 10 +- .../sse-api/sse.server.connect.test.ts | 20 +-- 11 files changed, 204 insertions(+), 95 deletions(-) diff --git a/src/core/future/compat.ts b/src/core/future/compat.ts index 4ea424d32..46e46b1ed 100644 --- a/src/core/future/compat.ts +++ b/src/core/future/compat.ts @@ -4,7 +4,7 @@ import { invariant } from 'outvariant' import { type UnhandledRequestStrategy } from '../utils/request/onUnhandledRequest' import { - onUnhandledFrame, + executeUnhandledFrameHandle, type UnhandledFrameCallback, } from './on-unhandled-frame' import { HttpNetworkFrame } from './frames/http-frame' @@ -16,7 +16,7 @@ export function fromLegacyOnUnhandledRequest( return ({ frame, defaults }) => { const legacyOnUnhandledRequestStrategy = getLegacyValue() - if (legacyOnUnhandledRequestStrategy === undefined) { + if (legacyOnUnhandledRequestStrategy == null) { return } @@ -45,6 +45,6 @@ export function fromLegacyOnUnhandledRequest( }) } - return onUnhandledFrame(frame, legacyOnUnhandledRequestStrategy) + return executeUnhandledFrameHandle(frame, legacyOnUnhandledRequestStrategy) } } diff --git a/src/core/future/define-network.ts b/src/core/future/define-network.ts index 9669c5fd4..62a5dd4de 100644 --- a/src/core/future/define-network.ts +++ b/src/core/future/define-network.ts @@ -6,7 +6,7 @@ import { getHandlerKindByFrame, } from './sources/network-source' import { type NetworkFrameResolutionContext } from './frames/network-frame' -import { onUnhandledFrame, UnhandledFrameHandle } from './on-unhandled-frame' +import { type UnhandledFrameHandle } from './on-unhandled-frame' import { AnyHandler, HandlersController, @@ -101,19 +101,11 @@ export function defineNetwork>>( getHandlerKindByFrame(frame), ) - const isHandledFrame = await frame.resolve( + await frame.resolve( matchingHandlers, + resolvedOptions.onUnhandledFrame || 'warn', resolvedOptions.context, ) - - if (isHandledFrame === false) { - await onUnhandledFrame( - frame, - resolvedOptions.onUnhandledFrame || 'warn', - ).catch((error) => { - frame.errorWith(error) - }) - } }, ) diff --git a/src/core/future/frames/http-frame.ts b/src/core/future/frames/http-frame.ts index 2a6f86d19..ecfaf58e7 100644 --- a/src/core/future/frames/http-frame.ts +++ b/src/core/future/frames/http-frame.ts @@ -8,6 +8,10 @@ import { executeHandlers } from '../../utils/executeHandlers' import { storeResponseCookies } from '../../utils/request/storeResponseCookies' import { isPassthroughResponse, shouldBypassRequest } from '../request-utils' import { devUtils } from '../../utils/internal/devUtils' +import { + executeUnhandledFrameHandle, + type UnhandledFrameHandle, +} from '../on-unhandled-frame' interface HttpNetworkFrameOptions { id?: string @@ -123,6 +127,7 @@ export abstract class HttpNetworkFrame extends NetworkFrame< public async resolve( handlers: Array, + onUnhandledFrame: UnhandledFrameHandle, resolutionContext?: NetworkFrameResolutionContext, ): Promise { const { id: requestId, request } = this.data @@ -183,6 +188,15 @@ export abstract class HttpNetworkFrame extends NetworkFrame< }), ) + /** + * @note The unhandled frame handle must be executed during the request resolution + * since it can influence it (e.g. error the request if the "error" startegy was used). + */ + await executeUnhandledFrameHandle(this, onUnhandledFrame).then( + () => this.passthrough(), + (error) => this.errorWith(error), + ) + this.events.emit( new RequestEvent('request:end', { requestId, @@ -190,7 +204,6 @@ export abstract class HttpNetworkFrame extends NetworkFrame< }), ) - this.passthrough() return false } diff --git a/src/core/future/frames/network-frame.ts b/src/core/future/frames/network-frame.ts index 660a9f972..8f42273be 100644 --- a/src/core/future/frames/network-frame.ts +++ b/src/core/future/frames/network-frame.ts @@ -1,5 +1,6 @@ import { Emitter, type DefaultEventMap } from 'rettime' import type { AnyHandler } from '../handlers-controller' +import type { UnhandledFrameHandle } from '../on-unhandled-frame' export type ExtractFrameEvents = Frame extends NetworkFrame ? Events : never @@ -33,6 +34,7 @@ export abstract class NetworkFrame< */ public abstract resolve( handlers: Array, + onUnhandledFrame: UnhandledFrameHandle, resolutionContext?: NetworkFrameResolutionContext, ): Promise diff --git a/src/core/future/frames/websocket-frame.ts b/src/core/future/frames/websocket-frame.ts index ddc455475..953bca301 100644 --- a/src/core/future/frames/websocket-frame.ts +++ b/src/core/future/frames/websocket-frame.ts @@ -9,6 +9,10 @@ import { NetworkFrame, type NetworkFrameResolutionContext, } from './network-frame' +import { + executeUnhandledFrameHandle, + UnhandledFrameHandle, +} from '../on-unhandled-frame' export interface WebSocketNetworkFrameOptions { connection: WebSocketConnectionData @@ -51,6 +55,7 @@ export abstract class WebSocketNetworkFrame extends NetworkFrame< public async resolve( handlers: Array, + onUnhandledFrame: UnhandledFrameHandle, resolutionContext?: NetworkFrameResolutionContext, ): Promise { const { connection } = this.data @@ -64,6 +69,11 @@ export abstract class WebSocketNetworkFrame extends NetworkFrame< // No WebSocket handlers defined. if (handlers.length === 0) { + await executeUnhandledFrameHandle(this, onUnhandledFrame).then( + () => this.passthrough(), + (error) => this.errorWith(error), + ) + return false } @@ -102,8 +112,12 @@ export abstract class WebSocketNetworkFrame extends NetworkFrame< // No matching WebSocket handlers found. if (matchingHandlers.length === 0) { - this.passthrough() - return null + await executeUnhandledFrameHandle(this, onUnhandledFrame).then( + () => this.passthrough(), + (error) => this.errorWith(error), + ) + + return false } return true diff --git a/src/core/future/on-unhandled-frame.ts b/src/core/future/on-unhandled-frame.ts index cd3a3b8e6..d7ac86b7a 100644 --- a/src/core/future/on-unhandled-frame.ts +++ b/src/core/future/on-unhandled-frame.ts @@ -1,3 +1,4 @@ +import { invariant } from 'outvariant' import { isCommonAssetRequest } from '../isCommonAssetRequest' import { devUtils, InternalError } from '../utils/internal/devUtils' import { HttpNetworkFrame } from './frames/http-frame' @@ -19,11 +20,13 @@ export type UnhandledFrameDefaults = { error: () => void } -export async function onUnhandledFrame( +export async function executeUnhandledFrameHandle( frame: AnyNetworkFrame, handle: UnhandledFrameHandle, ): Promise { - const applyStrategy = async (strategy: UnhandledFrameStrategy) => { + const printStrategyMessage = async ( + strategy: UnhandledFrameStrategy, + ): Promise => { if (strategy === 'bypass') { return } @@ -36,26 +39,37 @@ export async function onUnhandledFrame( } case 'error': { - // Print a developer-friendly error. - devUtils.error('Error: %s', message) - - return Promise.reject( - new InternalError( - devUtils.formatMessage( - 'Cannot bypass a request when using the "error" strategy for the "onUnhandledRequest" option.', - ), - ), - ) + return devUtils.error('Error: %s', message) } + } + } + + const applyStrategy = async ( + strategy: UnhandledFrameStrategy, + ): Promise => { + invariant.as( + InternalError, + strategy === 'bypass' || strategy === 'warn' || strategy === 'error', + devUtils.formatMessage( + 'Failed to react to an unhandled network frame: unknown strategy "%s". Please provide one of the supported strategies ("bypass", "warn", "error") or a custom callback function as the value of the "onUnhandledRequest" option.', + strategy, + ), + ) - default: { - throw new InternalError( + if (strategy === 'bypass') { + return + } + + await printStrategyMessage(strategy) + + if (strategy === 'error') { + return Promise.reject( + new InternalError( devUtils.formatMessage( - 'Failed to react to an unhandled network frame: unknown strategy "%s". Please provide one of the supported strategies ("bypass", "warn", "error") or a custom callback function as the value of the "onUnhandledRequest" option.', - strategy satisfies never, + 'Cannot bypass a request when using the "error" strategy for the "onUnhandledRequest" option.', ), - ) - } + ), + ) } } @@ -63,8 +77,14 @@ export async function onUnhandledFrame( return handle({ frame, defaults: { - warn: applyStrategy.bind(null, 'warn'), - error: applyStrategy.bind(null, 'error'), + warn: printStrategyMessage.bind(null, 'warn'), + /** + * @note The defaults only print the corresponding messages now. + * They do not affect the frame resolution (e.g. do not error the frame). + * That is only for backward compatibility reasons. In the future, these should + * be an alias to `applyStrategy.bind(null, 'error')` instead. + */ + error: printStrategyMessage.bind(null, 'error'), }, }) } diff --git a/src/core/utils/request/onUnhandledRequest.ts b/src/core/utils/request/onUnhandledRequest.ts index 3e1ff7080..e15987bc5 100644 --- a/src/core/utils/request/onUnhandledRequest.ts +++ b/src/core/utils/request/onUnhandledRequest.ts @@ -3,8 +3,8 @@ import { InternalError, devUtils } from '../internal/devUtils' import { isCommonAssetRequest } from '../../isCommonAssetRequest' export interface UnhandledRequestPrint { - warning(): void - error(): void + warning: () => void + error: () => void } export type UnhandledRequestCallback = ( diff --git a/test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.mocks.ts b/test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.mocks.ts index bd70c8252..1a8d1d556 100644 --- a/test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.mocks.ts +++ b/test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.mocks.ts @@ -1,22 +1,9 @@ -import { http, HttpResponse } from 'msw' import { setupWorker } from 'msw/browser' -const worker = setupWorker( - http.get('/user', () => { - return HttpResponse.json({ firstName: 'John' }) - }), -) +const worker = setupWorker() -worker.start({ - onUnhandledRequest(request, print) { - console.log(`Oops, unhandled ${request.method} ${request.url}`) - const url = new URL(request.url) - - if (url.pathname.includes('/use-warn')) { - // Using "print" allows you to execute the default strategy. - print.warning() - } else { - print.error() - } +Object.assign(window, { + msw: { + worker, }, }) diff --git a/test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.test.ts b/test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.test.ts index d7a884123..a508dd916 100644 --- a/test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.test.ts +++ b/test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.test.ts @@ -1,24 +1,58 @@ +import { createTestHttpServer } from '@epic-web/test-server/http' import { test, expect } from '../../../../playwright.extend' +import type { SetupWorkerApi } from '../../../../../../src/browser' + +declare namespace window { + export const msw: { + worker: SetupWorkerApi + } +} test('executes a default "warn" strategy in a custom callback', async ({ loadExample, spyOnConsole, + page, fetch, }) => { + await using server = await createTestHttpServer({ + defineRoutes(router) { + router.get('/resource', () => { + return new Response('original response', { + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE', + 'Access-Control-Allow-Headers': 'Content-Type', + }, + }) + }) + }, + }) + const consoleSpy = spyOnConsole() - await loadExample(new URL('./callback-print.mocks.ts', import.meta.url)) + await loadExample(new URL('./callback-print.mocks.ts', import.meta.url), { + skipActivation: true, + }) - const res = await fetch('https://mswjs.io/use-warn') - const status = res.status() + await page.evaluate(async () => { + await window.msw.worker.start({ + onUnhandledRequest(request, print) { + console.log(`Oops, unhandled ${request.method} ${request.url}`) + print.warning() + }, + }) + }) - // Request is performed as-is. - expect(status).toBe(404) + const url = server.http.url('/resource').href + const response = await fetch(url) - // Custom callback executed. - expect(consoleSpy.get('log')).toContain( - 'Oops, unhandled GET https://mswjs.io/use-warn', - ) - expect(consoleSpy.get('error')).toBeUndefined() + expect.soft(response.status(), 'Performs the request as-is').toBe(200) + await expect.soft(response.text()).resolves.toBe('original response') + expect + .soft(consoleSpy.get('log'), 'Executes the custom callback') + .toContain(`Oops, unhandled GET ${url}`) + expect + .soft(consoleSpy.get('error'), 'Does not print any errors') + .toBeUndefined() // Prints the unhandled request warning upon `print.warning()`. expect(consoleSpy.get('warning')).toEqual( @@ -26,44 +60,91 @@ test('executes a default "warn" strategy in a custom callback', async ({ expect.stringContaining(`\ [MSW] Warning: intercepted a request without a matching request handler: - • GET https://mswjs.io/use-warn + • GET ${url} If you still wish to intercept this unhandled request, please create a request handler for it. Read more: https://mswjs.io/docs/http/intercepting-requests`), ]), ) + + await page.waitForTimeout(1000) }) test('executes a default "error" strategy in a custom callback', async ({ loadExample, spyOnConsole, + page, fetch, }) => { + await using server = await createTestHttpServer({ + defineRoutes(router) { + router.get('/resource', () => { + return new Response('original response', { + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE', + 'Access-Control-Allow-Headers': 'Content-Type', + }, + }) + }) + }, + }) + const consoleSpy = spyOnConsole() - await loadExample(new URL('./callback-print.mocks.ts', import.meta.url)) + await loadExample(new URL('./callback-print.mocks.ts', import.meta.url), { + skipActivation: true, + }) - const res = await fetch('https://mswjs.io/use-error') - const status = res.status() + await page.evaluate(async () => { + await window.msw.worker.start({ + onUnhandledRequest(request, print) { + console.log(`Oops, unhandled ${request.method} ${request.url}`) + print.error() + }, + }) + }) - // Request is performed as-is. - expect(status).toBe(500) + const url = server.http.url('/resource') + const response = await fetch(url) - // Custom callback executed. - expect(consoleSpy.get('log')).toContain( - 'Oops, unhandled GET https://mswjs.io/use-error', - ) - expect(consoleSpy.get('warning')).toBeUndefined() + /** + * @note The custom unhandled request logic just prints the default error message, + * but the request is still performed. As of now, there's no way to both provide + * a custom callback and abort the request. + */ + expect.soft(response.status(), 'Performs the request as-is').toBe(200) + await expect.soft(response.text()).resolves.toBe('original response') + expect + .soft(consoleSpy.get('log'), 'Executes the custom callback') + .toContain(`Oops, unhandled GET ${url}`) + expect + .soft(consoleSpy.get('warning'), 'Does not print the default warning') + .toBeUndefined() - // Prints the unhandled request error upon `print.error()`. - expect(consoleSpy.get('error')).toEqual( + expect( + consoleSpy.get('error'), + `Prints the error from "print.error()"`, + ).toEqual( expect.arrayContaining([ expect.stringContaining(`\ [MSW] Error: intercepted a request without a matching request handler: - • GET https://mswjs.io/use-error + • GET ${url} If you still wish to intercept this unhandled request, please create a request handler for it. Read more: https://mswjs.io/docs/http/intercepting-requests`), ]), ) + expect( + consoleSpy.get('error'), + 'Does not print the failed bypass error', + ).not.toEqual( + expect.arrayContaining([ + expect.stringMatching( + `[MSW] Cannot bypass a request when using the "error" strategy for the "onUnhandledRequest" option.`, + ), + ]), + ) + + await page.waitForTimeout(1000) }) diff --git a/test/browser/playwright.extend.ts b/test/browser/playwright.extend.ts index 08b1a9da1..cd8909bea 100644 --- a/test/browser/playwright.extend.ts +++ b/test/browser/playwright.extend.ts @@ -42,7 +42,7 @@ export interface TestFixtures { workerConsole: WorkerConsole }> fetch( - url: string, + url: string | URL, init?: RequestInit, options?: FetchOptions, ): Promise @@ -179,18 +179,18 @@ export const test = base.extend({ // perform multiple requests in parallel. target.evaluate( ([url, init]) => fetch(url, init as RequestInit), - [url, resolvedInit], + [url.toString(), resolvedInit], ) - return target.waitForResponse(async (res) => { + return target.waitForResponse(async (response) => { if (typeof options.waitForResponse !== 'undefined') { - return options.waitForResponse(res) + return options.waitForResponse(response) } const { [identityHeaderName]: actualRequestId, ['x-msw-bypass']: isBypassRequest, - } = res.request().headers() + } = response.request().headers() return isBypassRequest !== 'true' && actualRequestId === requestId }) diff --git a/test/browser/sse-api/sse.server.connect.test.ts b/test/browser/sse-api/sse.server.connect.test.ts index 21eb1203a..bd1741901 100644 --- a/test/browser/sse-api/sse.server.connect.test.ts +++ b/test/browser/sse-api/sse.server.connect.test.ts @@ -29,8 +29,8 @@ test('makes the actual request when called "server.connect()"', async ({ }) await using server = await createTestHttpServer({ - defineRoutes(routes) { - routes.get('/stream', () => { + defineRoutes(router) { + router.get('/stream', () => { const stream = new ReadableStream({ start(controller) { controller.enqueue( @@ -85,8 +85,8 @@ test('forwards message event from the server to the client automatically', async }) await using server = await createTestHttpServer({ - defineRoutes(routes) { - routes.get('/stream', () => { + defineRoutes(router) { + router.get('/stream', () => { const stream = new ReadableStream({ start(controller) { controller.enqueue( @@ -141,8 +141,8 @@ test('forwards custom event from the server to the client automatically', async }) await using server = await createTestHttpServer({ - defineRoutes(routes) { - routes.get('/stream', () => { + defineRoutes(router) { + router.get('/stream', () => { const stream = new ReadableStream({ start(controller) { controller.enqueue( @@ -199,8 +199,8 @@ test('forwards error event from the server to the client automatically', async ( }) await using server = await createTestHttpServer({ - defineRoutes(routes) { - routes.get('/stream', () => { + defineRoutes(router) { + router.get('/stream', () => { const stream = new ReadableStream({ start(controller) { controller.error() @@ -251,8 +251,8 @@ test('forward custom stream errors from the original server to the client automa }) await using server = await createTestHttpServer({ - defineRoutes(routes) { - routes.get('/stream', () => { + defineRoutes(router) { + router.get('/stream', () => { const stream = new ReadableStream({ start(controller) { controller.error(new Error('Custom stream error')) From 31fe40fc621e521f90b45009de038f65dea6bcca Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 13 Feb 2026 21:22:15 +0100 Subject: [PATCH 54/68] fix(worker): add missing worker scope validation --- src/browser/sources/service-worker-source.ts | 5 +++++ src/browser/utils/validate-worker-scope.ts | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/browser/utils/validate-worker-scope.ts diff --git a/src/browser/sources/service-worker-source.ts b/src/browser/sources/service-worker-source.ts index 02b540a4e..54b0c0f8a 100644 --- a/src/browser/sources/service-worker-source.ts +++ b/src/browser/sources/service-worker-source.ts @@ -16,6 +16,7 @@ import { getWorkerInstance } from '../utils/get-worker-instance' import { WorkerChannel, WorkerChannelEventMap } from '../utils/workerChannel' import { FindWorker } from '../glossary' import { deserializeRequest } from '../utils/deserializeRequest' +import { validateWorkerScope } from '../utils/validate-worker-scope' export interface ServiceWorkerSourceOptions { quiet?: boolean @@ -198,6 +199,10 @@ Please consider using a custom "serviceWorker.url" option to point to the actual this.#channel.postMessage('KEEPALIVE_REQUEST') }, 5000) + if (!this.options.quiet) { + validateWorkerScope(registration) + } + return [worker, registration] as const } diff --git a/src/browser/utils/validate-worker-scope.ts b/src/browser/utils/validate-worker-scope.ts new file mode 100644 index 000000000..4a964c4db --- /dev/null +++ b/src/browser/utils/validate-worker-scope.ts @@ -0,0 +1,19 @@ +import { devUtils } from '#core/utils/internal/devUtils' + +/** + * Print a warning if the given Service Worker registration has a scope + * outside of the current page's location. That is to help with debugging + * issues caused by the incorrectly registered Service Worker. + */ +export function validateWorkerScope( + registration: ServiceWorkerRegistration, +): void { + if (!location.href.startsWith(registration.scope)) { + devUtils.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.`, + ) + } +} From 3b27f59edc720fbf4f437a58579165d2d3a36caf Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 13 Feb 2026 21:28:34 +0100 Subject: [PATCH 55/68] test(iframe): fix flaky test --- .../iframe-isolated-response.test.ts | 3 ++ .../iframe-isolated-response/one.html | 32 +++++++++---------- .../iframe-isolated-response/two.html | 32 +++++++++---------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/iframe-isolated-response.test.ts b/test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/iframe-isolated-response.test.ts index 0c5f62bb3..c76278f02 100644 --- a/test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/iframe-isolated-response.test.ts +++ b/test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/iframe-isolated-response.test.ts @@ -36,6 +36,9 @@ test('responds with different responses for the same request based on request re const frameOne = getFrameById('frame-one', page)! const frameTwo = getFrameById('frame-two', page)! + await frameOne.waitForFunction(() => window.request != null) + await frameTwo.waitForFunction(() => window.request != null) + await Promise.all([ frameOne.evaluate(() => window.request()), frameTwo.evaluate(() => window.request()), diff --git a/test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/one.html b/test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/one.html index 7f6f5aca8..a0c7dd6ef 100644 --- a/test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/one.html +++ b/test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/one.html @@ -1,25 +1,25 @@