fix misskey-js tests (unit and type)

This commit is contained in:
Hazelnoot 2025-10-01 14:49:43 -04:00
parent 02e80f6ea6
commit 5d645bd7ca
13 changed files with 60 additions and 201 deletions

View file

@ -1,23 +0,0 @@
{
"$schema": "https://swc.rs/schema.json",
"jsc": {
"parser": {
"syntax": "typescript",
"dynamicImport": true,
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"experimental": {
"keepImportAssertions": true
},
"baseUrl": "src",
"paths": {
"@/*": ["*"]
},
"target": "es2022"
},
"minify": false
}

View file

@ -45,7 +45,7 @@
* *
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName> * SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
*/ */
"mainEntryPointFilePath": "<projectFolder>/built/index.d.ts", "mainEntryPointFilePath": "<projectFolder>/built/src/index.d.ts",
/** /**
* A list of NPM package names whose exports should be treated as part of this package. * A list of NPM package names whose exports should be treated as part of this package.

View file

@ -1,109 +0,0 @@
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import * as esbuild from 'esbuild';
import { build } from 'esbuild';
import { globSync } from 'glob';
import { execa } from 'execa';
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
const _package = JSON.parse(fs.readFileSync(_dirname + '/package.json', 'utf-8'));
const entryPoints = globSync('./src/**/**.{ts,tsx}');
/** @type {import('esbuild').BuildOptions} */
const options = {
entryPoints,
minify: process.env.NODE_ENV === 'production',
outdir: './built',
target: 'es2022',
platform: 'browser',
format: 'esm',
sourcemap: 'linked',
};
// built配下をすべて削除する
const args = process.argv.slice(2).map(arg => arg.toLowerCase());
// built配下をすべて削除する
if (!args.includes('--no-clean')) {
fs.rmSync('./built', { recursive: true, force: true });
}
if (args.includes('--watch')) {
await watchSrc();
} else {
await buildSrc();
}
async function buildSrc() {
console.log(`[${_package.name}] start building...`);
await build(options)
.then(() => {
console.log(`[${_package.name}] build succeeded.`);
})
.catch((err) => {
process.stderr.write(err.stderr);
process.exit(1);
});
if (process.env.NODE_ENV === 'production') {
console.log(`[${_package.name}] skip building d.ts because NODE_ENV is production.`);
} else {
await buildDts();
}
console.log(`[${_package.name}] finish building.`);
}
function buildDts() {
return execa(
'tsc',
[
'--project', 'tsconfig.json',
'--outDir', 'built',
'--declaration', 'true',
'--emitDeclarationOnly', 'true',
],
{
stdout: process.stdout,
stderr: process.stderr,
},
);
}
async function watchSrc() {
const plugins = [{
name: 'gen-dts',
setup(build) {
build.onStart(() => {
console.log(`[${_package.name}] detect changed...`);
});
build.onEnd(async result => {
if (result.errors.length > 0) {
console.error(`[${_package.name}] watch build failed:`, result);
return;
}
await buildDts();
});
},
}];
console.log(`[${_package.name}] start watching...`);
const context = await esbuild.context({ ...options, plugins });
await context.watch();
await new Promise((resolve, reject) => {
process.on('SIGHUP', resolve);
process.on('SIGINT', resolve);
process.on('SIGTERM', resolve);
process.on('uncaughtExceptionMonitor', reject);
process.on('exit', resolve);
}).finally(async () => {
await context.dispose();
console.log(`[${_package.name}] finish watching.`);
});
}

View file

@ -18,10 +18,11 @@ export default [
'**/built/', '**/built/',
'**/coverage/', '**/coverage/',
'**/node_modules/', '**/node_modules/',
'scripts',
], ],
}, },
{ {
files: ['**/*.ts', '**/*.tsx'], files: ['src/**/*.ts', 'src/**/*.tsx'],
languageOptions: { languageOptions: {
parserOptions: { parserOptions: {
parser: tsParser, parser: tsParser,

View file

@ -2775,7 +2775,7 @@ type IResponse = operations['i']['responses']['200']['content']['application/jso
type IRevokeTokenRequest = operations['i___revoke-token']['requestBody']['content']['application/json']; type IRevokeTokenRequest = operations['i___revoke-token']['requestBody']['content']['application/json'];
// @public (undocumented) // @public (undocumented)
function isAPIError(reason: Record<PropertyKey, unknown>): reason is APIError; function isAPIError(reason: unknown): reason is APIError;
// @public (undocumented) // @public (undocumented)
type ISharedAccessListRequest = operations['i___shared-access___list']['requestBody']['content']['application/json']; type ISharedAccessListRequest = operations['i___shared-access___list']['requestBody']['content']['application/json'];
@ -3725,7 +3725,7 @@ type SponsorsResponse = operations['sponsors']['responses']['200']['content']['a
// @public (undocumented) // @public (undocumented)
type StatsResponse = operations['stats']['responses']['200']['content']['application/json']; type StatsResponse = operations['stats']['responses']['200']['content']['application/json'];
// @public (undocumented) // @public
export class Stream extends EventEmitter<StreamEvents> implements IStream { export class Stream extends EventEmitter<StreamEvents> implements IStream {
constructor(origin: string, user: { constructor(origin: string, user: {
token: string; token: string;
@ -3733,7 +3733,6 @@ export class Stream extends EventEmitter<StreamEvents> implements IStream {
WebSocket?: Options['WebSocket']; WebSocket?: Options['WebSocket'];
binaryType?: ReconnectingWebSocket['binaryType']; binaryType?: ReconnectingWebSocket['binaryType'];
}); });
// (undocumented)
close(): void; close(): void;
// (undocumented) // (undocumented)
disconnectToChannel(connection: NonSharedConnection): void; disconnectToChannel(connection: NonSharedConnection): void;
@ -3745,7 +3744,6 @@ export class Stream extends EventEmitter<StreamEvents> implements IStream {
removeSharedConnection(connection: SharedConnection): void; removeSharedConnection(connection: SharedConnection): void;
// (undocumented) // (undocumented)
removeSharedConnectionPool(pool: Pool): void; removeSharedConnectionPool(pool: Pool): void;
// (undocumented)
send(typeOrPayload: string): void; send(typeOrPayload: string): void;
// (undocumented) // (undocumented)
send(typeOrPayload: string, payload: unknown): void; send(typeOrPayload: string, payload: unknown): void;

View file

@ -4,26 +4,17 @@
"version": "2025.5.2-dev", "version": "2025.5.2-dev",
"description": "Misskey SDK for JavaScript", "description": "Misskey SDK for JavaScript",
"license": "MIT", "license": "MIT",
"main": "./built/index.js", "main": "./built/src/index.js",
"types": "./built/index.d.ts", "types": "./built/src/index.d.ts",
"exports": {
".": {
"import": "./built/index.js",
"types": "./built/index.d.ts"
},
"./*": {
"import": "./built/*",
"types": "./built/*"
}
},
"scripts": { "scripts": {
"build": "node ./build.js", "clean": "node scripts/clean.mjs",
"watch": "nodemon -w package.json -e json --exec \"node ./build.js --watch\"", "build": "tsc -b && ncp test-d ./built/test-d",
"tsd": "tsd", "rebuild": "pnpm clean && pnpm build",
"tsd": "tsd --files \"./built/test-d/**/*.ts\"",
"api": "pnpm api-extractor run --local --verbose", "api": "pnpm api-extractor run --local --verbose",
"api-prod": "pnpm api-extractor run --verbose", "api-prod": "pnpm api-extractor run --verbose",
"eslint": "eslint --quiet \"{src,test,js,@types}/**/*.{js,jsx,ts,tsx,vue}\" --cache", "eslint": "eslint --quiet \"{src,test,test-d,scripts}/**/*.{js,jsx,ts,tsx,vue}\" --cache",
"typecheck": "tsc --noEmit", "typecheck": "tsc -b --noEmit",
"lint": "pnpm typecheck && pnpm eslint", "lint": "pnpm typecheck && pnpm eslint",
"jest": "jest --coverage --detectOpenHandles", "jest": "jest --coverage --detectOpenHandles",
"test": "pnpm jest && pnpm tsd", "test": "pnpm jest && pnpm tsd",
@ -31,13 +22,12 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/misskey-dev/misskey.git", "url": "https://activitypub.software/TransFem-org/Sharkey.git",
"directory": "packages/misskey-js" "directory": "packages/misskey-js"
}, },
"devDependencies": { "devDependencies": {
"@microsoft/api-extractor": "7.52.5", "@microsoft/api-extractor": "7.52.5",
"@simplewebauthn/types": "12.0.0", "@simplewebauthn/types": "12.0.0",
"@swc/jest": "0.2.38",
"@types/jest": "29.5.14", "@types/jest": "29.5.14",
"@types/node": "22.15.2", "@types/node": "22.15.2",
"@typescript-eslint/eslint-plugin": "8.31.0", "@typescript-eslint/eslint-plugin": "8.31.0",
@ -47,15 +37,11 @@
"jest-websocket-mock": "2.5.0", "jest-websocket-mock": "2.5.0",
"mock-socket": "9.3.1", "mock-socket": "9.3.1",
"ncp": "2.0.0", "ncp": "2.0.0",
"nodemon": "3.1.10",
"execa": "9.5.2",
"tsd": "0.32.0", "tsd": "0.32.0",
"typescript": "5.8.3", "typescript": "5.8.3"
"esbuild": "0.25.3",
"glob": "11.0.2"
}, },
"files": [ "files": [
"built" "built/src"
], ],
"dependencies": { "dependencies": {
"eventemitter3": "5.0.1", "eventemitter3": "5.0.1",

View file

@ -0,0 +1,5 @@
import * as nodepath from 'path';
export const scriptsDir = import.meta.dirname;
export const rootDir = nodepath.join(scriptsDir, '../');
export const outDir = nodepath.join(rootDir, './built');

View file

@ -0,0 +1,5 @@
import { rm } from 'fs/promises';
import { outDir } from './_common.mjs';
console.log(`Cleaning ${outDir}...`);
await rm(outDir, { recursive: true, force: true });

View file

@ -18,7 +18,11 @@ export type APIError = {
info: Record<string, any>; info: Record<string, any>;
}; };
export function isAPIError(reason: Record<PropertyKey, unknown>): reason is APIError { export function isAPIError(reason: unknown): reason is APIError {
if (reason == null) return false;
if (typeof(reason) !== 'object') return false;
if (!(MK_API_ERROR in reason)) return false;
if (typeof(reason[MK_API_ERROR]) !== 'boolean') return false;
return reason[MK_API_ERROR] === true; return reason[MK_API_ERROR] === true;
} }

View file

@ -5,7 +5,7 @@
import { nyaize } from '../src/nyaize.js'; import { nyaize } from '../src/nyaize.js';
function runTests(cases) { function runTests(cases: [string, string][]) {
for (const c of cases) { for (const c of cases) {
const [input,expected] = c; const [input,expected] = c;
const got = nyaize(input); const got = nyaize(input);

View file

@ -1,4 +1,4 @@
import WS from 'jest-websocket-mock'; import { WS } from 'jest-websocket-mock';
import Stream from '../src/streaming.js'; import Stream from '../src/streaming.js';
describe('Streaming', () => { describe('Streaming', () => {
@ -43,7 +43,7 @@ describe('Streaming', () => {
const server = new WS('wss://misskey.test/streaming'); const server = new WS('wss://misskey.test/streaming');
const stream = new Stream('https://misskey.test', { token: 'TOKEN' }); const stream = new Stream('https://misskey.test', { token: 'TOKEN' });
const chatChannelReceived: any[] = []; const chatChannelReceived: any[] = [];
const chat = stream.useChannel('chat', { other: 'aaa' }); const chat = stream.useChannel('chatUser', { otherId: 'aaa' });
chat.on('message', payload => { chat.on('message', payload => {
chatChannelReceived.push(payload); chatChannelReceived.push(payload);
}); });
@ -54,8 +54,8 @@ describe('Streaming', () => {
const msg = JSON.parse(await server.nextMessage as string); const msg = JSON.parse(await server.nextMessage as string);
const chatChannelId = msg.body.id; const chatChannelId = msg.body.id;
expect(msg.type).toEqual('connect'); expect(msg.type).toEqual('connect');
expect(msg.body.channel).toEqual('chat'); expect(msg.body.channel).toEqual('chatUser');
expect(msg.body.params).toEqual({ other: 'aaa' }); expect(msg.body.params).toEqual({ otherId: 'aaa' });
expect(chatChannelId != null).toEqual(true); expect(chatChannelId != null).toEqual(true);
server.send(JSON.stringify({ server.send(JSON.stringify({
@ -81,8 +81,8 @@ describe('Streaming', () => {
const server = new WS('wss://misskey.test/streaming'); const server = new WS('wss://misskey.test/streaming');
const stream = new Stream('https://misskey.test', { token: 'TOKEN' }); const stream = new Stream('https://misskey.test', { token: 'TOKEN' });
stream.useChannel('chat', { other: 'aaa' }); stream.useChannel('chatUser', { otherId: 'aaa' });
stream.useChannel('chat', { other: 'bbb' }); stream.useChannel('chatUser', { otherId: 'bbb' });
const ws = await server.connected; const ws = await server.connected;
expect(new URLSearchParams(new URL(ws.url).search).get('i')).toEqual('TOKEN'); expect(new URLSearchParams(new URL(ws.url).search).get('i')).toEqual('TOKEN');
@ -104,7 +104,7 @@ describe('Streaming', () => {
const server = new WS('wss://misskey.test/streaming'); const server = new WS('wss://misskey.test/streaming');
const stream = new Stream('https://misskey.test', { token: 'TOKEN' }); const stream = new Stream('https://misskey.test', { token: 'TOKEN' });
const chat = stream.useChannel('chat', { other: 'aaa' }); const chat = stream.useChannel('chatUser', { otherId: 'aaa' });
chat.send('read', { id: 'aaa' }); chat.send('read', { id: 'aaa' });
const ws = await server.connected; const ws = await server.connected;

View file

@ -6,9 +6,11 @@
"moduleResolution": "nodenext", "moduleResolution": "nodenext",
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,
"sourceMap": false, "sourceMap": true,
"inlineSources": true,
"allowJs": true,
"checkJs": true,
"outDir": "./built/", "outDir": "./built/",
"removeComments": true,
"strict": true, "strict": true,
"strictFunctionTypes": true, "strictFunctionTypes": true,
"strictNullChecks": true, "strictNullChecks": true,
@ -16,21 +18,26 @@
"noImplicitReturns": true, "noImplicitReturns": true,
"esModuleInterop": true, "esModuleInterop": true,
"exactOptionalPropertyTypes": true, "exactOptionalPropertyTypes": true,
"skipLibCheck": true, "rootDir": ".",
"incremental": true, "incremental": true,
"composite": true,
"typeRoots": [ "typeRoots": [
"./node_modules/@types" "./node_modules/@types"
], ],
"lib": [ "lib": [
"esnext", "esnext",
"dom" "dom",
"dom.iterable" // https://dev.to/deciduously/formdata-in-typescript-24cl
] ]
}, },
"compileOnSave": false,
"include": [ "include": [
"src/**/*" "src/**/*",
"test/**/*",
"test-d/**/*",
"scripts/**/*",
], ],
"exclude": [ "exclude": [
"node_modules", "node_modules"
"test/**/*"
] ]
} }

29
pnpm-lock.yaml generated
View file

@ -938,7 +938,7 @@ importers:
version: 5.2.3(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.14(typescript@5.8.3)) version: 5.2.3(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.14(typescript@5.8.3))
'@vitest/coverage-v8': '@vitest/coverage-v8':
specifier: 3.1.2 specifier: 3.1.2
version: 3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0)(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) version: 3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))
'@vue/compiler-core': '@vue/compiler-core':
specifier: 3.5.14 specifier: 3.5.14
version: 3.5.14 version: 3.5.14
@ -1040,7 +1040,7 @@ importers:
version: 1.0.3 version: 1.0.3
vitest: vitest:
specifier: 3.1.2 specifier: 3.1.2
version: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0)(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) version: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)
vitest-fetch-mock: vitest-fetch-mock:
specifier: 0.4.5 specifier: 0.4.5
version: 0.4.5(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) version: 0.4.5(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))
@ -1140,7 +1140,7 @@ importers:
version: 5.2.3(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.14(typescript@5.8.3)) version: 5.2.3(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.14(typescript@5.8.3))
'@vitest/coverage-v8': '@vitest/coverage-v8':
specifier: 3.1.2 specifier: 3.1.2
version: 3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0)(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) version: 3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))
'@vue/compiler-sfc': '@vue/compiler-sfc':
specifier: 3.5.14 specifier: 3.5.14
version: 3.5.14 version: 3.5.14
@ -1346,9 +1346,6 @@ importers:
'@simplewebauthn/types': '@simplewebauthn/types':
specifier: 12.0.0 specifier: 12.0.0
version: 12.0.0 version: 12.0.0
'@swc/jest':
specifier: 0.2.38
version: 0.2.38(@swc/core@1.11.24)
'@types/jest': '@types/jest':
specifier: 29.5.14 specifier: 29.5.14
version: 29.5.14 version: 29.5.14
@ -1361,15 +1358,6 @@ importers:
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: 8.31.0 specifier: 8.31.0
version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) version: 8.31.0(eslint@9.25.1)(typescript@5.8.3)
esbuild:
specifier: 0.25.3
version: 0.25.3
execa:
specifier: 9.5.2
version: 9.5.2
glob:
specifier: 11.0.2
version: 11.0.2
jest: jest:
specifier: 29.7.0 specifier: 29.7.0
version: 29.7.0(@types/node@22.15.2) version: 29.7.0(@types/node@22.15.2)
@ -1385,9 +1373,6 @@ importers:
ncp: ncp:
specifier: 2.0.0 specifier: 2.0.0
version: 2.0.0 version: 2.0.0
nodemon:
specifier: 3.1.10
version: 3.1.10
tsd: tsd:
specifier: 0.32.0 specifier: 0.32.0
version: 0.32.0 version: 0.32.0
@ -14674,7 +14659,7 @@ snapshots:
vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)
vue: 3.5.14(typescript@5.8.3) vue: 3.5.14(typescript@5.8.3)
'@vitest/coverage-v8@3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0)(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))': '@vitest/coverage-v8@3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))':
dependencies: dependencies:
'@ampproject/remapping': 2.3.0 '@ampproject/remapping': 2.3.0
'@bcoe/v8-coverage': 1.0.2 '@bcoe/v8-coverage': 1.0.2
@ -14688,7 +14673,7 @@ snapshots:
std-env: 3.9.0 std-env: 3.9.0
test-exclude: 7.0.1 test-exclude: 7.0.1
tinyrainbow: 2.0.0 tinyrainbow: 2.0.0
vitest: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0)(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) vitest: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -21764,9 +21749,9 @@ snapshots:
vitest-fetch-mock@0.4.5(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)): vitest-fetch-mock@0.4.5(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)):
dependencies: dependencies:
vitest: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0)(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) vitest: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)
vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0)(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3): vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3):
dependencies: dependencies:
'@vitest/expect': 3.1.2 '@vitest/expect': 3.1.2
'@vitest/mocker': 3.1.2(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) '@vitest/mocker': 3.1.2(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))