From 46916e9229dc340fd8e574a9187de5c4c5bf1d8e Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 1 Jun 2026 15:02:40 -0700 Subject: [PATCH 1/4] fix(deps): upgrade vitest to ^4.1.0 to patch critical Vitest UI advisory (GHSA-5xrq-8626-4rwp) - Bump vitest and @vitest/coverage-v8 to ^4.1.0 across all workspaces (only patched release for the critical 'Vitest UI server arbitrary file read/execute' advisory; no 3.x backport exists) - Widen @sim/testing peer range to ^3.0.0 || ^4.0.0 - Migrate constructor mocks to class expressions: vitest 4 uses Reflect.construct for mocks invoked with new, and arrow/function implementations are not constructable (function expressions also get reverted to arrows by biome's useArrowFunction) - Remove deprecated test.poolOptions from apps/sim/vitest.config.ts (options are now top-level in vitest 4) --- apps/realtime/package.json | 2 +- .../copilot/checkpoints/revert/route.test.ts | 15 +- .../copilot/request/lifecycle/start.test.ts | 50 ++-- apps/sim/lib/core/config/redis.test.ts | 28 ++- .../core/rate-limiter/storage/factory.test.ts | 12 +- .../destinations/azure_blob.test.ts | 8 +- .../data-drains/destinations/bigquery.test.ts | 6 +- .../lib/data-drains/destinations/gcs.test.ts | 6 +- .../lib/data-drains/destinations/s3.test.ts | 27 +- apps/sim/lib/mcp/client.test.ts | 40 +-- apps/sim/lib/mcp/connection-manager.test.ts | 230 +++++++++++------- apps/sim/lib/mcp/service.test.ts | 22 +- apps/sim/lib/messaging/email/mailer.test.ts | 26 +- .../lib/uploads/providers/s3/client.test.ts | 15 +- .../workflows/executor/execution-core.test.ts | 25 +- apps/sim/package.json | 4 +- apps/sim/providers/baseten/index.test.ts | 8 +- apps/sim/providers/bedrock/index.test.ts | 8 +- apps/sim/providers/fireworks/index.test.ts | 8 +- apps/sim/providers/litellm/index.test.ts | 8 +- apps/sim/providers/ollama-cloud/index.test.ts | 12 +- apps/sim/providers/ollama/index.test.ts | 6 +- apps/sim/providers/openrouter/index.test.ts | 8 +- apps/sim/providers/together/index.test.ts | 8 +- apps/sim/providers/vllm/index.test.ts | 6 +- apps/sim/vitest.config.ts | 8 +- bun.lock | 128 +++------- packages/audit/package.json | 2 +- packages/logger/package.json | 2 +- packages/security/package.json | 2 +- packages/testing/package.json | 4 +- .../testing/src/mocks/logging-session.mock.ts | 32 +-- packages/testing/src/mocks/mcp-oauth.mock.ts | 8 +- packages/ts-sdk/package.json | 4 +- packages/utils/package.json | 2 +- 35 files changed, 447 insertions(+), 333 deletions(-) diff --git a/apps/realtime/package.json b/apps/realtime/package.json index a7ec69192bd..17f412773e1 100644 --- a/apps/realtime/package.json +++ b/apps/realtime/package.json @@ -43,6 +43,6 @@ "@types/node": "24.2.1", "socket.io-client": "4.8.1", "typescript": "^5.7.3", - "vitest": "^3.0.8" + "vitest": "^4.1.0" } } diff --git a/apps/sim/app/api/copilot/checkpoints/revert/route.test.ts b/apps/sim/app/api/copilot/checkpoints/revert/route.test.ts index 251578bbd80..9ce957da1ef 100644 --- a/apps/sim/app/api/copilot/checkpoints/revert/route.test.ts +++ b/apps/sim/app/api/copilot/checkpoints/revert/route.test.ts @@ -94,16 +94,23 @@ describe('Copilot Checkpoints Revert API Route', () => { vi.spyOn(Date, 'now').mockReturnValue(1640995200000) const originalDate = Date - vi.spyOn(global, 'Date').mockImplementation(((...args: any[]) => { + const buildDate = (args: any[]): Date => { if (args.length === 0) { - const mockDate = new originalDate('2024-01-01T00:00:00.000Z') - return mockDate + return new originalDate('2024-01-01T00:00:00.000Z') } if (args.length === 1) { return new originalDate(args[0]) } return new originalDate(args[0], args[1], args[2], args[3], args[4], args[5], args[6]) - }) as any) + } + vi.spyOn(global, 'Date').mockImplementation( + class { + constructor(...args: any[]) { + // biome-ignore lint/correctness/noConstructorReturn: vitest 4 constructs mocks via Reflect.construct; returning a real Date overrides the instance so `new Date(...)` yields a genuine Date the route can call .toISOString()/.getTime() on + return buildDate(args) + } + } as any + ) }) afterEach(() => { diff --git a/apps/sim/lib/copilot/request/lifecycle/start.test.ts b/apps/sim/lib/copilot/request/lifecycle/start.test.ts index e27f2a2919f..917c56ba339 100644 --- a/apps/sim/lib/copilot/request/lifecycle/start.test.ts +++ b/apps/sim/lib/copilot/request/lifecycle/start.test.ts @@ -65,31 +65,33 @@ vi.mock('@/lib/copilot/request/session', () => ({ startAbortPoller: vi.fn().mockReturnValue(setInterval(() => {}, 999999)), isExplicitStopReason: vi.fn().mockReturnValue(false), SSE_RESPONSE_HEADERS: {}, - StreamWriter: vi.fn().mockImplementation(() => ({ - attach: vi.fn().mockImplementation((ctrl: ReadableStreamDefaultController) => { - mockPublisherController = ctrl - }), - startKeepalive: vi.fn(), - stopKeepalive: vi.fn(), - flush: vi.fn(), - close: vi.fn().mockImplementation(() => { - try { - mockPublisherController?.close() - } catch { - // already closed + StreamWriter: vi.fn().mockImplementation( + class { + attach = vi.fn().mockImplementation((ctrl: ReadableStreamDefaultController) => { + mockPublisherController = ctrl + }) + startKeepalive = vi.fn() + stopKeepalive = vi.fn() + flush = vi.fn() + close = vi.fn().mockImplementation(() => { + try { + mockPublisherController?.close() + } catch { + // already closed + } + }) + markDisconnected = vi.fn() + publish = vi.fn().mockImplementation(async (event: Record) => { + appendEvent(event) + }) + get clientDisconnected() { + return false + } + get sawComplete() { + return false } - }), - markDisconnected: vi.fn(), - publish: vi.fn().mockImplementation(async (event: Record) => { - appendEvent(event) - }), - get clientDisconnected() { - return false - }, - get sawComplete() { - return false - }, - })), + } + ), })) vi.mock('@/lib/copilot/request/session/sse', () => ({ SSE_RESPONSE_HEADERS: {}, diff --git a/apps/sim/lib/core/config/redis.test.ts b/apps/sim/lib/core/config/redis.test.ts index 85ccc6c2e1a..7cd527d8ad0 100644 --- a/apps/sim/lib/core/config/redis.test.ts +++ b/apps/sim/lib/core/config/redis.test.ts @@ -6,7 +6,13 @@ const { MockRedisConstructor } = vi.hoisted(() => ({ })) const mockRedisInstance = createMockRedis() -MockRedisConstructor.mockImplementation(() => mockRedisInstance) +MockRedisConstructor.mockImplementation( + class { + constructor() { + Object.assign(this, mockRedisInstance) + } + } +) vi.mock('@/lib/core/config/env', () => createEnvMock({ REDIS_URL: 'redis://localhost:6379' })) vi.mock('ioredis', () => ({ @@ -26,7 +32,13 @@ describe('redis config', () => { vi.clearAllMocks() vi.useFakeTimers() resetForTesting() - MockRedisConstructor.mockImplementation(() => mockRedisInstance) + MockRedisConstructor.mockImplementation( + class { + constructor() { + Object.assign(this, mockRedisInstance) + } + } + ) }) afterEach(() => { @@ -197,10 +209,14 @@ describe('redis config', () => { describe('retryStrategy', () => { function captureRetryStrategy(): (times: number) => number { let capturedConfig: Record = {} - MockRedisConstructor.mockImplementation((_url: string, config: Record) => { - capturedConfig = config - return { ping: vi.fn(), on: vi.fn() } - }) + MockRedisConstructor.mockImplementation( + class { + constructor(_url: string, config: Record) { + capturedConfig = config + Object.assign(this, { ping: vi.fn(), on: vi.fn() }) + } + } + ) getRedisClient() diff --git a/apps/sim/lib/core/rate-limiter/storage/factory.test.ts b/apps/sim/lib/core/rate-limiter/storage/factory.test.ts index bd797d4beb2..4827d142d9a 100644 --- a/apps/sim/lib/core/rate-limiter/storage/factory.test.ts +++ b/apps/sim/lib/core/rate-limiter/storage/factory.test.ts @@ -19,11 +19,19 @@ vi.mock('@/lib/core/storage', () => ({ })) vi.mock('@/lib/core/rate-limiter/storage/db-token-bucket', () => ({ - DbTokenBucket: vi.fn(() => ({ type: 'db' })), + DbTokenBucket: vi.fn().mockImplementation( + class { + type = 'db' + } + ), })) vi.mock('@/lib/core/rate-limiter/storage/redis-token-bucket', () => ({ - RedisTokenBucket: vi.fn(() => ({ type: 'redis' })), + RedisTokenBucket: vi.fn().mockImplementation( + class { + type = 'redis' + } + ), })) import { createStorageAdapter, resetStorageAdapter } from '@/lib/core/rate-limiter/storage/factory' diff --git a/apps/sim/lib/data-drains/destinations/azure_blob.test.ts b/apps/sim/lib/data-drains/destinations/azure_blob.test.ts index e95424111ff..5ad6c99ba20 100644 --- a/apps/sim/lib/data-drains/destinations/azure_blob.test.ts +++ b/apps/sim/lib/data-drains/destinations/azure_blob.test.ts @@ -12,8 +12,12 @@ const { mockUpload, mockDeleteIfExists, BlobServiceClientCtor, StorageSharedKeyC return { mockUpload, mockDeleteIfExists, - BlobServiceClientCtor: vi.fn(() => ({ getContainerClient: vi.fn(() => containerClient) })), - StorageSharedKeyCredentialCtor: vi.fn(), + BlobServiceClientCtor: vi.fn().mockImplementation( + class { + getContainerClient = vi.fn(() => containerClient) + } + ), + StorageSharedKeyCredentialCtor: vi.fn().mockImplementation(class {}), } }) diff --git a/apps/sim/lib/data-drains/destinations/bigquery.test.ts b/apps/sim/lib/data-drains/destinations/bigquery.test.ts index 12c3df6c2d4..de1e6a2db3f 100644 --- a/apps/sim/lib/data-drains/destinations/bigquery.test.ts +++ b/apps/sim/lib/data-drains/destinations/bigquery.test.ts @@ -17,7 +17,11 @@ const { mockGetAccessToken, JWTCtor, loggerInstance } = vi.hoisted(() => { } return { mockGetAccessToken, - JWTCtor: vi.fn(() => ({ getAccessToken: mockGetAccessToken })), + JWTCtor: vi.fn().mockImplementation( + class { + getAccessToken = mockGetAccessToken + } + ), loggerInstance, } }) diff --git a/apps/sim/lib/data-drains/destinations/gcs.test.ts b/apps/sim/lib/data-drains/destinations/gcs.test.ts index 8ed02017836..0003d2b8095 100644 --- a/apps/sim/lib/data-drains/destinations/gcs.test.ts +++ b/apps/sim/lib/data-drains/destinations/gcs.test.ts @@ -7,7 +7,11 @@ const { mockGetAccessToken, JWTCtor } = vi.hoisted(() => { const mockGetAccessToken = vi.fn(async () => ({ token: 'fake-access-token' })) return { mockGetAccessToken, - JWTCtor: vi.fn(() => ({ getAccessToken: mockGetAccessToken })), + JWTCtor: vi.fn().mockImplementation( + class { + getAccessToken = mockGetAccessToken + } + ), } }) diff --git a/apps/sim/lib/data-drains/destinations/s3.test.ts b/apps/sim/lib/data-drains/destinations/s3.test.ts index 210ff2c03c7..441a83cdd0e 100644 --- a/apps/sim/lib/data-drains/destinations/s3.test.ts +++ b/apps/sim/lib/data-drains/destinations/s3.test.ts @@ -10,9 +10,30 @@ const { mockSend, mockDestroy, S3ClientCtor, PutObjectCommandCtor, DeleteObjectC return { mockSend, mockDestroy, - S3ClientCtor: vi.fn(() => ({ send: mockSend, destroy: mockDestroy })), - PutObjectCommandCtor: vi.fn((args: unknown) => ({ __cmd: 'put', args })), - DeleteObjectCommandCtor: vi.fn((args: unknown) => ({ __cmd: 'delete', args })), + S3ClientCtor: vi.fn().mockImplementation( + class { + send = mockSend + destroy = mockDestroy + } + ), + PutObjectCommandCtor: vi.fn().mockImplementation( + class { + __cmd = 'put' + args: unknown + constructor(args: unknown) { + this.args = args + } + } + ), + DeleteObjectCommandCtor: vi.fn().mockImplementation( + class { + __cmd = 'delete' + args: unknown + constructor(args: unknown) { + this.args = args + } + } + ), } }) diff --git a/apps/sim/lib/mcp/client.test.ts b/apps/sim/lib/mcp/client.test.ts index 8f6279a2d1a..31a5f038a2f 100644 --- a/apps/sim/lib/mcp/client.test.ts +++ b/apps/sim/lib/mcp/client.test.ts @@ -10,25 +10,33 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' let capturedNotificationHandler: (() => Promise) | null = null vi.mock('@modelcontextprotocol/sdk/client/index.js', () => ({ - Client: vi.fn().mockImplementation(() => ({ - connect: vi.fn().mockResolvedValue(undefined), - close: vi.fn().mockResolvedValue(undefined), - getServerVersion: vi.fn().mockReturnValue('2025-06-18'), - getServerCapabilities: vi.fn().mockReturnValue({ tools: { listChanged: true } }), - setNotificationHandler: vi - .fn() - .mockImplementation((_schema: unknown, handler: () => Promise) => { - capturedNotificationHandler = handler - }), - listTools: vi.fn().mockResolvedValue({ tools: [] }), - })), + Client: vi.fn().mockImplementation( + class { + constructor() { + Object.assign(this, { + connect: vi.fn().mockResolvedValue(undefined), + close: vi.fn().mockResolvedValue(undefined), + getServerVersion: vi.fn().mockReturnValue('2025-06-18'), + getServerCapabilities: vi.fn().mockReturnValue({ tools: { listChanged: true } }), + setNotificationHandler: vi + .fn() + .mockImplementation((_schema: unknown, handler: () => Promise) => { + capturedNotificationHandler = handler + }), + listTools: vi.fn().mockResolvedValue({ tools: [] }), + }) + } + } + ), })) vi.mock('@modelcontextprotocol/sdk/client/streamableHttp.js', () => ({ - StreamableHTTPClientTransport: vi.fn().mockImplementation(() => ({ - onclose: null, - sessionId: 'test-session', - })), + StreamableHTTPClientTransport: vi.fn().mockImplementation( + class { + onclose: null = null + sessionId = 'test-session' + } + ), })) vi.mock('@modelcontextprotocol/sdk/types.js', () => ({ diff --git a/apps/sim/lib/mcp/connection-manager.test.ts b/apps/sim/lib/mcp/connection-manager.test.ts index 83e32d50088..8b48392e52f 100644 --- a/apps/sim/lib/mcp/connection-manager.test.ts +++ b/apps/sim/lib/mcp/connection-manager.test.ts @@ -53,7 +53,13 @@ vi.mock('@/lib/mcp/client', () => ({ vi.mock('@/lib/mcp/oauth', () => ({ getOrCreateOauthRow: mockGetOrCreateOauthRow, loadPreregisteredClient: vi.fn(), - SimMcpOauthProvider: vi.fn().mockImplementation((value) => value), + SimMcpOauthProvider: vi.fn().mockImplementation( + class { + constructor(value: object) { + Object.assign(this, value) + } + } + ), })) import { McpConnectionManager } from '@/lib/mcp/connection-manager' @@ -93,16 +99,20 @@ describe('McpConnectionManager', () => { const deferred = createDeferred() const instances: MockMcpClient[] = [] - MockMcpClientConstructor.mockImplementation(() => { - const instance: MockMcpClient = { - connect: vi.fn().mockImplementation(() => deferred.promise), - disconnect: vi.fn().mockResolvedValue(undefined), - hasListChangedCapability: vi.fn().mockReturnValue(true), - onClose: vi.fn(), + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + const instance: MockMcpClient = { + connect: vi.fn().mockImplementation(() => deferred.promise), + disconnect: vi.fn().mockResolvedValue(undefined), + hasListChangedCapability: vi.fn().mockReturnValue(true), + onClose: vi.fn(), + } + instances.push(instance) + Object.assign(this, instance) + } } - instances.push(instance) - return instance - }) + ) const mgr = createFreshManager() @@ -122,16 +132,20 @@ describe('McpConnectionManager', () => { it('shares OAuth managed connections across workspace users for the same server', async () => { const instances: MockMcpClient[] = [] - MockMcpClientConstructor.mockImplementation(() => { - const instance: MockMcpClient = { - connect: vi.fn().mockResolvedValue(undefined), - disconnect: vi.fn().mockResolvedValue(undefined), - hasListChangedCapability: vi.fn().mockReturnValue(true), - onClose: vi.fn(), + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + const instance: MockMcpClient = { + connect: vi.fn().mockResolvedValue(undefined), + disconnect: vi.fn().mockResolvedValue(undefined), + hasListChangedCapability: vi.fn().mockReturnValue(true), + onClose: vi.fn(), + } + instances.push(instance) + Object.assign(this, instance) + } } - instances.push(instance) - return instance - }) + ) const mgr = createFreshManager() const config = { ...serverConfig('server-oauth'), authType: 'oauth' as const } @@ -153,16 +167,20 @@ describe('McpConnectionManager', () => { it('allows a new connect() after a previous one completes', async () => { const instances: MockMcpClient[] = [] - MockMcpClientConstructor.mockImplementation(() => { - const instance: MockMcpClient = { - connect: vi.fn().mockResolvedValue(undefined), - disconnect: vi.fn().mockResolvedValue(undefined), - hasListChangedCapability: vi.fn().mockReturnValue(false), - onClose: vi.fn(), + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + const instance: MockMcpClient = { + connect: vi.fn().mockResolvedValue(undefined), + disconnect: vi.fn().mockResolvedValue(undefined), + hasListChangedCapability: vi.fn().mockReturnValue(false), + onClose: vi.fn(), + } + instances.push(instance) + Object.assign(this, instance) + } } - instances.push(instance) - return instance - }) + ) const mgr = createFreshManager() @@ -181,20 +199,24 @@ describe('McpConnectionManager', () => { let callCount = 0 const instances: MockMcpClient[] = [] - MockMcpClientConstructor.mockImplementation(() => { - callCount++ - const instance: MockMcpClient = { - connect: - callCount === 1 - ? vi.fn().mockRejectedValue(new Error('Connection refused')) - : vi.fn().mockResolvedValue(undefined), - disconnect: vi.fn().mockResolvedValue(undefined), - hasListChangedCapability: vi.fn().mockReturnValue(true), - onClose: vi.fn(), + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + callCount++ + const instance: MockMcpClient = { + connect: + callCount === 1 + ? vi.fn().mockRejectedValue(new Error('Connection refused')) + : vi.fn().mockResolvedValue(undefined), + disconnect: vi.fn().mockResolvedValue(undefined), + hasListChangedCapability: vi.fn().mockReturnValue(true), + onClose: vi.fn(), + } + instances.push(instance) + Object.assign(this, instance) + } } - instances.push(instance) - return instance - }) + ) const mgr = createFreshManager() @@ -213,16 +235,20 @@ describe('McpConnectionManager', () => { const deferred = createDeferred() const instances: MockMcpClient[] = [] - MockMcpClientConstructor.mockImplementation(() => { - const instance: MockMcpClient = { - connect: vi.fn().mockImplementation(() => deferred.promise), - disconnect: vi.fn().mockResolvedValue(undefined), - hasListChangedCapability: vi.fn().mockReturnValue(true), - onClose: vi.fn(), + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + const instance: MockMcpClient = { + connect: vi.fn().mockImplementation(() => deferred.promise), + disconnect: vi.fn().mockResolvedValue(undefined), + hasListChangedCapability: vi.fn().mockReturnValue(true), + onClose: vi.fn(), + } + instances.push(instance) + Object.assign(this, instance) + } } - instances.push(instance) - return instance - }) + ) const mgr = createFreshManager() const resultPromise = mgr.connect(serverConfig('server-timeout'), 'user-1', 'ws-1') @@ -241,12 +267,18 @@ describe('McpConnectionManager', () => { describe('dispose', () => { it('rejects new connections after dispose', async () => { - MockMcpClientConstructor.mockImplementation(() => ({ - connect: vi.fn().mockResolvedValue(undefined), - disconnect: vi.fn().mockResolvedValue(undefined), - hasListChangedCapability: vi.fn().mockReturnValue(true), - onClose: vi.fn(), - })) + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + Object.assign(this, { + connect: vi.fn().mockResolvedValue(undefined), + disconnect: vi.fn().mockResolvedValue(undefined), + hasListChangedCapability: vi.fn().mockReturnValue(true), + onClose: vi.fn(), + }) + } + } + ) const mgr = createFreshManager() @@ -263,20 +295,24 @@ describe('McpConnectionManager', () => { let closeHandler: (() => void) | undefined const instances: MockMcpClient[] = [] - MockMcpClientConstructor.mockImplementation(() => { - const instance: MockMcpClient = { - connect: vi.fn().mockResolvedValue(undefined), - disconnect: vi.fn().mockImplementation(async () => { - closeHandler?.() - }), - hasListChangedCapability: vi.fn().mockReturnValue(true), - onClose: vi.fn().mockImplementation((handler: () => void) => { - closeHandler = handler - }), + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + const instance: MockMcpClient = { + connect: vi.fn().mockResolvedValue(undefined), + disconnect: vi.fn().mockImplementation(async () => { + closeHandler?.() + }), + hasListChangedCapability: vi.fn().mockReturnValue(true), + onClose: vi.fn().mockImplementation((handler: () => void) => { + closeHandler = handler + }), + } + instances.push(instance) + Object.assign(this, instance) + } } - instances.push(instance) - return instance - }) + ) const mgr = createFreshManager() await mgr.connect(serverConfig('server-5'), 'user-1', 'ws-1') @@ -293,18 +329,22 @@ describe('McpConnectionManager', () => { let closeHandler: (() => void) | undefined const instances: MockMcpClient[] = [] - MockMcpClientConstructor.mockImplementation(() => { - const instance: MockMcpClient = { - connect: vi.fn().mockResolvedValue(undefined), - disconnect: vi.fn().mockResolvedValue(undefined), - hasListChangedCapability: vi.fn().mockReturnValue(true), - onClose: vi.fn().mockImplementation((handler: () => void) => { - closeHandler = handler - }), + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + const instance: MockMcpClient = { + connect: vi.fn().mockResolvedValue(undefined), + disconnect: vi.fn().mockResolvedValue(undefined), + hasListChangedCapability: vi.fn().mockReturnValue(true), + onClose: vi.fn().mockImplementation((handler: () => void) => { + closeHandler = handler + }), + } + instances.push(instance) + Object.assign(this, instance) + } } - instances.push(instance) - return instance - }) + ) const mgr = createFreshManager() await mgr.connect(serverConfig('server-7'), 'user-1', 'ws-1') @@ -322,20 +362,24 @@ describe('McpConnectionManager', () => { const closeHandlers: Array<() => void> = [] const instances: MockMcpClient[] = [] - MockMcpClientConstructor.mockImplementation(() => { - const instance: MockMcpClient = { - connect: vi.fn().mockResolvedValue(undefined), - disconnect: vi.fn().mockImplementation(async () => { - closeHandlers.at(-1)?.() - }), - hasListChangedCapability: vi.fn().mockReturnValue(true), - onClose: vi.fn().mockImplementation((handler: () => void) => { - closeHandlers.push(handler) - }), + MockMcpClientConstructor.mockImplementation( + class { + constructor() { + const instance: MockMcpClient = { + connect: vi.fn().mockResolvedValue(undefined), + disconnect: vi.fn().mockImplementation(async () => { + closeHandlers.at(-1)?.() + }), + hasListChangedCapability: vi.fn().mockReturnValue(true), + onClose: vi.fn().mockImplementation((handler: () => void) => { + closeHandlers.push(handler) + }), + } + instances.push(instance) + Object.assign(this, instance) + } } - instances.push(instance) - return instance - }) + ) const mgr = createFreshManager() await mgr.connect(serverConfig('server-6'), 'user-1', 'ws-1') diff --git a/apps/sim/lib/mcp/service.test.ts b/apps/sim/lib/mcp/service.test.ts index 11a2631d34e..6745a0ffe16 100644 --- a/apps/sim/lib/mcp/service.test.ts +++ b/apps/sim/lib/mcp/service.test.ts @@ -18,14 +18,20 @@ const { const mockConnect = vi.fn() const mockDisconnect = vi.fn() return { - MockMcpClient: vi.fn().mockImplementation(() => ({ - connect: mockConnect, - disconnect: mockDisconnect, - listTools: mockListTools, - hasListChangedCapability: vi.fn(() => false), - onClose: vi.fn(), - getNegotiatedVersion: vi.fn(() => '2025-06-18'), - })), + MockMcpClient: vi.fn().mockImplementation( + class { + constructor() { + Object.assign(this, { + connect: mockConnect, + disconnect: mockDisconnect, + listTools: mockListTools, + hasListChangedCapability: vi.fn(() => false), + onClose: vi.fn(), + getNegotiatedVersion: vi.fn(() => '2025-06-18'), + }) + } + } + ), mockListTools, mockConnect, mockDisconnect, diff --git a/apps/sim/lib/messaging/email/mailer.test.ts b/apps/sim/lib/messaging/email/mailer.test.ts index eba95dc1c23..515dcff6c4c 100644 --- a/apps/sim/lib/messaging/email/mailer.test.ts +++ b/apps/sim/lib/messaging/email/mailer.test.ts @@ -8,22 +8,26 @@ const mockAzurePollUntilDone = vi.fn() vi.mock('resend', () => { return { - Resend: vi.fn().mockImplementation(() => ({ - emails: { - send: (...args: any[]) => mockSend(...args), - }, - batch: { - send: (...args: any[]) => mockBatchSend(...args), - }, - })), + Resend: vi.fn().mockImplementation( + class { + emails = { + send: (...args: any[]) => mockSend(...args), + } + batch = { + send: (...args: any[]) => mockBatchSend(...args), + } + } + ), } }) vi.mock('@azure/communication-email', () => { return { - EmailClient: vi.fn().mockImplementation(() => ({ - beginSend: (...args: any[]) => mockAzureBeginSend(...args), - })), + EmailClient: vi.fn().mockImplementation( + class { + beginSend = (...args: any[]) => mockAzureBeginSend(...args) + } + ), } }) diff --git a/apps/sim/lib/uploads/providers/s3/client.test.ts b/apps/sim/lib/uploads/providers/s3/client.test.ts index ff780b55864..4e62109a5d8 100644 --- a/apps/sim/lib/uploads/providers/s3/client.test.ts +++ b/apps/sim/lib/uploads/providers/s3/client.test.ts @@ -27,10 +27,17 @@ const { return { mockSend, mockS3Client, - mockS3ClientConstructor: vi.fn(() => mockS3Client), - mockPutObjectCommand: vi.fn(), - mockGetObjectCommand: vi.fn(), - mockDeleteObjectCommand: vi.fn(), + mockS3ClientConstructor: vi.fn().mockImplementation( + class { + constructor() { + // biome-ignore lint/correctness/noConstructorReturn: vitest 4 constructs mocks via Reflect.construct; returning the object overrides the instance so `new S3Client()` yields the shared mock the tests assert on + return mockS3Client + } + } + ), + mockPutObjectCommand: vi.fn().mockImplementation(class {}), + mockGetObjectCommand: vi.fn().mockImplementation(class {}), + mockDeleteObjectCommand: vi.fn().mockImplementation(class {}), mockGetSignedUrl: vi.fn(), mockEnv, } diff --git a/apps/sim/lib/workflows/executor/execution-core.test.ts b/apps/sim/lib/workflows/executor/execution-core.test.ts index 08be63da3fd..eba2011484a 100644 --- a/apps/sim/lib/workflows/executor/execution-core.test.ts +++ b/apps/sim/lib/workflows/executor/execution-core.test.ts @@ -72,19 +72,26 @@ vi.mock('@/lib/workflows/triggers/triggers', () => ({ vi.mock('@/lib/workflows/utils', () => workflowsUtilsMock) vi.mock('@/executor', () => ({ - Executor: vi.fn().mockImplementation((args) => { - executorConstructorMock(args) - return { - execute: executorExecuteMock, - executeFromBlock: executorExecuteMock, + Executor: vi.fn().mockImplementation( + class { + constructor(args: unknown) { + executorConstructorMock(args) + // biome-ignore lint/correctness/noConstructorReturn: vitest 4 constructs mocks via Reflect.construct; returning the instance overrides `new Executor(...)` + return { + execute: executorExecuteMock, + executeFromBlock: executorExecuteMock, + } + } } - }), + ), })) vi.mock('@/serializer', () => ({ - Serializer: vi.fn().mockImplementation(() => ({ - serializeWorkflow: serializeWorkflowMock, - })), + Serializer: vi.fn().mockImplementation( + class { + serializeWorkflow = serializeWorkflowMock + } + ), })) import { diff --git a/apps/sim/package.json b/apps/sim/package.json index 3cd37a986b6..48037fcbd7f 100644 --- a/apps/sim/package.json +++ b/apps/sim/package.json @@ -227,7 +227,7 @@ "@types/ssh2": "^1.15.5", "@types/three": "0.177.0", "@vitejs/plugin-react": "^4.3.4", - "@vitest/coverage-v8": "^3.0.8", + "@vitest/coverage-v8": "^4.1.0", "autoprefixer": "10.4.21", "jsdom": "^26.0.0", "postcss": "^8", @@ -235,7 +235,7 @@ "tailwindcss": "^3.4.1", "typescript": "^5.7.3", "vite-tsconfig-paths": "^5.1.4", - "vitest": "^3.0.8" + "vitest": "^4.1.0" }, "trustedDependencies": [ "canvas", diff --git a/apps/sim/providers/baseten/index.test.ts b/apps/sim/providers/baseten/index.test.ts index af5fa39f61b..6a8c2bd6d81 100644 --- a/apps/sim/providers/baseten/index.test.ts +++ b/apps/sim/providers/baseten/index.test.ts @@ -16,9 +16,11 @@ const { })) vi.mock('openai', () => ({ - default: vi.fn().mockImplementation(() => ({ - chat: { completions: { create: mockCreate } }, - })), + default: vi.fn().mockImplementation( + class { + chat = { completions: { create: mockCreate } } + } + ), })) vi.mock('@/providers', () => ({ MAX_TOOL_ITERATIONS: 5 })) diff --git a/apps/sim/providers/bedrock/index.test.ts b/apps/sim/providers/bedrock/index.test.ts index 8c938e01c87..aaf09ae6fb8 100644 --- a/apps/sim/providers/bedrock/index.test.ts +++ b/apps/sim/providers/bedrock/index.test.ts @@ -6,9 +6,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' const mockSend = vi.fn() vi.mock('@aws-sdk/client-bedrock-runtime', () => ({ - BedrockRuntimeClient: vi.fn().mockImplementation(() => { - return { send: mockSend } - }), + BedrockRuntimeClient: vi.fn().mockImplementation( + class { + send = mockSend + } + ), ConverseCommand: vi.fn(), ConverseStreamCommand: vi.fn(), })) diff --git a/apps/sim/providers/fireworks/index.test.ts b/apps/sim/providers/fireworks/index.test.ts index 68fba04c736..bb7fef32590 100644 --- a/apps/sim/providers/fireworks/index.test.ts +++ b/apps/sim/providers/fireworks/index.test.ts @@ -16,9 +16,11 @@ const { })) vi.mock('openai', () => ({ - default: vi.fn().mockImplementation(() => ({ - chat: { completions: { create: mockCreate } }, - })), + default: vi.fn().mockImplementation( + class { + chat = { completions: { create: mockCreate } } + } + ), })) vi.mock('@/providers', () => ({ MAX_TOOL_ITERATIONS: 5 })) diff --git a/apps/sim/providers/litellm/index.test.ts b/apps/sim/providers/litellm/index.test.ts index 5261f4e23d6..8365d4042c2 100644 --- a/apps/sim/providers/litellm/index.test.ts +++ b/apps/sim/providers/litellm/index.test.ts @@ -9,9 +9,11 @@ const { mockCreate, mockExecuteTool } = vi.hoisted(() => ({ })) vi.mock('openai', () => ({ - default: vi.fn().mockImplementation(() => ({ - chat: { completions: { create: mockCreate } }, - })), + default: vi.fn().mockImplementation( + class { + chat = { completions: { create: mockCreate } } + } + ), })) vi.mock('@/tools', () => ({ executeTool: mockExecuteTool })) diff --git a/apps/sim/providers/ollama-cloud/index.test.ts b/apps/sim/providers/ollama-cloud/index.test.ts index c4a1f921f58..9eb416b8261 100644 --- a/apps/sim/providers/ollama-cloud/index.test.ts +++ b/apps/sim/providers/ollama-cloud/index.test.ts @@ -31,10 +31,14 @@ const { mockCreate, mockExecuteTool, streamOnComplete, MockAPIError } = vi.hoist const mockOpenAIConstructor = vi.hoisted(() => vi.fn()) vi.mock('openai', () => { - const OpenAI = vi.fn((opts: unknown) => { - mockOpenAIConstructor(opts) - return { chat: { completions: { create: mockCreate } } } - }) + const OpenAI = vi.fn().mockImplementation( + class { + chat = { completions: { create: mockCreate } } + constructor(opts: unknown) { + mockOpenAIConstructor(opts) + } + } + ) ;(OpenAI as unknown as { APIError: typeof MockAPIError }).APIError = MockAPIError return { default: OpenAI } }) diff --git a/apps/sim/providers/ollama/index.test.ts b/apps/sim/providers/ollama/index.test.ts index c4d223ad13c..3c811906826 100644 --- a/apps/sim/providers/ollama/index.test.ts +++ b/apps/sim/providers/ollama/index.test.ts @@ -29,7 +29,11 @@ const { mockCreate, mockExecuteTool, streamOnComplete, MockAPIError } = vi.hoist }) vi.mock('openai', () => { - const OpenAI = vi.fn(() => ({ chat: { completions: { create: mockCreate } } })) + const OpenAI = vi.fn().mockImplementation( + class { + chat = { completions: { create: mockCreate } } + } + ) ;(OpenAI as unknown as { APIError: typeof MockAPIError }).APIError = MockAPIError return { default: OpenAI } }) diff --git a/apps/sim/providers/openrouter/index.test.ts b/apps/sim/providers/openrouter/index.test.ts index 88339fe4a93..0d0a667ccf0 100644 --- a/apps/sim/providers/openrouter/index.test.ts +++ b/apps/sim/providers/openrouter/index.test.ts @@ -25,9 +25,11 @@ const { })) vi.mock('openai', () => ({ - default: vi.fn().mockImplementation(() => ({ - chat: { completions: { create: mockCreate } }, - })), + default: vi.fn().mockImplementation( + class { + chat = { completions: { create: mockCreate } } + } + ), })) vi.mock('@/providers', () => ({ MAX_TOOL_ITERATIONS: 10 })) diff --git a/apps/sim/providers/together/index.test.ts b/apps/sim/providers/together/index.test.ts index 39e01ab7679..6e52dd0d268 100644 --- a/apps/sim/providers/together/index.test.ts +++ b/apps/sim/providers/together/index.test.ts @@ -16,9 +16,11 @@ const { })) vi.mock('openai', () => ({ - default: vi.fn().mockImplementation(() => ({ - chat: { completions: { create: mockCreate } }, - })), + default: vi.fn().mockImplementation( + class { + chat = { completions: { create: mockCreate } } + } + ), })) vi.mock('@/providers', () => ({ MAX_TOOL_ITERATIONS: 5 })) diff --git a/apps/sim/providers/vllm/index.test.ts b/apps/sim/providers/vllm/index.test.ts index 4477beeeda7..829c48168f1 100644 --- a/apps/sim/providers/vllm/index.test.ts +++ b/apps/sim/providers/vllm/index.test.ts @@ -23,7 +23,11 @@ const { })) vi.mock('openai', () => ({ - default: vi.fn(() => ({ chat: { completions: { create: mockCreate } } })), + default: vi.fn().mockImplementation( + class { + chat = { completions: { create: mockCreate } } + } + ), })) vi.mock('@/lib/core/config/env', () => ({ env: envState })) vi.mock('@/providers', () => ({ MAX_TOOL_ITERATIONS: 20 })) diff --git a/apps/sim/vitest.config.ts b/apps/sim/vitest.config.ts index f5aec399e8b..a966ad5233e 100644 --- a/apps/sim/vitest.config.ts +++ b/apps/sim/vitest.config.ts @@ -19,13 +19,7 @@ export default defineConfig({ exclude: [...configDefaults.exclude, '**/node_modules/**', '**/dist/**'], setupFiles: ['./vitest.setup.ts'], pool: 'threads', - poolOptions: { - threads: { - singleThread: false, - useAtomics: true, - isolate: true, - }, - }, + isolate: true, fileParallelism: true, maxConcurrency: 10, testTimeout: 10000, diff --git a/bun.lock b/bun.lock index fdee6edfc42..b5f47fe6bfb 100644 --- a/bun.lock +++ b/bun.lock @@ -78,7 +78,7 @@ "@types/node": "24.2.1", "socket.io-client": "4.8.1", "typescript": "^5.7.3", - "vitest": "^3.0.8", + "vitest": "^4.1.0", }, }, "apps/sim": { @@ -281,7 +281,7 @@ "@types/ssh2": "^1.15.5", "@types/three": "0.177.0", "@vitejs/plugin-react": "^4.3.4", - "@vitest/coverage-v8": "^3.0.8", + "@vitest/coverage-v8": "^4.1.0", "autoprefixer": "10.4.21", "jsdom": "^26.0.0", "postcss": "^8", @@ -289,7 +289,7 @@ "tailwindcss": "^3.4.1", "typescript": "^5.7.3", "vite-tsconfig-paths": "^5.1.4", - "vitest": "^3.0.8", + "vitest": "^4.1.0", }, }, "packages/audit": { @@ -305,7 +305,7 @@ "@sim/testing": "workspace:*", "@sim/tsconfig": "workspace:*", "typescript": "^5.7.3", - "vitest": "^3.0.8", + "vitest": "^4.1.0", }, }, "packages/auth": { @@ -365,7 +365,7 @@ "devDependencies": { "@sim/tsconfig": "workspace:*", "typescript": "^5.7.3", - "vitest": "^3.0.8", + "vitest": "^4.1.0", }, }, "packages/realtime-protocol": { @@ -386,7 +386,7 @@ "@sim/tsconfig": "workspace:*", "@types/node": "24.2.1", "typescript": "^5.7.3", - "vitest": "^3.0.8", + "vitest": "^4.1.0", }, }, "packages/testing": { @@ -398,10 +398,10 @@ "devDependencies": { "@sim/tsconfig": "workspace:*", "typescript": "^5.7.3", - "vitest": "^3.0.8", + "vitest": "^4.1.0", }, "peerDependencies": { - "vitest": "^3.0.0", + "vitest": "^3.0.0 || ^4.0.0", }, }, "packages/ts-sdk": { @@ -413,9 +413,9 @@ "devDependencies": { "@sim/tsconfig": "workspace:*", "@types/node": "^20.5.1", - "@vitest/coverage-v8": "^3.0.8", + "@vitest/coverage-v8": "^4.1.0", "typescript": "^5.7.3", - "vitest": "^3.0.8", + "vitest": "^4.1.0", }, }, "packages/tsconfig": { @@ -428,7 +428,7 @@ "devDependencies": { "@sim/tsconfig": "workspace:*", "typescript": "^5.7.3", - "vitest": "^3.0.8", + "vitest": "^4.1.0", }, }, "packages/workflow-authz": { @@ -532,8 +532,6 @@ "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], - "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.71.2", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-TGNDEUuEstk/DKu0/TflXAEt+p+p/WhTlFzEnoosvbaDU2LTjm42igSdlL0VijrKpWejtOKxX0b8A7uc+XiSAQ=="], @@ -982,8 +980,6 @@ "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], - "@istanbuljs/schema": ["@istanbuljs/schema@0.1.6", "", {}, "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw=="], - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], @@ -1170,8 +1166,6 @@ "@pinojs/redact": ["@pinojs/redact@0.4.0", "", {}, "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg=="], - "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], - "@posthog/core": ["@posthog/core@1.24.4", "", { "dependencies": { "cross-spawn": "^7.0.6" } }, "sha512-S+TolwBHSSJz7WWtgaELQWQqXviSm3uf1e+qorWUts0bZcgPwWzhnmhCUZAhvn0NVpTQHDJ3epv+hHbPLl5dHg=="], "@posthog/types": ["@posthog/types@1.364.4", "", {}, "sha512-U7NpIy9XWrzz1q/66xyDu8Wm12a7avNRKRn5ISPT5kuCJQRaeAaHuf+dpgrFnuqjCCgxg+oIY/ReJdlZ+8/z4Q=="], @@ -1826,21 +1820,21 @@ "@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="], - "@vitest/coverage-v8": ["@vitest/coverage-v8@3.2.4", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@bcoe/v8-coverage": "^1.0.2", "ast-v8-to-istanbul": "^0.3.3", "debug": "^4.4.1", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", "istanbul-reports": "^3.1.7", "magic-string": "^0.30.17", "magicast": "^0.3.5", "std-env": "^3.9.0", "test-exclude": "^7.0.1", "tinyrainbow": "^2.0.0" }, "peerDependencies": { "@vitest/browser": "3.2.4", "vitest": "3.2.4" }, "optionalPeers": ["@vitest/browser"] }, "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ=="], + "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.7", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.7", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "@vitest/browser": "4.1.7", "vitest": "4.1.7" }, "optionalPeers": ["@vitest/browser"] }, "sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ=="], - "@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="], + "@vitest/expect": ["@vitest/expect@4.1.7", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.7", "@vitest/utils": "4.1.7", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w=="], - "@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="], + "@vitest/mocker": ["@vitest/mocker@4.1.7", "", { "dependencies": { "@vitest/spy": "4.1.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA=="], - "@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="], + "@vitest/pretty-format": ["@vitest/pretty-format@4.1.7", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw=="], - "@vitest/runner": ["@vitest/runner@3.2.4", "", { "dependencies": { "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ=="], + "@vitest/runner": ["@vitest/runner@4.1.7", "", { "dependencies": { "@vitest/utils": "4.1.7", "pathe": "^2.0.3" } }, "sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw=="], - "@vitest/snapshot": ["@vitest/snapshot@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ=="], + "@vitest/snapshot": ["@vitest/snapshot@4.1.7", "", { "dependencies": { "@vitest/pretty-format": "4.1.7", "@vitest/utils": "4.1.7", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw=="], - "@vitest/spy": ["@vitest/spy@3.2.4", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw=="], + "@vitest/spy": ["@vitest/spy@4.1.7", "", {}, "sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q=="], - "@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="], + "@vitest/utils": ["@vitest/utils@4.1.7", "", { "dependencies": { "@vitest/pretty-format": "4.1.7", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw=="], "@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="], @@ -1898,7 +1892,7 @@ "ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="], - "ast-v8-to-istanbul": ["ast-v8-to-istanbul@0.3.12", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", "js-tokens": "^10.0.0" } }, "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g=="], + "ast-v8-to-istanbul": ["ast-v8-to-istanbul@1.0.2", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", "js-tokens": "^10.0.0" } }, "sha512-dKmJxJsGItLmc5CYZKuEjuG6GnBs6PG4gohMhyFOWKaNQoYCuRZJDECaBlHmcG0lv2wc2E0uU8lESmBEumC3DQ=="], "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], @@ -1994,8 +1988,6 @@ "c12": ["c12@3.1.0", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.6.1", "exsolve": "^1.0.7", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.2.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw=="], - "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], - "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], @@ -2012,7 +2004,7 @@ "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], - "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], + "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], @@ -2026,8 +2018,6 @@ "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], - "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], - "cheerio": ["cheerio@1.1.2", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "encoding-sniffer": "^0.2.1", "htmlparser2": "^10.0.0", "parse5": "^7.3.0", "parse5-htmlparser2-tree-adapter": "^7.1.0", "parse5-parser-stream": "^7.1.2", "undici": "^7.12.0", "whatwg-mimetype": "^4.0.0" } }, "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg=="], "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], @@ -2244,8 +2234,6 @@ "deep-diff": ["deep-diff@1.0.2", "", {}, "sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg=="], - "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], - "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], @@ -2362,7 +2350,7 @@ "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], - "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + "es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], @@ -2744,8 +2732,6 @@ "istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="], - "istanbul-lib-source-maps": ["istanbul-lib-source-maps@5.0.6", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0" } }, "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A=="], - "istanbul-reports": ["istanbul-reports@3.2.0", "", { "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA=="], "jackspeak": ["jackspeak@4.2.3", "", { "dependencies": { "@isaacs/cliui": "^9.0.0" } }, "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg=="], @@ -2888,8 +2874,6 @@ "lop": ["lop@0.4.2", "", { "dependencies": { "duck": "^0.1.12", "option": "~0.2.1", "underscore": "^1.13.1" } }, "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw=="], - "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="], - "lru-cache": ["lru-cache@11.3.6", "", {}, "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A=="], "lru.min": ["lru.min@1.1.4", "", {}, "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA=="], @@ -2898,7 +2882,7 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - "magicast": ["magicast@0.3.5", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="], + "magicast": ["magicast@0.5.3", "", { "dependencies": { "@babel/parser": "^7.29.3", "@babel/types": "^7.29.0", "source-map-js": "^1.2.1" } }, "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw=="], "mailchecker": ["mailchecker@6.0.20", "", {}, "sha512-mZ3kmtfXzGj06prtNm6d8an7D++Kf1G4jEkPZ1QQyhknYNLkmGoMtfaNPNHJU6E8J+Bm3AcZlIIfq5D6L4MS2g=="], @@ -3170,6 +3154,8 @@ "obliterator": ["obliterator@1.6.1", "", {}, "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig=="], + "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], + "officeparser": ["officeparser@5.2.2", "", { "dependencies": { "@xmldom/xmldom": "^0.8.10", "concat-stream": "^2.0.0", "file-type": "^16.5.4", "node-ensure": "^0.0.0", "pdfjs-dist": "^5.3.31", "yauzl": "^3.1.3" }, "bin": { "officeparser": "officeParser.js" } }, "sha512-5JrV1CZFqTv/27fXy2bcf+3g6BpDZiJ3XoSRW3fb2i2EFex0DduqjTxiU2RsJ08WBsk4Hp0nZoGi9ZtHMZFaPA=="], "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], @@ -3252,8 +3238,6 @@ "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="], - "pdf-lib": ["pdf-lib@1.17.1", "", { "dependencies": { "@pdf-lib/standard-fonts": "^1.0.0", "@pdf-lib/upng": "^1.0.1", "pako": "^1.0.11", "tslib": "^1.11.1" } }, "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw=="], "pdfjs-dist": ["pdfjs-dist@5.4.296", "", { "optionalDependencies": { "@napi-rs/canvas": "^0.1.80" } }, "sha512-DlOzet0HO7OEnmUmB6wWGJrrdvbyJKftI1bhMitK7O2N8W2gc757yyYBbINy9IDafXAV9wmKr9t7xsTaNKRG5Q=="], @@ -3650,7 +3634,7 @@ "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], - "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], + "std-env": ["std-env@4.1.0", "", {}, "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ=="], "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="], @@ -3662,8 +3646,6 @@ "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "string.prototype.codepointat": ["string.prototype.codepointat@0.2.1", "", {}, "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="], "string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], @@ -3672,8 +3654,6 @@ "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], "strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="], @@ -3684,8 +3664,6 @@ "strip-json-comments": ["strip-json-comments@5.0.3", "", {}, "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw=="], - "strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="], - "stripe": ["stripe@18.5.0", "", { "dependencies": { "qs": "^6.11.0" }, "peerDependencies": { "@types/node": ">=12.x.x" }, "optionalPeers": ["@types/node"] }, "sha512-Hp+wFiEQtCB0LlNgcFh5uVyKznpDjzyUZ+CNVEf+I3fhlYvh7rZruIg+jOwzJRCpy0ZTPMjlzm7J2/M2N6d+DA=="], "strnum": ["strnum@2.3.0", "", {}, "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q=="], @@ -3730,8 +3708,6 @@ "teex": ["teex@1.0.1", "", { "dependencies": { "streamx": "^2.12.5" } }, "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg=="], - "test-exclude": ["test-exclude@7.0.2", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^10.4.1", "minimatch": "^10.2.2" } }, "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw=="], - "text-decoder": ["text-decoder@1.2.7", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ=="], "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], @@ -3750,15 +3726,11 @@ "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], - "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + "tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="], "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], - "tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="], - - "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], - - "tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="], + "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], "tldts": ["tldts@7.0.30", "", { "dependencies": { "tldts-core": "^7.0.30" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw=="], @@ -3886,11 +3858,9 @@ "vite": ["vite@7.3.3", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA=="], - "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], - "vite-tsconfig-paths": ["vite-tsconfig-paths@5.1.4", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w=="], - "vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.4", "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="], + "vitest": ["vitest@4.1.7", "", { "dependencies": { "@vitest/expect": "4.1.7", "@vitest/mocker": "4.1.7", "@vitest/pretty-format": "4.1.7", "@vitest/runner": "4.1.7", "@vitest/snapshot": "4.1.7", "@vitest/spy": "4.1.7", "@vitest/utils": "4.1.7", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.7", "@vitest/browser-preview": "4.1.7", "@vitest/browser-webdriverio": "4.1.7", "@vitest/coverage-istanbul": "4.1.7", "@vitest/coverage-v8": "4.1.7", "@vitest/ui": "4.1.7", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA=="], "vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="], @@ -3922,8 +3892,6 @@ "wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], - "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], "ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], @@ -3982,8 +3950,6 @@ "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - "@antfu/install-pkg/tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="], - "@asamuzakjp/css-color/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "@aws-crypto/sha1-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], @@ -4152,6 +4118,10 @@ "@trigger.dev/core/socket.io-client": ["socket.io-client@4.7.5", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", "engine.io-client": "~6.5.2", "socket.io-parser": "~4.2.4" } }, "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ=="], + "@trigger.dev/core/std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], + + "@trigger.dev/core/tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + "@trigger.dev/core/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@trigger.dev/sdk/@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], @@ -4204,6 +4174,8 @@ "c12/jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], + "c12/magicast": ["magicast@0.3.5", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="], + "c12/pkg-types": ["pkg-types@2.3.1", "", { "dependencies": { "confbox": "^0.2.4", "exsolve": "^1.0.8", "pathe": "^2.0.3" } }, "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg=="], "chrome-launcher/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], @@ -4274,8 +4246,6 @@ "fumadocs-mdx/esbuild": ["esbuild@0.28.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.0", "@esbuild/android-arm": "0.28.0", "@esbuild/android-arm64": "0.28.0", "@esbuild/android-x64": "0.28.0", "@esbuild/darwin-arm64": "0.28.0", "@esbuild/darwin-x64": "0.28.0", "@esbuild/freebsd-arm64": "0.28.0", "@esbuild/freebsd-x64": "0.28.0", "@esbuild/linux-arm": "0.28.0", "@esbuild/linux-arm64": "0.28.0", "@esbuild/linux-ia32": "0.28.0", "@esbuild/linux-loong64": "0.28.0", "@esbuild/linux-mips64el": "0.28.0", "@esbuild/linux-ppc64": "0.28.0", "@esbuild/linux-riscv64": "0.28.0", "@esbuild/linux-s390x": "0.28.0", "@esbuild/linux-x64": "0.28.0", "@esbuild/netbsd-arm64": "0.28.0", "@esbuild/netbsd-x64": "0.28.0", "@esbuild/openbsd-arm64": "0.28.0", "@esbuild/openbsd-x64": "0.28.0", "@esbuild/openharmony-arm64": "0.28.0", "@esbuild/sunos-x64": "0.28.0", "@esbuild/win32-arm64": "0.28.0", "@esbuild/win32-ia32": "0.28.0", "@esbuild/win32-x64": "0.28.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw=="], - "fumadocs-mdx/tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="], - "fumadocs-openapi/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="], "fumadocs-openapi/ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], @@ -4364,6 +4334,8 @@ "nypm/pkg-types": ["pkg-types@2.3.1", "", { "dependencies": { "confbox": "^0.2.4", "exsolve": "^1.0.8", "pathe": "^2.0.3" } }, "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg=="], + "nypm/tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + "openai/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="], "openai/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], @@ -4464,12 +4436,8 @@ "string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "string_decoder/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], - "strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], - "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], "svix/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="], @@ -4478,8 +4446,6 @@ "tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - "test-exclude/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], - "tough-cookie/tldts": ["tldts@6.1.86", "", { "dependencies": { "tldts-core": "^6.1.86" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ=="], "tsx/esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], @@ -4890,10 +4856,6 @@ "tar-stream/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], - "test-exclude/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - - "test-exclude/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "tough-cookie/tldts/tldts-core": ["tldts-core@6.1.86", "", {}, "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA=="], "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="], @@ -5100,10 +5062,6 @@ "sim/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - "test-exclude/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - - "test-exclude/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "@browserbasehq/stagehand/@anthropic-ai/sdk/node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], "@browserbasehq/stagehand/@anthropic-ai/sdk/node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], @@ -5134,12 +5092,6 @@ "sim/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "test-exclude/glob/jackspeak/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], - - "test-exclude/glob/jackspeak/@isaacs/cliui/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], - - "test-exclude/glob/jackspeak/@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], - "@trigger.dev/core/@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-transformer/protobufjs/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], "@trigger.dev/core/@opentelemetry/exporter-metrics-otlp-http/@opentelemetry/otlp-transformer/protobufjs/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], @@ -5151,11 +5103,5 @@ "lint-staged/listr2/log-update/cli-cursor/restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], "posthog-js/@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-transformer/protobufjs/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], - - "test-exclude/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], - - "test-exclude/glob/jackspeak/@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - - "test-exclude/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], } } diff --git a/packages/audit/package.json b/packages/audit/package.json index bad5fe28b39..19510233d97 100644 --- a/packages/audit/package.json +++ b/packages/audit/package.json @@ -34,6 +34,6 @@ "@sim/testing": "workspace:*", "@sim/tsconfig": "workspace:*", "typescript": "^5.7.3", - "vitest": "^3.0.8" + "vitest": "^4.1.0" } } diff --git a/packages/logger/package.json b/packages/logger/package.json index 4f06d695658..c547b6e2e91 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -30,6 +30,6 @@ "devDependencies": { "@sim/tsconfig": "workspace:*", "typescript": "^5.7.3", - "vitest": "^3.0.8" + "vitest": "^4.1.0" } } diff --git a/packages/security/package.json b/packages/security/package.json index dc823111799..c6fefac2fe4 100644 --- a/packages/security/package.json +++ b/packages/security/package.json @@ -45,6 +45,6 @@ "@sim/tsconfig": "workspace:*", "@types/node": "24.2.1", "typescript": "^5.7.3", - "vitest": "^3.0.8" + "vitest": "^4.1.0" } } diff --git a/packages/testing/package.json b/packages/testing/package.json index 74227adb0c8..70faee8419d 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -49,12 +49,12 @@ "format:check": "biome format ." }, "peerDependencies": { - "vitest": "^3.0.0" + "vitest": "^3.0.0 || ^4.0.0" }, "devDependencies": { "@sim/tsconfig": "workspace:*", "typescript": "^5.7.3", - "vitest": "^3.0.8" + "vitest": "^4.1.0" }, "dependencies": { "@sim/utils": "workspace:*" diff --git a/packages/testing/src/mocks/logging-session.mock.ts b/packages/testing/src/mocks/logging-session.mock.ts index fdf025573e2..1e849b8bb19 100644 --- a/packages/testing/src/mocks/logging-session.mock.ts +++ b/packages/testing/src/mocks/logging-session.mock.ts @@ -36,21 +36,23 @@ export const loggingSessionMockFns = { * call returns an object whose methods point at the shared `vi.fn()` refs in * `loggingSessionMockFns`. */ -export const LoggingSessionMock = vi.fn().mockImplementation(() => ({ - start: loggingSessionMockFns.mockStart, - complete: loggingSessionMockFns.mockComplete, - completeWithError: loggingSessionMockFns.mockCompleteWithError, - completeWithCancellation: loggingSessionMockFns.mockCompleteWithCancellation, - completeWithPause: loggingSessionMockFns.mockCompleteWithPause, - safeStart: loggingSessionMockFns.mockSafeStart, - waitForCompletion: loggingSessionMockFns.mockWaitForCompletion, - waitForPostExecution: loggingSessionMockFns.mockWaitForPostExecution, - safeComplete: loggingSessionMockFns.mockSafeComplete, - safeCompleteWithError: loggingSessionMockFns.mockSafeCompleteWithError, - safeCompleteWithCancellation: loggingSessionMockFns.mockSafeCompleteWithCancellation, - safeCompleteWithPause: loggingSessionMockFns.mockSafeCompleteWithPause, - markAsFailed: loggingSessionMockFns.mockMarkAsFailed, -})) +export const LoggingSessionMock = vi.fn().mockImplementation( + class { + start = loggingSessionMockFns.mockStart + complete = loggingSessionMockFns.mockComplete + completeWithError = loggingSessionMockFns.mockCompleteWithError + completeWithCancellation = loggingSessionMockFns.mockCompleteWithCancellation + completeWithPause = loggingSessionMockFns.mockCompleteWithPause + safeStart = loggingSessionMockFns.mockSafeStart + waitForCompletion = loggingSessionMockFns.mockWaitForCompletion + waitForPostExecution = loggingSessionMockFns.mockWaitForPostExecution + safeComplete = loggingSessionMockFns.mockSafeComplete + safeCompleteWithError = loggingSessionMockFns.mockSafeCompleteWithError + safeCompleteWithCancellation = loggingSessionMockFns.mockSafeCompleteWithCancellation + safeCompleteWithPause = loggingSessionMockFns.mockSafeCompleteWithPause + markAsFailed = loggingSessionMockFns.mockMarkAsFailed + } +) /** * Static mock module for `@/lib/logs/execution/logging-session`. diff --git a/packages/testing/src/mocks/mcp-oauth.mock.ts b/packages/testing/src/mocks/mcp-oauth.mock.ts index bf23bdf6509..72f5c38470c 100644 --- a/packages/testing/src/mocks/mcp-oauth.mock.ts +++ b/packages/testing/src/mocks/mcp-oauth.mock.ts @@ -70,5 +70,11 @@ export const mcpOauthMock = { withMcpOauthRefreshLock: mcpOauthMockFns.mockWithMcpOauthRefreshLock, McpOauthRedirectRequired: McpOauthRedirectRequiredMock, McpOauthInsecureUrlError: McpOauthInsecureUrlErrorMock, - SimMcpOauthProvider: vi.fn().mockImplementation((value) => value), + SimMcpOauthProvider: vi.fn().mockImplementation( + class { + constructor(value: object) { + Object.assign(this, value) + } + } + ), } diff --git a/packages/ts-sdk/package.json b/packages/ts-sdk/package.json index ef7b0eef1a3..85589da2380 100644 --- a/packages/ts-sdk/package.json +++ b/packages/ts-sdk/package.json @@ -41,9 +41,9 @@ "devDependencies": { "@sim/tsconfig": "workspace:*", "@types/node": "^20.5.1", - "@vitest/coverage-v8": "^3.0.8", + "@vitest/coverage-v8": "^4.1.0", "typescript": "^5.7.3", - "vitest": "^3.0.8" + "vitest": "^4.1.0" }, "engines": { "node": ">=16" diff --git a/packages/utils/package.json b/packages/utils/package.json index d02e9bd46a8..9de01b4a73e 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -56,6 +56,6 @@ "devDependencies": { "@sim/tsconfig": "workspace:*", "typescript": "^5.7.3", - "vitest": "^3.0.8" + "vitest": "^4.1.0" } } From a6deca85bb20e0bcda22c3aad4a509e681d0e068 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 1 Jun 2026 15:16:53 -0700 Subject: [PATCH 2/4] fix(deps): exclude vulnerable vitest 4.0.x from @sim/testing peer range Tighten the v4 arm of the peer range to >=4.1.0 <5.0.0 so the peer requirement cannot be satisfied by the unpatched 4.0.x builds that GHSA-5xrq-8626-4rwp affects. --- bun.lock | 2 +- packages/testing/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bun.lock b/bun.lock index b5f47fe6bfb..42b1506b659 100644 --- a/bun.lock +++ b/bun.lock @@ -401,7 +401,7 @@ "vitest": "^4.1.0", }, "peerDependencies": { - "vitest": "^3.0.0 || ^4.0.0", + "vitest": "^3.0.0 || >=4.1.0 <5.0.0", }, }, "packages/ts-sdk": { diff --git a/packages/testing/package.json b/packages/testing/package.json index 70faee8419d..e729096f1ef 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -49,7 +49,7 @@ "format:check": "biome format ." }, "peerDependencies": { - "vitest": "^3.0.0 || ^4.0.0" + "vitest": "^3.0.0 || >=4.1.0 <5.0.0" }, "devDependencies": { "@sim/tsconfig": "workspace:*", From 8b6fc53b2fa73aff37b922ad1366006ea59dfd78 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 1 Jun 2026 15:27:50 -0700 Subject: [PATCH 3/4] fix(testing): make vitest 4 constructor mocks type-check cleanly - logging-session & mcp-oauth mocks: a class passed to mockImplementation has a construct signature that isn't assignable to its (...args) => any parameter, failing tsc. Use named function declarations instead (constructable via Reflect.construct, assignable to mockImplementation, and not rewritten to arrows by biome's useArrowFunction). - database.mock.ts: vitest 4's generic vi.fn typings no longer break the self-referential cycle on the transaction callback's tx param; loosen tx and annotate the callback's return type to resolve the implicit-any errors. --- packages/testing/src/mocks/database.mock.ts | 2 +- .../testing/src/mocks/logging-session.mock.ts | 42 +++++++++++-------- packages/testing/src/mocks/mcp-oauth.mock.ts | 18 ++++---- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/packages/testing/src/mocks/database.mock.ts b/packages/testing/src/mocks/database.mock.ts index dead81be44c..f4de1f54b4e 100644 --- a/packages/testing/src/mocks/database.mock.ts +++ b/packages/testing/src/mocks/database.mock.ts @@ -155,7 +155,7 @@ const set = vi.fn(() => ({ where })) const update = vi.fn(() => ({ set })) const del = vi.fn(() => ({ where })) const transaction: ReturnType = vi.fn( - async (cb: (tx: typeof dbChainMock.db) => unknown) => cb(dbChainMock.db) + async (cb: (tx: any) => unknown): Promise => cb(dbChainMock.db) ) export const dbChainMockFns = { diff --git a/packages/testing/src/mocks/logging-session.mock.ts b/packages/testing/src/mocks/logging-session.mock.ts index 1e849b8bb19..0f951db2484 100644 --- a/packages/testing/src/mocks/logging-session.mock.ts +++ b/packages/testing/src/mocks/logging-session.mock.ts @@ -31,28 +31,36 @@ export const loggingSessionMockFns = { mockMarkAsFailed: vi.fn().mockResolvedValue(undefined), } +/** + * Builds the object returned by each `new LoggingSession(...)` call. Declared as + * a named function (not an arrow) so it stays constructable under vitest 4's + * `Reflect.construct` path while remaining assignable to `mockImplementation`; a + * returned object overrides the constructed instance. + */ +function buildLoggingSessionInstance() { + return { + start: loggingSessionMockFns.mockStart, + complete: loggingSessionMockFns.mockComplete, + completeWithError: loggingSessionMockFns.mockCompleteWithError, + completeWithCancellation: loggingSessionMockFns.mockCompleteWithCancellation, + completeWithPause: loggingSessionMockFns.mockCompleteWithPause, + safeStart: loggingSessionMockFns.mockSafeStart, + waitForCompletion: loggingSessionMockFns.mockWaitForCompletion, + waitForPostExecution: loggingSessionMockFns.mockWaitForPostExecution, + safeComplete: loggingSessionMockFns.mockSafeComplete, + safeCompleteWithError: loggingSessionMockFns.mockSafeCompleteWithError, + safeCompleteWithCancellation: loggingSessionMockFns.mockSafeCompleteWithCancellation, + safeCompleteWithPause: loggingSessionMockFns.mockSafeCompleteWithPause, + markAsFailed: loggingSessionMockFns.mockMarkAsFailed, + } +} + /** * Constructor-shaped mock for `LoggingSession`. Each `new LoggingSession(...)` * call returns an object whose methods point at the shared `vi.fn()` refs in * `loggingSessionMockFns`. */ -export const LoggingSessionMock = vi.fn().mockImplementation( - class { - start = loggingSessionMockFns.mockStart - complete = loggingSessionMockFns.mockComplete - completeWithError = loggingSessionMockFns.mockCompleteWithError - completeWithCancellation = loggingSessionMockFns.mockCompleteWithCancellation - completeWithPause = loggingSessionMockFns.mockCompleteWithPause - safeStart = loggingSessionMockFns.mockSafeStart - waitForCompletion = loggingSessionMockFns.mockWaitForCompletion - waitForPostExecution = loggingSessionMockFns.mockWaitForPostExecution - safeComplete = loggingSessionMockFns.mockSafeComplete - safeCompleteWithError = loggingSessionMockFns.mockSafeCompleteWithError - safeCompleteWithCancellation = loggingSessionMockFns.mockSafeCompleteWithCancellation - safeCompleteWithPause = loggingSessionMockFns.mockSafeCompleteWithPause - markAsFailed = loggingSessionMockFns.mockMarkAsFailed - } -) +export const LoggingSessionMock = vi.fn().mockImplementation(buildLoggingSessionInstance) /** * Static mock module for `@/lib/logs/execution/logging-session`. diff --git a/packages/testing/src/mocks/mcp-oauth.mock.ts b/packages/testing/src/mocks/mcp-oauth.mock.ts index 72f5c38470c..86d6f5508d0 100644 --- a/packages/testing/src/mocks/mcp-oauth.mock.ts +++ b/packages/testing/src/mocks/mcp-oauth.mock.ts @@ -43,6 +43,16 @@ export class McpOauthInsecureUrlErrorMock extends Error { } } +/** + * Returns the provider config back as the constructed instance, matching the + * original identity passthrough. Declared as a named function (not an arrow) so + * it stays constructable under vitest 4's `Reflect.construct` path while + * remaining assignable to `mockImplementation`. + */ +function buildSimMcpOauthProvider(value: object) { + return value +} + /** * Static mock module for `@/lib/mcp/oauth`. * @@ -70,11 +80,5 @@ export const mcpOauthMock = { withMcpOauthRefreshLock: mcpOauthMockFns.mockWithMcpOauthRefreshLock, McpOauthRedirectRequired: McpOauthRedirectRequiredMock, McpOauthInsecureUrlError: McpOauthInsecureUrlErrorMock, - SimMcpOauthProvider: vi.fn().mockImplementation( - class { - constructor(value: object) { - Object.assign(this, value) - } - } - ), + SimMcpOauthProvider: vi.fn().mockImplementation(buildSimMcpOauthProvider), } From e8dc247a463835e095ba135a85bd53b40161531d Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 1 Jun 2026 15:45:13 -0700 Subject: [PATCH 4/4] test(isolated-vm): de-flake queue-capacity scheduler tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'queue is full' and 'per-owner queued limit' tests relied on 'await sleep(1)' to assume the first request had reached the queue before submitting the overflow request. The first request only enqueues after an async spawn-failure chain (acquireWorker -> spawn exit -> resolve null -> enqueue), which isn't guaranteed within 1ms under CI load — the overflow request then found an empty queue and hit the 200ms queue-wait timeout instead of the capacity rejection. Replace the wall-clock barrier with a deterministic, event-driven one: hold the single global concurrency slot (IVM_MAX_CONCURRENT=1) with an active worker and await an explicit 'dispatched' signal (fired when the worker receives its execute message, after the scheduler counts it active). The follow-up requests then deterministically hit the synchronous enqueue path. Also drops the queue-wait timeout from 200ms to 50ms, so the tests run faster. --- apps/sim/lib/execution/isolated-vm.test.ts | 121 +++++++++++++++++---- 1 file changed, 102 insertions(+), 19 deletions(-) diff --git a/apps/sim/lib/execution/isolated-vm.test.ts b/apps/sim/lib/execution/isolated-vm.test.ts index f19cebf61c7..85c479b40b4 100644 --- a/apps/sim/lib/execution/isolated-vm.test.ts +++ b/apps/sim/lib/execution/isolated-vm.test.ts @@ -8,7 +8,6 @@ import { redisConfigMock, redisConfigMockFns, } from '@sim/testing' -import { sleep } from '@sim/utils/helpers' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' type MockProc = EventEmitter & { @@ -83,6 +82,54 @@ function createReadyProcWithDelay(delayMs: number): MockProc { return proc } +type ControllableReadyProc = { + spawn: SpawnFactory + dispatched: Promise + release: (result?: unknown) => void +} + +/** + * A ready worker whose execution is held open until {@link ControllableReadyProc.release} + * is called. {@link ControllableReadyProc.dispatched} resolves the moment the worker + * receives its `execute` message — i.e. once the scheduler has counted the execution as + * active — giving tests a deterministic, event-driven signal that the concurrency slot is + * occupied without relying on wall-clock delays. The proc is built inside {@link spawn} so + * its `ready` event is emitted only after the module attaches its listeners. + */ +function createControllableReadyProc(): ControllableReadyProc { + let markDispatched: () => void = () => {} + const dispatched = new Promise((resolve) => { + markDispatched = resolve + }) + let proc: MockProc | undefined + let lastExecutionId = 0 + + const spawn: SpawnFactory = () => { + const current = createBaseProc() + current.send = (message: unknown) => { + const msg = message as { type?: string; executionId?: number } + if (msg.type === 'execute') { + lastExecutionId = msg.executionId ?? 0 + markDispatched() + } + return true + } + setImmediate(() => current.emit('message', { type: 'ready' })) + proc = current + return current + } + + const release = (result: unknown = 'released') => { + proc?.emit('message', { + type: 'result', + executionId: lastExecutionId, + result: { result, stdout: '' }, + }) + } + + return { spawn, dispatched, release } +} + function createReadyFetchProxyProc(fetchMessage: { url: string; optionsJson?: string }): MockProc { const proc = createBaseProc() let currentExecutionId = 0 @@ -256,15 +303,31 @@ describe('isolated-vm scheduler', () => { }) it('rejects new requests when the queue is full', async () => { + const holder = createControllableReadyProc() const { executeInIsolatedVM } = await loadExecutionModule({ envOverrides: { + IVM_MAX_CONCURRENT: '1', IVM_MAX_QUEUE_SIZE: '1', - IVM_QUEUE_TIMEOUT_MS: '200', + IVM_QUEUE_TIMEOUT_MS: '50', }, - spawns: [createStartupFailureProc, createStartupFailureProc, createStartupFailureProc], + spawns: [holder.spawn], }) - const firstPromise = executeInIsolatedVM({ + // Occupy the single global concurrency slot with an active execution. Awaiting + // `dispatched` is event-driven, so the queue state below is fully deterministic. + const holderPromise = executeInIsolatedVM({ + code: 'return "holder"', + params: {}, + envVars: {}, + contextVariables: {}, + timeoutMs: 1000, + requestId: 'req-holder', + ownerKey: 'user:holder', + }) + await holder.dispatched + + // With the slot held, this request lands in the queue (size 1, now full)... + const queuedPromise = executeInIsolatedVM({ code: 'return 1', params: {}, envVars: {}, @@ -274,9 +337,8 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:a', }) - await sleep(1) - - const second = await executeInIsolatedVM({ + // ...and this one overflows it and is rejected immediately. + const rejected = await executeInIsolatedVM({ code: 'return 2', params: {}, envVars: {}, @@ -286,22 +348,41 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:b', }) - expect(second.error?.message).toContain('at capacity') + expect(rejected.error?.message).toContain('at capacity') + + const queued = await queuedPromise + expect(queued.error?.message).toContain('timed out waiting') - const first = await firstPromise - expect(first.error?.message).toContain('timed out waiting') + holder.release() + await holderPromise }) it('enforces per-owner queued limit', async () => { + const holder = createControllableReadyProc() const { executeInIsolatedVM } = await loadExecutionModule({ envOverrides: { + IVM_MAX_CONCURRENT: '1', IVM_MAX_QUEUED_PER_OWNER: '1', - IVM_QUEUE_TIMEOUT_MS: '200', + IVM_QUEUE_TIMEOUT_MS: '50', }, - spawns: [createStartupFailureProc, createStartupFailureProc, createStartupFailureProc], + spawns: [holder.spawn], + }) + + // Hold the single global slot with one of the owner's executions so the next + // requests deterministically queue instead of dispatching. + const holderPromise = executeInIsolatedVM({ + code: 'return "holder"', + params: {}, + envVars: {}, + contextVariables: {}, + timeoutMs: 1000, + requestId: 'req-holder', + ownerKey: 'user:hog', }) + await holder.dispatched - const firstPromise = executeInIsolatedVM({ + // First queued request for the owner fills their per-owner queue allowance... + const queuedPromise = executeInIsolatedVM({ code: 'return 1', params: {}, envVars: {}, @@ -311,9 +392,8 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:hog', }) - await sleep(1) - - const second = await executeInIsolatedVM({ + // ...so the second is rejected for exceeding the per-owner queued limit. + const rejected = await executeInIsolatedVM({ code: 'return 2', params: {}, envVars: {}, @@ -323,10 +403,13 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:hog', }) - expect(second.error?.message).toContain('Too many concurrent') + expect(rejected.error?.message).toContain('Too many concurrent') + + const queued = await queuedPromise + expect(queued.error?.message).toContain('timed out waiting') - const first = await firstPromise - expect(first.error?.message).toContain('timed out waiting') + holder.release() + await holderPromise }) it('enforces distributed owner in-flight lease limit when Redis is configured', async () => {