diff --git a/.dockerignore b/.dockerignore index 11d03a1c54..514136ac91 100644 --- a/.dockerignore +++ b/.dockerignore @@ -61,7 +61,6 @@ __tests__ # Ignore development config files .eslintrc* .prettierrc* -jest.config* # Ignore most directories except what we need for the build apps/ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 391b356d0f..be722a6c8f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -230,7 +230,7 @@ importers: version: 4.1.6 vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@22.15.29)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) apps/web-roo-code: dependencies: @@ -346,7 +346,7 @@ importers: version: 20.17.57 vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) packages/cloud: dependencies: @@ -377,7 +377,7 @@ importers: version: 1.100.0 vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) packages/config-eslint: devDependencies: @@ -479,7 +479,7 @@ importers: version: 4.19.4 vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) packages/ipc: dependencies: @@ -504,7 +504,7 @@ importers: version: 9.2.3 vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) packages/telemetry: dependencies: @@ -532,7 +532,7 @@ importers: version: 1.100.0 vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) packages/types: dependencies: @@ -554,7 +554,7 @@ importers: version: 8.5.0(jiti@2.4.2)(postcss@8.5.4)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.8.0) vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) src: dependencies: @@ -855,7 +855,7 @@ importers: version: 5.8.3 vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.50)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.50)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) zod-to-ts: specifier: ^1.2.0 version: 1.2.0(typescript@5.8.3)(zod@3.25.61) @@ -1037,9 +1037,6 @@ importers: specifier: ^3.25.61 version: 3.25.61 devDependencies: - '@jest/globals': - specifier: ^29.7.0 - version: 29.7.0 '@roo-code/config-eslint': specifier: workspace:^ version: link:../packages/config-eslint @@ -1055,9 +1052,6 @@ importers: '@testing-library/user-event': specifier: ^14.6.1 version: 14.6.1(@testing-library/dom@10.4.0) - '@types/jest': - specifier: ^29.0.0 - version: 29.5.14 '@types/node': specifier: 20.x version: 20.17.57 @@ -1070,30 +1064,21 @@ importers: '@types/shell-quote': specifier: ^1.7.5 version: 1.7.5 - '@types/testing-library__jest-dom': - specifier: ^5.14.5 - version: 5.14.9 '@types/vscode-webview': specifier: ^1.57.5 version: 1.57.5 '@vitejs/plugin-react': specifier: ^4.3.4 version: 4.4.1(vite@6.3.5(@types/node@20.17.57)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/ui': + specifier: ^3.2.3 + version: 3.2.3(vitest@3.2.3) identity-obj-proxy: specifier: ^3.0.0 version: 3.0.0 - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0) - jest-environment-jsdom: - specifier: ^29.7.0 - version: 29.7.0 - jest-simple-dot-reporter: - specifier: ^1.0.5 - version: 1.0.5 - ts-jest: - specifier: ^29.2.5 - version: 29.3.3(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(esbuild@0.25.5)(jest@29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0))(typescript@5.8.3) + jsdom: + specifier: ^26.0.0 + version: 26.1.0 typescript: specifier: 5.8.3 version: 5.8.3 @@ -1102,12 +1087,12 @@ importers: version: 6.3.5(@types/node@20.17.57)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) vitest: specifier: ^3.2.3 - version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) packages: - '@adobe/css-tools@4.4.2': - resolution: {integrity: sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==} + '@adobe/css-tools@4.4.3': + resolution: {integrity: sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==} '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} @@ -1132,6 +1117,9 @@ packages: '@anthropic-ai/vertex-sdk@0.7.0': resolution: {integrity: sha512-zNm3hUXgYmYDTyveIxOyxbcnh5VXFkrLo4bSnG6LAfGzW7k3k2iCNDSVKtR9qZrK2BCid7JtVu7jsEKaZ/9dSw==} + '@asamuzakjp/css-color@3.2.0': + resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + '@aws-crypto/crc32@3.0.0': resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} @@ -1375,97 +1363,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-bigint@7.8.3': - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.27.1': - resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.27.1': - resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.27.1': - resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-self@7.27.1': resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} engines: {node: '>=6.9.0'} @@ -1578,6 +1475,34 @@ packages: '@chevrotain/utils@11.0.3': resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} + '@csstools/color-helpers@5.0.2': + resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.0.10': + resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + '@dotenvx/dotenvx@1.44.2': resolution: {integrity: sha512-2C44+G2dch4cB6zw7+oGQ9VcFQuuVhc5xOzfVvY7iUEj2PRhiVMIB6SpNMK1V5TvpdqrAqCYFjclK18Mh9vwNQ==} hasBin: true @@ -2266,80 +2191,10 @@ packages: resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} - '@istanbuljs/load-nyc-config@1.1.0': - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} @@ -2723,6 +2578,9 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@puppeteer/browsers@2.10.5': resolution: {integrity: sha512-eifa0o+i8dERnngJwKrfp3dEq7ia5XFyoqB17S4gK8GhsQE4/P8nxOfQSE0zQHxzzLo/cmF+7+ywEQ7wK7Fb+w==} engines: {node: '>=18'} @@ -3463,19 +3321,10 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - '@smithy/abort-controller@2.2.0': resolution: {integrity: sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==} engines: {node: '>=14.0.0'} @@ -4022,10 +3871,6 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} @@ -4173,30 +4018,15 @@ packages: '@types/glob@8.1.0': resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - - '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} - '@types/js-cookie@2.2.7': resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} - '@types/jsdom@20.0.1': - resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -4252,9 +4082,6 @@ packages: '@types/node@22.15.29': resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==} - '@types/parse-json@4.0.2': - resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} @@ -4272,24 +4099,15 @@ packages: '@types/shell-quote@1.7.5': resolution: {integrity: sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw==} - '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - '@types/string-similarity@4.0.2': resolution: {integrity: sha512-LkJQ/jsXtCVMK+sKYAmX/8zEq+/46f1PTQw7YtmQwb74jemS1SlNLmARM2Zml9DgdDTWKAtc5L13WorpHPDjDA==} '@types/stylis@4.2.5': resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==} - '@types/testing-library__jest-dom@5.14.9': - resolution: {integrity: sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==} - '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} - '@types/tough-cookie@4.0.5': - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -4314,12 +4132,6 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - - '@types/yargs@17.0.33': - resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} @@ -4409,6 +4221,11 @@ packages: '@vitest/spy@3.2.3': resolution: {integrity: sha512-JHu9Wl+7bf6FEejTCREy+DmgWe+rQKbK+y32C/k5f4TBIAlijhJbRBIRIOCEpVevgRsCQR2iHRUH2/qKVM/plw==} + '@vitest/ui@3.2.3': + resolution: {integrity: sha512-9aR2tY/WT7GRHGEH/9sSIipJqeA21Eh3C6xmiOVmfyBCFmezUSUFLalpaSmRHlRzWCKQU10yz3AHhKuYcdnZGQ==} + peerDependencies: + vitest: 3.2.3 + '@vitest/utils@3.2.3': resolution: {integrity: sha512-4zFBCU5Pf+4Z6v+rwnZ1HU1yzOKKvDkMXZrymE2PBlbjKJRlrOxbvpfPSvJTGRIwGoahaOGvp+kbCoxifhzJ1Q==} @@ -4490,10 +4307,6 @@ packages: '@xobotyi/scrollbar-width@1.9.5': resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} - abab@2.0.6: - resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - deprecated: Use your platform's native atob() and btoa() methods instead - abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -4502,18 +4315,11 @@ packages: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} - acorn-globals@7.0.1: - resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} - acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} - acorn@8.14.1: resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} engines: {node: '>=0.4.0'} @@ -4524,10 +4330,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -4543,10 +4345,6 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - ansi-escapes@7.0.0: resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} engines: {node: '>=18'} @@ -4613,10 +4411,6 @@ packages: aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - array-buffer-byte-length@1.0.2: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} @@ -4690,35 +4484,6 @@ packages: b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - - babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - - babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - babel-plugin-macros@3.1.0: - resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} - engines: {node: '>=10', npm: '>=6'} - - babel-preset-current-node-syntax@1.1.0: - resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} - peerDependencies: - '@babel/core': ^7.0.0 - - babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - bail@1.0.5: resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} @@ -4823,13 +4588,6 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - - bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} @@ -4897,10 +4655,6 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} @@ -4937,10 +4691,6 @@ packages: resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -5008,9 +4758,6 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} - class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -5061,17 +4808,10 @@ packages: react: ^18 || ^19 || ^19.0.0-rc react-dom: ^18 || ^19 || ^19.0.0-rc - co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - cockatiel@3.2.1: resolution: {integrity: sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==} engines: {node: '>=16'} - collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -5199,10 +4939,6 @@ packages: cose-base@2.2.0: resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} - cosmiconfig@7.1.0: - resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} - engines: {node: '>=10'} - crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} @@ -5212,11 +4948,6 @@ packages: resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} engines: {node: '>= 10'} - create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} @@ -5253,15 +4984,9 @@ packages: engines: {node: '>=4'} hasBin: true - cssom@0.3.8: - resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - - cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - - cssstyle@2.3.0: - resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} - engines: {node: '>=8'} + cssstyle@4.4.0: + resolution: {integrity: sha512-W0Y2HOXlPkb2yaKrCVRjinYKciu/qSLEmK0K9mcfDei3zwlnHFEHAs/Du3cIRwPqY+J4JsiBzUjoHyc8RsJ03A==} + engines: {node: '>=18'} csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -5430,9 +5155,9 @@ packages: resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} - data-urls@3.0.2: - resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} - engines: {node: '>=12'} + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} @@ -5490,14 +5215,6 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} - dedent@1.6.0: - resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -5509,10 +5226,6 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - default-browser-id@5.0.0: resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} engines: {node: '>=18'} @@ -5572,10 +5285,6 @@ packages: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} - detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} @@ -5591,10 +5300,6 @@ packages: diff-match-patch@1.0.5: resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - diff@5.2.0: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} @@ -5628,11 +5333,6 @@ packages: domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - domexception@4.0.0: - resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} - engines: {node: '>=12'} - deprecated: Use your platform's native DOMException instead - domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} @@ -5780,11 +5480,6 @@ packages: eight-colors@1.3.1: resolution: {integrity: sha512-7nXPYDeKh6DgJDR/mpt2G7N/hCNSGwwoPVmoI3+4TEwOb07VFN1WMPG0DFf6nMEjrkgdj8Og7l7IaEEk3VE6Zg==} - ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true - electron-to-chromium@1.5.152: resolution: {integrity: sha512-xBOfg/EBaIlVsHipHl2VdTPJRSvErNUaqW8ejTq5OlOlIYx1wOllCHsAvAIrr55jD1IYEfdR86miUEt8H5IeJg==} @@ -5811,10 +5506,6 @@ packages: embla-carousel@8.6.0: resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} - emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - emoji-regex@10.4.0: resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} @@ -5858,9 +5549,6 @@ packages: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - error-stack-parser@2.1.4: resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} @@ -5930,10 +5618,6 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -6102,10 +5786,6 @@ packages: exenv-es6@1.1.1: resolution: {integrity: sha512-vlVu3N8d6yEMpMsEm+7sUBAI81aqYYuEvfK0jNqmdb/OPXzzH7QWDDnVjMvDSY47JdHEqx/dfC/q8WkfoTmpGQ==} - exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -6114,10 +5794,6 @@ packages: resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} - expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - express-rate-limit@7.5.0: resolution: {integrity: sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==} engines: {node: '>= 16'} @@ -6195,9 +5871,6 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - fd-package-json@2.0.0: resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} @@ -6227,6 +5900,9 @@ packages: fflate@0.4.8: resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + figures@6.1.0: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} @@ -6238,9 +5914,6 @@ packages: file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -6419,10 +6092,6 @@ packages: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} - get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -6597,9 +6266,9 @@ packages: howler@2.2.4: resolution: {integrity: sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w==} - html-encoding-sniffer@3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -6620,18 +6289,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} - http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -6708,11 +6369,6 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-local@3.2.0: - resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} - engines: {node: '>=8'} - hasBin: true - imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -6775,9 +6431,6 @@ packages: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} @@ -6852,10 +6505,6 @@ packages: resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} engines: {node: '>=18'} - is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - is-generator-function@1.1.0: resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} engines: {node: '>= 0.4'} @@ -7016,22 +6665,10 @@ packages: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} - istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - - istanbul-lib-instrument@6.0.3: - resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} - engines: {node: '>=10'} - istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} - istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - istanbul-reports@3.1.7: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} @@ -7047,202 +6684,56 @@ packages: resolution: {integrity: sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==} engines: {node: 20 || >=22} - jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} - engines: {node: '>=10'} + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} - jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} - jest-environment-jsdom@29.7.0: - resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true + js-cookie@2.2.1: + resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} - jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + js-message@1.0.7: + resolution: {integrity: sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==} + engines: {node: '>=0.6.0'} - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + js-queue@2.0.2: + resolution: {integrity: sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==} + engines: {node: '>=1.0.0'} - jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true - jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true - jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - jest-pnp-resolver@1.2.3: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} + jsdom@26.1.0: + resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} + engines: {node: '>=18'} peerDependencies: - jest-resolve: '*' + canvas: ^3.0.0 peerDependenciesMeta: - jest-resolve: - optional: true - - jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-simple-dot-reporter@1.0.5: - resolution: {integrity: sha512-cZLFG/C7k0+WYoIGGuGXKm0vmJiXlWG/m3uCZ4RaMPYxt8lxjdXMLHYkxXaQ7gVWaSPe7uAPCEUcRxthC5xskg==} - - jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true - - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} - hasBin: true - - joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - - js-base64@3.7.7: - resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} - - js-cookie@2.2.1: - resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} - - js-message@1.0.7: - resolution: {integrity: sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==} - engines: {node: '>=0.6.0'} - - js-queue@2.0.2: - resolution: {integrity: sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==} - engines: {node: '>=1.0.0'} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - - jsdom@20.0.3: - resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} - engines: {node: '>=14'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: + canvas: optional: true jsesc@3.1.0: @@ -7256,9 +6747,6 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-parse-even-better-errors@4.0.0: resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -7323,10 +6811,6 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - knip@5.60.2: resolution: {integrity: sha512-TsYqEsoL3802RmhGL5MN7RLI6/03kocMYx/4BpMmwo3dSwEJxmzV7HqRxMVZr6c1llbd25+MqjgA86bv1IwsPA==} engines: {node: '>=18.18.0'} @@ -7592,9 +7076,6 @@ packages: lodash.isundefined@3.0.1: resolution: {integrity: sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==} - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -7682,12 +7163,6 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - - makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - mammoth@1.9.0: resolution: {integrity: sha512-F+0NxzankQV9XSUAuVKvkdQK0GbtGGuqVnND9aVf9VSeUA82LQa29GjLqYU6Eez8LHqSJG3eGiDW3224OKdpZg==} engines: {node: '>=12.0.0'} @@ -8002,6 +7477,10 @@ packages: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -8103,9 +7582,6 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-ipc@12.0.0: resolution: {integrity: sha512-QHJ2gAJiqA3cM7cQiRjLsfCOBRB0TwQ6axYD4FSllQWipEbP6i7Se1dP8EzPKk5J1nCe27W69eqPmCoKyQ61Vg==} engines: {node: '>=14'} @@ -8350,10 +7826,6 @@ packages: parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - parse-ms@4.0.0: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} @@ -8465,10 +7937,6 @@ packages: resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==} engines: {node: '>=16.20.0'} - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} @@ -8620,10 +8088,6 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - pretty-ms@9.2.0: resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} engines: {node: '>=18'} @@ -8638,10 +8102,6 @@ packages: promise-limit@2.7.0: resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -8671,9 +8131,6 @@ packages: engines: {node: '>= 0.10'} hasBin: true - psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -8692,9 +8149,6 @@ packages: resolution: {integrity: sha512-3HZ2/7hdDKZvZQ7dhhITOUg4/wOrDRjyK2ZBllRB0ZCOi9u0cwq1ACHDjBB+nX+7+kltHjQvBRdeY7+W0T+7Gg==} engines: {node: '>=18'} - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.14.0: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} @@ -8702,9 +8156,6 @@ packages: quansync@0.2.10: resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -8956,16 +8407,9 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - resize-observer-polyfill@1.5.1: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} - resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -8977,10 +8421,6 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} - resolve@1.22.10: resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} engines: {node: '>= 0.4'} @@ -9026,6 +8466,9 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + rtl-css-js@1.16.1: resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} @@ -9210,8 +8653,9 @@ packages: simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + engines: {node: '>=18'} slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} @@ -9254,9 +8698,6 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -9297,10 +8738,6 @@ packages: stack-generator@2.0.10: resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -9341,10 +8778,6 @@ packages: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} - string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - string-similarity@4.0.4: resolution: {integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. @@ -9401,10 +8834,6 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - strip-bom@5.0.0: resolution: {integrity: sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A==} engines: {node: '>=12'} @@ -9623,6 +9052,13 @@ packages: resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} engines: {node: '>=14.0.0'} + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + hasBin: true + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -9631,9 +9067,6 @@ packages: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} - tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -9645,19 +9078,23 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} tr46@1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} - tr46@3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} traverse@0.3.9: resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} @@ -9697,30 +9134,6 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - ts-jest@29.3.3: - resolution: {integrity: sha512-y6jLm19SL4GroiBmHwFK4dSHUfDNmOrJbRfp6QmDIlI9p5tT5Q8ItccB4pTIslCIqOZuQnBwpTR0bQ5eUMYwkw==} - engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 - esbuild: '*' - jest: ^29.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/transform': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -9802,22 +9215,10 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - type-is@2.0.1: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} @@ -9951,10 +9352,6 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -9978,9 +9375,6 @@ packages: url-join@4.0.1: resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -10186,17 +9580,14 @@ packages: '@types/react': '*' react: ^17 || ^18 || ^19 - w3c-xmlserializer@4.0.0: - resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} - engines: {node: '>=14'} + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} walk-up-path@4.0.0: resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} engines: {node: 20 || >=22} - walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - web-namespaces@1.1.4: resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==} @@ -10224,25 +9615,17 @@ packages: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} - whatwg-encoding@2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} - whatwg-encoding@3.1.1: resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} engines: {node: '>=18'} - whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} - whatwg-url@11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -10322,10 +9705,6 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - ws@8.18.2: resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} engines: {node: '>=10.0.0'} @@ -10338,9 +9717,9 @@ packages: utf-8-validate: optional: true - xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} xml2js@0.5.0: resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} @@ -10375,10 +9754,6 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} - yaml@2.8.0: resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} engines: {node: '>= 14.6'} @@ -10458,7 +9833,7 @@ packages: snapshots: - '@adobe/css-tools@4.4.2': {} + '@adobe/css-tools@4.4.3': {} '@alloc/quick-lru@5.2.0': {} @@ -10511,6 +9886,14 @@ snapshots: - encoding - supports-color + '@asamuzakjp/css-color@3.2.0': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 10.4.3 + '@aws-crypto/crc32@3.0.0': dependencies: '@aws-crypto/util': 3.0.0 @@ -11146,91 +10529,6 @@ snapshots: dependencies: '@babel/types': 7.27.1 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1 @@ -11433,6 +10731,26 @@ snapshots: '@chevrotain/utils@11.0.3': {} + '@csstools/color-helpers@5.0.2': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.0.2 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + '@dotenvx/dotenvx@1.44.2': dependencies: commander: 11.1.0 @@ -11924,198 +11242,28 @@ snapshots: dependencies: minipass: 7.1.2 - '@istanbuljs/load-nyc-config@1.1.0': - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - '@istanbuljs/schema@0.1.3': {} - '@jest/console@29.7.0': + '@jridgewell/gen-mapping@0.3.8': dependencies: - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node + '@jridgewell/resolve-uri@3.1.2': {} - '@jest/environment@29.7.0': - dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - jest-mock: 29.7.0 + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} - '@jest/expect-utils@29.7.0': + '@jridgewell/trace-mapping@0.3.25': dependencies: - jest-get-type: 29.6.3 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 - '@jest/expect@29.7.0': + '@kwsites/file-exists@1.1.1': dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/fake-timers@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.17.57 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - '@jest/globals@29.7.0': - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/reporters@29.7.0': - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.17.57 - chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color - - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - - '@jest/source-map@29.6.3': - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - callsites: 3.1.0 - graceful-fs: 4.2.11 - - '@jest/test-result@29.7.0': - dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 - - '@jest/test-sequencer@29.7.0': - dependencies: - '@jest/test-result': 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 - - '@jest/transform@29.7.0': - dependencies: - '@babel/core': 7.27.1 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - - '@jest/types@29.6.3': - dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 20.17.57 - '@types/yargs': 17.0.33 - chalk: 4.1.2 - - '@jridgewell/gen-mapping@0.3.8': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@kwsites/file-exists@1.1.1': - dependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -12447,6 +11595,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@polka/url@1.0.0-next.29': {} + '@puppeteer/browsers@2.10.5': dependencies: debug: 4.4.1(supports-color@8.1.1) @@ -13182,18 +12332,8 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} - '@sinclair/typebox@0.27.8': {} - '@sindresorhus/merge-streams@4.0.0': {} - '@sinonjs/commons@3.0.1': - dependencies: - type-detect: 4.0.8 - - '@sinonjs/fake-timers@10.3.0': - dependencies: - '@sinonjs/commons': 3.0.1 - '@smithy/abort-controller@2.2.0': dependencies: '@smithy/types': 2.12.0 @@ -13861,8 +13001,8 @@ snapshots: '@testing-library/jest-dom@6.6.3': dependencies: - '@adobe/css-tools': 4.4.2 - aria-query: 5.3.2 + '@adobe/css-tools': 4.4.3 + aria-query: 5.3.0 chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 @@ -13883,8 +13023,6 @@ snapshots: dependencies: '@testing-library/dom': 10.4.0 - '@tootallnate/once@2.0.0': {} - '@tootallnate/quickjs-emscripten@0.23.0': {} '@tybys/wasm-util@0.9.0': @@ -14063,37 +13201,14 @@ snapshots: '@types/minimatch': 5.1.2 '@types/node': 20.17.57 - '@types/graceful-fs@4.1.9': - dependencies: - '@types/node': 20.17.57 - '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 '@types/istanbul-lib-coverage@2.0.6': {} - '@types/istanbul-lib-report@3.0.3': - dependencies: - '@types/istanbul-lib-coverage': 2.0.6 - - '@types/istanbul-reports@3.0.4': - dependencies: - '@types/istanbul-lib-report': 3.0.3 - - '@types/jest@29.5.14': - dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 - '@types/js-cookie@2.2.7': {} - '@types/jsdom@20.0.1': - dependencies: - '@types/node': 20.17.57 - '@types/tough-cookie': 4.0.5 - parse5: 7.3.0 - '@types/json-schema@7.0.15': {} '@types/lodash.debounce@4.0.9': @@ -14154,9 +13269,6 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/parse-json@4.0.2': - optional: true - '@types/prop-types@15.7.14': {} '@types/ps-tree@1.1.6': {} @@ -14172,20 +13284,12 @@ snapshots: '@types/shell-quote@1.7.5': {} - '@types/stack-utils@2.0.3': {} - '@types/string-similarity@4.0.2': {} '@types/stylis@4.2.5': {} - '@types/testing-library__jest-dom@5.14.9': - dependencies: - '@types/jest': 29.5.14 - '@types/tmp@0.2.6': {} - '@types/tough-cookie@4.0.5': {} - '@types/trusted-types@2.0.7': optional: true @@ -14206,12 +13310,6 @@ snapshots: '@types/node': 20.19.0 optional: true - '@types/yargs-parser@21.0.3': {} - - '@types/yargs@17.0.33': - dependencies: - '@types/yargs-parser': 21.0.3 - '@types/yauzl@2.10.3': dependencies: '@types/node': 20.17.57 @@ -14367,6 +13465,17 @@ snapshots: dependencies: tinyspy: 4.0.3 + '@vitest/ui@3.2.3(vitest@3.2.3)': + dependencies: + '@vitest/utils': 3.2.3 + fflate: 0.8.2 + flatted: 3.3.3 + pathe: 2.0.3 + sirv: 3.0.1 + tinyglobby: 0.2.14 + tinyrainbow: 2.0.0 + vitest: 3.2.3(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + '@vitest/utils@3.2.3': dependencies: '@vitest/pretty-format': 3.2.3 @@ -14480,8 +13589,6 @@ snapshots: '@xobotyi/scrollbar-width@1.9.5': {} - abab@2.0.6: {} - abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -14491,11 +13598,6 @@ snapshots: mime-types: 3.0.1 negotiator: 1.0.0 - acorn-globals@7.0.1: - dependencies: - acorn: 8.14.1 - acorn-walk: 8.3.4 - acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -14504,20 +13606,10 @@ snapshots: dependencies: acorn: 8.15.0 - acorn-walk@8.3.4: - dependencies: - acorn: 8.14.1 - acorn@8.14.1: {} acorn@8.15.0: {} - agent-base@6.0.2: - dependencies: - debug: 4.4.1(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - agent-base@7.1.3: {} agentkeepalive@4.6.0: @@ -14533,10 +13625,6 @@ snapshots: ansi-colors@4.1.3: {} - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - ansi-escapes@7.0.0: dependencies: environment: 1.1.0 @@ -14618,8 +13706,6 @@ snapshots: dependencies: dequal: 2.0.3 - aria-query@5.3.2: {} - array-buffer-byte-length@1.0.2: dependencies: call-bound: 1.0.4 @@ -14722,68 +13808,6 @@ snapshots: b4a@1.6.7: {} - babel-jest@29.7.0(@babel/core@7.27.1): - dependencies: - '@babel/core': 7.27.1 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.27.1) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-istanbul@6.1.1: - dependencies: - '@babel/helper-plugin-utils': 7.27.1 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-jest-hoist@29.6.3: - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.27.1 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.7 - - babel-plugin-macros@3.1.0: - dependencies: - '@babel/runtime': 7.27.6 - cosmiconfig: 7.1.0 - resolve: 1.22.10 - optional: true - - babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.1): - dependencies: - '@babel/core': 7.27.1 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.1) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.1) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.1) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.1) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.1) - - babel-preset-jest@29.6.3(@babel/core@7.27.1): - dependencies: - '@babel/core': 7.27.1 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) - bail@1.0.5: {} bail@2.0.2: {} @@ -14895,14 +13919,6 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.24.5) - bs-logger@0.2.6: - dependencies: - fast-json-stable-stringify: 2.1.0 - - bser@2.1.1: - dependencies: - node-int64: 0.4.0 - buffer-crc32@0.2.13: {} buffer-equal-constant-time@1.0.1: {} @@ -14970,8 +13986,6 @@ snapshots: camelcase-css@2.0.1: {} - camelcase@5.3.1: {} - camelcase@6.3.0: {} camelize@1.0.1: {} @@ -15010,8 +14024,6 @@ snapshots: chalk@5.4.1: {} - char-regex@1.0.2: {} - character-entities-html4@2.1.0: {} character-entities-legacy@1.1.4: {} @@ -15095,8 +14107,6 @@ snapshots: ci-info@3.9.0: {} - cjs-module-lexer@1.4.3: {} - class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -15159,12 +14169,8 @@ snapshots: - '@types/react' - '@types/react-dom' - co@4.6.0: {} - cockatiel@3.2.1: {} - collect-v8-coverage@1.0.2: {} - color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -15275,15 +14281,6 @@ snapshots: dependencies: layout-base: 2.0.1 - cosmiconfig@7.1.0: - dependencies: - '@types/parse-json': 4.0.2 - import-fresh: 3.3.1 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.2 - optional: true - crc-32@1.2.2: {} crc32-stream@4.0.3: @@ -15291,21 +14288,6 @@ snapshots: crc-32: 1.2.2 readable-stream: 3.6.2 - create-jest@29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - cross-fetch@4.0.0: dependencies: node-fetch: 2.7.0 @@ -15349,13 +14331,10 @@ snapshots: cssesc@3.0.0: {} - cssom@0.3.8: {} - - cssom@0.5.0: {} - - cssstyle@2.3.0: + cssstyle@4.4.0: dependencies: - cssom: 0.3.8 + '@asamuzakjp/css-color': 3.2.0 + rrweb-cssom: 0.8.0 csstype@3.1.3: {} @@ -15548,11 +14527,10 @@ snapshots: data-uri-to-buffer@6.0.2: {} - data-urls@3.0.2: + data-urls@5.0.0: dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 data-view-buffer@1.0.2: dependencies: @@ -15603,10 +14581,6 @@ snapshots: mimic-response: 3.1.0 optional: true - dedent@1.6.0(babel-plugin-macros@3.1.0): - optionalDependencies: - babel-plugin-macros: 3.1.0 - deep-eql@5.0.2: {} deep-extend@0.6.0: @@ -15614,8 +14588,6 @@ snapshots: deep-is@0.1.4: {} - deepmerge@4.3.1: {} - default-browser-id@5.0.0: {} default-browser@5.2.1: @@ -15664,8 +14636,6 @@ snapshots: detect-libc@2.0.4: {} - detect-newline@3.1.0: {} - detect-node-es@1.1.0: {} devlop@1.1.0: @@ -15678,8 +14648,6 @@ snapshots: diff-match-patch@1.0.5: {} - diff-sequences@29.6.3: {} - diff@5.2.0: {} dingbat-to-unicode@1.0.1: {} @@ -15711,10 +14679,6 @@ snapshots: domelementtype@2.3.0: {} - domexception@4.0.0: - dependencies: - webidl-conversions: 7.0.0 - domhandler@5.0.3: dependencies: domelementtype: 2.3.0 @@ -15784,10 +14748,6 @@ snapshots: eight-colors@1.3.1: {} - ejs@3.1.10: - dependencies: - jake: 10.9.2 - electron-to-chromium@1.5.152: {} embla-carousel-auto-scroll@8.6.0(embla-carousel@8.6.0): @@ -15810,8 +14770,6 @@ snapshots: embla-carousel@8.6.0: {} - emittery@0.13.1: {} - emoji-regex@10.4.0: {} emoji-regex@8.0.0: {} @@ -15848,10 +14806,6 @@ snapshots: environment@1.1.0: {} - error-ex@1.3.2: - dependencies: - is-arrayish: 0.2.1 - error-stack-parser@2.1.4: dependencies: stackframe: 1.3.4 @@ -16050,8 +15004,6 @@ snapshots: escape-string-regexp@1.0.5: {} - escape-string-regexp@2.0.0: {} - escape-string-regexp@4.0.0: {} escape-string-regexp@5.0.0: {} @@ -16331,21 +15283,11 @@ snapshots: exenv-es6@1.1.1: {} - exit@0.1.2: {} - expand-template@2.0.3: optional: true expect-type@1.2.1: {} - expect@29.7.0: - dependencies: - '@jest/expect-utils': 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - express-rate-limit@7.5.0(express@5.1.0): dependencies: express: 5.1.0 @@ -16453,10 +15395,6 @@ snapshots: dependencies: reusify: 1.1.0 - fb-watchman@2.0.2: - dependencies: - bser: 2.1.1 - fd-package-json@2.0.0: dependencies: walk-up-path: 4.0.0 @@ -16481,6 +15419,8 @@ snapshots: fflate@0.4.8: {} + fflate@0.8.2: {} + figures@6.1.0: dependencies: is-unicode-supported: 2.1.0 @@ -16492,10 +15432,6 @@ snapshots: file-uri-to-path@1.0.0: optional: true - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -16697,8 +15633,6 @@ snapshots: get-nonce@1.0.1: {} - get-package-type@0.1.0: {} - get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -16922,9 +15856,9 @@ snapshots: howler@2.2.4: {} - html-encoding-sniffer@3.0.0: + html-encoding-sniffer@4.0.0: dependencies: - whatwg-encoding: 2.0.0 + whatwg-encoding: 3.1.1 html-escaper@2.0.2: {} @@ -16951,14 +15885,6 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 - http-proxy-agent@5.0.0: - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 - debug: 4.4.1(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 @@ -16966,13 +15892,6 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.1(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.3 @@ -17035,11 +15954,6 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - import-local@3.2.0: - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -17099,8 +16013,6 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 - is-arrayish@0.2.1: {} - is-arrayish@0.3.2: optional: true @@ -17168,8 +16080,6 @@ snapshots: dependencies: get-east-asian-width: 1.3.0 - is-generator-fn@2.1.0: {} - is-generator-function@1.1.0: dependencies: call-bound: 1.0.4 @@ -17296,40 +16206,12 @@ snapshots: istanbul-lib-coverage@3.2.2: {} - istanbul-lib-instrument@5.2.1: - dependencies: - '@babel/core': 7.27.1 - '@babel/parser': 7.27.2 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - istanbul-lib-instrument@6.0.3: - dependencies: - '@babel/core': 7.27.1 - '@babel/parser': 7.27.2 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - istanbul-lib-report@3.0.1: dependencies: istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1: - dependencies: - debug: 4.4.1(supports-color@8.1.1) - istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 @@ -17354,338 +16236,6 @@ snapshots: dependencies: '@isaacs/cliui': 8.0.2 - jake@10.9.2: - dependencies: - async: 3.2.6 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 - - jest-changed-files@29.7.0: - dependencies: - execa: 5.1.1 - jest-util: 29.7.0 - p-limit: 3.1.0 - - jest-circus@29.7.0(babel-plugin-macros@3.1.0): - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - chalk: 4.1.2 - co: 4.6.0 - dedent: 1.6.0(babel-plugin-macros@3.1.0) - is-generator-fn: 2.1.0 - jest-each: 29.7.0 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.1.0 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-cli@29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0): - dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest-config@29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0): - dependencies: - '@babel/core': 7.27.1 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.1) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0(babel-plugin-macros@3.1.0) - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 20.17.57 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-diff@29.7.0: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-docblock@29.7.0: - dependencies: - detect-newline: 3.1.0 - - jest-each@29.7.0: - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 - - jest-environment-jsdom@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/jsdom': 20.0.1 - '@types/node': 20.17.57 - jest-mock: 29.7.0 - jest-util: 29.7.0 - jsdom: 20.0.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - jest-environment-node@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - jest-get-type@29.6.3: {} - - jest-haste-map@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 20.17.57 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.7.0 - micromatch: 4.0.8 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - - jest-leak-detector@29.7.0: - dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-matcher-utils@29.7.0: - dependencies: - chalk: 4.1.2 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-message-util@29.7.0: - dependencies: - '@babel/code-frame': 7.27.1 - '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - stack-utils: 2.0.6 - - jest-mock@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - jest-util: 29.7.0 - - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): - optionalDependencies: - jest-resolve: 29.7.0 - - jest-regex-util@29.6.3: {} - - jest-resolve-dependencies@29.7.0: - dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - jest-resolve@29.7.0: - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.10 - resolve.exports: 2.0.3 - slash: 3.0.0 - - jest-runner@29.7.0: - dependencies: - '@jest/console': 29.7.0 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.7.0 - jest-environment-node: 29.7.0 - jest-haste-map: 29.7.0 - jest-leak-detector: 29.7.0 - jest-message-util: 29.7.0 - jest-resolve: 29.7.0 - jest-runtime: 29.7.0 - jest-util: 29.7.0 - jest-watcher: 29.7.0 - jest-worker: 29.7.0 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - - jest-runtime@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - chalk: 4.1.2 - cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - - jest-simple-dot-reporter@1.0.5: {} - - jest-snapshot@29.7.0: - dependencies: - '@babel/core': 7.27.1 - '@babel/generator': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) - '@babel/types': 7.27.1 - '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) - chalk: 4.1.2 - expect: 29.7.0 - graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - jest-util@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - chalk: 4.1.2 - ci-info: 3.9.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - - jest-validate@29.7.0: - dependencies: - '@jest/types': 29.6.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.6.3 - leven: 3.1.0 - pretty-format: 29.7.0 - - jest-watcher@29.7.0: - dependencies: - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.57 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.7.0 - string-length: 4.0.2 - - jest-worker@29.7.0: - dependencies: - '@types/node': 20.17.57 - jest-util: 29.7.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - jest@29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0): - dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) - '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - jiti@1.21.7: {} jiti@2.4.2: {} @@ -17718,34 +16268,28 @@ snapshots: jsbn@1.1.0: {} - jsdom@20.0.3: + jsdom@26.1.0: dependencies: - abab: 2.0.6 - acorn: 8.14.1 - acorn-globals: 7.0.1 - cssom: 0.5.0 - cssstyle: 2.3.0 - data-urls: 3.0.2 + cssstyle: 4.4.0 + data-urls: 5.0.0 decimal.js: 10.5.0 - domexception: 4.0.0 - escodegen: 2.1.0 - form-data: 4.0.2 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.20 parse5: 7.3.0 + rrweb-cssom: 0.8.0 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 4.1.4 - w3c-xmlserializer: 4.0.0 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 ws: 8.18.2 - xml-name-validator: 4.0.0 + xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil - supports-color @@ -17759,8 +16303,6 @@ snapshots: json-buffer@3.0.1: {} - json-parse-even-better-errors@2.3.1: {} - json-parse-even-better-errors@4.0.0: {} json-schema-traverse@0.4.1: {} @@ -17846,8 +16388,6 @@ snapshots: kind-of@6.0.3: {} - kleur@3.0.3: {} - knip@5.60.2(@types/node@22.15.29)(typescript@5.8.3): dependencies: '@nodelib/fs.walk': 1.2.8 @@ -18091,8 +16631,6 @@ snapshots: lodash.isundefined@3.0.1: {} - lodash.memoize@4.1.2: {} - lodash.merge@4.6.2: {} lodash.once@4.1.1: {} @@ -18175,12 +16713,6 @@ snapshots: dependencies: semver: 7.7.2 - make-error@1.3.6: {} - - makeerror@1.0.12: - dependencies: - tmpl: 1.0.5 - mammoth@1.9.0: dependencies: '@xmldom/xmldom': 0.8.10 @@ -18741,6 +17273,8 @@ snapshots: mri@1.2.0: {} + mrmime@2.0.1: {} + ms@2.1.3: {} mute-stream@0.0.8: {} @@ -18840,8 +17374,6 @@ snapshots: formdata-polyfill: 4.0.10 optional: true - node-int64@0.4.0: {} - node-ipc@12.0.0: dependencies: event-pubsub: 5.0.3 @@ -19151,13 +17683,6 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - parse-ms@4.0.0: {} parse-semver@1.1.1: @@ -19240,10 +17765,6 @@ snapshots: pkce-challenge@5.0.0: {} - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 - pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -19390,12 +17911,6 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - pretty-ms@9.2.0: dependencies: parse-ms: 4.0.0 @@ -19407,11 +17922,6 @@ snapshots: promise-limit@2.7.0: optional: true - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -19450,10 +17960,6 @@ snapshots: dependencies: event-stream: 3.3.4 - psl@1.15.0: - dependencies: - punycode: 2.3.1 - pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -19489,16 +17995,12 @@ snapshots: - supports-color - utf-8-validate - pure-rand@6.1.0: {} - qs@6.14.0: dependencies: side-channel: 1.1.0 quansync@0.2.10: {} - querystringify@2.2.0: {} - queue-microtask@1.2.3: {} randombytes@2.1.0: @@ -19844,22 +18346,14 @@ snapshots: require-directory@2.1.1: {} - requires-port@1.0.0: {} - resize-observer-polyfill@1.5.1: {} - resolve-cwd@3.0.0: - dependencies: - resolve-from: 5.0.0 - resolve-from@4.0.0: {} resolve-from@5.0.0: {} resolve-pkg-maps@1.0.0: {} - resolve.exports@2.0.3: {} - resolve@1.22.10: dependencies: is-core-module: 2.16.1 @@ -19935,6 +18429,8 @@ snapshots: transitivePeerDependencies: - supports-color + rrweb-cssom@0.8.0: {} + rtl-css-js@1.16.1: dependencies: '@babel/runtime': 7.27.4 @@ -20179,7 +18675,11 @@ snapshots: is-arrayish: 0.3.2 optional: true - sisteransi@1.0.5: {} + sirv@3.0.1: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 slash@3.0.0: {} @@ -20219,11 +18719,6 @@ snapshots: source-map-js@1.2.1: {} - source-map-support@0.5.13: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -20260,10 +18755,6 @@ snapshots: dependencies: stackframe: 1.3.4 - stack-utils@2.0.6: - dependencies: - escape-string-regexp: 2.0.0 - stackback@0.0.2: {} stackframe@1.3.4: {} @@ -20302,11 +18793,6 @@ snapshots: string-argv@0.3.2: {} - string-length@4.0.2: - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - string-similarity@4.0.4: {} string-width@4.2.3: @@ -20392,8 +18878,6 @@ snapshots: strip-bom@3.0.0: {} - strip-bom@4.0.0: {} - strip-bom@5.0.0: {} strip-final-newline@2.0.0: {} @@ -20623,14 +19107,18 @@ snapshots: tinyspy@4.0.3: {} + tldts-core@6.1.86: {} + + tldts@6.1.86: + dependencies: + tldts-core: 6.1.86 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 tmp@0.2.3: {} - tmpl@1.0.5: {} - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -20639,12 +19127,11 @@ snapshots: toidentifier@1.0.1: {} - tough-cookie@4.1.4: + totalist@3.0.1: {} + + tough-cookie@5.1.2: dependencies: - psl: 1.15.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 + tldts: 6.1.86 tr46@0.0.3: {} @@ -20652,7 +19139,7 @@ snapshots: dependencies: punycode: 2.3.1 - tr46@3.0.0: + tr46@5.1.1: dependencies: punycode: 2.3.1 @@ -20682,27 +19169,6 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.3.3(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(esbuild@0.25.5)(jest@29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0))(typescript@5.8.3): - dependencies: - bs-logger: 0.2.6 - ejs: 3.1.10 - fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.17.57)(babel-plugin-macros@3.1.0) - jest-util: 29.7.0 - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.2 - type-fest: 4.41.0 - typescript: 5.8.3 - yargs-parser: 21.1.1 - optionalDependencies: - '@babel/core': 7.27.1 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.1) - esbuild: 0.25.5 - tslib@1.14.1: {} tslib@2.6.2: {} @@ -20786,14 +19252,8 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-detect@4.0.8: {} - - type-fest@0.21.3: {} - type-fest@2.19.0: {} - type-fest@4.41.0: {} - type-is@2.0.1: dependencies: content-type: 1.0.5 @@ -20968,8 +19428,6 @@ snapshots: universalify@0.1.2: {} - universalify@0.2.0: {} - unpipe@1.0.0: {} untildify@4.0.0: {} @@ -20999,11 +19457,6 @@ snapshots: url-join@4.0.1: {} - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - use-callback-ref@1.3.3(@types/react@18.3.23)(react@18.3.1): dependencies: react: 18.3.1 @@ -21220,7 +19673,7 @@ snapshots: tsx: 4.19.4 yaml: 2.8.0 - vitest@3.2.3(@types/debug@4.1.12)(@types/node@20.17.50)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): + vitest@3.2.3(@types/debug@4.1.12)(@types/node@20.17.50)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.3 @@ -21248,7 +19701,8 @@ snapshots: optionalDependencies: '@types/debug': 4.1.12 '@types/node': 20.17.50 - jsdom: 20.0.3 + '@vitest/ui': 3.2.3(vitest@3.2.3) + jsdom: 26.1.0 transitivePeerDependencies: - jiti - less @@ -21263,7 +19717,7 @@ snapshots: - tsx - yaml - vitest@3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): + vitest@3.2.3(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.3 @@ -21291,7 +19745,8 @@ snapshots: optionalDependencies: '@types/debug': 4.1.12 '@types/node': 20.17.57 - jsdom: 20.0.3 + '@vitest/ui': 3.2.3(vitest@3.2.3) + jsdom: 26.1.0 transitivePeerDependencies: - jiti - less @@ -21306,7 +19761,7 @@ snapshots: - tsx - yaml - vitest@3.2.3(@types/debug@4.1.12)(@types/node@22.15.29)(jiti@2.4.2)(jsdom@20.0.3)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): + vitest@3.2.3(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.3 @@ -21334,7 +19789,8 @@ snapshots: optionalDependencies: '@types/debug': 4.1.12 '@types/node': 22.15.29 - jsdom: 20.0.3 + '@vitest/ui': 3.2.3(vitest@3.2.3) + jsdom: 26.1.0 transitivePeerDependencies: - jiti - less @@ -21375,16 +19831,12 @@ snapshots: '@types/react': 18.3.23 react: 18.3.1 - w3c-xmlserializer@4.0.0: + w3c-xmlserializer@5.0.0: dependencies: - xml-name-validator: 4.0.0 + xml-name-validator: 5.0.0 walk-up-path@4.0.0: {} - walker@1.0.8: - dependencies: - makeerror: 1.0.12 - web-namespaces@1.1.4: {} web-streams-polyfill@3.3.3: @@ -21402,21 +19854,15 @@ snapshots: webidl-conversions@7.0.0: {} - whatwg-encoding@2.0.0: - dependencies: - iconv-lite: 0.6.3 - whatwg-encoding@3.1.1: dependencies: iconv-lite: 0.6.3 - whatwg-mimetype@3.0.0: {} - whatwg-mimetype@4.0.0: {} - whatwg-url@11.0.0: + whatwg-url@14.2.0: dependencies: - tr46: 3.0.0 + tr46: 5.1.1 webidl-conversions: 7.0.0 whatwg-url@5.0.0: @@ -21524,14 +19970,9 @@ snapshots: wrappy@1.0.2: {} - write-file-atomic@4.0.2: - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - ws@8.18.2: {} - xml-name-validator@4.0.0: {} + xml-name-validator@5.0.0: {} xml2js@0.5.0: dependencies: @@ -21554,9 +19995,6 @@ snapshots: yallist@5.0.0: {} - yaml@1.10.2: - optional: true - yaml@2.8.0: {} yargs-parser@20.2.9: {} diff --git a/webview-ui/jest.config.cjs b/webview-ui/jest.config.cjs deleted file mode 100644 index 367bbff3c7..0000000000 --- a/webview-ui/jest.config.cjs +++ /dev/null @@ -1,34 +0,0 @@ -/** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { - preset: "ts-jest", - testEnvironment: "jsdom", - injectGlobals: true, - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], - transform: { "^.+\\.(ts|tsx)$": ["ts-jest", { tsconfig: { jsx: "react-jsx", module: "ESNext" } }] }, - testMatch: ["/src/**/__tests__/**/*.{js,jsx,ts,tsx}", "/src/**/*.{spec,test}.{js,jsx,ts,tsx}"], - setupFilesAfterEnv: ["/src/setupTests.tsx"], - moduleNameMapper: { - "\\.(css|less|scss|sass)$": "identity-obj-proxy", - "^vscrui$": "/src/__mocks__/vscrui.ts", - "^@vscode/webview-ui-toolkit/react$": "/src/__mocks__/@vscode/webview-ui-toolkit/react.ts", - "^@/(.*)$": "/src/$1", - "^@roo/(.*)$": "/../src/shared/$1", - "^@src/(.*)$": "/src/$1", - "^src/i18n/setup$": "/src/__mocks__/i18n/setup.ts", - "^\\.\\./setup$": "/src/__mocks__/i18n/setup.ts", - "^\\./setup$": "/src/__mocks__/i18n/setup.ts", - "^src/i18n/TranslationContext$": "/src/__mocks__/i18n/TranslationContext.tsx", - "^\\.\\./TranslationContext$": "/src/__mocks__/i18n/TranslationContext.tsx", - "^\\./TranslationContext$": "/src/__mocks__/i18n/TranslationContext.tsx", - "^@src/utils/highlighter$": "/src/__mocks__/utils/highlighter.ts", - "^shiki$": "/src/__mocks__/shiki.ts", - "^react-markdown$": "/src/__mocks__/react-markdown.tsx", - "^remark-gfm$": "/src/__mocks__/remark-gfm.ts", - }, - reporters: [["jest-simple-dot-reporter", {}]], - transformIgnorePatterns: [ - "/node_modules/(?!(shiki|rehype-highlight|react-remark|unist-util-visit|unist-util-find-after|vfile|unified|bail|is-plain-obj|trough|vfile-message|unist-util-stringify-position|mdast-util-from-markdown|mdast-util-to-string|micromark|decode-named-character-reference|character-entities|markdown-table|zwitch|longest-streak|escape-string-regexp|unist-util-is|hast-util-to-text|@vscode/webview-ui-toolkit|@microsoft/fast-react-wrapper|@microsoft/fast-element|@microsoft/fast-foundation|@microsoft/fast-web-utilities|exenv-es6|vscrui)/)", - ], - roots: [""], - moduleDirectories: ["node_modules", "src"], -} diff --git a/webview-ui/package.json b/webview-ui/package.json index ee7b2e01c4..e0bd57ecc0 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -6,7 +6,7 @@ "lint": "eslint src --ext=ts,tsx --max-warnings=0", "check-types": "tsc", "pretest": "turbo run bundle --cwd ..", - "test": "jest -w=40%", + "test": "vitest run", "format": "prettier --write src", "dev": "vite", "build": "tsc -b && vite build", @@ -75,25 +75,20 @@ "zod": "^3.25.61" }, "devDependencies": { - "@jest/globals": "^29.7.0", "@roo-code/config-eslint": "workspace:^", "@roo-code/config-typescript": "workspace:^", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", "@testing-library/user-event": "^14.6.1", - "@types/jest": "^29.0.0", "@types/node": "20.x", "@types/react": "^18.3.23", "@types/react-dom": "^18.3.5", "@types/shell-quote": "^1.7.5", - "@types/testing-library__jest-dom": "^5.14.5", "@types/vscode-webview": "^1.57.5", "@vitejs/plugin-react": "^4.3.4", + "@vitest/ui": "^3.2.3", "identity-obj-proxy": "^3.0.0", - "jest": "^29.7.0", - "jest-environment-jsdom": "^29.7.0", - "jest-simple-dot-reporter": "^1.0.5", - "ts-jest": "^29.2.5", + "jsdom": "^26.0.0", "typescript": "5.8.3", "vite": "6.3.5", "vitest": "^3.2.3" diff --git a/webview-ui/src/__mocks__/@vscode/webview-ui-toolkit/react.ts b/webview-ui/src/__mocks__/@vscode/webview-ui-toolkit/react.ts deleted file mode 100644 index 2062efb141..0000000000 --- a/webview-ui/src/__mocks__/@vscode/webview-ui-toolkit/react.ts +++ /dev/null @@ -1,105 +0,0 @@ -import React from "react" - -interface VSCodeProps { - children?: React.ReactNode - onClick?: () => void - onChange?: (e: any) => void - onInput?: (e: any) => void - appearance?: string - checked?: boolean - value?: string | number - placeholder?: string - href?: string - "data-testid"?: string - style?: React.CSSProperties - slot?: string - role?: string - disabled?: boolean - className?: string - title?: string -} - -export const VSCodeButton: React.FC = ({ children, onClick, appearance, className, ...props }) => { - // For icon buttons, render children directly without any wrapping - if (appearance === "icon") { - return React.createElement( - "button", - { - onClick, - className: `${className || ""}`, - "data-appearance": appearance, - ...props, - }, - children, - ) - } - - // For regular buttons - return React.createElement( - "button", - { - onClick, - className: className, - ...props, - }, - children, - ) -} - -export const VSCodeCheckbox: React.FC = ({ children, onChange, checked, ...props }) => - React.createElement("label", {}, [ - React.createElement("input", { - key: "input", - type: "checkbox", - checked, - onChange: (e: any) => onChange?.({ target: { checked: e.target.checked } }), - "aria-label": typeof children === "string" ? children : undefined, - ...props, - }), - children && React.createElement("span", { key: "label" }, children), - ]) - -export const VSCodeTextField: React.FC = ({ children, value, onInput, placeholder, ...props }) => - React.createElement("div", { style: { position: "relative", display: "inline-block", width: "100%" } }, [ - React.createElement("input", { - key: "input", - type: "text", - value, - onChange: (e: any) => onInput?.({ target: { value: e.target.value } }), - placeholder, - ...props, - }), - children, - ]) - -export const VSCodeTextArea: React.FC = ({ value, onChange, ...props }) => - React.createElement("textarea", { - value, - onChange: (e: any) => onChange?.({ target: { value: e.target.value } }), - ...props, - }) - -export const VSCodeLink: React.FC = ({ children, href, ...props }) => - React.createElement("a", { href: href || "#", ...props }, children) - -export const VSCodeDropdown: React.FC = ({ children, value, onChange, ...props }) => - React.createElement("select", { value, onChange, ...props }, children) - -export const VSCodeOption: React.FC = ({ children, value, ...props }) => - React.createElement("option", { value, ...props }, children) - -export const VSCodeRadio: React.FC = ({ children, value, checked, onChange, ...props }) => - React.createElement("label", { style: { display: "inline-flex", alignItems: "center" } }, [ - React.createElement("input", { - key: "input", - type: "radio", - value, - checked, - onChange, - ...props, - }), - children && React.createElement("span", { key: "label", style: { marginLeft: "4px" } }, children), - ]) - -export const VSCodeRadioGroup: React.FC = ({ children, onChange, ...props }) => - React.createElement("div", { role: "radiogroup", onChange, ...props }, children) diff --git a/webview-ui/src/__mocks__/components/chat/TaskHeader.tsx b/webview-ui/src/__mocks__/components/chat/TaskHeader.tsx deleted file mode 100644 index 4407a1c6ce..0000000000 --- a/webview-ui/src/__mocks__/components/chat/TaskHeader.tsx +++ /dev/null @@ -1,3 +0,0 @@ -const TaskHeader = () =>
Mocked TaskHeader
- -export default TaskHeader diff --git a/webview-ui/src/__mocks__/i18n/TranslationContext.tsx b/webview-ui/src/__mocks__/i18n/TranslationContext.tsx deleted file mode 100644 index 1b838923bc..0000000000 --- a/webview-ui/src/__mocks__/i18n/TranslationContext.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { ReactNode } from "react" -import i18next from "./setup" - -// Create a mock context -export const TranslationContext = React.createContext<{ - t: (key: string, options?: Record) => string - i18n: typeof i18next -}>({ - t: (key: string, options?: Record) => { - // Handle specific test cases - if (key === "settings.autoApprove.title") { - return "Auto-Approve" - } - if (key === "notifications.error" && options?.message) { - return `Operation failed: ${options.message}` - } - return key // Default fallback - }, - i18n: i18next, -}) - -// Mock translation provider -export const TranslationProvider: React.FC<{ children: ReactNode }> = ({ children }) => { - return ( - ) => { - // Handle specific test cases - if (key === "settings.autoApprove.title") { - return "Auto-Approve" - } - if (key === "notifications.error" && options?.message) { - return `Operation failed: ${options.message}` - } - return key // Default fallback - }, - i18n: i18next, - }}> - {children} - - ) -} - -// Custom hook for easy translations -export const useAppTranslation = () => React.useContext(TranslationContext) - -export default TranslationProvider diff --git a/webview-ui/src/__mocks__/i18n/setup.ts b/webview-ui/src/__mocks__/i18n/setup.ts deleted file mode 100644 index 6ba0cf7e38..0000000000 --- a/webview-ui/src/__mocks__/i18n/setup.ts +++ /dev/null @@ -1,62 +0,0 @@ -import i18next from "i18next" -import { initReactI18next } from "react-i18next" - -// Mock translations for testing -const translations: Record> = { - en: { - chat: { - greeting: "What can Roo do for you?", - }, - settings: { - autoApprove: { - title: "Auto-Approve", - }, - }, - common: { - notifications: { - error: "Operation failed: {{message}}", - }, - }, - }, - es: { - chat: { - greeting: "¿Qué puede hacer Roo por ti?", - }, - }, -} - -// Initialize i18next for React -i18next.use(initReactI18next).init({ - lng: "en", - fallbackLng: "en", - debug: false, - interpolation: { - escapeValue: false, - }, - resources: { - en: { - chat: translations.en.chat, - settings: translations.en.settings, - common: translations.en.common, - }, - es: { - chat: translations.es.chat, - }, - }, -}) - -export function loadTranslations() { - // Translations are already loaded in the mock -} - -export function addTranslation(language: string, namespace: string, resources: any) { - if (!translations[language]) { - translations[language] = {} - } - translations[language][namespace] = resources - - // Also add to i18next - i18next.addResourceBundle(language, namespace, resources, true, true) -} - -export default i18next diff --git a/webview-ui/src/__mocks__/lucide-react.ts b/webview-ui/src/__mocks__/lucide-react.ts deleted file mode 100644 index 56615f86eb..0000000000 --- a/webview-ui/src/__mocks__/lucide-react.ts +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react" - -export const Check = () => React.createElement("div") -export const ChevronsUpDown = () => React.createElement("div") -export const Loader = () => React.createElement("div") -export const X = () => React.createElement("div") -export const Edit = () => React.createElement("div") -export const Database = (props: any) => React.createElement("span", { "data-testid": "database-icon", ...props }) -export const MoreVertical = () => React.createElement("div", {}, "VerticalMenu") -export const ExternalLink = () => React.createElement("div") -export const Download = () => React.createElement("div") diff --git a/webview-ui/src/__mocks__/posthog-js.ts b/webview-ui/src/__mocks__/posthog-js.ts deleted file mode 100644 index 3e55a9eed0..0000000000 --- a/webview-ui/src/__mocks__/posthog-js.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Mock implementation of posthog-js -const posthogMock = { - init: jest.fn(), - capture: jest.fn(), - opt_in_capturing: jest.fn(), - opt_out_capturing: jest.fn(), - reset: jest.fn(), - identify: jest.fn(), -} - -export default posthogMock diff --git a/webview-ui/src/__mocks__/pretty-bytes.js b/webview-ui/src/__mocks__/pretty-bytes.js deleted file mode 100644 index 61660edd9d..0000000000 --- a/webview-ui/src/__mocks__/pretty-bytes.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = function prettyBytes(bytes) { - if (typeof bytes !== "number") { - throw new TypeError("Expected a number") - } - - // Simple mock implementation that returns formatted strings. - if (bytes === 0) return "0 B" - if (bytes < 1024) return `${bytes} B` - if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB` - if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB` - return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB` -} diff --git a/webview-ui/src/__mocks__/react-markdown.tsx b/webview-ui/src/__mocks__/react-markdown.tsx deleted file mode 100644 index aed17dfc2f..0000000000 --- a/webview-ui/src/__mocks__/react-markdown.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react" - -interface ReactMarkdownProps { - children?: React.ReactNode - className?: string - remarkPlugins?: any[] - components?: any -} - -const ReactMarkdown: React.FC = ({ children, className }) => { - return ( -
- {children} -
- ) -} - -export default ReactMarkdown -export type { ReactMarkdownProps as Options } diff --git a/webview-ui/src/__mocks__/remark-gfm.ts b/webview-ui/src/__mocks__/remark-gfm.ts deleted file mode 100644 index 3789ec1c55..0000000000 --- a/webview-ui/src/__mocks__/remark-gfm.ts +++ /dev/null @@ -1,3 +0,0 @@ -const remarkGfm = () => {} - -export default remarkGfm diff --git a/webview-ui/src/__mocks__/shiki.ts b/webview-ui/src/__mocks__/shiki.ts deleted file mode 100644 index ade97997ef..0000000000 --- a/webview-ui/src/__mocks__/shiki.ts +++ /dev/null @@ -1,32 +0,0 @@ -export const bundledLanguages = { - javascript: jest.fn(), - typescript: jest.fn(), - python: jest.fn(), - html: jest.fn(), - css: jest.fn(), - json: jest.fn(), - // Add more as needed -} - -export const bundledThemes = {} - -export type BundledTheme = string -export type BundledLanguage = string -export type Highlighter = any -export type ShikiTransformer = any - -export const createHighlighter = jest.fn(() => - Promise.resolve({ - codeToHtml: jest.fn((code: string) => `
${code}
`), - getLoadedThemes: jest.fn(() => []), - loadTheme: jest.fn(), - }), -) - -export const codeToHast = jest.fn() -export const codeToHtml = jest.fn((code: string) => `
${code}
`) -export const codeToTokens = jest.fn() -export const codeToTokensBase = jest.fn() -export const codeToTokensWithThemes = jest.fn() -export const getLastGrammarState = jest.fn() -export const getSingletonHighlighter = jest.fn() diff --git a/webview-ui/src/__mocks__/utils/highlighter.ts b/webview-ui/src/__mocks__/utils/highlighter.ts deleted file mode 100644 index 1a51ee274d..0000000000 --- a/webview-ui/src/__mocks__/utils/highlighter.ts +++ /dev/null @@ -1,24 +0,0 @@ -export type ExtendedLanguage = string - -export const highlighter = { - codeToHtml: jest.fn((code: string) => `
${code}
`), - getLoadedThemes: jest.fn(() => []), - loadTheme: jest.fn(), -} - -export const getHighlighter = jest.fn(() => Promise.resolve(highlighter)) - -export const isLanguageLoaded = jest.fn(() => true) - -export const normalizeLanguage = jest.fn((lang: string): ExtendedLanguage => lang) - -// Mock bundledLanguages -export const bundledLanguages = { - javascript: jest.fn(), - typescript: jest.fn(), - python: jest.fn(), - html: jest.fn(), - css: jest.fn(), - json: jest.fn(), - // Add more as needed -} diff --git a/webview-ui/src/__mocks__/vscrui.ts b/webview-ui/src/__mocks__/vscrui.ts deleted file mode 100644 index 08f6d6982a..0000000000 --- a/webview-ui/src/__mocks__/vscrui.ts +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react" - -export const Checkbox = ({ children, onChange }: any) => - React.createElement("div", { "data-testid": "mock-checkbox", onClick: onChange }, children) - -export const Dropdown = ({ children, onChange }: any) => - React.createElement("div", { "data-testid": "mock-dropdown", onClick: onChange }, children) - -export const Pane = ({ children }: any) => React.createElement("div", { "data-testid": "mock-pane" }, children) - -export const Button = ({ children, ...props }: any) => - React.createElement("div", { "data-testid": "mock-button", ...props }, children) - -export type DropdownOption = { - label: string - value: string -} diff --git a/webview-ui/src/__tests__/App.test.tsx b/webview-ui/src/__tests__/App.spec.tsx similarity index 90% rename from webview-ui/src/__tests__/App.test.tsx rename to webview-ui/src/__tests__/App.spec.tsx index 6d9859a4d8..d4e8b26818 100644 --- a/webview-ui/src/__tests__/App.test.tsx +++ b/webview-ui/src/__tests__/App.spec.tsx @@ -1,18 +1,17 @@ -// npx jest src/__tests__/App.test.tsx +// npx vitest run src/__tests__/App.spec.tsx import React from "react" import { render, screen, act, cleanup } from "@testing-library/react" -import "@testing-library/jest-dom" import AppWithProviders from "../App" -jest.mock("@src/utils/vscode", () => ({ +vi.mock("@src/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) -jest.mock("@src/components/chat/ChatView", () => ({ +vi.mock("@src/components/chat/ChatView", () => ({ __esModule: true, default: function ChatView({ isHidden }: { isHidden: boolean }) { return ( @@ -23,7 +22,7 @@ jest.mock("@src/components/chat/ChatView", () => ({ }, })) -jest.mock("@src/components/settings/SettingsView", () => ({ +vi.mock("@src/components/settings/SettingsView", () => ({ __esModule: true, default: function SettingsView({ onDone }: { onDone: () => void }) { return ( @@ -34,7 +33,7 @@ jest.mock("@src/components/settings/SettingsView", () => ({ }, })) -jest.mock("@src/components/history/HistoryView", () => ({ +vi.mock("@src/components/history/HistoryView", () => ({ __esModule: true, default: function HistoryView({ onDone }: { onDone: () => void }) { return ( @@ -45,7 +44,7 @@ jest.mock("@src/components/history/HistoryView", () => ({ }, })) -jest.mock("@src/components/mcp/McpView", () => ({ +vi.mock("@src/components/mcp/McpView", () => ({ __esModule: true, default: function McpView({ onDone }: { onDone: () => void }) { return ( @@ -56,7 +55,7 @@ jest.mock("@src/components/mcp/McpView", () => ({ }, })) -jest.mock("@src/components/modes/ModesView", () => ({ +vi.mock("@src/components/modes/ModesView", () => ({ __esModule: true, default: function ModesView({ onDone }: { onDone: () => void }) { return ( @@ -67,7 +66,7 @@ jest.mock("@src/components/modes/ModesView", () => ({ }, })) -jest.mock("@src/components/marketplace/MarketplaceView", () => ({ +vi.mock("@src/components/marketplace/MarketplaceView", () => ({ MarketplaceView: function MarketplaceView({ onDone }: { onDone: () => void }) { return (
@@ -77,7 +76,7 @@ jest.mock("@src/components/marketplace/MarketplaceView", () => ({ }, })) -jest.mock("@src/components/account/AccountView", () => ({ +vi.mock("@src/components/account/AccountView", () => ({ AccountView: function AccountView({ onDone }: { onDone: () => void }) { return (
@@ -87,16 +86,16 @@ jest.mock("@src/components/account/AccountView", () => ({ }, })) -const mockUseExtensionState = jest.fn() +const mockUseExtensionState = vi.fn() -jest.mock("@src/context/ExtensionStateContext", () => ({ +vi.mock("@src/context/ExtensionStateContext", () => ({ useExtensionState: () => mockUseExtensionState(), ExtensionStateContextProvider: ({ children }: { children: React.ReactNode }) => <>{children}, })) describe("App", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() window.removeEventListener("message", () => {}) // Set up default mock return value diff --git a/webview-ui/src/__tests__/ContextWindowProgress.test.tsx b/webview-ui/src/__tests__/ContextWindowProgress.spec.tsx similarity index 84% rename from webview-ui/src/__tests__/ContextWindowProgress.test.tsx rename to webview-ui/src/__tests__/ContextWindowProgress.spec.tsx index a4db28cf6a..5a5ff463ef 100644 --- a/webview-ui/src/__tests__/ContextWindowProgress.test.tsx +++ b/webview-ui/src/__tests__/ContextWindowProgress.spec.tsx @@ -1,43 +1,41 @@ -// npx jest src/__tests__/ContextWindowProgress.test.tsx +// npm run test ContextWindowProgress.spec.tsx import { render, screen } from "@testing-library/react" -import "@testing-library/jest-dom" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import TaskHeader from "@src/components/chat/TaskHeader" // Mock formatLargeNumber function -jest.mock("@/utils/format", () => ({ - formatLargeNumber: jest.fn((num) => num.toString()), +vi.mock("@/utils/format", () => ({ + formatLargeNumber: vi.fn((num) => num.toString()), })) // Mock VSCodeBadge component for all tests -jest.mock("@vscode/webview-ui-toolkit/react", () => ({ +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ VSCodeBadge: ({ children }: { children: React.ReactNode }) =>
{children}
, })) // Mock ExtensionStateContext since we use useExtensionState -jest.mock("@src/context/ExtensionStateContext", () => ({ - useExtensionState: jest.fn(() => ({ +vi.mock("@src/context/ExtensionStateContext", () => ({ + useExtensionState: vi.fn(() => ({ apiConfiguration: { apiProvider: "openai" }, currentTaskItem: { id: "test-id", number: 1, size: 1024 }, })), })) // Mock highlighting function to avoid JSX parsing issues in tests -jest.mock("@src/components/chat/TaskHeader", () => { - const originalModule = jest.requireActual("@src/components/chat/TaskHeader") +vi.mock("@src/components/chat/TaskHeader", async () => { + const originalModule = await vi.importActual("@src/components/chat/TaskHeader") return { - __esModule: true, ...originalModule, - highlightMentions: jest.fn((text) => text), + highlightMentions: vi.fn((text) => text), } }) // Mock useSelectedModel hook -jest.mock("@src/components/ui/hooks/useSelectedModel", () => ({ - useSelectedModel: jest.fn(() => ({ +vi.mock("@src/components/ui/hooks/useSelectedModel", () => ({ + useSelectedModel: vi.fn(() => ({ id: "test", info: { contextWindow: 4000 }, })), @@ -56,9 +54,9 @@ describe("ContextWindowProgress", () => { doesModelSupportPromptCache: true, totalCost: 0.001, contextTokens: 1000, - onClose: jest.fn(), + onClose: vi.fn(), buttonsDisabled: false, - handleCondenseContext: jest.fn((_taskId: string) => {}), + handleCondenseContext: vi.fn((_taskId: string) => {}), } return render( @@ -68,7 +66,7 @@ describe("ContextWindowProgress", () => { ) } - beforeEach(() => jest.clearAllMocks()) + beforeEach(() => vi.clearAllMocks()) it("renders correctly with valid inputs", () => { renderComponent({ contextTokens: 1000, contextWindow: 4000 }) diff --git a/webview-ui/src/__tests__/ContextWindowProgressLogic.test.ts b/webview-ui/src/__tests__/ContextWindowProgressLogic.spec.ts similarity index 98% rename from webview-ui/src/__tests__/ContextWindowProgressLogic.test.ts rename to webview-ui/src/__tests__/ContextWindowProgressLogic.spec.ts index c905d79aa4..39c6cd40d5 100644 --- a/webview-ui/src/__tests__/ContextWindowProgressLogic.test.ts +++ b/webview-ui/src/__tests__/ContextWindowProgressLogic.spec.ts @@ -1,6 +1,5 @@ // This test directly tests the logic of the ContextWindowProgress component calculations // without needing to render the full component -import { describe, test, expect } from "@jest/globals" import { calculateTokenDistribution } from "@src/utils/model-utils" export {} // This makes the file a proper TypeScript module diff --git a/webview-ui/src/__tests__/TelemetryClient.test.ts b/webview-ui/src/__tests__/TelemetryClient.spec.ts similarity index 91% rename from webview-ui/src/__tests__/TelemetryClient.test.ts rename to webview-ui/src/__tests__/TelemetryClient.spec.ts index e417dac466..02e6ffa974 100644 --- a/webview-ui/src/__tests__/TelemetryClient.test.ts +++ b/webview-ui/src/__tests__/TelemetryClient.spec.ts @@ -1,13 +1,19 @@ -/** - * Tests for TelemetryClient - */ -import { telemetryClient } from "@src/utils/TelemetryClient" import posthog from "posthog-js" +import { telemetryClient } from "@src/utils/TelemetryClient" + +vi.mock("posthog-js", () => ({ + default: { + init: vi.fn(), + reset: vi.fn(), + identify: vi.fn(), + capture: vi.fn(), + }, +})) + describe("TelemetryClient", () => { - // Reset all mocks before each test beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) /** @@ -87,7 +93,7 @@ describe("TelemetryClient", () => { it("captures events when telemetry is enabled", () => { // Arrange - set telemetry to enabled telemetryClient.updateTelemetryState("enabled", "test-key", "test-user") - jest.clearAllMocks() // Clear previous calls + vi.clearAllMocks() // Clear previous calls // Act telemetryClient.capture("test_event", { property: "value" }) @@ -99,7 +105,7 @@ describe("TelemetryClient", () => { it("doesn't capture events when telemetry is disabled", () => { // Arrange - set telemetry to disabled telemetryClient.updateTelemetryState("disabled") - jest.clearAllMocks() // Clear previous calls + vi.clearAllMocks() // Clear previous calls // Act telemetryClient.capture("test_event") @@ -115,7 +121,7 @@ describe("TelemetryClient", () => { it("doesn't capture events when telemetry is unset", () => { // Arrange - set telemetry to unset telemetryClient.updateTelemetryState("unset") - jest.clearAllMocks() // Clear previous calls + vi.clearAllMocks() // Clear previous calls // Act telemetryClient.capture("test_event", { property: "test value" }) diff --git a/webview-ui/src/components/chat/__tests__/Announcement.test.tsx b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx similarity index 89% rename from webview-ui/src/components/chat/__tests__/Announcement.test.tsx rename to webview-ui/src/components/chat/__tests__/Announcement.spec.tsx index d2f109f365..7048022440 100644 --- a/webview-ui/src/components/chat/__tests__/Announcement.test.tsx +++ b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx @@ -1,12 +1,11 @@ import { render, screen } from "@testing-library/react" -import { jest } from "@jest/globals" // Or 'jest' if using Jest import { Package } from "@roo/package" import Announcement from "../Announcement" // Mock the components from @src/components/ui -jest.mock("@src/components/ui", () => ({ +vi.mock("@src/components/ui", () => ({ Dialog: ({ children }: { children: React.ReactNode }) =>
{children}
, DialogContent: ({ children }: { children: React.ReactNode }) =>
{children}
, DialogDescription: ({ children }: { children: React.ReactNode }) =>
{children}
, @@ -15,7 +14,7 @@ jest.mock("@src/components/ui", () => ({ })) // Mock the useAppTranslation hook -jest.mock("@src/i18n/TranslationContext", () => ({ +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string, options?: { version: string }) => { if (key === "chat:announcement.title") { @@ -31,7 +30,7 @@ jest.mock("@src/i18n/TranslationContext", () => ({ })) describe("Announcement", () => { - const mockHideAnnouncement = jest.fn() + const mockHideAnnouncement = vi.fn() const expectedVersion = Package.version it("renders the announcement with the version number from package.json", () => { diff --git a/webview-ui/src/components/chat/__tests__/BatchFilePermission.test.tsx b/webview-ui/src/components/chat/__tests__/BatchFilePermission.spec.tsx similarity index 96% rename from webview-ui/src/components/chat/__tests__/BatchFilePermission.test.tsx rename to webview-ui/src/components/chat/__tests__/BatchFilePermission.spec.tsx index 5682af038d..7aef88d0de 100644 --- a/webview-ui/src/components/chat/__tests__/BatchFilePermission.test.tsx +++ b/webview-ui/src/components/chat/__tests__/BatchFilePermission.spec.tsx @@ -1,19 +1,19 @@ -import React from "react" import { render, screen, fireEvent } from "@testing-library/react" -import { BatchFilePermission } from "../BatchFilePermission" + import { TranslationProvider } from "@/i18n/__mocks__/TranslationContext" -const mockVscodePostMessage = jest.fn() +import { BatchFilePermission } from "../BatchFilePermission" + +const mockVscodePostMessage = vi.fn() -// Mock vscode API -jest.mock("@src/utils/vscode", () => ({ +vi.mock("@src/utils/vscode", () => ({ vscode: { postMessage: (...args: any[]) => mockVscodePostMessage(...args), }, })) describe("BatchFilePermission", () => { - const mockOnPermissionResponse = jest.fn() + const mockOnPermissionResponse = vi.fn() const mockFiles = [ { @@ -40,7 +40,7 @@ describe("BatchFilePermission", () => { ] beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("renders file list correctly", () => { diff --git a/webview-ui/src/components/chat/__tests__/ChatTextArea.test.tsx b/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx similarity index 88% rename from webview-ui/src/components/chat/__tests__/ChatTextArea.test.tsx rename to webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx index 6d07849938..e31803b99e 100644 --- a/webview-ui/src/components/chat/__tests__/ChatTextArea.test.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx @@ -1,20 +1,23 @@ import { render, fireEvent, screen } from "@testing-library/react" -import ChatTextArea from "../ChatTextArea" + +import { defaultModeSlug } from "@roo/modes" + import { useExtensionState } from "@src/context/ExtensionStateContext" import { vscode } from "@src/utils/vscode" -import { defaultModeSlug } from "@roo/modes" import * as pathMentions from "@src/utils/path-mentions" -// Mock modules -jest.mock("@src/utils/vscode", () => ({ +import ChatTextArea from "../ChatTextArea" + +vi.mock("@src/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) -jest.mock("@src/components/common/CodeBlock") -jest.mock("@src/components/common/MarkdownBlock") -jest.mock("@src/utils/path-mentions", () => ({ - convertToMentionPath: jest.fn((path, cwd) => { + +vi.mock("@src/components/common/CodeBlock") +vi.mock("@src/components/common/MarkdownBlock") +vi.mock("@src/utils/path-mentions", () => ({ + convertToMentionPath: vi.fn((path, cwd) => { // Simple mock implementation that mimics the real function's behavior if (cwd && path.toLowerCase().startsWith(cwd.toLowerCase())) { const relativePath = path.substring(cwd.length) @@ -25,11 +28,11 @@ jest.mock("@src/utils/path-mentions", () => ({ })) // Get the mocked postMessage function -const mockPostMessage = vscode.postMessage as jest.Mock -const mockConvertToMentionPath = pathMentions.convertToMentionPath as jest.Mock +const mockPostMessage = vscode.postMessage as ReturnType +const mockConvertToMentionPath = pathMentions.convertToMentionPath as ReturnType // Mock ExtensionStateContext -jest.mock("@src/context/ExtensionStateContext") +vi.mock("@src/context/ExtensionStateContext") // Custom query function to get the enhance prompt button const getEnhancePromptButton = () => { @@ -44,25 +47,25 @@ const getEnhancePromptButton = () => { describe("ChatTextArea", () => { const defaultProps = { inputValue: "", - setInputValue: jest.fn(), - onSend: jest.fn(), + setInputValue: vi.fn(), + onSend: vi.fn(), sendingDisabled: false, selectApiConfigDisabled: false, - onSelectImages: jest.fn(), + onSelectImages: vi.fn(), shouldDisableImages: false, placeholderText: "Type a message...", selectedImages: [], - setSelectedImages: jest.fn(), - onHeightChange: jest.fn(), + setSelectedImages: vi.fn(), + onHeightChange: vi.fn(), mode: defaultModeSlug, - setMode: jest.fn(), + setMode: vi.fn(), modeShortcutText: "(⌘. for next mode)", } beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() // Default mock implementation for useExtensionState - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -75,7 +78,7 @@ describe("ChatTextArea", () => { describe("enhance prompt button", () => { it("should be disabled when sendingDisabled is true", () => { - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], taskHistory: [], @@ -94,7 +97,7 @@ describe("ChatTextArea", () => { apiKey: "test-key", } - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration, @@ -114,7 +117,7 @@ describe("ChatTextArea", () => { }) it("should not send message when input is empty", () => { - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -136,7 +139,7 @@ describe("ChatTextArea", () => { }) it("should show loading state while enhancing", () => { - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -161,7 +164,7 @@ describe("ChatTextArea", () => { const { rerender } = render() // Update apiConfiguration - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -181,7 +184,7 @@ describe("ChatTextArea", () => { describe("enhanced prompt response", () => { it("should update input value when receiving enhanced prompt", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() render() @@ -203,8 +206,8 @@ describe("ChatTextArea", () => { const mockCwd = "/Users/test/project" beforeEach(() => { - jest.clearAllMocks() - ;(useExtensionState as jest.Mock).mockReturnValue({ + vi.clearAllMocks() + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], cwd: mockCwd, @@ -213,7 +216,7 @@ describe("ChatTextArea", () => { }) it("should process multiple file paths separated by newlines", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , @@ -221,14 +224,14 @@ describe("ChatTextArea", () => { // Create a mock dataTransfer object with text data containing multiple file paths const dataTransfer = { - getData: jest.fn().mockReturnValue("/Users/test/project/file1.js\n/Users/test/project/file2.js"), + getData: vi.fn().mockReturnValue("/Users/test/project/file1.js\n/Users/test/project/file2.js"), files: [], } // Simulate drop event fireEvent.drop(container.querySelector(".chat-text-area")!, { dataTransfer, - preventDefault: jest.fn(), + preventDefault: vi.fn(), }) // Verify convertToMentionPath was called for each file path @@ -242,7 +245,7 @@ describe("ChatTextArea", () => { }) it("should filter out empty lines in the dragged text", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , @@ -250,14 +253,14 @@ describe("ChatTextArea", () => { // Create a mock dataTransfer object with text data containing empty lines const dataTransfer = { - getData: jest.fn().mockReturnValue("/Users/test/project/file1.js\n\n/Users/test/project/file2.js\n\n"), + getData: vi.fn().mockReturnValue("/Users/test/project/file1.js\n\n/Users/test/project/file2.js\n\n"), files: [], } // Simulate drop event fireEvent.drop(container.querySelector(".chat-text-area")!, { dataTransfer, - preventDefault: jest.fn(), + preventDefault: vi.fn(), }) // Verify convertToMentionPath was called only for non-empty lines @@ -268,7 +271,7 @@ describe("ChatTextArea", () => { }) it("should correctly update cursor position after adding multiple mentions", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const initialCursorPosition = 5 const { container } = render( @@ -284,14 +287,14 @@ describe("ChatTextArea", () => { // Create a mock dataTransfer object with text data const dataTransfer = { - getData: jest.fn().mockReturnValue("/Users/test/project/file1.js\n/Users/test/project/file2.js"), + getData: vi.fn().mockReturnValue("/Users/test/project/file1.js\n/Users/test/project/file2.js"), files: [], } // Simulate drop event fireEvent.drop(container.querySelector(".chat-text-area")!, { dataTransfer, - preventDefault: jest.fn(), + preventDefault: vi.fn(), }) // The cursor position should be updated based on the implementation in the component @@ -299,7 +302,7 @@ describe("ChatTextArea", () => { }) it("should handle very long file paths correctly", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render() @@ -309,14 +312,14 @@ describe("ChatTextArea", () => { // Create a mock dataTransfer object with the long path const dataTransfer = { - getData: jest.fn().mockReturnValue(longPath), + getData: vi.fn().mockReturnValue(longPath), files: [], } // Simulate drop event fireEvent.drop(container.querySelector(".chat-text-area")!, { dataTransfer, - preventDefault: jest.fn(), + preventDefault: vi.fn(), }) // Verify convertToMentionPath was called with the long path @@ -329,7 +332,7 @@ describe("ChatTextArea", () => { }) it("should handle paths with special characters correctly", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render() @@ -341,16 +344,14 @@ describe("ChatTextArea", () => { // Create a mock dataTransfer object with the special paths const dataTransfer = { - getData: jest - .fn() - .mockReturnValue(`${specialPath1}\n${specialPath2}\n${specialPath3}\n${specialPath4}`), + getData: vi.fn().mockReturnValue(`${specialPath1}\n${specialPath2}\n${specialPath3}\n${specialPath4}`), files: [], } // Simulate drop event fireEvent.drop(container.querySelector(".chat-text-area")!, { dataTransfer, - preventDefault: jest.fn(), + preventDefault: vi.fn(), }) // Verify convertToMentionPath was called for each path @@ -367,7 +368,7 @@ describe("ChatTextArea", () => { }) it("should handle paths outside the current working directory", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render() @@ -381,14 +382,14 @@ describe("ChatTextArea", () => { // Create a mock dataTransfer object with the outside path const dataTransfer = { - getData: jest.fn().mockReturnValue(outsidePath), + getData: vi.fn().mockReturnValue(outsidePath), files: [], } // Simulate drop event fireEvent.drop(container.querySelector(".chat-text-area")!, { dataTransfer, - preventDefault: jest.fn(), + preventDefault: vi.fn(), }) // Verify convertToMentionPath was called with the outside path @@ -399,7 +400,7 @@ describe("ChatTextArea", () => { }) it("should do nothing when dropped text is empty", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , @@ -407,14 +408,14 @@ describe("ChatTextArea", () => { // Create a mock dataTransfer object with empty text const dataTransfer = { - getData: jest.fn().mockReturnValue(""), + getData: vi.fn().mockReturnValue(""), files: [], } // Simulate drop event fireEvent.drop(container.querySelector(".chat-text-area")!, { dataTransfer, - preventDefault: jest.fn(), + preventDefault: vi.fn(), }) // Verify convertToMentionPath was not called @@ -432,7 +433,7 @@ describe("ChatTextArea", () => { ] beforeEach(() => { - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -445,7 +446,7 @@ describe("ChatTextArea", () => { }) it("should navigate to previous prompt on arrow up", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -460,7 +461,7 @@ describe("ChatTextArea", () => { }) it("should navigate through history with multiple arrow up presses", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -480,7 +481,7 @@ describe("ChatTextArea", () => { }) it("should navigate forward with arrow down", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -498,7 +499,7 @@ describe("ChatTextArea", () => { }) it("should preserve current input when starting navigation", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -517,7 +518,7 @@ describe("ChatTextArea", () => { }) it("should reset history navigation when user types", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -536,8 +537,8 @@ describe("ChatTextArea", () => { }) it("should reset history navigation when sending message", () => { - const onSend = jest.fn() - const setInputValue = jest.fn() + const onSend = vi.fn() + const setInputValue = vi.fn() const { container } = render( { }) it("should navigate history when cursor is at first line", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -583,7 +584,7 @@ describe("ChatTextArea", () => { { type: "say", say: "user_feedback", text: "Workspace 1 prompt 2", ts: 3000 }, ] - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -594,7 +595,7 @@ describe("ChatTextArea", () => { cwd: "/test/workspace", }) - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -611,7 +612,7 @@ describe("ChatTextArea", () => { }) it("should handle empty conversation history gracefully", () => { - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -622,7 +623,7 @@ describe("ChatTextArea", () => { cwd: "/test/workspace", }) - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -642,7 +643,7 @@ describe("ChatTextArea", () => { { type: "say", say: "user_feedback", text: "Another valid prompt", ts: 4000 }, ] - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -653,7 +654,7 @@ describe("ChatTextArea", () => { cwd: "/test/workspace", }) - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -676,7 +677,7 @@ describe("ChatTextArea", () => { { task: "Third task", workspace: "/test/workspace" }, ] - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -687,7 +688,7 @@ describe("ChatTextArea", () => { cwd: "/test/workspace", }) - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { container } = render( , ) @@ -704,13 +705,13 @@ describe("ChatTextArea", () => { }) it("should reset navigation position when switching between history sources", () => { - const setInputValue = jest.fn() + const setInputValue = vi.fn() const { rerender } = render( , ) // Start with task history - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { @@ -733,7 +734,7 @@ describe("ChatTextArea", () => { expect(setInputValue).toHaveBeenCalledWith("Task 1") // Switch to conversation messages - ;(useExtensionState as jest.Mock).mockReturnValue({ + ;(useExtensionState as ReturnType).mockReturnValue({ filePaths: [], openedTabs: [], apiConfiguration: { diff --git a/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.test.tsx b/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.spec.tsx similarity index 95% rename from webview-ui/src/components/chat/__tests__/ChatView.auto-approve.test.tsx rename to webview-ui/src/components/chat/__tests__/ChatView.auto-approve.spec.tsx index 56d7eb3f41..3e819904fe 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.test.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.auto-approve.spec.tsx @@ -1,4 +1,4 @@ -// npx jest src/components/chat/__tests__/ChatView.auto-approve.test.tsx +// npx vitest run src/components/chat/__tests__/ChatView.auto-approve.spec.tsx import { render, waitFor } from "@testing-library/react" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" @@ -9,63 +9,54 @@ import { vscode } from "@src/utils/vscode" import ChatView, { ChatViewProps } from "../ChatView" // Mock vscode API -jest.mock("@src/utils/vscode", () => ({ +vi.mock("@src/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) // Mock all problematic dependencies -jest.mock("rehype-highlight", () => ({ - __esModule: true, +vi.mock("rehype-highlight", () => ({ default: () => () => {}, })) -jest.mock("hast-util-to-text", () => ({ - __esModule: true, +vi.mock("hast-util-to-text", () => ({ default: () => "", })) // Mock components that use ESM dependencies -jest.mock("../BrowserSessionRow", () => ({ - __esModule: true, +vi.mock("../BrowserSessionRow", () => ({ default: function MockBrowserSessionRow({ messages }: { messages: any[] }) { return
{JSON.stringify(messages)}
}, })) -jest.mock("../ChatRow", () => ({ - __esModule: true, +vi.mock("../ChatRow", () => ({ default: function MockChatRow({ message }: { message: any }) { return
{JSON.stringify(message)}
}, })) -jest.mock("../TaskHeader", () => ({ - __esModule: true, +vi.mock("../TaskHeader", () => ({ default: function MockTaskHeader({ task }: { task: any }) { return
{JSON.stringify(task)}
}, })) -jest.mock("../AutoApproveMenu", () => ({ - __esModule: true, +vi.mock("../AutoApproveMenu", () => ({ default: () => null, })) -jest.mock("@src/components/common/CodeBlock", () => ({ - __esModule: true, +vi.mock("@src/components/common/CodeBlock", () => ({ default: () => null, CODE_BLOCK_BG_COLOR: "rgb(30, 30, 30)", })) -jest.mock("@src/components/common/CodeAccordian", () => ({ - __esModule: true, +vi.mock("@src/components/common/CodeAccordian", () => ({ default: () => null, })) -jest.mock("@src/components/chat/ContextMenu", () => ({ - __esModule: true, +vi.mock("@src/components/chat/ContextMenu", () => ({ default: () => null, })) @@ -109,7 +100,7 @@ const renderChatView = (props: Partial = {}) => { describe("ChatView - Auto Approval Tests", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("auto-approves read operations when enabled", async () => { diff --git a/webview-ui/src/components/chat/__tests__/ChatView.test.tsx b/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx similarity index 96% rename from webview-ui/src/components/chat/__tests__/ChatView.test.tsx rename to webview-ui/src/components/chat/__tests__/ChatView.spec.tsx index 5b618378c4..f6ecbaf0e4 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.test.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.spec.tsx @@ -1,4 +1,4 @@ -// npx jest src/components/chat/__tests__/ChatView.test.tsx +// npx vitest run src/components/chat/__tests__/ChatView.spec.tsx import React from "react" import { render, waitFor, act } from "@testing-library/react" @@ -30,37 +30,34 @@ interface ExtensionState { } // Mock vscode API -jest.mock("@src/utils/vscode", () => ({ +vi.mock("@src/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) // Mock use-sound hook -const mockPlayFunction = jest.fn() -jest.mock("use-sound", () => { - return jest.fn().mockImplementation(() => { +const mockPlayFunction = vi.fn() +vi.mock("use-sound", () => ({ + default: vi.fn().mockImplementation(() => { return [mockPlayFunction] - }) -}) + }), +})) // Mock components that use ESM dependencies -jest.mock("../BrowserSessionRow", () => ({ - __esModule: true, +vi.mock("../BrowserSessionRow", () => ({ default: function MockBrowserSessionRow({ messages }: { messages: ClineMessage[] }) { return
{JSON.stringify(messages)}
}, })) -jest.mock("../ChatRow", () => ({ - __esModule: true, +vi.mock("../ChatRow", () => ({ default: function MockChatRow({ message }: { message: ClineMessage }) { return
{JSON.stringify(message)}
}, })) -jest.mock("../AutoApproveMenu", () => ({ - __esModule: true, +vi.mock("../AutoApproveMenu", () => ({ default: () => null, })) @@ -74,14 +71,13 @@ interface ChatTextAreaProps { } const mockInputRef = React.createRef() -const mockFocus = jest.fn() +const mockFocus = vi.fn() -jest.mock("../ChatTextArea", () => { +vi.mock("../ChatTextArea", () => { // eslint-disable-next-line @typescript-eslint/no-require-imports const mockReact = require("react") return { - __esModule: true, default: mockReact.forwardRef(function MockChatTextArea( props: ChatTextAreaProps, ref: React.ForwardedRef<{ focus: () => void }>, @@ -101,7 +97,7 @@ jest.mock("../ChatTextArea", () => { }) // Mock VSCode components -jest.mock("@vscode/webview-ui-toolkit/react", () => ({ +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ VSCodeButton: function MockVSCodeButton({ children, onClick, @@ -178,7 +174,7 @@ const renderChatView = (props: Partial = {}) => { } describe("ChatView - Auto Approval Tests", () => { - beforeEach(() => jest.clearAllMocks()) + beforeEach(() => vi.clearAllMocks()) it("does not auto-approve any actions when autoApprovalEnabled is false", () => { renderChatView() @@ -558,7 +554,7 @@ describe("ChatView - Auto Approval Tests", () => { ] for (const command of allowedChainedCommands) { - jest.clearAllMocks() + vi.clearAllMocks() // First hydrate state with initial task mockPostMessage({ @@ -689,7 +685,7 @@ describe("ChatView - Auto Approval Tests", () => { // Test allowed PowerShell commands for (const command of powershellCommands.allowed) { - jest.clearAllMocks() + vi.clearAllMocks() mockPostMessage({ autoApprovalEnabled: true, @@ -736,7 +732,7 @@ describe("ChatView - Auto Approval Tests", () => { // Test disallowed PowerShell commands for (const command of powershellCommands.disallowed) { - jest.clearAllMocks() + vi.clearAllMocks() mockPostMessage({ autoApprovalEnabled: true, @@ -784,7 +780,7 @@ describe("ChatView - Auto Approval Tests", () => { describe("ChatView - Sound Playing Tests", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() mockPlayFunction.mockClear() }) @@ -984,7 +980,7 @@ describe("ChatView - Sound Playing Tests", () => { }) describe("ChatView - Focus Grabbing Tests", () => { - beforeEach(() => jest.clearAllMocks()) + beforeEach(() => vi.clearAllMocks()) it("does not grab focus when follow-up question presented", async () => { const sleep = async (timeout: number) => { diff --git a/webview-ui/src/components/chat/__tests__/IndexingStatusBadge.test.tsx b/webview-ui/src/components/chat/__tests__/IndexingStatusBadge.spec.tsx similarity index 88% rename from webview-ui/src/components/chat/__tests__/IndexingStatusBadge.test.tsx rename to webview-ui/src/components/chat/__tests__/IndexingStatusBadge.spec.tsx index 4297c485d5..e75b16606a 100644 --- a/webview-ui/src/components/chat/__tests__/IndexingStatusBadge.test.tsx +++ b/webview-ui/src/components/chat/__tests__/IndexingStatusBadge.spec.tsx @@ -1,23 +1,23 @@ import React from "react" import { render, screen, fireEvent, waitFor, act } from "@testing-library/react" -import { IndexingStatusDot } from "../IndexingStatusBadge" + import { vscode } from "@src/utils/vscode" -// Mock i18n setup to prevent initialization errors -jest.mock("@/i18n/setup", () => ({ +import { IndexingStatusDot } from "../IndexingStatusBadge" + +vi.mock("@/i18n/setup", () => ({ __esModule: true, default: { - use: jest.fn().mockReturnThis(), - init: jest.fn().mockReturnThis(), - addResourceBundle: jest.fn(), + use: vi.fn().mockReturnThis(), + init: vi.fn().mockReturnThis(), + addResourceBundle: vi.fn(), language: "en", - changeLanguage: jest.fn(), + changeLanguage: vi.fn(), }, - loadTranslations: jest.fn(), + loadTranslations: vi.fn(), })) -// Mock react-i18next -jest.mock("react-i18next", () => ({ +vi.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key: string, params?: any) => { const translations: Record = { @@ -38,34 +38,34 @@ jest.mock("react-i18next", () => ({ }, i18n: { language: "en", - changeLanguage: jest.fn(), + changeLanguage: vi.fn(), }, }), initReactI18next: { type: "3rdParty", - init: jest.fn(), + init: vi.fn(), }, })) // Mock vscode API -jest.mock("@src/utils/vscode", () => ({ +vi.mock("@src/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) // Mock the useTooltip hook -jest.mock("@/hooks/useTooltip", () => ({ - useTooltip: jest.fn(() => ({ +vi.mock("@/hooks/useTooltip", () => ({ + useTooltip: vi.fn(() => ({ showTooltip: false, - handleMouseEnter: jest.fn(), - handleMouseLeave: jest.fn(), - cleanup: jest.fn(), + handleMouseEnter: vi.fn(), + handleMouseLeave: vi.fn(), + cleanup: vi.fn(), })), })) // Mock the ExtensionStateContext -jest.mock("@/context/ExtensionStateContext", () => ({ +vi.mock("@/context/ExtensionStateContext", () => ({ useExtensionState: () => ({ version: "1.0.0", clineMessages: [], @@ -77,7 +77,7 @@ jest.mock("@/context/ExtensionStateContext", () => ({ })) // Mock TranslationContext to provide t function directly -jest.mock("@/i18n/TranslationContext", () => ({ +vi.mock("@/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string, params?: any) => { // Remove namespace prefix if present @@ -109,7 +109,7 @@ describe("IndexingStatusDot", () => { } beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("renders the status dot", () => { @@ -126,7 +126,7 @@ describe("IndexingStatusDot", () => { it("posts settingsButtonClicked message when clicked", () => { // Mock window.postMessage - const postMessageSpy = jest.spyOn(window, "postMessage") + const postMessageSpy = vi.spyOn(window, "postMessage") renderComponent() @@ -233,7 +233,7 @@ describe("IndexingStatusDot", () => { it("cleans up event listener on unmount", () => { const { unmount } = renderComponent() - const removeEventListenerSpy = jest.spyOn(window, "removeEventListener") + const removeEventListenerSpy = vi.spyOn(window, "removeEventListener") unmount() diff --git a/webview-ui/src/components/chat/__tests__/TaskHeader.test.tsx b/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx similarity index 88% rename from webview-ui/src/components/chat/__tests__/TaskHeader.test.tsx rename to webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx index 9d0de80191..784a263531 100644 --- a/webview-ui/src/components/chat/__tests__/TaskHeader.test.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskHeader.spec.tsx @@ -1,4 +1,4 @@ -// npx jest src/components/chat/__tests__/TaskHeader.test.tsx +// npx vitest src/components/chat/__tests__/TaskHeader.spec.tsx import React from "react" import { render, screen, fireEvent } from "@testing-library/react" @@ -9,31 +9,31 @@ import type { ProviderSettings } from "@roo-code/types" import TaskHeader, { TaskHeaderProps } from "../TaskHeader" // Mock i18n -jest.mock("react-i18next", () => ({ +vi.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key: string) => key, // Simple mock that returns the key }), // Mock initReactI18next to prevent initialization errors in tests initReactI18next: { type: "3rdParty", - init: jest.fn(), + init: vi.fn(), }, })) // Mock the vscode API -jest.mock("@/utils/vscode", () => ({ +vi.mock("@/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) // Mock the VSCodeBadge component -jest.mock("@vscode/webview-ui-toolkit/react", () => ({ +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ VSCodeBadge: ({ children }: { children: React.ReactNode }) =>
{children}
, })) // Mock the ExtensionStateContext -jest.mock("@src/context/ExtensionStateContext", () => ({ +vi.mock("@src/context/ExtensionStateContext", () => ({ useExtensionState: () => ({ apiConfiguration: { apiProvider: "anthropic", @@ -53,8 +53,8 @@ describe("TaskHeader", () => { totalCost: 0.05, contextTokens: 200, buttonsDisabled: false, - handleCondenseContext: jest.fn(), - onClose: jest.fn(), + handleCondenseContext: vi.fn(), + onClose: vi.fn(), } const queryClient = new QueryClient() @@ -98,7 +98,7 @@ describe("TaskHeader", () => { }) it("should call handleCondenseContext when condense context button is clicked", () => { - const handleCondenseContext = jest.fn() + const handleCondenseContext = vi.fn() renderTaskHeader({ handleCondenseContext }) const condenseButton = screen.getByTitle("chat:task.condenseContext") fireEvent.click(condenseButton) @@ -106,7 +106,7 @@ describe("TaskHeader", () => { }) it("should disable the condense context button when buttonsDisabled is true", () => { - const handleCondenseContext = jest.fn() + const handleCondenseContext = vi.fn() renderTaskHeader({ buttonsDisabled: true, handleCondenseContext }) const condenseButton = screen.getByTitle("chat:task.condenseContext") fireEvent.click(condenseButton) diff --git a/webview-ui/src/components/common/__tests__/CodeBlock.test.tsx b/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx similarity index 80% rename from webview-ui/src/components/common/__tests__/CodeBlock.test.tsx rename to webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx index c8f37e5dd6..a1d3849744 100644 --- a/webview-ui/src/components/common/__tests__/CodeBlock.test.tsx +++ b/webview-ui/src/components/common/__tests__/CodeBlock.spec.tsx @@ -1,9 +1,11 @@ +// npx vitest run src/components/common/__tests__/CodeBlock.spec.tsx + import { render, screen, fireEvent, act } from "@testing-library/react" -import "@testing-library/jest-dom" + import CodeBlock from "../CodeBlock" // Mock the translation context -jest.mock("../../../i18n/TranslationContext", () => ({ +vi.mock("../../../i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => { // Return fixed English strings for tests @@ -20,7 +22,7 @@ jest.mock("../../../i18n/TranslationContext", () => ({ })) // Mock shiki module -jest.mock("shiki", () => ({ +vi.mock("shiki", () => ({ bundledLanguages: { typescript: {}, javascript: {}, @@ -29,31 +31,31 @@ jest.mock("shiki", () => ({ })) // Mock the highlighter utility -jest.mock("../../../utils/highlighter", () => { +vi.mock("../../../utils/highlighter", () => { const mockHighlighter = { - codeToHtml: jest.fn().mockImplementation((code, options) => { + codeToHtml: vi.fn().mockImplementation((code, options) => { const theme = options.theme === "github-light" ? "light" : "dark" return `
${code} [${theme}-theme]
` }), } return { - normalizeLanguage: jest.fn((lang) => lang || "txt"), - isLanguageLoaded: jest.fn().mockReturnValue(true), - getHighlighter: jest.fn().mockResolvedValue(mockHighlighter), + normalizeLanguage: vi.fn((lang) => lang || "txt"), + isLanguageLoaded: vi.fn().mockReturnValue(true), + getHighlighter: vi.fn().mockResolvedValue(mockHighlighter), } }) // Mock clipboard utility -jest.mock("../../../utils/clipboard", () => ({ +vi.mock("../../../utils/clipboard", () => ({ useCopyToClipboard: () => ({ showCopyFeedback: false, - copyWithFeedback: jest.fn(), + copyWithFeedback: vi.fn(), }), })) describe("CodeBlock", () => { - const mockIntersectionObserver = jest.fn() + const mockIntersectionObserver = vi.fn() const originalGetComputedStyle = window.getComputedStyle beforeEach(() => { @@ -66,14 +68,14 @@ describe("CodeBlock", () => { window.IntersectionObserver = mockIntersectionObserver // Mock getComputedStyle - window.getComputedStyle = jest.fn().mockImplementation((element) => ({ + window.getComputedStyle = vi.fn().mockImplementation((element) => ({ ...originalGetComputedStyle(element), getPropertyValue: () => "12px", })) }) afterEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() const scrollContainer = document.querySelector('[data-virtuoso-scroller="true"]') if (scrollContainer) { document.body.removeChild(scrollContainer) @@ -124,12 +126,11 @@ describe("CodeBlock", () => { it("handles WASM loading errors", async () => { const mockError = new Error("WASM load failed") - // eslint-disable-next-line @typescript-eslint/no-require-imports - const highlighterUtil = require("../../../utils/highlighter") - highlighterUtil.getHighlighter.mockRejectedValueOnce(mockError) + const highlighterUtil = await import("../../../utils/highlighter") + vi.mocked(highlighterUtil.getHighlighter).mockRejectedValueOnce(mockError) const code = "const x = 1;" - const consoleSpy = jest.spyOn(console, "error").mockImplementation() + const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {}) await act(async () => { render() @@ -148,8 +149,7 @@ describe("CodeBlock", () => { it("verifies highlighter utility is used correctly", async () => { const code = "const x = 1;" - // eslint-disable-next-line @typescript-eslint/no-require-imports - const highlighterUtil = require("../../../utils/highlighter") + const highlighterUtil = await import("../../../utils/highlighter") await act(async () => { render() diff --git a/webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.test.tsx b/webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.spec.tsx similarity index 95% rename from webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.test.tsx rename to webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.spec.tsx index 6b13c92b06..9fe49663d1 100644 --- a/webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.test.tsx +++ b/webview-ui/src/components/history/__tests__/BatchDeleteTaskDialog.spec.tsx @@ -1,9 +1,12 @@ import { render, screen, fireEvent } from "@testing-library/react" -import { BatchDeleteTaskDialog } from "../BatchDeleteTaskDialog" + import { vscode } from "@/utils/vscode" -jest.mock("@/utils/vscode") -jest.mock("@/i18n/TranslationContext", () => ({ +import { BatchDeleteTaskDialog } from "../BatchDeleteTaskDialog" + +vi.mock("@/utils/vscode") + +vi.mock("@/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string, options?: Record) => { const translations: Record = { @@ -20,10 +23,10 @@ jest.mock("@/i18n/TranslationContext", () => ({ describe("BatchDeleteTaskDialog", () => { const mockTaskIds = ["task-1", "task-2", "task-3"] - const mockOnOpenChange = jest.fn() + const mockOnOpenChange = vi.fn() beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("renders dialog with correct content", () => { diff --git a/webview-ui/src/components/history/__tests__/CopyButton.test.tsx b/webview-ui/src/components/history/__tests__/CopyButton.spec.tsx similarity index 75% rename from webview-ui/src/components/history/__tests__/CopyButton.test.tsx rename to webview-ui/src/components/history/__tests__/CopyButton.spec.tsx index f1de9bf8ea..0ba1b27a1f 100644 --- a/webview-ui/src/components/history/__tests__/CopyButton.test.tsx +++ b/webview-ui/src/components/history/__tests__/CopyButton.spec.tsx @@ -1,20 +1,22 @@ import { render, screen, fireEvent } from "@testing-library/react" -import { CopyButton } from "../CopyButton" + import { useClipboard } from "@/components/ui/hooks" -jest.mock("@/components/ui/hooks") -jest.mock("@src/i18n/TranslationContext", () => ({ +import { CopyButton } from "../CopyButton" + +vi.mock("@/components/ui/hooks") +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), })) describe("CopyButton", () => { - const mockCopy = jest.fn() + const mockCopy = vi.fn() beforeEach(() => { - jest.clearAllMocks() - ;(useClipboard as jest.Mock).mockReturnValue({ + vi.clearAllMocks() + ;(useClipboard as any).mockReturnValue({ isCopied: false, copy: mockCopy, }) diff --git a/webview-ui/src/components/history/__tests__/DeleteButton.test.tsx b/webview-ui/src/components/history/__tests__/DeleteButton.spec.tsx similarity index 85% rename from webview-ui/src/components/history/__tests__/DeleteButton.test.tsx rename to webview-ui/src/components/history/__tests__/DeleteButton.spec.tsx index d6c10ad6ca..42c17f5335 100644 --- a/webview-ui/src/components/history/__tests__/DeleteButton.test.tsx +++ b/webview-ui/src/components/history/__tests__/DeleteButton.spec.tsx @@ -1,7 +1,8 @@ import { render, screen, fireEvent } from "@testing-library/react" + import { DeleteButton } from "../DeleteButton" -jest.mock("@src/i18n/TranslationContext", () => ({ +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), @@ -9,7 +10,7 @@ jest.mock("@src/i18n/TranslationContext", () => ({ describe("DeleteButton", () => { it("calls onDelete when clicked", () => { - const onDelete = jest.fn() + const onDelete = vi.fn() render() const deleteButton = screen.getByRole("button") diff --git a/webview-ui/src/components/history/__tests__/DeleteTaskDialog.test.tsx b/webview-ui/src/components/history/__tests__/DeleteTaskDialog.spec.tsx similarity index 94% rename from webview-ui/src/components/history/__tests__/DeleteTaskDialog.test.tsx rename to webview-ui/src/components/history/__tests__/DeleteTaskDialog.spec.tsx index ceecb42063..e78101f37d 100644 --- a/webview-ui/src/components/history/__tests__/DeleteTaskDialog.test.tsx +++ b/webview-ui/src/components/history/__tests__/DeleteTaskDialog.spec.tsx @@ -1,9 +1,12 @@ import { render, screen, fireEvent } from "@testing-library/react" -import { DeleteTaskDialog } from "../DeleteTaskDialog" + import { vscode } from "@/utils/vscode" -jest.mock("@/utils/vscode") -jest.mock("@/i18n/TranslationContext", () => ({ +import { DeleteTaskDialog } from "../DeleteTaskDialog" + +vi.mock("@/utils/vscode") + +vi.mock("@/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => { const translations: Record = { @@ -17,20 +20,20 @@ jest.mock("@/i18n/TranslationContext", () => ({ }), })) -jest.mock("react-use", () => ({ - useKeyPress: jest.fn(), +vi.mock("react-use", () => ({ + useKeyPress: vi.fn(), })) import { useKeyPress } from "react-use" -const mockUseKeyPress = useKeyPress as jest.MockedFunction +const mockUseKeyPress = useKeyPress as any describe("DeleteTaskDialog", () => { const mockTaskId = "test-task-id" - const mockOnOpenChange = jest.fn() + const mockOnOpenChange = vi.fn() beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() mockUseKeyPress.mockReturnValue([false, null]) }) diff --git a/webview-ui/src/components/history/__tests__/ExportButton.test.tsx b/webview-ui/src/components/history/__tests__/ExportButton.spec.tsx similarity index 84% rename from webview-ui/src/components/history/__tests__/ExportButton.test.tsx rename to webview-ui/src/components/history/__tests__/ExportButton.spec.tsx index a2d68e5682..68f4407400 100644 --- a/webview-ui/src/components/history/__tests__/ExportButton.test.tsx +++ b/webview-ui/src/components/history/__tests__/ExportButton.spec.tsx @@ -1,9 +1,12 @@ import { render, screen, fireEvent } from "@testing-library/react" -import { ExportButton } from "../ExportButton" + import { vscode } from "@src/utils/vscode" -jest.mock("@src/utils/vscode") -jest.mock("@src/i18n/TranslationContext", () => ({ +import { ExportButton } from "../ExportButton" + +vi.mock("@src/utils/vscode") + +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), @@ -11,7 +14,7 @@ jest.mock("@src/i18n/TranslationContext", () => ({ describe("ExportButton", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("sends export message when clicked", () => { diff --git a/webview-ui/src/components/history/__tests__/HistoryPreview.test.tsx b/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx similarity index 78% rename from webview-ui/src/components/history/__tests__/HistoryPreview.test.tsx rename to webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx index c4c7fb3e95..179c51b1c0 100644 --- a/webview-ui/src/components/history/__tests__/HistoryPreview.test.tsx +++ b/webview-ui/src/components/history/__tests__/HistoryPreview.spec.tsx @@ -1,12 +1,14 @@ import { render, screen } from "@testing-library/react" -import HistoryPreview from "../HistoryPreview" + import type { HistoryItem } from "@roo-code/types" -jest.mock("../useTaskSearch") -jest.mock("../TaskItem", () => { +import HistoryPreview from "../HistoryPreview" + +vi.mock("../useTaskSearch") + +vi.mock("../TaskItem", () => { return { - __esModule: true, - default: jest.fn(({ item, variant }) => ( + default: vi.fn(({ item, variant }) => (
{item.task}
@@ -17,8 +19,8 @@ jest.mock("../TaskItem", () => { import { useTaskSearch } from "../useTaskSearch" import TaskItem from "../TaskItem" -const mockUseTaskSearch = useTaskSearch as jest.MockedFunction -const mockTaskItem = TaskItem as jest.MockedFunction +const mockUseTaskSearch = useTaskSearch as any +const mockTaskItem = TaskItem as any const mockTasks: HistoryItem[] = [ { @@ -61,20 +63,20 @@ const mockTasks: HistoryItem[] = [ describe("HistoryPreview", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("renders nothing when no tasks are available", () => { mockUseTaskSearch.mockReturnValue({ tasks: [], searchQuery: "", - setSearchQuery: jest.fn(), + setSearchQuery: vi.fn(), sortOption: "newest", - setSortOption: jest.fn(), + setSortOption: vi.fn(), lastNonRelevantSort: null, - setLastNonRelevantSort: jest.fn(), + setLastNonRelevantSort: vi.fn(), showAllWorkspaces: false, - setShowAllWorkspaces: jest.fn(), + setShowAllWorkspaces: vi.fn(), }) const { container } = render() @@ -88,13 +90,13 @@ describe("HistoryPreview", () => { mockUseTaskSearch.mockReturnValue({ tasks: mockTasks, searchQuery: "", - setSearchQuery: jest.fn(), + setSearchQuery: vi.fn(), sortOption: "newest", - setSortOption: jest.fn(), + setSortOption: vi.fn(), lastNonRelevantSort: null, - setLastNonRelevantSort: jest.fn(), + setLastNonRelevantSort: vi.fn(), showAllWorkspaces: false, - setShowAllWorkspaces: jest.fn(), + setShowAllWorkspaces: vi.fn(), }) render() @@ -111,13 +113,13 @@ describe("HistoryPreview", () => { mockUseTaskSearch.mockReturnValue({ tasks: threeTasks, searchQuery: "", - setSearchQuery: jest.fn(), + setSearchQuery: vi.fn(), sortOption: "newest", - setSortOption: jest.fn(), + setSortOption: vi.fn(), lastNonRelevantSort: null, - setLastNonRelevantSort: jest.fn(), + setLastNonRelevantSort: vi.fn(), showAllWorkspaces: false, - setShowAllWorkspaces: jest.fn(), + setShowAllWorkspaces: vi.fn(), }) render() @@ -132,13 +134,13 @@ describe("HistoryPreview", () => { mockUseTaskSearch.mockReturnValue({ tasks: oneTask, searchQuery: "", - setSearchQuery: jest.fn(), + setSearchQuery: vi.fn(), sortOption: "newest", - setSortOption: jest.fn(), + setSortOption: vi.fn(), lastNonRelevantSort: null, - setLastNonRelevantSort: jest.fn(), + setLastNonRelevantSort: vi.fn(), showAllWorkspaces: false, - setShowAllWorkspaces: jest.fn(), + setShowAllWorkspaces: vi.fn(), }) render() @@ -151,13 +153,13 @@ describe("HistoryPreview", () => { mockUseTaskSearch.mockReturnValue({ tasks: mockTasks.slice(0, 2), searchQuery: "", - setSearchQuery: jest.fn(), + setSearchQuery: vi.fn(), sortOption: "newest", - setSortOption: jest.fn(), + setSortOption: vi.fn(), lastNonRelevantSort: null, - setLastNonRelevantSort: jest.fn(), + setLastNonRelevantSort: vi.fn(), showAllWorkspaces: false, - setShowAllWorkspaces: jest.fn(), + setShowAllWorkspaces: vi.fn(), }) render() @@ -183,13 +185,13 @@ describe("HistoryPreview", () => { mockUseTaskSearch.mockReturnValue({ tasks: mockTasks.slice(0, 1), searchQuery: "", - setSearchQuery: jest.fn(), + setSearchQuery: vi.fn(), sortOption: "newest", - setSortOption: jest.fn(), + setSortOption: vi.fn(), lastNonRelevantSort: null, - setLastNonRelevantSort: jest.fn(), + setLastNonRelevantSort: vi.fn(), showAllWorkspaces: false, - setShowAllWorkspaces: jest.fn(), + setShowAllWorkspaces: vi.fn(), }) const { container } = render() diff --git a/webview-ui/src/components/history/__tests__/HistoryView.test.tsx b/webview-ui/src/components/history/__tests__/HistoryView.spec.tsx similarity index 82% rename from webview-ui/src/components/history/__tests__/HistoryView.test.tsx rename to webview-ui/src/components/history/__tests__/HistoryView.spec.tsx index 1c63abc837..030c36f503 100644 --- a/webview-ui/src/components/history/__tests__/HistoryView.test.tsx +++ b/webview-ui/src/components/history/__tests__/HistoryView.spec.tsx @@ -1,10 +1,13 @@ import { render, screen, fireEvent } from "@testing-library/react" -import HistoryView from "../HistoryView" + import { useExtensionState } from "@src/context/ExtensionStateContext" -jest.mock("@src/context/ExtensionStateContext") -jest.mock("@src/utils/vscode") -jest.mock("@src/i18n/TranslationContext", () => ({ +import HistoryView from "../HistoryView" + +vi.mock("@src/context/ExtensionStateContext") +vi.mock("@src/utils/vscode") + +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), @@ -33,15 +36,15 @@ const mockTaskHistory = [ describe("HistoryView", () => { beforeEach(() => { - jest.clearAllMocks() - ;(useExtensionState as jest.Mock).mockReturnValue({ + vi.clearAllMocks() + ;(useExtensionState as ReturnType).mockReturnValue({ taskHistory: mockTaskHistory, cwd: "/test/workspace", }) }) it("renders the history interface", () => { - const onDone = jest.fn() + const onDone = vi.fn() render() // Check for main UI elements @@ -51,7 +54,7 @@ describe("HistoryView", () => { }) it("calls onDone when done button is clicked", () => { - const onDone = jest.fn() + const onDone = vi.fn() render() const doneButton = screen.getByText("history:done") diff --git a/webview-ui/src/components/history/__tests__/TaskItem.test.tsx b/webview-ui/src/components/history/__tests__/TaskItem.spec.tsx similarity index 89% rename from webview-ui/src/components/history/__tests__/TaskItem.test.tsx rename to webview-ui/src/components/history/__tests__/TaskItem.spec.tsx index c57eec8567..9fcc11e572 100644 --- a/webview-ui/src/components/history/__tests__/TaskItem.test.tsx +++ b/webview-ui/src/components/history/__tests__/TaskItem.spec.tsx @@ -1,8 +1,9 @@ import { render, screen, fireEvent } from "@testing-library/react" + import TaskItem from "../TaskItem" -jest.mock("@src/utils/vscode") -jest.mock("@src/i18n/TranslationContext", () => ({ +vi.mock("@src/utils/vscode") +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), @@ -21,7 +22,7 @@ const mockTask = { describe("TaskItem", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("renders task information", () => { @@ -30,7 +31,7 @@ describe("TaskItem", () => { item={mockTask} variant="full" isSelected={false} - onToggleSelection={jest.fn()} + onToggleSelection={vi.fn()} isSelectionMode={false} />, ) @@ -40,7 +41,7 @@ describe("TaskItem", () => { }) it("handles selection in selection mode", () => { - const onToggleSelection = jest.fn() + const onToggleSelection = vi.fn() render( { item={mockTask} variant="full" isSelected={false} - onToggleSelection={jest.fn()} + onToggleSelection={vi.fn()} isSelectionMode={false} />, ) @@ -85,7 +86,7 @@ describe("TaskItem", () => { item={mockTaskWithCache} variant="full" isSelected={false} - onToggleSelection={jest.fn()} + onToggleSelection={vi.fn()} isSelectionMode={false} />, ) @@ -108,7 +109,7 @@ describe("TaskItem", () => { item={mockTaskWithoutCache} variant="full" isSelected={false} - onToggleSelection={jest.fn()} + onToggleSelection={vi.fn()} isSelectionMode={false} />, ) diff --git a/webview-ui/src/components/history/__tests__/TaskItemFooter.test.tsx b/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx similarity index 97% rename from webview-ui/src/components/history/__tests__/TaskItemFooter.test.tsx rename to webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx index f7ed5640f1..f1390b7d55 100644 --- a/webview-ui/src/components/history/__tests__/TaskItemFooter.test.tsx +++ b/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx @@ -1,7 +1,8 @@ import { render, screen } from "@testing-library/react" + import TaskItemFooter from "../TaskItemFooter" -jest.mock("@src/i18n/TranslationContext", () => ({ +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), diff --git a/webview-ui/src/components/history/__tests__/TaskItemHeader.test.tsx b/webview-ui/src/components/history/__tests__/TaskItemHeader.spec.tsx similarity index 89% rename from webview-ui/src/components/history/__tests__/TaskItemHeader.test.tsx rename to webview-ui/src/components/history/__tests__/TaskItemHeader.spec.tsx index 10ce7ca0f5..02f554d697 100644 --- a/webview-ui/src/components/history/__tests__/TaskItemHeader.test.tsx +++ b/webview-ui/src/components/history/__tests__/TaskItemHeader.spec.tsx @@ -1,7 +1,8 @@ import { render, screen } from "@testing-library/react" + import TaskItemHeader from "../TaskItemHeader" -jest.mock("@src/i18n/TranslationContext", () => ({ +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), @@ -20,14 +21,14 @@ const mockItem = { describe("TaskItemHeader", () => { it("renders date information", () => { - render() + render() // TaskItemHeader shows the formatted date, not the task text expect(screen.getByText(/\w+ \d{1,2}, \d{1,2}:\d{2} \w{2}/)).toBeInTheDocument() // Date format like "JUNE 14, 10:15 AM" }) it("shows delete button when not in selection mode", () => { - render() + render() expect(screen.getByRole("button")).toBeInTheDocument() }) diff --git a/webview-ui/src/components/history/__tests__/useTaskSearch.test.tsx b/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx similarity index 96% rename from webview-ui/src/components/history/__tests__/useTaskSearch.test.tsx rename to webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx index 077ec93f55..e047a81cf3 100644 --- a/webview-ui/src/components/history/__tests__/useTaskSearch.test.tsx +++ b/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx @@ -1,18 +1,20 @@ import { renderHook, act } from "@testing-library/react" -import { useTaskSearch } from "../useTaskSearch" + import type { HistoryItem } from "@roo-code/types" -jest.mock("@/context/ExtensionStateContext", () => ({ - useExtensionState: jest.fn(), +import { useTaskSearch } from "../useTaskSearch" + +vi.mock("@/context/ExtensionStateContext", () => ({ + useExtensionState: vi.fn(), })) -jest.mock("@/utils/highlight", () => ({ - highlightFzfMatch: jest.fn((text) => `${text}`), +vi.mock("@/utils/highlight", () => ({ + highlightFzfMatch: vi.fn((text) => `${text}`), })) import { useExtensionState } from "@/context/ExtensionStateContext" -const mockUseExtensionState = useExtensionState as jest.MockedFunction +const mockUseExtensionState = useExtensionState as ReturnType const mockTaskHistory: HistoryItem[] = [ { @@ -51,7 +53,7 @@ const mockTaskHistory: HistoryItem[] = [ describe("useTaskSearch", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() mockUseExtensionState.mockReturnValue({ taskHistory: mockTaskHistory, cwd: "/workspace/project1", diff --git a/webview-ui/src/components/marketplace/__tests__/MarketplaceListView.test.tsx b/webview-ui/src/components/marketplace/__tests__/MarketplaceListView.spec.tsx similarity index 87% rename from webview-ui/src/components/marketplace/__tests__/MarketplaceListView.test.tsx rename to webview-ui/src/components/marketplace/__tests__/MarketplaceListView.spec.tsx index e696f04495..8e62af73c9 100644 --- a/webview-ui/src/components/marketplace/__tests__/MarketplaceListView.test.tsx +++ b/webview-ui/src/components/marketplace/__tests__/MarketplaceListView.spec.tsx @@ -1,25 +1,21 @@ +// npx vitest run src/components/marketplace/__tests__/MarketplaceListView.spec.tsx + import { render, screen, fireEvent } from "@testing-library/react" -import { MarketplaceListView } from "../MarketplaceListView" -import { ViewState } from "../MarketplaceViewStateManager" import userEvent from "@testing-library/user-event" + import { TooltipProvider } from "@/components/ui/tooltip" import { ExtensionStateContextProvider } from "@/context/ExtensionStateContext" -jest.mock("@/i18n/TranslationContext", () => ({ +import { MarketplaceListView } from "../MarketplaceListView" +import { ViewState } from "../MarketplaceViewStateManager" + +vi.mock("@/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), })) -class MockResizeObserver { - observe() {} - unobserve() {} - disconnect() {} -} - -global.ResizeObserver = MockResizeObserver - -const mockTransition = jest.fn() +const mockTransition = vi.fn() const mockState: ViewState = { allItems: [], displayItems: [], @@ -32,24 +28,10 @@ const mockState: ViewState = { }, } -jest.mock("../useStateManager", () => ({ +vi.mock("../useStateManager", () => ({ useStateManager: () => [mockState, { transition: mockTransition }], })) -jest.mock("lucide-react", () => { - return new Proxy( - {}, - { - get: function (_obj, prop) { - if (prop === "__esModule") { - return true - } - return () =>
{String(prop)}
- }, - }, - ) -}) - const defaultProps = { stateManager: {} as any, allTags: ["tag1", "tag2"], @@ -58,7 +40,7 @@ const defaultProps = { describe("MarketplaceListView", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() mockState.filters.tags = [] mockState.isFetching = false mockState.displayItems = [] diff --git a/webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx b/webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx index f071cc98a8..10290b70b3 100644 --- a/webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx +++ b/webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx @@ -1,25 +1,24 @@ -import React from "react" import { render, screen } from "@testing-library/react" import userEvent from "@testing-library/user-event" + import { MarketplaceView } from "../MarketplaceView" import { MarketplaceViewStateManager } from "../MarketplaceViewStateManager" -// Mock all the dependencies to keep the test simple -jest.mock("@/utils/vscode", () => ({ +vi.mock("@/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), - getState: jest.fn(() => ({})), - setState: jest.fn(), + postMessage: vi.fn(), + getState: vi.fn(() => ({})), + setState: vi.fn(), }, })) -jest.mock("@/i18n/TranslationContext", () => ({ +vi.mock("@/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => key, }), })) -jest.mock("../useStateManager", () => ({ +vi.mock("../useStateManager", () => ({ useStateManager: () => [ { allItems: [], @@ -29,20 +28,20 @@ jest.mock("../useStateManager", () => ({ filters: { type: "", search: "", tags: [] }, }, { - transition: jest.fn(), - onStateChange: jest.fn(() => jest.fn()), + transition: vi.fn(), + onStateChange: vi.fn(() => vi.fn()), }, ], })) -jest.mock("../MarketplaceListView", () => ({ +vi.mock("../MarketplaceListView", () => ({ MarketplaceListView: ({ filterByType }: { filterByType: string }) => (
MarketplaceListView - {filterByType}
), })) // Mock Tab components to avoid ExtensionStateContext dependency -jest.mock("@/components/common/Tab", () => ({ +vi.mock("@/components/common/Tab", () => ({ Tab: ({ children, ...props }: any) =>
{children}
, TabHeader: ({ children, ...props }: any) =>
{children}
, TabContent: ({ children, ...props }: any) =>
{children}
, @@ -50,20 +49,12 @@ jest.mock("@/components/common/Tab", () => ({ TabTrigger: ({ children, ...props }: any) => , })) -// Mock ResizeObserver -class MockResizeObserver { - observe() {} - unobserve() {} - disconnect() {} -} -global.ResizeObserver = MockResizeObserver - describe("MarketplaceView", () => { - const mockOnDone = jest.fn() + const mockOnDone = vi.fn() const mockStateManager = new MarketplaceViewStateManager() beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("renders without crashing", () => { diff --git a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.test.tsx b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.spec.tsx similarity index 94% rename from webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.test.tsx rename to webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.spec.tsx index ff8b51e2e5..8ffb15abd4 100644 --- a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.test.tsx +++ b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal-optional-params.spec.tsx @@ -1,18 +1,19 @@ -import React from "react" import { render, screen, fireEvent, waitFor } from "@testing-library/react" -import { MarketplaceInstallModal } from "../MarketplaceInstallModal" + import { MarketplaceItem } from "@roo-code/types" -// Mock vscode -const mockPostMessage = jest.fn() -jest.mock("@/utils/vscode", () => ({ +import { MarketplaceInstallModal } from "../MarketplaceInstallModal" + +vi.mock("@/utils/vscode", () => ({ vscode: { - postMessage: mockPostMessage, + postMessage: vi.fn(), }, })) -// Mock translation -jest.mock("@/i18n/TranslationContext", () => ({ +import { vscode } from "@/utils/vscode" +const mockPostMessage = vscode.postMessage as any + +vi.mock("@/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string, params?: any) => { // Simple mock translation @@ -28,10 +29,10 @@ jest.mock("@/i18n/TranslationContext", () => ({ })) describe("MarketplaceInstallModal - Optional Parameters", () => { - const mockOnClose = jest.fn() + const mockOnClose = vi.fn() beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) const createMcpItemWithParams = (parameters: any[]): MarketplaceItem => ({ diff --git a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.test.tsx b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.spec.tsx similarity index 95% rename from webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.test.tsx rename to webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.spec.tsx index a5426575fd..6bc9453cd9 100644 --- a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.test.tsx +++ b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceInstallModal.spec.tsx @@ -1,21 +1,21 @@ -import React from "react" import { render, screen, fireEvent, waitFor } from "@testing-library/react" -import { MarketplaceInstallModal } from "../MarketplaceInstallModal" + import { MarketplaceItem } from "@roo-code/types" -// Mock the vscode module before importing the component -jest.mock("@/utils/vscode", () => ({ +import { MarketplaceInstallModal } from "../MarketplaceInstallModal" + +vi.mock("@/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) // Import the mocked vscode after setting up the mock import { vscode } from "@/utils/vscode" -const mockedVscode = vscode as jest.Mocked +const mockedVscode = vscode as any // Mock the translation hook -jest.mock("@/i18n/TranslationContext", () => ({ +vi.mock("@/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string, params?: any) => { // Simple mock translation that returns the key with params @@ -31,10 +31,10 @@ jest.mock("@/i18n/TranslationContext", () => ({ })) describe("MarketplaceInstallModal - Nested Parameters", () => { - const mockOnClose = jest.fn() + const mockOnClose = vi.fn() beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() // Reset the mock function mockedVscode.postMessage.mockClear() }) diff --git a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.test.tsx b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.spec.tsx similarity index 92% rename from webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.test.tsx rename to webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.spec.tsx index cdde67f58c..bd88de7229 100644 --- a/webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.test.tsx +++ b/webview-ui/src/components/marketplace/components/__tests__/MarketplaceItemCard.spec.tsx @@ -1,26 +1,27 @@ import { render, screen } from "@testing-library/react" import userEvent from "@testing-library/user-event" -import { MarketplaceItemCard } from "../MarketplaceItemCard" -import { vscode } from "@/utils/vscode" + import { MarketplaceItem } from "@roo-code/types" + +import { vscode } from "@/utils/vscode" import { TooltipProvider } from "@/components/ui/tooltip" -// Mock vscode API -jest.mock("@/utils/vscode", () => ({ + +import { MarketplaceItemCard } from "../MarketplaceItemCard" + +vi.mock("@/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) -// Mock ExtensionStateContext -jest.mock("@/context/ExtensionStateContext", () => ({ +vi.mock("@/context/ExtensionStateContext", () => ({ useExtensionState: () => ({ cwd: "/test/workspace", filePaths: ["/test/workspace/file1.ts", "/test/workspace/file2.ts"], }), })) -// Mock translation hook -jest.mock("@/i18n/TranslationContext", () => ({ +vi.mock("@/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string, params?: any) => { if (key === "marketplace:items.card.by") { @@ -78,7 +79,7 @@ describe("MarketplaceItemCard", () => { search: "", tags: [], }, - setFilters: jest.fn(), + setFilters: vi.fn(), installed: { project: undefined, global: undefined, @@ -86,7 +87,7 @@ describe("MarketplaceItemCard", () => { } beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("renders basic item information", () => { @@ -106,7 +107,7 @@ describe("MarketplaceItemCard", () => { it("renders tags and handles tag clicks", async () => { const user = userEvent.setup() - const setFilters = jest.fn() + const setFilters = vi.fn() renderWithProviders() @@ -143,7 +144,7 @@ describe("MarketplaceItemCard", () => { describe("MarketplaceItemCard install button", () => { it("renders install button", () => { - const setFilters = jest.fn() + const setFilters = vi.fn() const item: MarketplaceItem = { id: "test-item", name: "Test Item", @@ -172,8 +173,7 @@ describe("MarketplaceItemCard", () => { it("shows install button when no workspace is open", async () => { // Mock useExtensionState to simulate no workspace - // eslint-disable-next-line @typescript-eslint/no-require-imports - jest.spyOn(require("@/context/ExtensionStateContext"), "useExtensionState").mockReturnValue({ + vi.spyOn(await import("@/context/ExtensionStateContext"), "useExtensionState").mockReturnValue({ cwd: undefined, filePaths: [], } as any) diff --git a/webview-ui/src/components/marketplace/utils/__tests__/grouping.test.ts b/webview-ui/src/components/marketplace/utils/__tests__/grouping.test.ts deleted file mode 100644 index fe617cca08..0000000000 --- a/webview-ui/src/components/marketplace/utils/__tests__/grouping.test.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { groupItemsByType, formatItemText, getTotalItemCount, getUniqueTypes } from "../grouping" -import { MarketplaceItem } from "@roo-code/types" - -describe("grouping utilities", () => { - const mockItems: MarketplaceItem[] = [ - { - id: "test-server", - name: "Test Server", - description: "A test MCP server", - type: "mcp", - url: "https://example.com/test-server", - content: "test content", - }, - { - id: "test-mode", - name: "Test Mode", - description: "A test mode", - type: "mode", - content: "test content", - }, - { - id: "another-server", - name: "Another Server", - description: "Another test MCP server", - type: "mcp", - url: "https://example.com/another-server", - content: "test content", - }, - ] - - describe("groupItemsByType", () => { - it("should group items by type correctly", () => { - const result = groupItemsByType(mockItems) - - expect(Object.keys(result)).toHaveLength(2) - expect(result["mcp"].items).toHaveLength(2) - expect(result["mode"].items).toHaveLength(1) - - expect(result["mcp"].items[0].name).toBe("Test Server") - expect(result["mode"].items[0].name).toBe("Test Mode") - }) - - it("should handle empty items array", () => { - expect(groupItemsByType([])).toEqual({}) - expect(groupItemsByType(undefined)).toEqual({}) - }) - - it("should handle items with missing metadata", () => { - const itemsWithMissingData: MarketplaceItem[] = [ - { - id: "test-item", - name: "", - description: "", - type: "mcp", - url: "https://example.com/test-item", - content: "test content", - }, - ] - - const result = groupItemsByType(itemsWithMissingData) - expect(result["mcp"].items[0].name).toBe("Unnamed item") - }) - - it("should preserve item order within groups", () => { - const result = groupItemsByType(mockItems) - const servers = result["mcp"].items - - expect(servers[0].name).toBe("Test Server") - expect(servers[1].name).toBe("Another Server") - }) - - it("should skip items without type", () => { - const itemsWithoutType = [ - { - id: "test-item", - name: "Test Item", - description: "Test description", - type: undefined as any, // Force undefined type to test the skip logic - content: "test content", - }, - ] as MarketplaceItem[] - - const result = groupItemsByType(itemsWithoutType) - expect(Object.keys(result)).toHaveLength(0) - }) - }) - - describe("formatItemText", () => { - it("should format item with name and description", () => { - const item = { name: "Test", description: "Description" } - expect(formatItemText(item)).toBe("Test - Description") - }) - - it("should handle items without description", () => { - const item = { name: "Test" } - expect(formatItemText(item)).toBe("Test") - }) - }) - - describe("getTotalItemCount", () => { - it("should count total items across all groups", () => { - const groups = groupItemsByType(mockItems) - expect(getTotalItemCount(groups)).toBe(3) - }) - - it("should handle empty groups", () => { - expect(getTotalItemCount({})).toBe(0) - }) - }) - - describe("getUniqueTypes", () => { - it("should return sorted array of unique types", () => { - const groups = groupItemsByType(mockItems) - const types = getUniqueTypes(groups) - - expect(types).toEqual(["mcp", "mode"]) - }) - - it("should handle empty groups", () => { - expect(getUniqueTypes({})).toEqual([]) - }) - }) -}) diff --git a/webview-ui/src/components/marketplace/utils/grouping.ts b/webview-ui/src/components/marketplace/utils/grouping.ts deleted file mode 100644 index b2b4a9e9e6..0000000000 --- a/webview-ui/src/components/marketplace/utils/grouping.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { MarketplaceItem } from "@roo-code/types" - -export interface GroupedItems { - [type: string]: { - type: string - items: Array<{ - name: string - description?: string - metadata?: any - path?: string - matchInfo?: { - matched: boolean - matchReason?: Record - } - }> - } -} - -/** - * Groups package items by their type - * @param items Array of items to group - * @returns Object with items grouped by type - */ -export function groupItemsByType(items: MarketplaceItem[] = []): GroupedItems { - if (!items?.length) { - return {} - } - - const groups: GroupedItems = {} - - for (const item of items) { - if (!item.type) continue - - if (!groups[item.type]) { - groups[item.type] = { - type: item.type, - items: [], - } - } - - groups[item.type].items.push({ - name: item.name || "Unnamed item", - description: item.description, - metadata: undefined, - path: item.id, // Use id as path since MarketplaceItem doesn't have path - matchInfo: undefined, - }) - } - - return groups -} - -/** - * Gets a formatted string representation of an item - * @param item The item to format - * @returns Formatted string with name and description - */ -export function formatItemText(item: { name: string; description?: string }): string { - if (!item.description) { - return item.name - } - - const maxLength = 100 - const result = - item.name + - " - " + - (item.description.length > maxLength ? item.description.substring(0, maxLength) + "..." : item.description) - - return result -} - -/** - * Gets the total number of items across all groups - * @param groups Grouped items object - * @returns Total number of items - */ -export function getTotalItemCount(groups: GroupedItems): number { - return Object.values(groups).reduce((total, group) => total + group.items.length, 0) -} - -/** - * Gets an array of unique types from the grouped items - * @param groups Grouped items object - * @returns Array of type strings - */ -export function getUniqueTypes(groups: GroupedItems): string[] { - const types = Object.keys(groups) - types.sort() - return types -} diff --git a/webview-ui/src/components/mcp/__tests__/McpToolRow.test.tsx b/webview-ui/src/components/mcp/__tests__/McpToolRow.spec.tsx similarity index 93% rename from webview-ui/src/components/mcp/__tests__/McpToolRow.test.tsx rename to webview-ui/src/components/mcp/__tests__/McpToolRow.spec.tsx index 87323d1e91..43889c3cc5 100644 --- a/webview-ui/src/components/mcp/__tests__/McpToolRow.test.tsx +++ b/webview-ui/src/components/mcp/__tests__/McpToolRow.spec.tsx @@ -1,10 +1,11 @@ import React from "react" import { render, fireEvent, screen } from "@testing-library/react" -import McpToolRow from "../McpToolRow" + import { vscode } from "@src/utils/vscode" -// Mock the translation hook -jest.mock("@src/i18n/TranslationContext", () => ({ +import McpToolRow from "../McpToolRow" + +vi.mock("@src/i18n/TranslationContext", () => ({ useAppTranslation: () => ({ t: (key: string) => { const translations: Record = { @@ -17,13 +18,13 @@ jest.mock("@src/i18n/TranslationContext", () => ({ }), })) -jest.mock("@src/utils/vscode", () => ({ +vi.mock("@src/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vi.fn(), }, })) -jest.mock("@vscode/webview-ui-toolkit/react", () => ({ +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ VSCodeCheckbox: function MockVSCodeCheckbox({ children, checked, @@ -50,7 +51,7 @@ describe("McpToolRow", () => { } beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("renders tool name and description", () => { @@ -100,7 +101,7 @@ describe("McpToolRow", () => { }) it("prevents event propagation when clicking the checkbox", () => { - const mockOnClick = jest.fn() + const mockOnClick = vi.fn() render(
diff --git a/webview-ui/src/components/modes/__tests__/ModesView.test.tsx b/webview-ui/src/components/modes/__tests__/ModesView.spec.tsx similarity index 80% rename from webview-ui/src/components/modes/__tests__/ModesView.test.tsx rename to webview-ui/src/components/modes/__tests__/ModesView.spec.tsx index ea21c72410..47ff05613c 100644 --- a/webview-ui/src/components/modes/__tests__/ModesView.test.tsx +++ b/webview-ui/src/components/modes/__tests__/ModesView.spec.tsx @@ -1,4 +1,4 @@ -// npx jest src/components/prompts/__tests__/PromptsView.test.tsx +// npx vitest src/components/modes/__tests__/ModesView.spec.tsx import { render, screen, fireEvent, waitFor } from "@testing-library/react" import ModesView from "../ModesView" @@ -6,9 +6,9 @@ import { ExtensionStateContext } from "@src/context/ExtensionStateContext" import { vscode } from "@src/utils/vscode" // Mock vscode API -jest.mock("@src/utils/vscode", () => ({ +vitest.mock("@src/utils/vscode", () => ({ vscode: { - postMessage: jest.fn(), + postMessage: vitest.fn(), }, })) @@ -19,17 +19,17 @@ const mockExtensionState = { { id: "config2", name: "Config 2" }, ], enhancementApiConfigId: "", - setEnhancementApiConfigId: jest.fn(), + setEnhancementApiConfigId: vitest.fn(), mode: "code", customModes: [], customSupportPrompts: [], currentApiConfigName: "", customInstructions: "Initial instructions", - setCustomInstructions: jest.fn(), + setCustomInstructions: vitest.fn(), } const renderPromptsView = (props = {}) => { - const mockOnDone = jest.fn() + const mockOnDone = vitest.fn() return render( @@ -37,19 +37,11 @@ const renderPromptsView = (props = {}) => { ) } -class MockResizeObserver { - observe() {} - unobserve() {} - disconnect() {} -} - -global.ResizeObserver = MockResizeObserver - -Element.prototype.scrollIntoView = jest.fn() +Element.prototype.scrollIntoView = vitest.fn() describe("PromptsView", () => { beforeEach(() => { - jest.clearAllMocks() + vitest.clearAllMocks() }) it("displays the current mode name in the select trigger", () => { @@ -105,10 +97,18 @@ describe("PromptsView", () => { // Get the textarea const textarea = await waitFor(() => screen.getByTestId("code-prompt-textarea")) - fireEvent.change(textarea, { - target: { value: "New prompt value" }, + + // Simulate VSCode TextArea change event + const changeEvent = new CustomEvent("change", { + detail: { + target: { + value: "New prompt value", + }, + }, }) + fireEvent(textarea, changeEvent) + expect(vscode.postMessage).toHaveBeenCalledWith({ type: "updatePrompt", promptMode: "code", @@ -128,7 +128,7 @@ describe("PromptsView", () => { const { unmount } = render( - + , ) @@ -151,7 +151,7 @@ describe("PromptsView", () => { render( - + , ) @@ -160,7 +160,7 @@ describe("PromptsView", () => { }) it("handles clearing custom instructions correctly", async () => { - const setCustomInstructions = jest.fn() + const setCustomInstructions = vitest.fn() renderPromptsView({ ...mockExtensionState, customInstructions: "Initial instructions", @@ -168,10 +168,20 @@ describe("PromptsView", () => { }) const textarea = screen.getByTestId("global-custom-instructions-textarea") - fireEvent.change(textarea, { - target: { value: "" }, + + // Simulate VSCode TextArea change event with empty value + // We need to simulate both the CustomEvent format and regular event format + // since the component handles both + Object.defineProperty(textarea, "value", { + writable: true, + value: "", }) + const changeEvent = new Event("change", { bubbles: true }) + fireEvent(textarea, changeEvent) + + // The component calls setCustomInstructions with value || undefined + // Since empty string is falsy, it should be undefined expect(setCustomInstructions).toHaveBeenCalledWith(undefined) expect(vscode.postMessage).toHaveBeenCalledWith({ type: "customInstructions", diff --git a/webview-ui/src/components/settings/ApiConfigManager.tsx b/webview-ui/src/components/settings/ApiConfigManager.tsx index ddcfae49b3..d0a0a6aa44 100644 --- a/webview-ui/src/components/settings/ApiConfigManager.tsx +++ b/webview-ui/src/components/settings/ApiConfigManager.tsx @@ -54,6 +54,7 @@ const ApiConfigManager = ({ const inputRef = useRef(null) const newProfileInputRef = useRef(null) const searchInputRef = useRef(null) + const searchResetTimeoutRef = useRef(null) // Check if a profile is valid based on the organization allow list const isProfileValid = (profile: ProviderSettingsEntry): boolean => { @@ -127,15 +128,29 @@ const ApiConfigManager = ({ resetCreateState() resetRenameState() // Reset search value when current profile changes - setTimeout(() => setSearchValue(""), 100) + const timeoutId = setTimeout(() => setSearchValue(""), 100) + return () => clearTimeout(timeoutId) }, [currentApiConfigName]) + // Cleanup timeout on unmount + useEffect(() => { + return () => { + if (searchResetTimeoutRef.current) { + clearTimeout(searchResetTimeoutRef.current) + } + } + }, []) + const onOpenChange = (open: boolean) => { setOpen(open) // Reset search when closing the popover if (!open) { - setTimeout(() => setSearchValue(""), 100) + // Clear any existing timeout + if (searchResetTimeoutRef.current) { + clearTimeout(searchResetTimeoutRef.current) + } + searchResetTimeoutRef.current = setTimeout(() => setSearchValue(""), 100) } } diff --git a/webview-ui/src/components/settings/__tests__/ApiConfigManager.test.tsx b/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx similarity index 96% rename from webview-ui/src/components/settings/__tests__/ApiConfigManager.test.tsx rename to webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx index 37cbdabcda..553f60c79e 100644 --- a/webview-ui/src/components/settings/__tests__/ApiConfigManager.test.tsx +++ b/webview-ui/src/components/settings/__tests__/ApiConfigManager.spec.tsx @@ -1,11 +1,11 @@ -// npx jest src/components/settings/__tests__/ApiConfigManager.test.tsx +// npx vitest src/components/settings/__tests__/ApiConfigManager.spec.tsx import { render, screen, fireEvent, within } from "@testing-library/react" import ApiConfigManager from "../ApiConfigManager" // Mock VSCode components -jest.mock("@vscode/webview-ui-toolkit/react", () => ({ +vitest.mock("@vscode/webview-ui-toolkit/react", () => ({ VSCodeTextField: ({ value, onInput, placeholder, onKeyDown, "data-testid": dataTestId }: any) => ( ({ ), })) -jest.mock("@/components/ui", () => ({ - ...jest.requireActual("@/components/ui"), +vitest.mock("@/components/ui", () => ({ + ...vitest.importActual("@/components/ui"), Dialog: ({ children, open }: any) => (
{children} @@ -91,10 +91,10 @@ jest.mock("@/components/ui", () => ({ })) describe("ApiConfigManager", () => { - const mockOnSelectConfig = jest.fn() - const mockOnDeleteConfig = jest.fn() - const mockOnRenameConfig = jest.fn() - const mockOnUpsertConfig = jest.fn() + const mockOnSelectConfig = vitest.fn() + const mockOnDeleteConfig = vitest.fn() + const mockOnRenameConfig = vitest.fn() + const mockOnUpsertConfig = vitest.fn() const defaultProps = { currentApiConfigName: "Default Config", @@ -109,7 +109,7 @@ describe("ApiConfigManager", () => { } beforeEach(() => { - jest.clearAllMocks() + vitest.clearAllMocks() }) const getRenameForm = () => screen.getByTestId("rename-form") diff --git a/webview-ui/src/components/settings/__tests__/ApiOptions.test.tsx b/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx similarity index 94% rename from webview-ui/src/components/settings/__tests__/ApiOptions.test.tsx rename to webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx index 17421d3960..31cc2ec82f 100644 --- a/webview-ui/src/components/settings/__tests__/ApiOptions.test.tsx +++ b/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx @@ -1,4 +1,4 @@ -// npx jest src/components/settings/__tests__/ApiOptions.test.tsx +// npx vitest src/components/settings/__tests__/ApiOptions.spec.tsx import { render, screen, fireEvent } from "@testing-library/react" import { QueryClient, QueryClientProvider } from "@tanstack/react-query" @@ -10,7 +10,7 @@ import { ExtensionStateContextProvider } from "@src/context/ExtensionStateContex import ApiOptions, { ApiOptionsProps } from "../ApiOptions" // Mock VSCode components -jest.mock("@vscode/webview-ui-toolkit/react", () => ({ +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ VSCodeTextField: ({ children, value, onBlur }: any) => (
{children} @@ -24,7 +24,7 @@ jest.mock("@vscode/webview-ui-toolkit/react", () => ({ })) // Mock other components -jest.mock("vscrui", () => ({ +vi.mock("vscrui", () => ({ Checkbox: ({ children, checked, onChange }: any) => (