diff --git a/eslint.config.mjs b/eslint.config.mjs index a5abacc22809..198d22ef5f33 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -390,6 +390,18 @@ export default tseslint.config( }, settings: { vitest: { typecheck: true } }, }, + { + files: ['packages/*/tests/**/vitest-custom-matchers.d.ts'], + name: 'vitest-custom-matchers-declaration-files', + rules: { + '@typescript-eslint/no-empty-object-type': [ + 'error', + { allowInterfaces: 'with-single-extends' }, + ], + + '@typescript-eslint/no-explicit-any': 'off', + }, + }, // plugin rule tests { files: [ diff --git a/knip.ts b/knip.ts index 1056f78dc743..0c53742d0247 100644 --- a/knip.ts +++ b/knip.ts @@ -96,6 +96,15 @@ export default { }, 'packages/type-utils': { ignore: ['tests/fixtures/**', 'typings/typescript.d.ts'], + + vitest: { + config: ['vitest.config.mts'], + entry: [ + 'tests/**/*.{bench,test,test-d}.?(c|m)ts?(x)', + 'tests/test-utils/custom-matchers/custom-matchers.ts', + 'tests/test-utils/custom-matchers/vitest-custom-matchers.d.ts', + ], + }, }, 'packages/typescript-estree': { entry: ['src/use-at-your-own-risk.ts'], diff --git a/package.json b/package.json index 624fa884fb48..0e9a710ff72c 100644 --- a/package.json +++ b/package.json @@ -82,8 +82,8 @@ "@typescript-eslint/types": "workspace:^", "@typescript-eslint/typescript-estree": "workspace:^", "@typescript-eslint/utils": "workspace:^", - "@vitest/coverage-v8": "^3.1.1", - "@vitest/eslint-plugin": "^1.1.43", + "@vitest/coverage-v8": "^3.1.2", + "@vitest/eslint-plugin": "^1.1.44", "console-fail-test": "^0.5.0", "cross-fetch": "^4.0.0", "cspell": "^8.15.2", @@ -114,8 +114,8 @@ "tsx": "*", "typescript": ">=4.8.4 <5.9.0", "typescript-eslint": "workspace:^", - "vite": "^6.3.3", - "vitest": "^3.1.1", + "vite": "^6.3.4", + "vitest": "^3.1.2", "yargs": "17.7.2" }, "resolutions": { diff --git a/packages/ast-spec/package.json b/packages/ast-spec/package.json index 0e79574cb489..25022d597fc5 100644 --- a/packages/ast-spec/package.json +++ b/packages/ast-spec/package.json @@ -50,13 +50,13 @@ "@babel/eslint-parser": "*", "@microsoft/api-extractor": "^7.47.11", "@typescript-eslint/typescript-estree": "workspace:*", - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "glob": "*", "jest-diff": "^29.7.0", "prettier": "^3.2.5", "pretty-format": "*", "rimraf": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" } } diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 2446f9acb6a3..7df8ec9e5418 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -31,8 +31,8 @@ "prettier": "^3.2.5" }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "rimraf": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" } } diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 79aa9f997102..ce594cb746d9 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -77,7 +77,7 @@ "@types/natural-compare": "*", "@typescript-eslint/rule-schema-to-typescript-types": "8.31.1", "@typescript-eslint/rule-tester": "8.31.1", - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "ajv": "^6.12.6", "cross-fetch": "*", "eslint": "*", @@ -93,7 +93,7 @@ "tsx": "*", "typescript": "*", "unist-util-visit": "^5.0.0", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index c1298201a5a8..0e9edffb45b4 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -18,7 +18,7 @@ "check-types": "npx nx typecheck" }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", - "vitest": "^3.1.1" + "@vitest/coverage-v8": "^3.1.2", + "vitest": "^3.1.2" } } diff --git a/packages/parser/package.json b/packages/parser/package.json index 3d1c4cfbca4a..f537dc12f16f 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -59,12 +59,12 @@ "debug": "^4.3.4" }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "glob": "*", "prettier": "^3.2.5", "rimraf": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/packages/rule-schema-to-typescript-types/package.json b/packages/rule-schema-to-typescript-types/package.json index 17e809154e59..8a19a7231e6a 100644 --- a/packages/rule-schema-to-typescript-types/package.json +++ b/packages/rule-schema-to-typescript-types/package.json @@ -37,9 +37,9 @@ "prettier": "^3.2.5" }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/packages/rule-tester/package.json b/packages/rule-tester/package.json index dbffde6687a2..e7c7fd936f01 100644 --- a/packages/rule-tester/package.json +++ b/packages/rule-tester/package.json @@ -61,8 +61,8 @@ "devDependencies": { "@types/json-stable-stringify-without-jsonify": "^1.0.2", "@types/lodash.merge": "4.6.9", - "@vitest/coverage-v8": "^3.1.1", - "chai": "^4.4.1", + "@vitest/coverage-v8": "^3.1.2", + "chai": "^5.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esprima": "^4.0.1", @@ -70,7 +70,7 @@ "sinon": "^16.1.3", "source-map-support": "^0.5.21", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index 0756ca897e67..0563db56f86f 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -52,12 +52,12 @@ }, "devDependencies": { "@typescript-eslint/typescript-estree": "8.31.1", - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "glob": "*", "prettier": "^3.2.5", "pretty-format": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/packages/type-utils/package.json b/packages/type-utils/package.json index 33dc30ee634f..e8637375930c 100644 --- a/packages/type-utils/package.json +++ b/packages/type-utils/package.json @@ -37,8 +37,7 @@ ], "scripts": { "build": "tsc -b tsconfig.build.json", - "clean": "tsc -b tsconfig.build.json --clean", - "postclean": "rimraf dist/ coverage/", + "clean": "rimraf dist/ coverage/", "format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore", "lint": "npx nx lint", "test": "vitest --run --config=$INIT_CWD/vitest.config.mts", @@ -56,12 +55,13 @@ }, "devDependencies": { "@typescript-eslint/parser": "8.31.1", - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "ajv": "^6.12.6", + "eslint": "*", "prettier": "^3.2.5", "rimraf": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/packages/type-utils/tests/TypeOrValueSpecifier.test.ts b/packages/type-utils/tests/TypeOrValueSpecifier.test.ts index 70ae2bda9313..a9cf0347a314 100644 --- a/packages/type-utils/tests/TypeOrValueSpecifier.test.ts +++ b/packages/type-utils/tests/TypeOrValueSpecifier.test.ts @@ -1,13 +1,8 @@ -import type { TSESTree } from '@typescript-eslint/utils'; -import type { TestContext } from 'vitest'; - -import { parseForESLint } from '@typescript-eslint/parser'; -import Ajv from 'ajv'; import path from 'node:path'; import type { TypeOrValueSpecifier } from '../src/TypeOrValueSpecifier'; -import { typeMatchesSpecifier, typeOrValueSpecifiersSchema } from '../src'; +import { typeMatchesSpecifier } from '../src'; const ROOT_DIR = path.posix.join( ...path.relative(process.cwd(), path.join(__dirname, '..')).split(path.sep), @@ -15,26 +10,11 @@ const ROOT_DIR = path.posix.join( describe('TypeOrValueSpecifier', () => { describe('Schema', () => { - const ajv = new Ajv(); - const validate = ajv.compile(typeOrValueSpecifiersSchema); - - function runTestPositive( - [typeOrValueSpecifier]: readonly [typeOrValueSpecifier: unknown], - { expect }: TestContext, - ): void { - expect(validate([typeOrValueSpecifier])).toBe(true); - } - - function runTestNegative( - [typeOrValueSpecifier]: readonly [typeOrValueSpecifier: unknown], - { expect }: TestContext, - ): void { - expect(validate([typeOrValueSpecifier])).toBe(false); - } - it.for([['MyType'], ['myValue'], ['any'], ['void'], ['never']] as const)( 'matches a simple string specifier %s', - runTestPositive, + ([typeOrValueSpecifier], { expect }) => { + expect([typeOrValueSpecifier]).toBeValidSpecifier(); + }, ); it.for([ @@ -44,41 +24,64 @@ describe('TypeOrValueSpecifier', () => { [undefined], [['MyType']], [(): void => {}], - ] as const)("doesn't match any non-string basic type: %s", runTestNegative); + ] as const)( + "doesn't match any non-string basic type: %s", + ([typeOrValueSpecifier], { expect }) => { + expect([typeOrValueSpecifier]).not.toBeValidSpecifier(); + }, + ); it.for([ [{ from: 'file', name: 'MyType' }], [{ from: 'file', name: ['MyType', 'myValue'] }], [{ from: 'file', name: 'MyType', path: './filename.js' }], [{ from: 'file', name: ['MyType', 'myValue'], path: './filename.js' }], - ] as const)('matches a file specifier: %s', runTestPositive); + ] as const)( + 'matches a file specifier: %s', + ([typeOrValueSpecifier], { expect }) => { + expect([typeOrValueSpecifier]).toBeValidSpecifier(); + }, + ); it.for([ [{ from: 'file', name: 42 }], [{ from: 'file', name: ['MyType', 42] }], [{ from: 'file', name: ['MyType', 'MyType'] }], [{ from: 'file', name: [] }], - [{ from: 'file', path: './filename.js' }], + [{ from: 'file', path: `${ROOT_DIR}/filename.js` }], [{ from: 'file', name: 'MyType', path: 42 }], - [{ from: 'file', name: ['MyType', 'MyType'], path: './filename.js' }], - [{ from: 'file', name: [], path: './filename.js' }], + [ + { + from: 'file', + name: ['MyType', 'MyType'], + path: `${ROOT_DIR}/filename.js`, + }, + ], + [{ from: 'file', name: [], path: `${ROOT_DIR}/filename.js` }], [ { from: 'file', name: ['MyType', 'myValue'], - path: ['./filename.js', './another-file.js'], + path: [`${ROOT_DIR}/filename.js`, `${ROOT_DIR}/another-file.js`], }, ], [{ from: 'file', name: 'MyType', unrelatedProperty: '' }], ] as const)( "doesn't match a malformed file specifier: %s", - runTestNegative, + ([typeOrValueSpecifier], { expect }) => { + expect([typeOrValueSpecifier]).not.toBeValidSpecifier(); + }, ); it.for([ [{ from: 'lib', name: 'MyType' }], [{ from: 'lib', name: ['MyType', 'myValue'] }], - ] as const)('matches a lib specifier: %s', runTestPositive); + ] as const)( + 'matches a lib specifier: %s', + ([typeOrValueSpecifier], { expect }) => { + expect([typeOrValueSpecifier]).toBeValidSpecifier(); + }, + ); it.for([ [{ from: 'lib', name: 42 }], @@ -87,7 +90,12 @@ describe('TypeOrValueSpecifier', () => { [{ from: 'lib', name: [] }], [{ from: 'lib' }], [{ from: 'lib', name: 'MyType', unrelatedProperty: '' }], - ] as const)("doesn't match a malformed lib specifier: %s", runTestNegative); + ] as const)( + "doesn't match a malformed lib specifier: %s", + ([typeOrValueSpecifier], { expect }) => { + expect([typeOrValueSpecifier]).not.toBeValidSpecifier(); + }, + ); it.for([ [{ from: 'package', name: 'MyType', package: 'jquery' }], @@ -98,7 +106,12 @@ describe('TypeOrValueSpecifier', () => { package: 'jquery', }, ], - ] as const)('matches a package specifier: %s', runTestPositive); + ] as const)( + 'matches a package specifier: %s', + ([typeOrValueSpecifier], { expect }) => { + expect([typeOrValueSpecifier]).toBeValidSpecifier(); + }, + ); it.for([ [{ from: 'package', name: 42, package: 'jquery' }], @@ -122,7 +135,7 @@ describe('TypeOrValueSpecifier', () => { { from: 'package', name: ['MyType', 'myValue'], - package: ['jquery', './another-file.js'], + package: ['jquery', `${ROOT_DIR}/another-file.js`], }, ], [ @@ -135,67 +148,21 @@ describe('TypeOrValueSpecifier', () => { ], ] as const)( "doesn't match a malformed package specifier: %s", - runTestNegative, + ([typeOrValueSpecifier], { expect }) => { + expect([typeOrValueSpecifier]).not.toBeValidSpecifier(); + }, ); }); describe(typeMatchesSpecifier, () => { - function runTests( - code: string, - specifier: TypeOrValueSpecifier, - expected: boolean, - expect: TestContext['expect'], - ): void { - const rootDir = path.join(__dirname, 'fixtures'); - const { ast, services } = parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); - const type = services - .program!.getTypeChecker() - .getTypeAtLocation( - services.esTreeNodeToTSNodeMap.get( - (ast.body[ast.body.length - 1] as TSESTree.TSTypeAliasDeclaration) - .id, - ), - ); - expect(typeMatchesSpecifier(type, specifier, services.program!)).toBe( - expected, - ); - } - - function runTestPositive( - [code, specifier]: readonly [ - code: string, - specifier: TypeOrValueSpecifier, - ], - testContext: Partial & Pick = { - expect, - }, - ): void { - runTests(code, specifier, true, testContext.expect); - } - - function runTestNegative( - [code, specifier]: readonly [ - code: string, - specifier: TypeOrValueSpecifier, - ], - testContext: Partial & Pick = { - expect, - }, - ): void { - runTests(code, specifier, false, testContext.expect); - } - it.for([ ['interface Foo {prop: string}; type Test = Foo;', 'Foo'], ['type Test = RegExp;', 'RegExp'], ] as const satisfies [string, TypeOrValueSpecifier][])( 'matches a matching universal string specifier', - runTestPositive, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -205,7 +172,9 @@ describe('TypeOrValueSpecifier', () => { ['type Test = RegExp;', 'BigInt'], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match a mismatched universal string specifier", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -279,7 +248,9 @@ describe('TypeOrValueSpecifier', () => { ], ] as const satisfies [string, TypeOrValueSpecifier][])( 'matches a matching file specifier: %s', - runTestPositive, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -293,19 +264,25 @@ describe('TypeOrValueSpecifier', () => { ], [ 'interface Foo {prop: string}; type Test = Foo;', - { from: 'file', name: 'Foo', path: 'tests/fixtures/wrong-file.ts' }, + { + from: 'file', + name: 'Foo', + path: `${ROOT_DIR}/tests/fixtures/wrong-file.ts`, + }, ], [ 'interface Foo {prop: string}; type Test = Foo;', { from: 'file', name: ['Foo', 'Bar'], - path: 'tests/fixtures/wrong-file.ts', + path: `${ROOT_DIR}/tests/fixtures/wrong-file.ts`, }, ], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match a mismatched file specifier: %s", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -313,7 +290,9 @@ describe('TypeOrValueSpecifier', () => { ['type Test = RegExp;', { from: 'lib', name: ['RegExp', 'BigInt'] }], ] as const satisfies [string, TypeOrValueSpecifier][])( 'matches a matching lib specifier: %s', - runTestPositive, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -321,7 +300,9 @@ describe('TypeOrValueSpecifier', () => { ['type Test = RegExp;', { from: 'lib', name: ['BigInt', 'Date'] }], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match a mismatched lib specifier: %s", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -329,7 +310,9 @@ describe('TypeOrValueSpecifier', () => { ['type Test = string;', { from: 'lib', name: ['string', 'number'] }], ] as const satisfies [string, TypeOrValueSpecifier][])( 'matches a matching intrinsic type specifier: %s', - runTestPositive, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -337,7 +320,9 @@ describe('TypeOrValueSpecifier', () => { ['type Test = string;', { from: 'lib', name: ['number', 'boolean'] }], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match a mismatched intrinsic type specifier: %s", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -422,7 +407,9 @@ describe('TypeOrValueSpecifier', () => { ], ] as const satisfies [string, TypeOrValueSpecifier][])( 'matches a matching package specifier: %s', - runTestPositive, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -445,7 +432,9 @@ describe('TypeOrValueSpecifier', () => { ], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match a mismatched type specifier for an intersection type: %s", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -459,7 +448,9 @@ describe('TypeOrValueSpecifier', () => { ], ] as const satisfies [string, TypeOrValueSpecifier][])( 'matches a matching type specifier for an intersection type: %s', - runTestPositive, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -484,7 +475,9 @@ describe('TypeOrValueSpecifier', () => { ], ] as const satisfies [string, TypeOrValueSpecifier][])( 'matches a matching package specifier for an intersection type: %s', - runTestPositive, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -509,24 +502,23 @@ describe('TypeOrValueSpecifier', () => { ], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match a mismatched package specifier for an intersection type: %s", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); it("does not match a `declare global` with the 'global' package name", () => { - runTestNegative([ - ` + expect(` declare global { export type URL = {}; } type Test = URL; - `, - { - from: 'package', - name: 'URL', - package: 'global', - }, - ]); + `).not.toMatchSpecifier({ + from: 'package', + name: 'URL', + package: 'global', + }); }); it.for([ @@ -556,7 +548,9 @@ describe('TypeOrValueSpecifier', () => { ], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match a mismatched package specifier: %s", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -619,7 +613,9 @@ describe('TypeOrValueSpecifier', () => { ], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match a mismatched specifier type: %s", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); it.for([ @@ -627,7 +623,9 @@ describe('TypeOrValueSpecifier', () => { ['type Test = Foo;', { from: 'lib', name: ['Foo', 'number'] }], ] as const satisfies [string, TypeOrValueSpecifier][])( "doesn't match an error type: %s", - runTestNegative, + ([code, typeOrValueSpecifier], { expect }) => { + expect(code).not.toMatchSpecifier(typeOrValueSpecifier); + }, ); }); }); diff --git a/packages/type-utils/tests/containsAllTypesByName.test.ts b/packages/type-utils/tests/containsAllTypesByName.test.ts index 351e5fb84c91..fba03d753881 100644 --- a/packages/type-utils/tests/containsAllTypesByName.test.ts +++ b/packages/type-utils/tests/containsAllTypesByName.test.ts @@ -1,116 +1,82 @@ -import type { TSESTree } from '@typescript-eslint/typescript-estree'; -import type * as ts from 'typescript'; -import type { TestContext } from 'vitest'; - -import { parseForESLint } from '@typescript-eslint/parser'; -import path from 'node:path'; - import { containsAllTypesByName } from '../src'; -import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; describe(containsAllTypesByName, () => { - const rootDir = path.join(__dirname, 'fixtures'); - - function getType(code: string): ts.Type { - const { ast, services } = parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); - expectToHaveParserServices(services); - const declaration = ast.body[0] as TSESTree.TSTypeAliasDeclaration; - return services.getTypeAtLocation(declaration.id); - } - describe('allowAny', () => { - function runTestForAliasDeclaration( - code: string, - allowAny: boolean, - expected: boolean, - { expect }: TestContext, - ): void { - const type = getType(code); - const result = containsAllTypesByName(type, allowAny, new Set()); - expect(result).toBe(expected); - } - describe('is true', () => { - function runTest( - [code, expected]: readonly [code: string, expected: boolean], - testContext: TestContext, - ): void { - runTestForAliasDeclaration(code, true, expected, testContext); - } + const options = { allowAny: true }; it.for([ - ['type Test = unknown;', false], - ['type Test = any;', false], - ['type Test = string;', false], - ] as const)('when code is "%s" expected is %s', runTest); + ['type Test = unknown;'], + ['type Test = any;'], + ['type Test = string;'], + ] as const)( + 'when code is "%s" it does not contain all types by name', + ([code], { expect }) => { + expect(code).not.toContainsAllTypesByName(options); + }, + ); }); describe('is false', () => { - function runTest( - [code, expected]: readonly [code: string, expected: boolean], - testContext: TestContext, - ): void { - runTestForAliasDeclaration(code, false, expected, testContext); - } + const options = { allowAny: false }; - it.for([ - ['type Test = unknown;', true], - ['type Test = any;', true], - ['type Test = string;', false], - ] as const)('when code is "%s" expected is %s', runTest); + it.for([['type Test = unknown;'], ['type Test = any;']] as const)( + 'when code is "%s" it contains all types by name', + ([code], { expect }) => { + expect(code).toContainsAllTypesByName(options); + }, + ); + + it.for([['type Test = string;']] as const)( + 'when code is "%s" it does not contain all types by name', + ([code], { expect }) => { + expect(code).not.toContainsAllTypesByName(options); + }, + ); }); }); describe('matchAnyInstead', () => { - function runTestForAliasDeclaration( - code: string, - matchAnyInstead: boolean, - expected: boolean, - { expect }: TestContext, - ): void { - const type = getType(code); - const result = containsAllTypesByName( - type, - false, - new Set(['Object', 'Promise']), - matchAnyInstead, - ); - expect(result).toBe(expected); - } - describe('is true', () => { - function runTest( - [code, expected]: readonly [code: string, expected: boolean], - testContext: TestContext, - ): void { - runTestForAliasDeclaration(code, true, expected, testContext); - } + const options = { + allowedNames: new Set(['Object', 'Promise']), + matchAnyInstead: true, + }; it.for([ - [`type Test = Promise & string`, true], - ['type Test = Promise | string', true], - ['type Test = Promise | Object', true], - ] as const)('when code is "%s" expected is %s', runTest); + [`type Test = Promise & string`], + ['type Test = Promise | string'], + ['type Test = Promise | Object'], + ] as const)( + 'when code is "%s" it contains all types by name', + ([code], { expect }) => { + expect(code).toContainsAllTypesByName(options); + }, + ); }); describe('is false', () => { - function runTest( - [code, expected]: readonly [code: string, expected: boolean], - testContext: TestContext, - ): void { - runTestForAliasDeclaration(code, false, expected, testContext); - } + const options = { + allowedNames: new Set(['Object', 'Promise']), + matchAnyInstead: false, + }; + + it.for([['type Test = Promise | Object']] as const)( + 'when code is "%s" it contains all types by name', + ([code], { expect }) => { + expect(code).toContainsAllTypesByName(options); + }, + ); it.for([ - ['type Test = Promise & string', false], - ['type Test = Promise | string', false], - ['type Test = Promise | Object', true], - ] as const)('when code is "%s" expected is %s', runTest); + ['type Test = Promise & string'], + ['type Test = Promise | string'], + ] as const)( + 'when code is "%s" it does not contain all types by name', + ([code], { expect }) => { + expect(code).not.toContainsAllTypesByName(options); + }, + ); }); }); }); diff --git a/packages/type-utils/tests/discriminateAnyType.test.ts b/packages/type-utils/tests/discriminateAnyType.test.ts index 6b933322086e..a6fcdb7e535c 100644 --- a/packages/type-utils/tests/discriminateAnyType.test.ts +++ b/packages/type-utils/tests/discriminateAnyType.test.ts @@ -1,31 +1,19 @@ import type { TSESTree } from '@typescript-eslint/typescript-estree'; -import type { TestContext } from 'vitest'; - -import { parseForESLint } from '@typescript-eslint/parser'; -import path from 'node:path'; import { AnyType, discriminateAnyType } from '../src'; -import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; +import { parseCodeForEslint } from './test-utils/custom-matchers/custom-matchers.js'; type GetNode = (ast: TSESTree.Program) => TSESTree.Node; describe(discriminateAnyType, () => { - const rootDir = path.join(__dirname, 'fixtures'); - function getDeclarationId(ast: TSESTree.Program): TSESTree.Node { const declaration = ast.body.at(-1) as TSESTree.VariableDeclaration; - const id = declaration.declarations[0].id; + const { id } = declaration.declarations[0]; return id; } function getTypes(code: string, getNode: GetNode) { - const { ast, services } = parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); - expectToHaveParserServices(services); + const { ast, services } = parseCodeForEslint(code); const node = getNode(ast); const type = services.getTypeAtLocation(getNode(ast)); return { @@ -36,27 +24,24 @@ describe(discriminateAnyType, () => { }; } - function runTest( - [code, expected, getNode = getDeclarationId]: readonly [ - code: string, - expected: AnyType, - getNode?: GetNode, - ], - { expect }: TestContext, - ): void { - const { checker, program, tsNode, type } = getTypes(code, getNode); - const result = discriminateAnyType(type, checker, program, tsNode); - expect(result).toBe(expected); - } - describe('returns Safe', () => { it.for([ ['const foo = "foo";', AnyType.Safe], ['const foo = 1;', AnyType.Safe], ['const foo = [1, 2];', AnyType.Safe], - ] as const)('when code is %s, returns %s', runTest); + ] as const satisfies [string, AnyType.Safe][])( + 'when code is %s, returns %s', + ([code, expected], { expect }) => { + const { checker, program, tsNode, type } = getTypes( + code, + getDeclarationId, + ); + const result = discriminateAnyType(type, checker, program, tsNode); + expect(result).toBe(expected); + }, + ); - it('should returns Safe for a recursive thenable.', testContext => { + it('should returns Safe for a recursive thenable.', () => { const code = ` class Foo { foo() { @@ -67,22 +52,18 @@ class Foo { } }; `; - runTest( - [ - code, - AnyType.Safe, - ast => { - const classDeclration = ast.body[0] as TSESTree.ClassDeclaration; - const method = classDeclration.body - .body[0] as TSESTree.MethodDefinition; - const returnStatement = method.value.body?.body.at( - -1, - ) as TSESTree.ReturnStatement; - return returnStatement.argument!; - }, - ], - testContext, - ); + + const { checker, program, tsNode, type } = getTypes(code, ast => { + const classDeclration = ast.body[0] as TSESTree.ClassDeclaration; + const method = classDeclration.body + .body[0] as TSESTree.MethodDefinition; + const returnStatement = method.value.body?.body.at( + -1, + ) as TSESTree.ReturnStatement; + return returnStatement.argument!; + }); + const result = discriminateAnyType(type, checker, program, tsNode); + expect(result).toBe(AnyType.Safe); }); }); @@ -90,7 +71,17 @@ class Foo { it.for([ ['const foo = 1 as any;', AnyType.Any], ['let foo;', AnyType.Any], - ] as const)('when code is %s, returns %s', runTest); + ] as const satisfies [string, AnyType.Any][])( + 'when code is %s, returns %s', + ([code, expected], { expect }) => { + const { checker, program, tsNode, type } = getTypes( + code, + getDeclarationId, + ); + const result = discriminateAnyType(type, checker, program, tsNode); + expect(result).toBe(expected); + }, + ); }); describe('returns PromiseAny', () => { @@ -100,13 +91,33 @@ class Foo { 'const foo = Promise.resolve(Promise.resolve({} as any));', AnyType.PromiseAny, ], - ] as const)('when code is %s, returns %s', runTest); + ] as const satisfies [string, AnyType.PromiseAny][])( + 'when code is %s, returns %s', + ([code, expected], { expect }) => { + const { checker, program, tsNode, type } = getTypes( + code, + getDeclarationId, + ); + const result = discriminateAnyType(type, checker, program, tsNode); + expect(result).toBe(expected); + }, + ); }); describe('returns AnyArray', () => { it.for([ ['const foo = [{} as any];', AnyType.AnyArray], ['const foo = [{} as any, 2];', AnyType.AnyArray], - ] as const)('when code is %s, returns %s', runTest); + ] as const satisfies [string, AnyType.AnyArray][])( + 'when code is %s, returns %s', + ([code, expected], { expect }) => { + const { checker, program, tsNode, type } = getTypes( + code, + getDeclarationId, + ); + const result = discriminateAnyType(type, checker, program, tsNode); + expect(result).toBe(expected); + }, + ); }); }); diff --git a/packages/type-utils/tests/getConstrainedTypeAtLocation.test.ts b/packages/type-utils/tests/getConstrainedTypeAtLocation.test.ts index c033dba526d7..faf500c380bf 100644 --- a/packages/type-utils/tests/getConstrainedTypeAtLocation.test.ts +++ b/packages/type-utils/tests/getConstrainedTypeAtLocation.test.ts @@ -1,25 +1,9 @@ import type { TSESTree } from '@typescript-eslint/types'; -import type { ParserServicesWithTypeInformation } from '@typescript-eslint/typescript-estree'; -import { parseForESLint } from '@typescript-eslint/parser'; -import path from 'node:path'; import * as tsutils from 'ts-api-utils'; import { getConstrainedTypeAtLocation, isTypeUnknownType } from '../src'; - -function parseCodeForEslint(code: string): ReturnType & { - services: ParserServicesWithTypeInformation; -} { - const rootDir = path.join(__dirname, 'fixtures'); - - // @ts-expect-error -- services will have type information. - return parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); -} +import { parseCodeForEslint } from './test-utils/custom-matchers/custom-matchers.js'; describe(getConstrainedTypeAtLocation, () => { // See https://github.com/typescript-eslint/typescript-eslint/issues/10438 diff --git a/packages/type-utils/tests/getTypeName.test.ts b/packages/type-utils/tests/getTypeName.test.ts index 92aa0140204b..40c5347114af 100644 --- a/packages/type-utils/tests/getTypeName.test.ts +++ b/packages/type-utils/tests/getTypeName.test.ts @@ -1,39 +1,17 @@ -import type { TSESTree } from '@typescript-eslint/typescript-estree'; +import type { TSESTree } from '@typescript-eslint/types'; import type * as ts from 'typescript'; -import type { TestContext } from 'vitest'; - -import { parseForESLint } from '@typescript-eslint/parser'; -import path from 'node:path'; import { getTypeName } from '../src'; -import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; +import { parseCodeForEslint } from './test-utils/custom-matchers/custom-matchers.js'; describe(getTypeName, () => { function getTypes(code: string): { checker: ts.TypeChecker; type: ts.Type } { - const rootDir = path.join(__dirname, 'fixtures'); - - const { ast, services } = parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); - expectToHaveParserServices(services); + const { ast, services } = parseCodeForEslint(code); const checker = services.program.getTypeChecker(); const declaration = ast.body[0] as TSESTree.TSTypeAliasDeclaration; return { checker, type: services.getTypeAtLocation(declaration.id) }; } - - function runTest( - [code, expected]: readonly [code: string, expected: string], - { expect }: TestContext, - ): void { - const { checker, type } = getTypes(code); - const result = getTypeName(checker, type); - expect(result).toBe(expected); - } - describe('returns primitive type', () => { it.for([ ['type Test = string;', 'string'], @@ -49,7 +27,14 @@ describe(getTypeName, () => { ['type Test = undefined;', 'undefined'], ['type Test = null;', 'null'], ['type Test = symbol;', 'symbol'], - ] as const)('when code is %s, returns %s', runTest); + ] as const)( + 'when code is %s, returns %s', + ([code, expected], { expect }) => { + const { checker, type } = getTypes(code); + const result = getTypeName(checker, type); + expect(result).toBe(expected); + }, + ); }); describe('returns non-primitive type', () => { @@ -61,6 +46,13 @@ describe(getTypeName, () => { ['type Test = T & boolean;', 'Test'], ['type Test = string | number;', 'Test'], ['type Test = string | string[];', 'Test'], - ] as const)('when code is %s, returns %s', runTest); + ] as const)( + 'when code is %s, returns %s', + ([code, expected], { expect }) => { + const { checker, type } = getTypes(code); + const result = getTypeName(checker, type); + expect(result).toBe(expected); + }, + ); }); }); diff --git a/packages/type-utils/tests/isSymbolFromDefaultLibrary.test.ts b/packages/type-utils/tests/isSymbolFromDefaultLibrary.test.ts index eb4ecbf55b83..221396e541a8 100644 --- a/packages/type-utils/tests/isSymbolFromDefaultLibrary.test.ts +++ b/packages/type-utils/tests/isSymbolFromDefaultLibrary.test.ts @@ -1,71 +1,43 @@ import type { TSESTree } from '@typescript-eslint/typescript-estree'; import type * as ts from 'typescript'; -import type { TestContext } from 'vitest'; - -import { parseForESLint } from '@typescript-eslint/parser'; -import path from 'node:path'; import { isSymbolFromDefaultLibrary } from '../src'; -import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; +import { parseCodeForEslint } from './test-utils/custom-matchers/custom-matchers.js'; describe(isSymbolFromDefaultLibrary, () => { - const rootDir = path.join(__dirname, 'fixtures'); - function getTypes(code: string): { program: ts.Program; symbol: ts.Symbol | undefined; } { - const { ast, services } = parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); - expectToHaveParserServices(services); + const { ast, services } = parseCodeForEslint(code); const declaration = ast.body[0] as TSESTree.TSTypeAliasDeclaration; const type = services.getTypeAtLocation(declaration.id); return { program: services.program, symbol: type.getSymbol() }; } - function runTestForAliasDeclaration( - code: string, - expected: boolean, - expect: TestContext['expect'], - ): void { - const { program, symbol } = getTypes(code); - const result = isSymbolFromDefaultLibrary(program, symbol); - expect(result).toBe(expected); - } - describe('is symbol from default library', () => { - function runTest( - [code]: readonly [code: string], - { expect }: TestContext, - ): void { - runTestForAliasDeclaration(code, true, expect); - } - it.for([ ['type Test = Array;'], ['type Test = Map;'], ['type Test = Promise'], ['type Test = Error'], ['type Test = Object'], - ] as const)('when code is %s, returns true', runTest); + ] as const)('when code is %s, returns true', ([code], { expect }) => { + const { program, symbol } = getTypes(code); + const result = isSymbolFromDefaultLibrary(program, symbol); + expect(result).toBe(true); + }); }); describe('is not symbol from default library', () => { - function runTest( - [code]: readonly [code: string], - { expect }: TestContext, - ): void { - runTestForAliasDeclaration(code, false, expect); - } - it.for([ ['const test: Array = [1,2,3];'], ['type Test = number;'], ['interface Test { bar: string; };'], - ] as const)('when code is %s, returns false', runTest); + ] as const)('when code is %s, returns false', ([code], { expect }) => { + const { program, symbol } = getTypes(code); + const result = isSymbolFromDefaultLibrary(program, symbol); + expect(result).toBe(false); + }); }); }); diff --git a/packages/type-utils/tests/isTypeReadonly.test.ts b/packages/type-utils/tests/isTypeReadonly.test.ts index 8f2d04765cb8..96193819540b 100644 --- a/packages/type-utils/tests/isTypeReadonly.test.ts +++ b/packages/type-utils/tests/isTypeReadonly.test.ts @@ -1,176 +1,160 @@ -import type { TSESTree } from '@typescript-eslint/utils'; -import type * as ts from 'typescript'; - -import { parseForESLint } from '@typescript-eslint/parser'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import path from 'node:path'; import type { ReadonlynessOptions } from '../src/isTypeReadonly'; import { isTypeReadonly } from '../src/isTypeReadonly'; -import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; describe(isTypeReadonly, () => { - const rootDir = path.join(__dirname, 'fixtures'); - describe(AST_NODE_TYPES.TSTypeAliasDeclaration, () => { - function getType(code: string): { - program: ts.Program; - type: ts.Type; - } { - const { ast, services } = parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); - expectToHaveParserServices(services); - const { esTreeNodeToTSNodeMap, program } = services; - - const declaration = ast.body[0] as TSESTree.TSTypeAliasDeclaration; - return { - program, - type: program - .getTypeChecker() - .getTypeAtLocation(esTreeNodeToTSNodeMap.get(declaration.id)), - }; - } - - function runTestForAliasDeclaration( - code: string, - options: ReadonlynessOptions | undefined, - expected: boolean, - ): void { - const { program, type } = getType(code); - - const result = isTypeReadonly(program, type, options); - expect(result).toBe(expected); - } - describe('default options', () => { const options = undefined; - function runTestIsReadonly(code: string): void { - runTestForAliasDeclaration(code, options, true); - } - - function runTestIsNotReadonly(code: string): void { - runTestForAliasDeclaration(code, options, false); - } - describe('basics', () => { - describe('is readonly', { timeout: 10_000 }, () => { - const runTests = runTestIsReadonly; - + describe('is readonly', () => { // Record. - it.each([ + it.for([ ['type Test = { readonly bar: string; };'], ['type Test = Readonly<{ bar: string; }>;'], - ] as const)('handles fully readonly records', runTests); + ] as const)( + 'handles fully readonly records', + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, + ); // Array. - it.each([ + it.for([ ['type Test = Readonly;'], ['type Test = Readonly>;'], - ] as const)('handles fully readonly arrays', runTests); + ] as const)('handles fully readonly arrays', ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }); // Array - special case. // Note: Methods are mutable but arrays are treated special; hence no failure. - it.each([ + it.for([ ['type Test = readonly string[];'], ['type Test = ReadonlyArray;'], - ] as const)('treats readonly arrays as fully readonly', runTests); + ] as const)( + 'treats readonly arrays as fully readonly', + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, + ); // Set and Map. - it.each([ + it.for([ ['type Test = Readonly>;'], ['type Test = Readonly>;'], - ] as const)('handles fully readonly sets and maps', runTests); + ] as const)( + 'handles fully readonly sets and maps', + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, + ); // Private Identifier. // Note: It can't be accessed from outside of class thus exempt from the checks. - it.each([ + it.for([ ['class Foo { readonly #readonlyPrivateField = "foo"; }'], ['class Foo { #privateField = "foo"; }'], ['class Foo { #privateMember() {}; }'], - ] as const)('treat private identifier as readonly', runTests); + ] as const)( + 'treat private identifier as readonly', + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, + ); }); describe('is not readonly', () => { - const runTests = runTestIsNotReadonly; - // Record. - it.each([ + it.for([ ['type Test = { foo: string; };'], ['type Test = { foo: string; readonly bar: number; };'], - ] as const)('handles non fully readonly records', runTests); + ] as const)( + 'handles non fully readonly records', + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, + ); // Array. - it.each([ + it.for([ ['type Test = string[]'], ['type Test = Array'], - ] as const)('handles non fully readonly arrays', runTests); + ] as const)( + 'handles non fully readonly arrays', + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, + ); // Set and Map. // Note: Methods are mutable for ReadonlySet and ReadonlyMet; hence failure. - it.each([ + it.for([ ['type Test = Set;'], ['type Test = Map;'], ['type Test = ReadonlySet;'], ['type Test = ReadonlyMap;'], - ] as const)('handles non fully readonly sets and maps', runTests); + ] as const)( + 'handles non fully readonly sets and maps', + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, + ); }); }); describe('IndexSignature', () => { describe('is readonly', () => { - const runTests = runTestIsReadonly; - - it.each([ + it.for([ ['type Test = { readonly [key: string]: string };'], [ 'type Test = { readonly [key: string]: { readonly foo: readonly string[]; }; };', ], ] as const)( 'handles readonly PropertySignature inside a readonly IndexSignature', - runTests, + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, ); }); describe('is readonly circular', () => { - const runTests = runTestIsReadonly; - it('handles circular readonly PropertySignature inside a readonly IndexSignature', () => { - runTests('interface Test { readonly [key: string]: Test };'); + expect( + 'interface Test { readonly [key: string]: Test };', + ).toBeReadOnly(options); }); it('handles circular readonly PropertySignature inside interdependent objects', () => { - runTests( + expect( 'interface Test1 { readonly [key: string]: Test } interface Test { readonly [key: string]: Test1 }', - ); + ).toBeReadOnly(options); }); }); describe('is not readonly', () => { - const runTests = runTestIsNotReadonly; - - it.each([ + it.for([ ['type Test = { [key: string]: string };'], ['type Test = { readonly [key: string]: { foo: string[]; }; };'], ] as const)( 'handles mutable PropertySignature inside a readonly IndexSignature', - runTests, + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, ); }); describe('is not readonly circular', () => { - const runTests = runTestIsNotReadonly; - it('handles circular mutable PropertySignature', () => { - runTests('interface Test { [key: string]: Test };'); + expect('interface Test { [key: string]: Test };').not.toBeReadOnly( + options, + ); }); - it.each([ + it.for([ [ 'interface Test1 { [key: string]: Test } interface Test { readonly [key: string]: Test1 }', ], @@ -182,27 +166,30 @@ describe(isTypeReadonly, () => { ], ] as const)( 'handles circular mutable PropertySignature inside interdependent objects', - runTests, + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, ); }); }); describe('Union', () => { describe('is readonly', () => { - const runTests = runTestIsReadonly; - - it.each([ + it.for([ [ 'type Test = Readonly<{ foo: string; bar: number; }> & Readonly<{ bar: number; }>;', ], ['type Test = readonly string[] | readonly number[];'], - ] as const)('handles a union of 2 fully readonly types', runTests); + ] as const)( + 'handles a union of 2 fully readonly types', + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, + ); }); describe('is not readonly', () => { - const runTests = runTestIsNotReadonly; - - it.each([ + it.for([ ['type Test = { foo: string; bar: number; } | { bar: number; };'], [ 'type Test = { foo: string; bar: number; } | Readonly<{ bar: number; }>;', @@ -210,49 +197,56 @@ describe(isTypeReadonly, () => { [ 'type Test = Readonly<{ foo: string; bar: number; }> | { bar: number; };', ], - ] as const)('handles a union of non fully readonly types', runTests); + ] as const)( + 'handles a union of non fully readonly types', + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, + ); }); }); describe('Intersection', () => { describe('is readonly', () => { - const runTests = runTestIsReadonly; - - it.each([ + it.for([ [ 'type Test = Readonly<{ foo: string; bar: number; }> & Readonly<{ bar: number; }>;', ], ] as const)( 'handles an intersection of 2 fully readonly types', - runTests, + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, ); - it.each([ + it.for([ [ 'type Test = Readonly<{ foo: string; bar: number; }> & { foo: string; };', ], ] as const)( 'handles an intersection of a fully readonly type with a mutable subtype', - runTests, + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, ); // Array - special case. // Note: Methods are mutable but arrays are treated special; hence no failure. - it.each([ + it.for([ ['type Test = ReadonlyArray & Readonly<{ foo: string; }>;'], [ 'type Test = readonly [string, number] & Readonly<{ foo: string; }>;', ], ] as const)( 'handles an intersections involving a readonly array', - runTests, + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, ); }); describe('is not readonly', () => { - const runTests = runTestIsNotReadonly; - - it.each([ + it.for([ ['type Test = { foo: string; bar: number; } & { bar: number; };'], [ 'type Test = { foo: string; bar: number; } & Readonly<{ bar: number; }>;', @@ -262,35 +256,40 @@ describe(isTypeReadonly, () => { ], ] as const)( 'handles an intersection of non fully readonly types', - runTests, + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, ); }); }); describe('Conditional Types', () => { describe('is readonly', () => { - const runTests = runTestIsReadonly; - - it.each([ + it.for([ [ 'type Test = T extends readonly number[] ? readonly string[] : readonly number[];', ], ] as const)( 'handles conditional type that are fully readonly', - runTests, + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, ); - it.each([ + it.for([ [ 'type Test = T extends number[] ? readonly string[] : readonly number[];', ], - ] as const)('should ignore mutable conditions', runTests); + ] as const)( + 'should ignore mutable conditions', + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, + ); }); describe('is not readonly', () => { - const runTests = runTestIsNotReadonly; - - it.each([ + it.for([ ['type Test = T extends number[] ? string[] : number[];'], [ 'type Test = T extends number[] ? string[] : readonly number[];', @@ -298,7 +297,12 @@ describe(isTypeReadonly, () => { [ 'type Test = T extends number[] ? readonly string[] : number[];', ], - ] as const)('handles non fully readonly conditional types', runTests); + ] as const)( + 'handles non fully readonly conditional types', + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, + ); }); }); }); @@ -308,22 +312,17 @@ describe(isTypeReadonly, () => { treatMethodsAsReadonly: true, }; - function runTestIsReadonly(code: string): void { - runTestForAliasDeclaration(code, options, true); - } - - // function runTestIsNotReadonly(code: string): void { - // runTestForAliasDeclaration(code, options, false); - // } - describe('is readonly', () => { - const runTests = runTestIsReadonly; - // Set and Map. - it.each([ + it.for([ ['type Test = ReadonlySet;'], ['type Test = ReadonlyMap;'], - ] as const)('handles non fully readonly sets and maps', runTests); + ] as const)( + 'handles non fully readonly sets and maps', + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, + ); }); }); @@ -341,16 +340,8 @@ describe(isTypeReadonly, () => { ], }; - function runTestIsReadonly(code: string): void { - runTestForAliasDeclaration(code, options, true); - } - - function runTestIsNotReadonly(code: string): void { - runTestForAliasDeclaration(code, options, false); - } - describe('is readonly', () => { - it.each([ + it.for([ [ 'interface Foo {readonly prop: RegExp}; type Test = (arg: Foo) => void;', ], @@ -360,19 +351,23 @@ describe(isTypeReadonly, () => { ['interface Foo {prop: string}; type Test = (arg: Foo) => void;'], ] as const)( 'correctly marks allowlisted types as readonly', - runTestIsReadonly, + ([code], { expect }) => { + expect(code).toBeReadOnly(options); + }, ); }); describe('is not readonly', () => { - it.each([ + it.for([ [ 'interface Bar {prop: RegExp}; type Test = (arg: Readonly) => void;', ], ['interface Bar {prop: string}; type Test = (arg: Bar) => void;'], ] as const)( 'correctly marks allowlisted types as readonly', - runTestIsNotReadonly, + ([code], { expect }) => { + expect(code).not.toBeReadOnly(options); + }, ); }); }); diff --git a/packages/type-utils/tests/isUnsafeAssignment.test.ts b/packages/type-utils/tests/isUnsafeAssignment.test.ts index af605b73a441..250995960aa0 100644 --- a/packages/type-utils/tests/isUnsafeAssignment.test.ts +++ b/packages/type-utils/tests/isUnsafeAssignment.test.ts @@ -1,240 +1,123 @@ -import type { TSESTree } from '@typescript-eslint/utils'; -import type * as ts from 'typescript'; - -import { parseForESLint } from '@typescript-eslint/parser'; -import path from 'node:path'; - import { isUnsafeAssignment } from '../src/isUnsafeAssignment'; -import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; describe(isUnsafeAssignment, () => { - const rootDir = path.join(__dirname, 'fixtures'); - - function getTypes( - code: string, - declarationIndex = 0, - ): { - checker: ts.TypeChecker; - receiver: ts.Type; - sender: ts.Type; - senderNode: TSESTree.Node; - } { - const { ast, services } = parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); - expectToHaveParserServices(services); - const checker = services.program.getTypeChecker(); - - const declaration = ast.body[ - declarationIndex - ] as TSESTree.VariableDeclaration; - const declarator = declaration.declarations[0]; - return { - checker, - receiver: services.getTypeAtLocation(declarator.id), - sender: services.getTypeAtLocation(declarator.init!), - senderNode: declarator.init!, - }; - } - describe('unsafe', () => { - function expectTypesAre( - result: ReturnType, - checker: ts.TypeChecker, - senderStr: string, - receiverStr: string, - ): void { - expect(result).toBeTruthy(); - const { receiver, sender } = result as Exclude; - - expect(checker.typeToString(sender)).toBe(senderStr); - expect(checker.typeToString(receiver)).toBe(receiverStr); - } - it('any to a non-any', () => { - const { checker, receiver, sender } = getTypes( - 'const test: string = (1 as any);', - ); - - expectTypesAre( - isUnsafeAssignment(sender, receiver, checker, null), - checker, - 'any', - 'string', - ); + expect('const test: string = (1 as any);').toHaveTypes({ + receiverStr: 'string', + senderStr: 'any', + }); }); it('any in a generic position to a non-any', () => { - const { checker, receiver, sender } = getTypes( - 'const test: Set = new Set();', - ); - - expectTypesAre( - isUnsafeAssignment(sender, receiver, checker, null), - checker, - 'Set', - 'Set', - ); + expect('const test: Set = new Set();').toHaveTypes({ + receiverStr: 'Set', + senderStr: 'Set', + }); }); it('any in a generic position to a non-any (multiple generics)', () => { - const { checker, receiver, sender } = getTypes( + expect( 'const test: Map = new Map();', - ); - - expectTypesAre( - isUnsafeAssignment(sender, receiver, checker, null), - checker, - 'Map', - 'Map', - ); + ).toHaveTypes({ + receiverStr: 'Map', + senderStr: 'Map', + }); }); it('any[] in a generic position to a non-any[]', () => { - const { checker, receiver, sender } = getTypes( - 'const test: Set = new Set();', - ); - - expectTypesAre( - isUnsafeAssignment(sender, receiver, checker, null), - checker, - 'Set', - 'Set', - ); + expect('const test: Set = new Set();').toHaveTypes({ + receiverStr: 'Set', + senderStr: 'Set', + }); }); it('any in a generic position to a non-any (nested)', () => { - const { checker, receiver, sender } = getTypes( + expect( 'const test: Set>> = new Set>>();', - ); - - expectTypesAre( - isUnsafeAssignment(sender, receiver, checker, null), - checker, - 'Set>>', - 'Set>>', - ); + ).toHaveTypes({ + receiverStr: 'Set>>', + senderStr: 'Set>>', + }); }); it('circular reference', () => { - const { checker, receiver, sender, senderNode } = getTypes( - `type T = [string, T[]]; - const test: T = ["string", []] as any;`, - 1, - ); - - expectTypesAre( - isUnsafeAssignment(sender, receiver, checker, senderNode), - checker, - 'any', - 'T', - ); + expect(`type T = [string, T[]]; + const test: T = ["string", []] as any;`).toHaveTypes({ + declarationIndex: 1, + passSenderNode: true, + receiverStr: 'T', + senderStr: 'any', + }); }); }); describe('safe', () => { it('non-any to a non-any', () => { - const { checker, receiver, sender } = getTypes( - 'const test: string = "";', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + expect('const test: string = "";').toBeSafeAssignment(); }); it('non-any to a any', () => { - const { checker, receiver, sender } = getTypes('const test: any = "";'); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + expect('const test: any = "";').toBeSafeAssignment(); }); it('non-any in a generic position to a non-any', () => { - const { checker, receiver, sender } = getTypes( + expect( 'const test: Set = new Set();', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + ).toBeSafeAssignment(); }); it('non-any in a generic position to a non-any (multiple generics)', () => { - const { checker, receiver, sender } = getTypes( + expect( 'const test: Map = new Map();', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + ).toBeSafeAssignment(); }); it('non-any[] in a generic position to a non-any[]', () => { - const { checker, receiver, sender } = getTypes( + expect( 'const test: Set = new Set();', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + ).toBeSafeAssignment(); }); it('non-any in a generic position to a non-any (nested)', () => { - const { checker, receiver, sender } = getTypes( + expect( 'const test: Set>> = new Set>>();', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + ).toBeSafeAssignment(); }); it('non-any in a generic position to a any (nested)', () => { - const { checker, receiver, sender } = getTypes( + expect( 'const test: Set>> = new Set>>();', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + ).toBeSafeAssignment(); }); it('any to a unknown', () => { - const { checker, receiver, sender } = getTypes( - 'const test: unknown = [] as any;', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + expect('const test: unknown = [] as any;').toBeSafeAssignment(); }); it('any[] in a generic position to a unknown[]', () => { - const { checker, receiver, sender } = getTypes( - 'const test: unknown[] = [] as any[]', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + expect('const test: unknown[] = [] as any[]').toBeSafeAssignment(); }); it('any in a generic position to a unknown (nested)', () => { - const { checker, receiver, sender } = getTypes( + expect( 'const test: Set>> = new Set>>();', - ); - - expect(isUnsafeAssignment(sender, receiver, checker, null)).toBeFalsy(); + ).toBeSafeAssignment(); }); // https://github.com/typescript-eslint/typescript-eslint/issues/2109 it('special cases the empty map constructor with no generics', () => { - const { checker, receiver, sender, senderNode } = getTypes( - 'const test: Map = new Map();', + expect('const test: Map = new Map();').toBeSafeAssignment( + { passSenderNode: true }, ); - - expect( - isUnsafeAssignment(sender, receiver, checker, senderNode), - ).toBeFalsy(); }); it('circular reference', () => { - const { checker, receiver, sender, senderNode } = getTypes( - `type T = [string, T[]]; - const test: T = ["string", []] as T;`, - 1, - ); - - expect( - isUnsafeAssignment(sender, receiver, checker, senderNode), - ).toBeFalsy(); + expect(`type T = [string, T[]]; + const test: T = ["string", []] as T;`).toBeSafeAssignment({ + declarationIndex: 1, + passSenderNode: true, + }); }); }); }); diff --git a/packages/type-utils/tests/test-utils/custom-matchers/custom-matchers.ts b/packages/type-utils/tests/test-utils/custom-matchers/custom-matchers.ts new file mode 100644 index 000000000000..b0849b091e22 --- /dev/null +++ b/packages/type-utils/tests/test-utils/custom-matchers/custom-matchers.ts @@ -0,0 +1,333 @@ +import type { ParserOptions } from '@typescript-eslint/parser'; +import type { + ParserServices, + ParserServicesWithTypeInformation, + TSESTree, +} from '@typescript-eslint/typescript-estree'; +import type * as ts from 'typescript'; + +import { parseForESLint } from '@typescript-eslint/parser'; +import Ajv from 'ajv'; +import * as path from 'node:path'; + +import type { ReadonlynessOptions } from '../../../src/isTypeReadonly.js'; +import type { TypeOrValueSpecifier } from '../../../src/TypeOrValueSpecifier.js'; + +import { containsAllTypesByName } from '../../../src/containsAllTypesByName.js'; +import { isTypeReadonly } from '../../../src/isTypeReadonly.js'; +import { isUnsafeAssignment } from '../../../src/isUnsafeAssignment.js'; +import { + typeMatchesSpecifier, + typeOrValueSpecifiersSchema, +} from '../../../src/TypeOrValueSpecifier.js'; + +const FIXTURES_DIR = path.join(__dirname, '..', '..', 'fixtures'); + +const DEFAULT_PARSER_OPTIONS = { + disallowAutomaticSingleRunInference: true, + filePath: path.join(FIXTURES_DIR, 'file.ts'), + project: './tsconfig.json', + tsconfigRootDir: FIXTURES_DIR, +} satisfies ParserOptions; + +chai.use((chai, utils) => { + function parserServices(this: Chai.AssertionStatic, errorMessage?: string) { + const services: ParserServices | null | undefined = utils.flag( + this, + 'object', + ); + + if (errorMessage) { + utils.flag(this, 'message', errorMessage); + } + + const pass = services?.program != null; + + this.assert( + pass, + 'expected #{this} to exist', + 'expected #{this} to not exist', + ); + } + + chai.Assertion.addMethod(parserServices.name, parserServices); + + chai.assert.isParserServices = (services, errorMessage) => { + new chai.Assertion(services, errorMessage).to.be.parserServices(); + }; +}); + +function hasParserServicesWithTypeInformation< + T extends ReturnType, +>( + parseForESLintResult: T, +): asserts parseForESLintResult is T & { + services: ParserServicesWithTypeInformation; +} { + assert.isParserServices(parseForESLintResult.services); +} + +export function parseCodeForEslint(code: string): ReturnType< + typeof parseForESLint +> & { + services: ParserServicesWithTypeInformation; +} { + const parseForESLintResult = parseForESLint(code, DEFAULT_PARSER_OPTIONS); + + hasParserServicesWithTypeInformation(parseForESLintResult); + + return parseForESLintResult; +} + +function getTypes( + code: string, + declarationIndex = 0, +): { + checker: ts.TypeChecker; + receiver: ts.Type; + sender: ts.Type; + senderNode: TSESTree.Node; +} { + const { ast, services } = parseCodeForEslint(code); + + const checker = services.program.getTypeChecker(); + + const declaration = ast.body[ + declarationIndex + ] as TSESTree.VariableDeclaration; + + const declarator = declaration.declarations[0]; + + assert.isNotNull(declarator.init); + + return { + checker, + receiver: services.getTypeAtLocation(declarator.id), + sender: services.getTypeAtLocation(declarator.init), + senderNode: declarator.init, + }; +} + +expect.extend({ + toBeReadOnly( + code: string, + readOnlyNessOptions: ReadonlynessOptions | undefined, + ) { + const { isNot, utils } = this; + + const { printReceived } = utils; + + const { ast, services } = parseCodeForEslint(code); + + const { esTreeNodeToTSNodeMap, program } = services; + + const declaration = ast.body[0] as TSESTree.TSTypeAliasDeclaration; + + const type = program + .getTypeChecker() + .getTypeAtLocation(esTreeNodeToTSNodeMap.get(declaration.id)); + + const actual = isTypeReadonly(program, type, readOnlyNessOptions); + + return { + actual, + expected: true, + message: () => + `Expected type to${isNot ? ' not' : ''} be readonly:\n\n${printReceived( + code, + )}`, + pass: actual, + }; + }, + toBeSafeAssignment( + code: string, + additionalOptions: { + declarationIndex?: number; + passSenderNode?: boolean; + } = {}, + ) { + const { isNot } = this; + + const { declarationIndex = 0, passSenderNode = false } = additionalOptions; + + const { checker, receiver, sender, senderNode } = getTypes( + code, + declarationIndex, + ); + + const actual = isUnsafeAssignment( + sender, + receiver, + checker, + passSenderNode ? senderNode : null, + ); + + const expected = false; + + const pass = actual === expected; + + return { + actual, + expected: isNot + ? expect.objectContaining({ + receiver: expect.anything(), + sender: expect.anything(), + }) + : expected, + message: () => `Expected Assignment${isNot ? ' not' : ''} to be safe.`, + pass, + }; + }, + + toBeValidSpecifier(typeOrValueSpecifier: unknown) { + const { isNot, utils } = this; + + const { printReceived } = utils; + + const ajv = new Ajv(); + + const validate = ajv.compile(typeOrValueSpecifiersSchema); + + const actual = validate(typeOrValueSpecifier); + + const expected = true; + + const pass = actual === expected; + + return { + actual, + expected, + message: () => + `Expected specifier to${isNot ? ' not' : ''} be valid:\n\n${printReceived( + typeOrValueSpecifier, + )}`, + pass, + }; + }, + + toContainsAllTypesByName( + code: string, + additionalOptions: { + allowAny?: boolean; + allowedNames?: Set; + matchAnyInstead?: boolean; + } = {}, + ) { + const { isNot, utils } = this; + + const { printReceived } = utils; + + const { + allowAny = false, + allowedNames = new Set(), + matchAnyInstead, + } = additionalOptions; + + const { ast, services } = parseCodeForEslint(code); + + const declaration = ast.body[0] as TSESTree.TSTypeAliasDeclaration; + + const type = services.getTypeAtLocation(declaration.id); + + const actual = containsAllTypesByName( + type, + allowAny, + allowedNames, + matchAnyInstead, + ); + + return { + actual, + expected: true, + message: () => + `Expected type to${isNot ? ' not' : ''} contain all types by name:\n\n${printReceived( + code, + )}`, + pass: actual, + }; + }, + + toHaveTypes( + code: string, + additionalOptions: { + senderStr: string; + receiverStr: string; + declarationIndex?: number; + passSenderNode?: boolean; + }, + ) { + const { isNot } = this; + + const { + declarationIndex = 0, + passSenderNode = false, + receiverStr, + senderStr, + } = additionalOptions; + + const { checker, receiver, sender, senderNode } = getTypes( + code, + declarationIndex, + ); + + const result = isUnsafeAssignment( + sender, + receiver, + checker, + passSenderNode ? senderNode : null, + ); + + assert.isNotFalse(result); + + const senderType = checker.typeToString(result.sender); + const receiverType = checker.typeToString(result.receiver); + + const actual = { receiver: receiverType, sender: senderType }; + const expected = { receiver: receiverStr, sender: senderStr }; + + const pass = receiverType === receiverStr && senderType === senderStr; + + return { + actual, + expected, + message: () => + `Expected types of sender and receiver to${isNot ? ' not' : ''} match.`, + pass, + }; + }, + + toMatchSpecifier( + code: string, + expectedTypeOrValueSpecifier: TypeOrValueSpecifier, + ) { + const { isNot, utils } = this; + + const { printReceived } = utils; + + const { ast, services } = parseCodeForEslint(code); + + const type = services.program + .getTypeChecker() + .getTypeAtLocation( + services.esTreeNodeToTSNodeMap.get( + (ast.body.at(-1) as TSESTree.TSTypeAliasDeclaration).id, + ), + ); + + const actual = typeMatchesSpecifier( + type, + expectedTypeOrValueSpecifier, + services.program, + ); + + return { + actual, + expected: true, + message: () => + `Expected type to${isNot ? ' not' : ''} match specifier:\n\n${printReceived( + expectedTypeOrValueSpecifier, + )}`, + pass: actual, + }; + }, +}); diff --git a/packages/type-utils/tests/test-utils/custom-matchers/vitest-custom-matchers.d.ts b/packages/type-utils/tests/test-utils/custom-matchers/vitest-custom-matchers.d.ts new file mode 100644 index 000000000000..7897fd88a8d4 --- /dev/null +++ b/packages/type-utils/tests/test-utils/custom-matchers/vitest-custom-matchers.d.ts @@ -0,0 +1,54 @@ +import 'vitest'; + +import type { + ParserServices, + ParserServicesWithTypeInformation, +} from '@typescript-eslint/typescript-estree'; + +import type { ReadonlynessOptions } from '../../../src/isTypeReadonly.js'; + +declare global { + namespace Chai { + interface Assertion { + parserServices(errorMessage?: string): void; + } + + interface Assert { + isParserServices( + services: ParserServices | null | undefined, + errorMessage?: string, + ): asserts services is ParserServicesWithTypeInformation; + } + } +} + +interface CustomMatchers { + toHaveTypes(additionalOptions: { + senderStr: string; + receiverStr: string; + declarationIndex?: number; + passSenderNode?: boolean; + }): Actual; + + toBeValidSpecifier(): Actual; + + toMatchSpecifier(expectedTypeOrValueSpecifier: TypeOrValueSpecifier): Actual; + + toBeReadOnly(readOnlyNessOptions: ReadonlynessOptions | undefined): Actual; + + toContainsAllTypesByName(additionalOptions?: { + allowAny?: boolean; + allowedNames?: Set; + matchAnyInstead?: boolean; + }): Actual; + + toBeSafeAssignment(additionalOptions?: { + declarationIndex?: number; + passSenderNode?: boolean; + }): Actual; +} + +declare module 'vitest' { + interface Assertion extends CustomMatchers {} + interface AsymmetricMatchersContaining extends CustomMatchers {} +} diff --git a/packages/type-utils/tests/test-utils/expectToHaveParserServices.ts b/packages/type-utils/tests/test-utils/expectToHaveParserServices.ts deleted file mode 100644 index 6ff95a7076be..000000000000 --- a/packages/type-utils/tests/test-utils/expectToHaveParserServices.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { - ParserServices, - ParserServicesWithTypeInformation, -} from '@typescript-eslint/typescript-estree'; - -export function expectToHaveParserServices( - services: ParserServices | null | undefined, -): asserts services is ParserServicesWithTypeInformation { - expect(services?.program).toBeDefined(); - expect(services?.esTreeNodeToTSNodeMap).toBeDefined(); - expect(services?.tsNodeToESTreeNodeMap).toBeDefined(); -} diff --git a/packages/type-utils/tests/typeFlagUtils.test.ts b/packages/type-utils/tests/typeFlagUtils.test.ts index c5d6fcc4f552..863020b405be 100644 --- a/packages/type-utils/tests/typeFlagUtils.test.ts +++ b/packages/type-utils/tests/typeFlagUtils.test.ts @@ -1,109 +1,70 @@ import type { TSESTree } from '@typescript-eslint/typescript-estree'; -import type { TestContext } from 'vitest'; -import { parseForESLint } from '@typescript-eslint/parser'; -import path from 'node:path'; import * as ts from 'typescript'; import { getTypeFlags, isTypeFlagSet } from '../src'; -import { expectToHaveParserServices } from './test-utils/expectToHaveParserServices'; +import { parseCodeForEslint } from './test-utils/custom-matchers/custom-matchers.js'; describe('typeFlagUtils', () => { - const rootDir = path.join(__dirname, 'fixtures'); - function getType(code: string): ts.Type { - const { ast, services } = parseForESLint(code, { - disallowAutomaticSingleRunInference: true, - filePath: path.join(rootDir, 'file.ts'), - project: './tsconfig.json', - tsconfigRootDir: rootDir, - }); - expectToHaveParserServices(services); + const { ast, services } = parseCodeForEslint(code); const declaration = ast.body[0] as TSESTree.TSTypeAliasDeclaration; return services.getTypeAtLocation(declaration.id); } describe(getTypeFlags, () => { - function runTestForAliasDeclaration( - [code, expected]: readonly [code: string, expected: ts.TypeFlags], - { expect }: TestContext, - ): void { - const type = getType(code); - const result = getTypeFlags(type); - expect(result).toBe(expected); - } - it.for([ - ['type Test = any;', 1], - ['type Test = unknown;', 2], - ['type Test = string;', 4], - ['type Test = number;', 8], - ['type Test = "text";', 128], - ['type Test = 123;', 256], + ['type Test = any;', ts.TypeFlags.Any], + ['type Test = unknown;', ts.TypeFlags.Unknown], + ['type Test = string;', ts.TypeFlags.String], + ['type Test = number;', ts.TypeFlags.Number], + ['type Test = "text";', ts.TypeFlags.StringLiteral], + ['type Test = 123;', ts.TypeFlags.NumberLiteral], [ 'type Test = string | number', ts.TypeFlags.String | ts.TypeFlags.Number, ], - ['type Test = "text" | 123', 384], - ] as const)( + ['type Test = "text" | 123', ts.TypeFlags.StringOrNumberLiteral], + ] as const satisfies [string, ts.TypeFlags][])( 'when code is "%s", type flags is %d', - runTestForAliasDeclaration, + ([code, expected], { expect }) => { + const type = getType(code); + const result = getTypeFlags(type); + expect(result).toBe(expected); + }, ); }); describe(isTypeFlagSet, () => { - function runTestForAliasDeclaration( - code: string, - flagsToCheck: ts.TypeFlags, - expected: boolean, - { expect }: TestContext, - ): void { - const type = getType(code); - const result = isTypeFlagSet(type, flagsToCheck); - expect(result).toBe(expected); - } - describe('is type flags set', () => { - function runTestIsTypeFlagSet( - [code, flagsToCheck]: readonly [ - code: string, - flagsToCheck: ts.TypeFlags, - ], - testContext: TestContext, - ): void { - runTestForAliasDeclaration(code, flagsToCheck, true, testContext); - } - it.for([ ['type Test = any;', ts.TypeFlags.Any], ['type Test = string;', ts.TypeFlags.String], ['type Test = string | number;', ts.TypeFlags.String], ['type Test = string & { foo: string };', ts.TypeFlags.Intersection], - ] as const)( + ] as const satisfies [string, ts.TypeFlags][])( 'when code is "%s" and flagsToCheck is %d , returns true', - runTestIsTypeFlagSet, + ([code, flagsToCheck], { expect }) => { + const type = getType(code); + const result = isTypeFlagSet(type, flagsToCheck); + expect(result).toBe(true); + }, ); }); describe('is not type flags set', () => { - function runTestIsNotTypeFlagSet( - [code, flagsToCheck]: readonly [ - code: string, - flagsToCheck: ts.TypeFlags, - ], - testContext: TestContext, - ): void { - runTestForAliasDeclaration(code, flagsToCheck, false, testContext); - } - it.for([ ['type Test = string', ts.TypeFlags.Any], ['type Test = string | number;', ts.TypeFlags.Any], ['type Test = string & { foo: string }', ts.TypeFlags.String], - ] as const)( + ] as const satisfies [string, ts.TypeFlags][])( 'when code is "%s" and flagsToCheck is %d , returns false', - runTestIsNotTypeFlagSet, + ([code, flagsToCheck], { expect }) => { + const type = getType(code); + const result = isTypeFlagSet(type, flagsToCheck); + expect(result).toBe(false); + }, ); }); }); diff --git a/packages/type-utils/vitest.config.mts b/packages/type-utils/vitest.config.mts index 674ea2ded3b5..9227def9f445 100644 --- a/packages/type-utils/vitest.config.mts +++ b/packages/type-utils/vitest.config.mts @@ -11,9 +11,14 @@ const vitestConfig = mergeConfig( root: import.meta.dirname, test: { + diff: { + maxDepth: 1, + }, + dir: path.join(import.meta.dirname, 'tests'), name: packageJson.name.replace('@typescript-eslint/', ''), root: import.meta.dirname, + setupFiles: ['./tests/test-utils/custom-matchers/custom-matchers.ts'], testTimeout: 10_000, }, }), diff --git a/packages/types/package.json b/packages/types/package.json index 168528f73cde..a6fc67b817e9 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -67,12 +67,12 @@ } }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "prettier": "^3.2.5", "rimraf": "*", "tsx": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/packages/typescript-eslint/package.json b/packages/typescript-eslint/package.json index 5a5a7769ff9d..b33a91517df3 100644 --- a/packages/typescript-eslint/package.json +++ b/packages/typescript-eslint/package.json @@ -60,11 +60,11 @@ "typescript": ">=4.8.4 <5.9.0" }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "prettier": "^3.2.5", "rimraf": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 14864784bb3c..4cd2a80cec81 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -63,12 +63,12 @@ "ts-api-utils": "^2.0.1" }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "glob": "*", "prettier": "^3.2.5", "rimraf": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" diff --git a/packages/utils/package.json b/packages/utils/package.json index f83e1f61c29d..ae2f028b911f 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -72,11 +72,11 @@ "typescript": ">=4.8.4 <5.9.0" }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "prettier": "^3.2.5", "rimraf": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/packages/visitor-keys/package.json b/packages/visitor-keys/package.json index 92d512cc0d61..57a07ca21216 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -50,11 +50,11 @@ "eslint-visitor-keys": "^4.2.0" }, "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", + "@vitest/coverage-v8": "^3.1.2", "prettier": "^3.2.5", "rimraf": "*", "typescript": "*", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "funding": { "type": "opencollective", diff --git a/yarn.lock b/yarn.lock index e44db1de218c..03c34a7dd6cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -522,6 +522,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 0a8464adc4b39b138aedcb443b09f4005d86207d7126e5e079177e05c3116107d856ec08282b365e9a79a9872f40f4092a6127f8d74c8a01c1ef789dacfc25d6 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.24.7, @babel/helper-validator-identifier@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-identifier@npm:7.25.9" @@ -529,6 +536,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-identifier@npm:7.27.1" + checksum: 3c7e8391e59d6c85baeefe9afb86432f2ab821c6232b00ea9082a51d3e7e95a2f3fb083d74dc1f49ac82cf238e1d2295dafcb001f7b0fab479f3f56af5eaaa47 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-option@npm:7.25.9" @@ -569,13 +583,13 @@ __metadata: linkType: hard "@babel/parser@npm:^7.25.4": - version: 7.27.0 - resolution: "@babel/parser@npm:7.27.0" + version: 7.27.1 + resolution: "@babel/parser@npm:7.27.1" dependencies: - "@babel/types": ^7.27.0 + "@babel/types": ^7.27.1 bin: parser: ./bin/babel-parser.js - checksum: 062a4e6d51553603253990c84e051ed48671a55b9d4e9caf2eff9dc888465070a0cfd288a467dbf0d99507781ea4a835b5606e32ddc0319f1b9273f913676829 + checksum: 36042c744c4648a8cebf5579a0f8dc6c056648a5b017c1f1c896ce99468764dad91dfc3dd215684e0e4e648a28b62cdd2e6537b34f4a83dda01cb97a846166b0 languageName: node linkType: hard @@ -1596,13 +1610,13 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.25.4, @babel/types@npm:^7.27.0": - version: 7.27.0 - resolution: "@babel/types@npm:7.27.0" +"@babel/types@npm:^7.25.4, @babel/types@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/types@npm:7.27.1" dependencies: - "@babel/helper-string-parser": ^7.25.9 - "@babel/helper-validator-identifier": ^7.25.9 - checksum: 59582019eb8a693d4277015d4dec0233874d884b9019dcd09550332db7f0f2ac9e30eca685bb0ada4bab5a4dc8bbc2a6bcaadb151c69b7e6aa94b5eaf8fc8c51 + "@babel/helper-string-parser": ^7.27.1 + "@babel/helper-validator-identifier": ^7.27.1 + checksum: 357c13f37aaa2f2e2cfcdb63f986d5f7abc9f38df20182b620ace34387d2460620415770fe5856eb54d70c9f0ba2f71230d29465e789188635a948476b830ae4 languageName: node linkType: hard @@ -2900,9 +2914,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/aix-ppc64@npm:0.25.2" +"@esbuild/aix-ppc64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/aix-ppc64@npm:0.25.3" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -2921,9 +2935,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/android-arm64@npm:0.25.2" +"@esbuild/android-arm64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/android-arm64@npm:0.25.3" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -2942,9 +2956,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/android-arm@npm:0.25.2" +"@esbuild/android-arm@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/android-arm@npm:0.25.3" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -2963,9 +2977,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/android-x64@npm:0.25.2" +"@esbuild/android-x64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/android-x64@npm:0.25.3" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -2984,9 +2998,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/darwin-arm64@npm:0.25.2" +"@esbuild/darwin-arm64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/darwin-arm64@npm:0.25.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -3005,9 +3019,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/darwin-x64@npm:0.25.2" +"@esbuild/darwin-x64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/darwin-x64@npm:0.25.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -3026,9 +3040,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/freebsd-arm64@npm:0.25.2" +"@esbuild/freebsd-arm64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/freebsd-arm64@npm:0.25.3" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -3047,9 +3061,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/freebsd-x64@npm:0.25.2" +"@esbuild/freebsd-x64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/freebsd-x64@npm:0.25.3" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -3068,9 +3082,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-arm64@npm:0.25.2" +"@esbuild/linux-arm64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-arm64@npm:0.25.3" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -3089,9 +3103,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-arm@npm:0.25.2" +"@esbuild/linux-arm@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-arm@npm:0.25.3" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -3110,9 +3124,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-ia32@npm:0.25.2" +"@esbuild/linux-ia32@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-ia32@npm:0.25.3" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -3131,9 +3145,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-loong64@npm:0.25.2" +"@esbuild/linux-loong64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-loong64@npm:0.25.3" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -3152,9 +3166,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-mips64el@npm:0.25.2" +"@esbuild/linux-mips64el@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-mips64el@npm:0.25.3" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -3173,9 +3187,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-ppc64@npm:0.25.2" +"@esbuild/linux-ppc64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-ppc64@npm:0.25.3" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -3194,9 +3208,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-riscv64@npm:0.25.2" +"@esbuild/linux-riscv64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-riscv64@npm:0.25.3" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -3215,9 +3229,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-s390x@npm:0.25.2" +"@esbuild/linux-s390x@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-s390x@npm:0.25.3" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -3236,9 +3250,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/linux-x64@npm:0.25.2" +"@esbuild/linux-x64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/linux-x64@npm:0.25.3" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -3250,9 +3264,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/netbsd-arm64@npm:0.25.2" +"@esbuild/netbsd-arm64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/netbsd-arm64@npm:0.25.3" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard @@ -3271,9 +3285,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/netbsd-x64@npm:0.25.2" +"@esbuild/netbsd-x64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/netbsd-x64@npm:0.25.3" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -3285,9 +3299,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/openbsd-arm64@npm:0.25.2" +"@esbuild/openbsd-arm64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/openbsd-arm64@npm:0.25.3" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -3306,9 +3320,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/openbsd-x64@npm:0.25.2" +"@esbuild/openbsd-x64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/openbsd-x64@npm:0.25.3" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -3327,9 +3341,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/sunos-x64@npm:0.25.2" +"@esbuild/sunos-x64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/sunos-x64@npm:0.25.3" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -3348,9 +3362,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/win32-arm64@npm:0.25.2" +"@esbuild/win32-arm64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/win32-arm64@npm:0.25.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -3369,9 +3383,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/win32-ia32@npm:0.25.2" +"@esbuild/win32-ia32@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/win32-ia32@npm:0.25.3" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -3390,9 +3404,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.25.2": - version: 0.25.2 - resolution: "@esbuild/win32-x64@npm:0.25.2" +"@esbuild/win32-x64@npm:0.25.3": + version: 0.25.3 + resolution: "@esbuild/win32-x64@npm:0.25.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4295,142 +4309,142 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.40.0" +"@rollup/rollup-android-arm-eabi@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.40.1" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-android-arm64@npm:4.40.0" +"@rollup/rollup-android-arm64@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-android-arm64@npm:4.40.1" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-darwin-arm64@npm:4.40.0" +"@rollup/rollup-darwin-arm64@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.40.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-darwin-x64@npm:4.40.0" +"@rollup/rollup-darwin-x64@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.40.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.40.0" +"@rollup/rollup-freebsd-arm64@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.40.1" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-freebsd-x64@npm:4.40.0" +"@rollup/rollup-freebsd-x64@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-freebsd-x64@npm:4.40.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.40.0" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.40.1" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.40.0" +"@rollup/rollup-linux-arm-musleabihf@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.40.1" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.40.0" +"@rollup/rollup-linux-arm64-gnu@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.40.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.40.0" +"@rollup/rollup-linux-arm64-musl@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.40.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loongarch64-gnu@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.40.0" +"@rollup/rollup-linux-loongarch64-gnu@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.40.1" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.0" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.1" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.40.0" +"@rollup/rollup-linux-riscv64-gnu@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.40.1" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.40.0" +"@rollup/rollup-linux-riscv64-musl@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.40.1" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.40.0" +"@rollup/rollup-linux-s390x-gnu@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.40.1" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.40.0" +"@rollup/rollup-linux-x64-gnu@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.40.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.40.0" +"@rollup/rollup-linux-x64-musl@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.40.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.40.0" +"@rollup/rollup-win32-arm64-msvc@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.40.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.40.0" +"@rollup/rollup-win32-ia32-msvc@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.40.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.40.0": - version: 4.40.0 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.40.0" +"@rollup/rollup-win32-x64-msvc@npm:4.40.1": + version: 4.40.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.40.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4939,11 +4953,11 @@ __metadata: linkType: hard "@swc/helpers@npm:~0.5.0": - version: 0.5.15 - resolution: "@swc/helpers@npm:0.5.15" + version: 0.5.17 + resolution: "@swc/helpers@npm:0.5.17" dependencies: tslib: ^2.8.0 - checksum: 1a9e0dbb792b2d1e0c914d69c201dbc96af3a0e6e6e8cf5a7f7d6a5d7b0e8b762915cd4447acb6b040e2ecc1ed49822875a7239f99a2d63c96c3c3407fb6fccf + checksum: 085e13b536323945dfc3a270debf270bda6dfc80a1c68fd2ed08f7cbdfcbdaeead402650b5b10722e54e4a24193afc8a3c6f63d3d6d719974e7470557fb415bd languageName: node linkType: hard @@ -5541,14 +5555,14 @@ __metadata: "@babel/eslint-parser": "*" "@microsoft/api-extractor": ^7.47.11 "@typescript-eslint/typescript-estree": "workspace:*" - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 glob: "*" jest-diff: ^29.7.0 prettier: ^3.2.5 pretty-format: "*" rimraf: "*" typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 languageName: unknown linkType: soft @@ -5561,10 +5575,10 @@ __metadata: "@typescript-eslint/scope-manager": "workspace:*" "@typescript-eslint/type-utils": "workspace:*" "@typescript-eslint/utils": "workspace:*" - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 prettier: ^3.2.5 rimraf: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 languageName: unknown linkType: soft @@ -5582,7 +5596,7 @@ __metadata: "@typescript-eslint/type-utils": 8.31.1 "@typescript-eslint/utils": 8.31.1 "@typescript-eslint/visitor-keys": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 ajv: ^6.12.6 cross-fetch: "*" eslint: "*" @@ -5602,7 +5616,7 @@ __metadata: tsx: "*" typescript: "*" unist-util-visit: ^5.0.0 - vitest: ^3.1.1 + vitest: ^3.1.2 peerDependencies: "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 @@ -5614,8 +5628,8 @@ __metadata: version: 0.0.0-use.local resolution: "@typescript-eslint/integration-tests@workspace:packages/integration-tests" dependencies: - "@vitest/coverage-v8": ^3.1.1 - vitest: ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 + vitest: ^3.1.2 languageName: unknown linkType: soft @@ -5627,13 +5641,13 @@ __metadata: "@typescript-eslint/types": 8.31.1 "@typescript-eslint/typescript-estree": 8.31.1 "@typescript-eslint/visitor-keys": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 debug: ^4.3.4 glob: "*" prettier: ^3.2.5 rimraf: "*" typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.9.0" @@ -5646,11 +5660,11 @@ __metadata: dependencies: "@typescript-eslint/type-utils": 8.31.1 "@typescript-eslint/utils": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 natural-compare: ^1.4.0 prettier: ^3.2.5 typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 languageName: unknown linkType: soft @@ -5663,9 +5677,9 @@ __metadata: "@typescript-eslint/parser": 8.31.1 "@typescript-eslint/typescript-estree": 8.31.1 "@typescript-eslint/utils": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 ajv: ^6.12.6 - chai: ^4.4.1 + chai: ^5.2.0 eslint-visitor-keys: ^4.2.0 espree: ^10.3.0 esprima: ^4.0.1 @@ -5676,7 +5690,7 @@ __metadata: sinon: ^16.1.3 source-map-support: ^0.5.21 typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 peerDependencies: eslint: ^8.57.0 || ^9.0.0 languageName: unknown @@ -5689,12 +5703,12 @@ __metadata: "@typescript-eslint/types": 8.31.1 "@typescript-eslint/typescript-estree": 8.31.1 "@typescript-eslint/visitor-keys": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 glob: "*" prettier: ^3.2.5 pretty-format: "*" typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 languageName: unknown linkType: soft @@ -5705,14 +5719,15 @@ __metadata: "@typescript-eslint/parser": 8.31.1 "@typescript-eslint/typescript-estree": 8.31.1 "@typescript-eslint/utils": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 ajv: ^6.12.6 debug: ^4.3.4 + eslint: "*" prettier: ^3.2.5 rimraf: "*" ts-api-utils: ^2.0.1 typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.9.0" @@ -5723,12 +5738,12 @@ __metadata: version: 0.0.0-use.local resolution: "@typescript-eslint/types@workspace:packages/types" dependencies: - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 prettier: ^3.2.5 rimraf: "*" tsx: "*" typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 languageName: unknown linkType: soft @@ -5767,8 +5782,8 @@ __metadata: "@typescript-eslint/types": "workspace:^" "@typescript-eslint/typescript-estree": "workspace:^" "@typescript-eslint/utils": "workspace:^" - "@vitest/coverage-v8": ^3.1.1 - "@vitest/eslint-plugin": ^1.1.43 + "@vitest/coverage-v8": ^3.1.2 + "@vitest/eslint-plugin": ^1.1.44 console-fail-test: ^0.5.0 cross-fetch: ^4.0.0 cspell: ^8.15.2 @@ -5799,8 +5814,8 @@ __metadata: tsx: "*" typescript: ">=4.8.4 <5.9.0" typescript-eslint: "workspace:^" - vite: ^6.3.3 - vitest: ^3.1.1 + vite: ^6.3.4 + vitest: ^3.1.2 yargs: 17.7.2 languageName: unknown linkType: soft @@ -5811,7 +5826,7 @@ __metadata: dependencies: "@typescript-eslint/types": 8.31.1 "@typescript-eslint/visitor-keys": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 debug: ^4.3.4 fast-glob: ^3.3.2 glob: "*" @@ -5822,7 +5837,7 @@ __metadata: semver: ^7.6.0 ts-api-utils: ^2.0.1 typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 peerDependencies: typescript: ">=4.8.4 <5.9.0" languageName: unknown @@ -5836,11 +5851,11 @@ __metadata: "@typescript-eslint/scope-manager": 8.31.1 "@typescript-eslint/types": 8.31.1 "@typescript-eslint/typescript-estree": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 prettier: ^3.2.5 rimraf: "*" typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.9.0" @@ -5852,12 +5867,12 @@ __metadata: resolution: "@typescript-eslint/visitor-keys@workspace:packages/visitor-keys" dependencies: "@typescript-eslint/types": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 eslint-visitor-keys: ^4.2.0 prettier: ^3.2.5 rimraf: "*" typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 languageName: unknown linkType: soft @@ -5899,7 +5914,7 @@ __metadata: languageName: node linkType: hard -"@vitest/coverage-v8@npm:^3.1.1": +"@vitest/coverage-v8@npm:^3.1.2": version: 3.1.2 resolution: "@vitest/coverage-v8@npm:3.1.2" dependencies: @@ -5925,9 +5940,9 @@ __metadata: languageName: node linkType: hard -"@vitest/eslint-plugin@npm:^1.1.43": - version: 1.1.43 - resolution: "@vitest/eslint-plugin@npm:1.1.43" +"@vitest/eslint-plugin@npm:^1.1.44": + version: 1.1.44 + resolution: "@vitest/eslint-plugin@npm:1.1.44" peerDependencies: "@typescript-eslint/utils": ">= 8.24.0" eslint: ">= 8.57.0" @@ -5938,7 +5953,7 @@ __metadata: optional: true vitest: optional: true - checksum: dd036629703c53f5608afe503069f82719bf79c83ad067275e746d40e3c8e65735ed2a6a7d8692d3656cf530caa247b6447f9b2a0fae559e22af2a4ce43b32ec + checksum: bd78c75c01cb964888b0fb8c468469bbef3a4dcc25ed9618b82fd6b83c236ac54fad9dd9aa67d3da892796d4c982b9bcee37fa16a412744f50fc9a27ece3bb1f languageName: node linkType: hard @@ -6700,13 +6715,6 @@ __metadata: languageName: node linkType: hard -"assertion-error@npm:^1.1.0": - version: 1.1.0 - resolution: "assertion-error@npm:1.1.0" - checksum: fd9429d3a3d4fd61782eb3962ae76b6d08aa7383123fca0596020013b3ebd6647891a85b05ce821c47d1471ed1271f00b0545cf6a4326cf2fc91efcc3b0fbecf - languageName: node - linkType: hard - "assertion-error@npm:^2.0.1": version: 2.0.1 resolution: "assertion-error@npm:2.0.1" @@ -7294,21 +7302,6 @@ __metadata: languageName: node linkType: hard -"chai@npm:^4.4.1": - version: 4.5.0 - resolution: "chai@npm:4.5.0" - dependencies: - assertion-error: ^1.1.0 - check-error: ^1.0.3 - deep-eql: ^4.1.3 - get-func-name: ^2.0.2 - loupe: ^2.3.6 - pathval: ^1.1.1 - type-detect: ^4.1.0 - checksum: 70e5a8418a39e577e66a441cc0ce4f71fd551a650a71de30dd4e3e31e75ed1f5aa7119cf4baf4a2cb5e85c0c6befdb4d8a05811fad8738c1a6f3aa6a23803821 - languageName: node - linkType: hard - "chai@npm:^5.2.0": version: 5.2.0 resolution: "chai@npm:5.2.0" @@ -7383,15 +7376,6 @@ __metadata: languageName: node linkType: hard -"check-error@npm:^1.0.3": - version: 1.0.3 - resolution: "check-error@npm:1.0.3" - dependencies: - get-func-name: ^2.0.2 - checksum: e2131025cf059b21080f4813e55b3c480419256914601750b0fee3bd9b2b8315b531e551ef12560419b8b6d92a3636511322752b1ce905703239e7cc451b6399 - languageName: node - linkType: hard - "check-error@npm:^2.1.1": version: 2.1.1 resolution: "check-error@npm:2.1.1" @@ -8564,15 +8548,6 @@ __metadata: languageName: node linkType: hard -"deep-eql@npm:^4.1.3": - version: 4.1.3 - resolution: "deep-eql@npm:4.1.3" - dependencies: - type-detect: ^4.0.0 - checksum: 7f6d30cb41c713973dc07eaadded848b2ab0b835e518a88b91bea72f34e08c4c71d167a722a6f302d3a6108f05afd8e6d7650689a84d5d29ec7fe6220420397f - languageName: node - linkType: hard - "deep-eql@npm:^5.0.1": version: 5.0.2 resolution: "deep-eql@npm:5.0.2" @@ -9289,34 +9264,34 @@ __metadata: linkType: hard "esbuild@npm:^0.25.0": - version: 0.25.2 - resolution: "esbuild@npm:0.25.2" - dependencies: - "@esbuild/aix-ppc64": 0.25.2 - "@esbuild/android-arm": 0.25.2 - "@esbuild/android-arm64": 0.25.2 - "@esbuild/android-x64": 0.25.2 - "@esbuild/darwin-arm64": 0.25.2 - "@esbuild/darwin-x64": 0.25.2 - "@esbuild/freebsd-arm64": 0.25.2 - "@esbuild/freebsd-x64": 0.25.2 - "@esbuild/linux-arm": 0.25.2 - "@esbuild/linux-arm64": 0.25.2 - "@esbuild/linux-ia32": 0.25.2 - "@esbuild/linux-loong64": 0.25.2 - "@esbuild/linux-mips64el": 0.25.2 - "@esbuild/linux-ppc64": 0.25.2 - "@esbuild/linux-riscv64": 0.25.2 - "@esbuild/linux-s390x": 0.25.2 - "@esbuild/linux-x64": 0.25.2 - "@esbuild/netbsd-arm64": 0.25.2 - "@esbuild/netbsd-x64": 0.25.2 - "@esbuild/openbsd-arm64": 0.25.2 - "@esbuild/openbsd-x64": 0.25.2 - "@esbuild/sunos-x64": 0.25.2 - "@esbuild/win32-arm64": 0.25.2 - "@esbuild/win32-ia32": 0.25.2 - "@esbuild/win32-x64": 0.25.2 + version: 0.25.3 + resolution: "esbuild@npm:0.25.3" + dependencies: + "@esbuild/aix-ppc64": 0.25.3 + "@esbuild/android-arm": 0.25.3 + "@esbuild/android-arm64": 0.25.3 + "@esbuild/android-x64": 0.25.3 + "@esbuild/darwin-arm64": 0.25.3 + "@esbuild/darwin-x64": 0.25.3 + "@esbuild/freebsd-arm64": 0.25.3 + "@esbuild/freebsd-x64": 0.25.3 + "@esbuild/linux-arm": 0.25.3 + "@esbuild/linux-arm64": 0.25.3 + "@esbuild/linux-ia32": 0.25.3 + "@esbuild/linux-loong64": 0.25.3 + "@esbuild/linux-mips64el": 0.25.3 + "@esbuild/linux-ppc64": 0.25.3 + "@esbuild/linux-riscv64": 0.25.3 + "@esbuild/linux-s390x": 0.25.3 + "@esbuild/linux-x64": 0.25.3 + "@esbuild/netbsd-arm64": 0.25.3 + "@esbuild/netbsd-x64": 0.25.3 + "@esbuild/openbsd-arm64": 0.25.3 + "@esbuild/openbsd-x64": 0.25.3 + "@esbuild/sunos-x64": 0.25.3 + "@esbuild/win32-arm64": 0.25.3 + "@esbuild/win32-ia32": 0.25.3 + "@esbuild/win32-x64": 0.25.3 dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -9370,7 +9345,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 2c4e91948b939e711e9342e692fc3c8b0a95acbc1fc9c7628db6092c4aef7c32aa643b2782111625871756084536cebc4831b3f1d5c3b6bd4e4774e21bc4bbea + checksum: 1f9af51aa1d7d1f57e7294823d19ed69b0f6da413b7b0e8123abcebd1bb4011ef19961e2e6679c07301fcd00a85c4d102160fc40a91c25ceeaf594932509d84d languageName: node linkType: hard @@ -10769,13 +10744,6 @@ __metadata: languageName: node linkType: hard -"get-func-name@npm:^2.0.1, get-func-name@npm:^2.0.2": - version: 2.0.2 - resolution: "get-func-name@npm:2.0.2" - checksum: 3f62f4c23647de9d46e6f76d2b3eafe58933a9b3830c60669e4180d6c601ce1b4aa310ba8366143f55e52b139f992087a9f0647274e8745621fa2af7e0acf13b - languageName: node - linkType: hard - "get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6": version: 1.2.6 resolution: "get-intrinsic@npm:1.2.6" @@ -12425,14 +12393,7 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-coverage@npm:^3.0.0": - version: 3.2.0 - resolution: "istanbul-lib-coverage@npm:3.2.0" - checksum: a2a545033b9d56da04a8571ed05c8120bf10e9bce01cf8633a3a2b0d1d83dff4ac4fe78d6d5673c27fc29b7f21a41d75f83a36be09f82a61c367b56aa73c1ff9 - languageName: node - linkType: hard - -"istanbul-lib-coverage@npm:^3.2.2": +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.2": version: 3.2.2 resolution: "istanbul-lib-coverage@npm:3.2.2" checksum: 2367407a8d13982d8f7a859a35e7f8dd5d8f75aae4bb5484ede3a9ea1b426dc245aff28b976a2af48ee759fdd9be374ce2bd2669b644f31e76c5f46a2e29a831 @@ -13168,15 +13129,6 @@ __metadata: languageName: node linkType: hard -"loupe@npm:^2.3.6": - version: 2.3.7 - resolution: "loupe@npm:2.3.7" - dependencies: - get-func-name: ^2.0.1 - checksum: 96c058ec7167598e238bb7fb9def2f9339215e97d6685d9c1e3e4bdb33d14600e11fe7a812cf0c003dfb73ca2df374f146280b2287cae9e8d989e9d7a69a203b - languageName: node - linkType: hard - "loupe@npm:^3.1.0, loupe@npm:^3.1.3": version: 3.1.3 resolution: "loupe@npm:3.1.3" @@ -15514,13 +15466,6 @@ __metadata: languageName: node linkType: hard -"pathval@npm:^1.1.1": - version: 1.1.1 - resolution: "pathval@npm:1.1.1" - checksum: 090e3147716647fb7fb5b4b8c8e5b55e5d0a6086d085b6cd23f3d3c01fcf0ff56fd3cc22f2f4a033bd2e46ed55d61ed8379e123b42afe7d531a2a5fc8bb556d6 - languageName: node - linkType: hard - "pathval@npm:^2.0.0": version: 2.0.0 resolution: "pathval@npm:2.0.0" @@ -17164,29 +17109,29 @@ __metadata: linkType: hard "rollup@npm:^4.34.9": - version: 4.40.0 - resolution: "rollup@npm:4.40.0" - dependencies: - "@rollup/rollup-android-arm-eabi": 4.40.0 - "@rollup/rollup-android-arm64": 4.40.0 - "@rollup/rollup-darwin-arm64": 4.40.0 - "@rollup/rollup-darwin-x64": 4.40.0 - "@rollup/rollup-freebsd-arm64": 4.40.0 - "@rollup/rollup-freebsd-x64": 4.40.0 - "@rollup/rollup-linux-arm-gnueabihf": 4.40.0 - "@rollup/rollup-linux-arm-musleabihf": 4.40.0 - "@rollup/rollup-linux-arm64-gnu": 4.40.0 - "@rollup/rollup-linux-arm64-musl": 4.40.0 - "@rollup/rollup-linux-loongarch64-gnu": 4.40.0 - "@rollup/rollup-linux-powerpc64le-gnu": 4.40.0 - "@rollup/rollup-linux-riscv64-gnu": 4.40.0 - "@rollup/rollup-linux-riscv64-musl": 4.40.0 - "@rollup/rollup-linux-s390x-gnu": 4.40.0 - "@rollup/rollup-linux-x64-gnu": 4.40.0 - "@rollup/rollup-linux-x64-musl": 4.40.0 - "@rollup/rollup-win32-arm64-msvc": 4.40.0 - "@rollup/rollup-win32-ia32-msvc": 4.40.0 - "@rollup/rollup-win32-x64-msvc": 4.40.0 + version: 4.40.1 + resolution: "rollup@npm:4.40.1" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.40.1 + "@rollup/rollup-android-arm64": 4.40.1 + "@rollup/rollup-darwin-arm64": 4.40.1 + "@rollup/rollup-darwin-x64": 4.40.1 + "@rollup/rollup-freebsd-arm64": 4.40.1 + "@rollup/rollup-freebsd-x64": 4.40.1 + "@rollup/rollup-linux-arm-gnueabihf": 4.40.1 + "@rollup/rollup-linux-arm-musleabihf": 4.40.1 + "@rollup/rollup-linux-arm64-gnu": 4.40.1 + "@rollup/rollup-linux-arm64-musl": 4.40.1 + "@rollup/rollup-linux-loongarch64-gnu": 4.40.1 + "@rollup/rollup-linux-powerpc64le-gnu": 4.40.1 + "@rollup/rollup-linux-riscv64-gnu": 4.40.1 + "@rollup/rollup-linux-riscv64-musl": 4.40.1 + "@rollup/rollup-linux-s390x-gnu": 4.40.1 + "@rollup/rollup-linux-x64-gnu": 4.40.1 + "@rollup/rollup-linux-x64-musl": 4.40.1 + "@rollup/rollup-win32-arm64-msvc": 4.40.1 + "@rollup/rollup-win32-ia32-msvc": 4.40.1 + "@rollup/rollup-win32-x64-msvc": 4.40.1 "@types/estree": 1.0.7 fsevents: ~2.3.2 dependenciesMeta: @@ -17234,7 +17179,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 4826d7bbb48147403023133b6d8a67f792efe3463def637713bed392b5d7fc9903b4b86de44c58420304beca9e8d108268036e9081fff675af6c01822ef6b2b9 + checksum: b25c1a20192bc7d6a483c6dc61f93899fed8d6fbdf42a92f843ed3ab0f729485325e5d2e86b7039a0bd1f4c0eb786f5d8f6054b99e7e1f72dfa2206a528f2b4e languageName: node linkType: hard @@ -18897,7 +18842,7 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:^4.0.0, type-detect@npm:^4.0.8, type-detect@npm:^4.1.0": +"type-detect@npm:^4.0.8": version: 4.1.0 resolution: "type-detect@npm:4.1.0" checksum: 3b32f873cd02bc7001b00a61502b7ddc4b49278aabe68d652f732e1b5d768c072de0bc734b427abf59d0520a5f19a2e07309ab921ef02018fa1cb4af155cdb37 @@ -19051,11 +18996,11 @@ __metadata: "@typescript-eslint/eslint-plugin": 8.31.1 "@typescript-eslint/parser": 8.31.1 "@typescript-eslint/utils": 8.31.1 - "@vitest/coverage-v8": ^3.1.1 + "@vitest/coverage-v8": ^3.1.2 prettier: ^3.2.5 rimraf: "*" typescript: "*" - vitest: ^3.1.1 + vitest: ^3.1.2 peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.9.0" @@ -19486,9 +19431,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.0 || ^6.0.0, vite@npm:^6.3.3": - version: 6.3.3 - resolution: "vite@npm:6.3.3" +"vite@npm:^5.0.0 || ^6.0.0, vite@npm:^6.3.4": + version: 6.3.4 + resolution: "vite@npm:6.3.4" dependencies: esbuild: ^0.25.0 fdir: ^6.4.4 @@ -19537,11 +19482,11 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: b12dcd715324d5033226005b514f281541578d619675724c6ba0f684efe875d145ae53404fc7dc604332f2b52b5bd197ed6b6edea219abd604336052f3f3c79e + checksum: 6b86f267319342393d2aeea3436d64716dd6d769acd96b13f9be416f751f4f3380119594baebb2ead71f738c6bd20956017320fad4cd79ba00168f4b9a747393 languageName: node linkType: hard -"vitest@npm:^3.1.1": +"vitest@npm:^3.1.2": version: 3.1.2 resolution: "vitest@npm:3.1.2" dependencies: