diff --git a/.changeset/strong-dragons-check.md b/.changeset/strong-dragons-check.md new file mode 100644 index 0000000000..285a9a670e --- /dev/null +++ b/.changeset/strong-dragons-check.md @@ -0,0 +1,10 @@ +--- +"@definitelytyped/dtslint": patch +"@definitelytyped/eslint-plugin": patch +"@definitelytyped/typescript-packages": patch +"@definitelytyped/typescript-versions": patch +"@definitelytyped/utils": patch +--- + +Add TypeScript 7.0 and 7.1 support through the Corsa compiler API, including compiler diagnostics, `$ExpectType` +assertions, version-ranged `@ts-expect-error` directives, multi-project failure reporting, and local TypeScript packages. diff --git a/.changeset/tidy-tigers-compile.md b/.changeset/tidy-tigers-compile.md new file mode 100644 index 0000000000..85e1c05568 --- /dev/null +++ b/.changeset/tidy-tigers-compile.md @@ -0,0 +1,8 @@ +--- +"@definitelytyped/dts-critic": patch +"@definitelytyped/dtslint": patch +"@definitelytyped/eslint-plugin": patch +"dts-gen": patch +--- + +Upgrade bundled TypeScript dependencies to 6.0 and update TypeScript ESLint dependencies for compatibility. diff --git a/package.json b/package.json index b25c424fb1..3f083e45d6 100644 --- a/package.json +++ b/package.json @@ -19,16 +19,16 @@ "@types/jest": "^30.0.0", "@types/node": "^25.3.3", "@types/yargs": "^17.0.35", - "@typescript-eslint/eslint-plugin": "^8.56.1", - "@typescript-eslint/parser": "^8.56.1", + "@typescript-eslint/eslint-plugin": "^8.67.0", + "@typescript-eslint/parser": "^8.67.0", "eslint": "^8.57.1", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsdoc": "^48.11.0", "jest": "^30.2.0", "knip": "^5.85.0", "prettier": "^3.8.1", - "ts-jest": "^29.4.6", - "typescript": "^5.9.3" + "ts-jest": "^29.4.12", + "typescript": "^6.0.3" }, "pnpm": { "overrides": { diff --git a/packages/definitions-parser/package.json b/packages/definitions-parser/package.json index 036f5a9a29..dc584eb7c0 100644 --- a/packages/definitions-parser/package.json +++ b/packages/definitions-parser/package.json @@ -29,7 +29,7 @@ }, "devDependencies": { "@types/pacote": "^11.1.8", - "typescript": "^5.9.3" + "typescript": "^6.0.3" }, "peerDependencies": { "typescript": "<7" diff --git a/packages/dts-critic/package.json b/packages/dts-critic/package.json index 30d7741cef..3826b69959 100644 --- a/packages/dts-critic/package.json +++ b/packages/dts-critic/package.json @@ -8,13 +8,12 @@ }, "dependencies": { "@definitelytyped/header-parser": "workspace:*", - "typescript": "^5.9.3", + "typescript": "^6.0.3", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "<7" }, - "devDependencies": {}, "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { diff --git a/packages/dts-gen/package.json b/packages/dts-gen/package.json index 1b9c9f3d05..af8cdb91f4 100644 --- a/packages/dts-gen/package.json +++ b/packages/dts-gen/package.json @@ -25,7 +25,7 @@ }, "dependencies": { "dts-dom": "^3.7.0", - "typescript": "^5.9.3", + "typescript": "^6.0.3", "which": "^6.0.1", "yargs": "^17.7.2" }, diff --git a/packages/dtslint/README.md b/packages/dtslint/README.md index 4e8aeaa1cb..2d2b4c8a69 100644 --- a/packages/dtslint/README.md +++ b/packages/dtslint/README.md @@ -182,6 +182,13 @@ Use your locally installed version of TypeScript. ```sh dtslint --localTs node_modules/typescript/lib types ``` + +For TypeScript 7, pass the TypeScript package directory after building both the native compiler and JavaScript API: + +```sh +dtslint --localTs ../TypeScript/packages/typescript types +``` + - `--expectOnly` Disable all the lint rules except the one that checks for type correctness. diff --git a/packages/dtslint/package.json b/packages/dtslint/package.json index d3173cedd7..f67f512653 100644 --- a/packages/dtslint/package.json +++ b/packages/dtslint/package.json @@ -28,23 +28,21 @@ "@definitelytyped/typescript-packages": "workspace:*", "@definitelytyped/typescript-versions": "workspace:*", "@definitelytyped/utils": "workspace:*", - "@typescript-eslint/eslint-plugin": "^8.56.1", - "@typescript-eslint/parser": "^8.56.1", - "@typescript-eslint/types": "^8.56.1", - "@typescript-eslint/typescript-estree": "^8.56.1", - "@typescript-eslint/utils": "^8.56.1", + "@typescript-eslint/eslint-plugin": "^8.67.0", + "@typescript-eslint/parser": "^8.67.0", + "@typescript-eslint/types": "^8.67.0", + "@typescript-eslint/typescript-estree": "^8.67.0", + "@typescript-eslint/utils": "^8.67.0", "eslint": "^8.57.1", "eslint-plugin-import": "^2.32.0", "semver": "^7.7.4", - "strip-json-comments": "^3.1.1" - }, - "peerDependencies": { - "typescript": "<7" + "strip-json-comments": "^3.1.1", + "typescript": "^6.0.3" }, "devDependencies": { "@types/eslint": "^8.56.12", "@types/semver": "^7.7.1", - "typescript": "^5.9.3" + "typescript-7.1": "npm:typescript@~7.1.0-0" }, "engines": { "node": ">=20.17.0" diff --git a/packages/dtslint/src/index.ts b/packages/dtslint/src/index.ts index 64ca690d68..2b845e11f6 100644 --- a/packages/dtslint/src/index.ts +++ b/packages/dtslint/src/index.ts @@ -91,6 +91,9 @@ async function main(): Promise { if (onlyNpmChecks && skipNpmChecks) { throw new Error("Cannot use --onlyNpmChecks and --skipNpmChecks together."); } + if (onlyTestTsNext && tsLocal) { + throw new Error("Cannot use --onlyTestTsNext and --localTs together."); + } if (lookingForTsLocal) { throw new Error("Path for --localTs was not provided."); } @@ -299,7 +302,7 @@ async function testTypesVersion( } } - const err = await lint(dirPath, lowVersion, hiVersion, isLatest, expectOnly, tsLocal); + const err = await lint(dirPath, tsconfigs, lowVersion, hiVersion, isLatest, expectOnly, tsLocal); if (err) { errors.push(err); } diff --git a/packages/dtslint/src/lint.ts b/packages/dtslint/src/lint.ts index e560b21290..2c62d2a374 100644 --- a/packages/dtslint/src/lint.ts +++ b/packages/dtslint/src/lint.ts @@ -6,10 +6,12 @@ import { ESLint } from "eslint"; import * as TsType from "typescript"; import { createProgram } from "./createProgram"; -import { typeScriptPath } from "./typescript-installer"; +import { lintCorsaVersions } from "./lintCorsa"; +import { resolveLocalTypeScript, typeScriptPath } from "./typescript-installer"; export async function lint( dirPath: string, + tsconfigs: readonly string[], minVersion: TsVersion, maxVersion: TsVersion, isLatest: boolean, @@ -31,17 +33,38 @@ export async function lint( return files; } - const options = getEslintOptions(expectOnly, minVersion, maxVersion, tsLocal); - const eslint = new ESLint(options); - const formatter = await eslint.loadFormatter("stylish"); - const results = await eslint.lintFiles(files); - const output = formatter.format(results); - for (const estreePath of estrees) { - if (!estreePath) continue; - const estree = require(estreePath) as typeof import("@typescript-eslint/typescript-estree"); - estree.clearCaches(); + const versions = range(minVersion, maxVersion); + const legacyVersions: TsVersion[] = []; + const corsaVersions: TsVersion[] = []; + for (const version of versions) { + (usesCorsa(version, tsLocal) ? corsaVersions : legacyVersions).push(version); } - return output; + + const outputs: string[] = []; + if (!expectOnly || legacyVersions.length) { + const options = getEslintOptions(expectOnly, legacyVersions, tsLocal); + const eslint = new ESLint(options); + const formatter = await eslint.loadFormatter("stylish"); + const results = await eslint.lintFiles(files); + const output = await formatter.format(results); + if (output) { + outputs.push(output); + } + for (const estreePath of estrees) { + if (!estreePath) continue; + const estree = require(estreePath) as typeof import("@typescript-eslint/typescript-estree"); + estree.clearCaches(); + } + } + + if (corsaVersions.length) { + const output = await lintCorsaVersions(dirPath, tsconfigs, corsaVersions, isLatest, tsLocal, files); + if (output) { + outputs.push(output); + } + } + + return outputs.join("\n") || undefined; } function getSourceFiles(dirPath: string, isLatest: boolean) { @@ -84,11 +107,10 @@ function tryResolve(path: string, options?: { paths?: string[] | undefined }): s function getEslintOptions( expectOnly: boolean, - minVersion: TsVersion, - maxVersion: TsVersion, + versions: readonly TsVersion[], tsLocal: string | undefined, ): ESLint.Options { - const versionsToTest = range(minVersion, maxVersion).map((versionName) => ({ + const versionsToTest = versions.map((versionName) => ({ versionName, path: typeScriptPath(versionName, tsLocal), })); @@ -105,8 +127,8 @@ function getEslintOptions( { files: allFiles, rules: { - // This prevents anyone from disabling this rule. - "@definitelytyped/expect": ["error"], + // This prevents anyone from disabling this rule when it is responsible for ExpectType. + "@definitelytyped/expect": versions.length ? ["error"] : "off", }, }, ], @@ -196,7 +218,7 @@ function range(minVersion: TsVersion, maxVersion: TsVersion): readonly TsVersion const minIdx = TypeScriptVersion.supported.indexOf(minVersion); assert(minIdx >= 0); if (maxVersion === TypeScriptVersion.latest) { - return [...TypeScriptVersion.supported.slice(minIdx), TypeScriptVersion.latest]; + return TypeScriptVersion.supported.slice(minIdx); } const maxIdx = TypeScriptVersion.supported.indexOf(maxVersion as TypeScriptVersion); assert(maxIdx >= minIdx); @@ -204,3 +226,12 @@ function range(minVersion: TsVersion, maxVersion: TsVersion): readonly TsVersion } export type TsVersion = TypeScriptVersion | "local"; + +function usesCorsa(version: TsVersion, tsLocal: string | undefined): boolean { + if (version !== "local") { + return parseFloat(version) >= 7; + } + + assert(tsLocal); + return resolveLocalTypeScript(tsLocal).kind === "corsa"; +} diff --git a/packages/dtslint/src/lintCorsa.ts b/packages/dtslint/src/lintCorsa.ts new file mode 100644 index 0000000000..c48563db07 --- /dev/null +++ b/packages/dtslint/src/lintCorsa.ts @@ -0,0 +1,391 @@ +import { TypeScriptVersion } from "@definitelytyped/typescript-versions"; +import * as typeScriptPackages from "@definitelytyped/typescript-packages"; +import { isVersionedExpectErrorOutsideRange } from "@definitelytyped/utils"; +import fs from "fs"; +import path from "path"; +import * as ts from "typescript"; +import type { Diagnostic, Project } from "typescript-7.1/unstable/sync"; +import type { Node, SourceFile } from "typescript-7.1/unstable/ast"; +import type { TsVersion } from "./lint"; +import { resolveLocalTypeScript } from "./typescript-installer"; + +type CorsaApi = typeof import("typescript-7.1/unstable/sync"); +type CorsaAst = typeof import("typescript-7.1/unstable/ast"); + +interface Failure { + readonly fileName?: string; + readonly start?: number; + readonly end?: number; + readonly message: string; +} + +const expectTypeToken = "$ExpectType"; + +export async function lintCorsaVersions( + dirPath: string, + tsconfigs: readonly string[], + versions: readonly TsVersion[], + isLatest: boolean, + tsLocal: string | undefined, + sourceFiles?: readonly string[], +): Promise { + const reportTsconfigName = tsconfigs.length !== 1 || tsconfigs[0] !== "tsconfig.json"; + const failures = new Map }>(); + + for (const version of versions) { + const localTypeScript = version === "local" ? resolveLocalTypeScript(tsLocal!) : undefined; + if (localTypeScript?.kind === "legacy") { + throw new Error(`Expected a TypeScript package exposing unstable/sync and unstable/ast at ${tsLocal}.`); + } + const clientVersion = version === "local" ? TypeScriptVersion.latest : version; + const apiPath = localTypeScript?.apiPath ?? typeScriptPackages.resolve(clientVersion, "unstable/sync"); + const astPath = localTypeScript?.astPath ?? typeScriptPackages.resolve(clientVersion, "unstable/ast"); + const apiModule = require(apiPath) as CorsaApi; + const astModule = require(astPath) as CorsaAst; + const rangeVersion = localTypeScript?.version ?? version; + const api = new apiModule.API({ cwd: dirPath }); + const configPaths = tsconfigs.map((config) => path.resolve(dirPath, config)); + const matchedFiles = new Set(); + + try { + const snapshot = api.updateSnapshot({ openProjects: configPaths }); + try { + for (let i = 0; i < configPaths.length; i++) { + const configPath = configPaths[i]; + const run = `${version} ${tsconfigs[i]}`; + const project = snapshot.getProject(configPath); + if (!project) { + addFailures([{ message: `could not open ${configPath}.` }], run); + continue; + } + for (const fileName of project.program.getSourceFileNames()) { + matchedFiles.add(normalizePath(fileName)); + } + addFailures(getDiagnosticFailures(project, dirPath, rangeVersion, isLatest), run); + addFailures(getExpectTypeFailures(project, apiModule, astModule, dirPath, isLatest), run); + } + } finally { + snapshot.dispose(); + } + } finally { + api.close(); + } + + for (const fileName of sourceFiles ?? []) { + if (!matchedFiles.has(normalizePath(fileName))) { + addFailures([{ fileName, start: 0, message: "could not find a tsconfig that includes this file." }], version); + } + } + } + + return formatFailures( + [...failures.values()].map(({ failure, runs }) => ({ + ...failure, + message: `TypeScript@${formatRuns(runs, reportTsconfigName)} ${failure.message}`, + })), + ); + + function addFailures(newFailures: readonly Failure[], run: string): void { + for (const failure of newFailures) { + const key = JSON.stringify(failure); + let existing = failures.get(key); + if (!existing) { + failures.set(key, (existing = { failure, runs: new Set() })); + } + existing.runs.add(run); + } + } +} + +function formatRuns(runs: ReadonlySet, reportTsconfigName: boolean): string { + return [...runs] + .sort() + .map((run) => (reportTsconfigName ? run : run.split(" ")[0])) + .join(", "); +} + +function getDiagnosticFailures(project: Project, dirPath: string, version: string, isLatest: boolean): Failure[] { + const diagnostics = [ + ...project.program.getConfigFileParsingDiagnostics(), + ...project.program.getProgramDiagnostics(), + ...project.program.getGlobalDiagnostics(), + ]; + const compilerOptions = project.program.getCompilerOptions(); + const checkDeclarationDiagnostics = compilerOptions.declaration || compilerOptions.composite; + + // TODO: Keep this aligned with the legacy expect rule's getPreEmitDiagnostics(program, sourceFile) calls. + // dtslint historically reports diagnostics only for files it lints, suppressing errors inside dependencies. + for (const fileName of project.program.getSourceFileNames()) { + const sourceFile = project.program.getSourceFile(fileName); + const metadata = project.program.getSourceFileMetadata(fileName); + if ( + !sourceFile || + metadata?.isDefaultLibrary || + metadata?.isFromExternalLibrary || + !startsWithDirectory(fileName, dirPath) || + (isLatest && isTypesVersionPath(fileName, dirPath)) + ) { + continue; + } + diagnostics.push( + ...project.program.getSyntacticDiagnostics(fileName), + ...project.program.getSemanticDiagnostics(fileName), + ); + if (checkDeclarationDiagnostics) { + diagnostics.push(...project.program.getDeclarationDiagnostics(fileName)); + } + } + const failures = new Map(); + + for (const diagnostic of diagnostics) { + if (diagnostic.code === 2578 && isDiagnosticOutsideExpectErrorRange(diagnostic, project, version)) { + continue; + } + const failure = { + fileName: diagnostic.fileName, + start: diagnostic.pos >= 0 ? diagnostic.pos : undefined, + end: diagnostic.end >= 0 ? diagnostic.end : undefined, + message: `compile error TS${diagnostic.code}:\n${flattenDiagnostic(diagnostic)}`, + }; + failures.set(JSON.stringify(failure), failure); + } + return [...failures.values()]; +} + +function isDiagnosticOutsideExpectErrorRange(diagnostic: Diagnostic, project: Project, version: string): boolean { + if (!diagnostic.fileName || diagnostic.pos < 0 || diagnostic.end < diagnostic.pos) { + return false; + } + const sourceFile = project.program.getSourceFile(diagnostic.fileName); + if (!sourceFile) { + return false; + } + const text = sourceFile.text.slice(diagnostic.pos, diagnostic.end); + return isVersionedExpectErrorOutsideRange(text, version); +} + +function flattenDiagnostic(diagnostic: Diagnostic): string { + if (!diagnostic.messageChain?.length) { + return diagnostic.text; + } + return [diagnostic.text, ...diagnostic.messageChain.map(flattenDiagnostic)].join("\n"); +} + +function getExpectTypeFailures( + project: Project, + apiModule: CorsaApi, + astModule: CorsaAst, + dirPath: string, + isLatest: boolean, +): Failure[] { + const failures: Failure[] = []; + for (const fileName of project.program.getSourceFileNames()) { + const sourceFile = project.program.getSourceFile(fileName); + const metadata = project.program.getSourceFileMetadata(fileName); + if ( + !sourceFile || + metadata?.isDefaultLibrary || + metadata?.isFromExternalLibrary || + !startsWithDirectory(fileName, dirPath) || + (isLatest && isTypesVersionPath(fileName, dirPath)) || + sourceFile.isDeclarationFile || + !sourceFile.text.includes(expectTypeToken) + ) { + continue; + } + + const { typeAssertions, duplicates } = parseAssertions(sourceFile); + for (const line of duplicates) { + failures.push(failureAtLine(sourceFile, line, "This line has 2 $ExpectType assertions.")); + } + + sourceFile.forEachChild(function visit(node) { + if (node.kind === astModule.SyntaxKind.EndOfFile) { + return; + } + const line = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line; + const expected = typeAssertions.get(line); + if (expected !== undefined) { + const target = getNodeForExpectType(node, astModule); + const type = project.checker.getTypeAtLocation(target); + const actual = + type === undefined + ? "" + : project.checker.typeToString(type, undefined, apiModule.NodeBuilderFlags.NoTruncation); + if (!typeStringsMatch(expected, actual)) { + failures.push({ + fileName, + start: node.getStart(sourceFile), + end: node.getEnd(), + message: `expected type to be:\n ${expected}\ngot:\n ${actual}`, + }); + } + typeAssertions.delete(line); + } + node.forEachChild(visit); + }); + + for (const line of typeAssertions.keys()) { + failures.push( + failureAtLine( + sourceFile, + line - 1, + "Cannot match a node to this assertion. If this is a multiline function call, ensure the assertion is on the line above.", + ), + ); + } + } + return failures; +} + +function typeStringsMatch(expected: string, actual: string): boolean { + const candidates = expected.split(/\s*\|\|\s*/).map((candidate) => candidate.trim()); + if (candidates.includes(actual)) { + return true; + } + const actualNormalized = normalizedTypeToString(actual); + return candidates.some((candidate) => normalizedTypeToString(candidate) === actualNormalized); +} + +function normalizedTypeToString(type: string): string { + const sourceFile = ts.createSourceFile("type.ts", `declare var x: ${type};`, ts.ScriptTarget.Latest); + const typeNode = (sourceFile.statements[0] as ts.VariableStatement).declarationList.declarations[0].type!; + const printer = ts.createPrinter({}); + const context = (ts as typeof ts & { nullTransformationContext: ts.TransformationContext }).nullTransformationContext; + + function print(node: ts.Node): string { + return printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); + } + function visit(node: ts.Node): ts.VisitResult { + node = ts.visitEachChild(node, visit, context); + if (ts.isUnionTypeNode(node)) { + const types = node.types + .map((item) => [item, print(item)] as const) + .sort((a, b) => a[1].localeCompare(b[1])) + .map(([item]) => item); + return ts.factory.updateUnionTypeNode(node, ts.factory.createNodeArray(types)); + } + if (ts.isTypeLiteralNode(node) && node.members.every(ts.isPropertySignature)) { + const members = [...node.members].sort((a, b) => print(a).localeCompare(print(b))); + return ts.factory.updateTypeLiteralNode(node, ts.factory.createNodeArray(members)); + } + if ( + ts.isTypeOperatorNode(node) && + node.operator === ts.SyntaxKind.ReadonlyKeyword && + ts.isArrayTypeNode(node.type) + ) { + return ts.factory.createTypeReferenceNode("ReadonlyArray", [skipTypeParentheses(node.type.elementType)]); + } + return node; + } + + return print(ts.visitNode(typeNode, visit)); +} + +function skipTypeParentheses(node: ts.TypeNode): ts.TypeNode { + while (ts.isParenthesizedTypeNode(node)) { + node = node.type; + } + return node; +} + +function getNodeForExpectType(node: Node, astModule: CorsaAst): Node { + if (astModule.isExpressionStatement(node)) { + return node.expression; + } + if (astModule.isVariableStatement(node) && node.declarationList.declarations.length === 1) { + return node.declarationList.declarations[0].initializer ?? node; + } + return node; +} + +interface Assertions { + readonly typeAssertions: Map; + readonly duplicates: readonly number[]; +} + +function parseAssertions(sourceFile: SourceFile): Assertions { + const typeAssertions = new Map(); + const duplicates: number[] = []; + const commentRegexp = /^(.*?)\/\/(.*)$/gm; + const lineStarts = sourceFile.getLineStarts(); + let currentLine = 0; + + while (true) { + const commentMatch = commentRegexp.exec(sourceFile.text); + if (!commentMatch) { + break; + } + const comment = commentMatch[2].trim(); + if (!comment.startsWith(expectTypeToken)) { + continue; + } + const commentPosition = commentMatch.index + commentMatch[1].length; + while (lineStarts[currentLine + 1] <= commentPosition) { + currentLine++; + } + const line = isFirstOnLine(sourceFile.text, lineStarts[currentLine], commentPosition) + ? currentLine + 1 + : currentLine; + const expectedType = comment.slice(expectTypeToken.length).trim(); + if (typeAssertions.delete(line)) { + duplicates.push(line); + } else { + typeAssertions.set(line, expectedType); + } + } + return { typeAssertions, duplicates }; +} + +function isFirstOnLine(text: string, lineStart: number, position: number): boolean { + for (let i = lineStart; i < position; i++) { + if (text[i] !== " ") { + return false; + } + } + return true; +} + +function failureAtLine(sourceFile: SourceFile, line: number, message: string): Failure { + const start = sourceFile.getPositionOfLineAndCharacter(line, 0); + let end = start + sourceFile.text.split("\n")[line].length; + if (sourceFile.text[end - 1] === "\r") { + end--; + } + return { fileName: sourceFile.fileName, start, end, message }; +} + +function formatFailures(failures: readonly Failure[]): string | undefined { + if (!failures.length) { + return undefined; + } + return failures + .map((failure) => { + if (!failure.fileName || failure.start === undefined) { + return failure.message; + } + const text = fs.readFileSync(failure.fileName, "utf8"); + const sourceFile = ts.createSourceFile(failure.fileName, text, ts.ScriptTarget.Latest); + const { line, character } = sourceFile.getLineAndCharacterOfPosition(failure.start); + return `${failure.fileName}:${line + 1}:${character + 1}\n${failure.message}`; + }) + .join("\n\n"); +} + +function normalizePath(fileName: string): string { + return path + .normalize(fileName) + .replace(/\\/g, "/") + .replace(/^[a-z](?=:)/, (character) => character.toUpperCase()); +} + +function startsWithDirectory(fileName: string, dirPath: string): boolean { + const normalizedFileName = normalizePath(fileName); + const normalizedDirPath = normalizePath(dirPath).replace(/\/$/, ""); + return normalizedFileName.startsWith(normalizedDirPath + "/"); +} + +function isTypesVersionPath(fileName: string, dirPath: string): boolean { + const subdirPath = normalizePath(fileName).slice(normalizePath(dirPath).length); + return /^\/ts\d+\.\d/.test(subdirPath); +} diff --git a/packages/dtslint/src/typescript-installer.ts b/packages/dtslint/src/typescript-installer.ts index bdcfe4c78a..a4abae0086 100644 --- a/packages/dtslint/src/typescript-installer.ts +++ b/packages/dtslint/src/typescript-installer.ts @@ -1,11 +1,94 @@ import { TypeScriptVersion } from "@definitelytyped/typescript-versions"; import * as typeScriptPackages from "@definitelytyped/typescript-packages"; +import fs from "fs"; +import { createRequire } from "module"; +import path from "path"; export type TsVersion = TypeScriptVersion | "local"; +export type LocalTypeScript = + | { readonly kind: "legacy"; readonly compilerPath: string } + | { + readonly kind: "corsa"; + readonly apiPath: string; + readonly astPath: string; + readonly version: string; + }; + export function typeScriptPath(version: TsVersion, tsLocal: string | undefined): string { if (version === "local") { - return tsLocal! + "/typescript.js"; + const localTypeScript = resolveLocalTypeScript(tsLocal!); + if (localTypeScript.kind !== "legacy") { + throw new Error(`Expected a TypeScript compiler library at ${tsLocal}.`); + } + return localTypeScript.compilerPath; } return typeScriptPackages.resolve(version); } + +export function resolveLocalTypeScript(tsLocal: string): LocalTypeScript { + if (!fs.existsSync(tsLocal)) { + throw new Error(`Could not find the TypeScript build at ${tsLocal}.`); + } + + const stat = fs.statSync(tsLocal); + if (stat.isFile()) { + if (/\.[cm]?js$/i.test(tsLocal)) { + return { kind: "legacy", compilerPath: tsLocal }; + } + throw new Error(`The file at ${tsLocal} is not a TypeScript compiler library.`); + } + if (!stat.isDirectory()) { + throw new Error(`The TypeScript build path ${tsLocal} is not a file or directory.`); + } + + const compilerPath = path.join(tsLocal, "typescript.js"); + if (fs.existsSync(compilerPath) && fs.statSync(compilerPath).isFile()) { + return { kind: "legacy", compilerPath }; + } + + const packageJsonPath = path.join(tsLocal, "package.json"); + if (!fs.existsSync(packageJsonPath) || !fs.statSync(packageJsonPath).isFile()) { + throw new Error(`The directory at ${tsLocal} does not contain typescript.js or package.json.`); + } + + let packageJson: { readonly name?: unknown }; + try { + packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as { readonly name?: unknown }; + } catch (error) { + throw new Error(`Could not read the TypeScript package at ${tsLocal}.`, { cause: error }); + } + if (typeof packageJson.name !== "string") { + throw new Error(`The package at ${tsLocal} does not have a valid name.`); + } + + const localRequire = createRequire(packageJsonPath); + try { + const versionModule = localRequire(packageJson.name) as { + readonly version?: unknown; + readonly versionMajorMinor?: unknown; + }; + const version = isCorsaVersion(versionModule.version) ? versionModule.version : versionModule.versionMajorMinor; + if (!isCorsaVersion(version)) { + throw new Error(`The package reports an unsupported TypeScript version: ${String(version)}.`); + } + return { + kind: "corsa", + apiPath: localRequire.resolve(`${packageJson.name}/unstable/sync`), + astPath: localRequire.resolve(`${packageJson.name}/unstable/ast`), + version, + }; + } catch (error) { + throw new Error(`The package at ${tsLocal} does not expose usable unstable/sync and unstable/ast entrypoints.`, { + cause: error, + }); + } +} + +function isCorsaVersion(version: unknown): version is string { + if (typeof version !== "string") { + return false; + } + const major = /^(\d+)(?:\.|$)/.exec(version)?.[1]; + return major !== undefined && Number.parseInt(major, 10) >= 7; +} diff --git a/packages/dtslint/test/corsa-eslint/.eslintrc.json b/packages/dtslint/test/corsa-eslint/.eslintrc.json new file mode 100644 index 0000000000..e3ba04dd16 --- /dev/null +++ b/packages/dtslint/test/corsa-eslint/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": true + }, + "plugins": ["@typescript-eslint"], + "rules": { + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "interface", + "format": [], + "custom": { + "regex": "^I[A-Z]", + "match": false + } + } + ], + "no-var": "error" + } +} diff --git a/packages/dtslint/test/corsa-eslint/index.d.ts b/packages/dtslint/test/corsa-eslint/index.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/packages/dtslint/test/corsa-eslint/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/dtslint/test/corsa-eslint/test.cts b/packages/dtslint/test/corsa-eslint/test.cts new file mode 100644 index 0000000000..3e4a26fb75 --- /dev/null +++ b/packages/dtslint/test/corsa-eslint/test.cts @@ -0,0 +1,4 @@ +export interface IFoo {} + +var value = 1; +value; diff --git a/packages/dtslint/test/corsa-eslint/tsconfig.json b/packages/dtslint/test/corsa-eslint/tsconfig.json new file mode 100644 index 0000000000..ea4774bacb --- /dev/null +++ b/packages/dtslint/test/corsa-eslint/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noEmit": true, + "strict": true, + "target": "esnext" + }, + "files": ["index.d.ts", "test.cts"] +} diff --git a/packages/dtslint/test/fixtures/corsa/external/index.d.ts b/packages/dtslint/test/fixtures/corsa/external/index.d.ts new file mode 100644 index 0000000000..5be6dc8f0d --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/external/index.d.ts @@ -0,0 +1,3 @@ +export interface ExternalType { + broken: MissingType; +} diff --git a/packages/dtslint/test/fixtures/corsa/fail/index.d.ts b/packages/dtslint/test/fixtures/corsa/fail/index.d.ts new file mode 100644 index 0000000000..4c05c227e7 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/fail/index.d.ts @@ -0,0 +1 @@ +export declare function literal(): 1; diff --git a/packages/dtslint/test/fixtures/corsa/fail/test.ts b/packages/dtslint/test/fixtures/corsa/fail/test.ts new file mode 100644 index 0000000000..916e74ee39 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/fail/test.ts @@ -0,0 +1,26 @@ +import { literal } from "./index"; + +// $ExpectType 2 +literal(); + +const bad: string = 1; + +// @ts-expect-error >=7.0 +const unusedInTypeScript7: string = ""; + +// @ts-expect-error >=7.1 +const unusedInTypeScript71: string = ""; + +declare const overloaded: { + (value: string): string; + (value: number): number; +}; +// $ExpectType { (value: number): number; (value: string): string; } +overloaded; + +declare const overloadedMethod: { + method(value: string): string; + method(value: number): number; +}; +// $ExpectType { method(value: number): number; method(value: string): string; } +overloadedMethod; diff --git a/packages/dtslint/test/fixtures/corsa/fail/tsconfig.alternate.json b/packages/dtslint/test/fixtures/corsa/fail/tsconfig.alternate.json new file mode 100644 index 0000000000..7f9cd80f95 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/fail/tsconfig.alternate.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "module": "node16", + "lib": ["es2024"], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": ["index.d.ts", "test.ts"] +} diff --git a/packages/dtslint/test/fixtures/corsa/fail/tsconfig.json b/packages/dtslint/test/fixtures/corsa/fail/tsconfig.json new file mode 100644 index 0000000000..b918e4146a --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/fail/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noEmit": true, + "strict": true, + "target": "esnext" + }, + "files": ["index.d.ts", "test.ts"] +} diff --git a/packages/dtslint/test/fixtures/corsa/partial/excluded.ts b/packages/dtslint/test/fixtures/corsa/partial/excluded.ts new file mode 100644 index 0000000000..eb6593d5d9 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/partial/excluded.ts @@ -0,0 +1 @@ +const excluded: string = 1; diff --git a/packages/dtslint/test/fixtures/corsa/partial/included.ts b/packages/dtslint/test/fixtures/corsa/partial/included.ts new file mode 100644 index 0000000000..7d3fb8a2a0 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/partial/included.ts @@ -0,0 +1,3 @@ +import { value } from "./index"; + +value; diff --git a/packages/dtslint/test/fixtures/corsa/partial/index.d.ts b/packages/dtslint/test/fixtures/corsa/partial/index.d.ts new file mode 100644 index 0000000000..a5987fbd29 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/partial/index.d.ts @@ -0,0 +1 @@ +export declare const value: string; diff --git a/packages/dtslint/test/fixtures/corsa/partial/tsconfig.alternate.json b/packages/dtslint/test/fixtures/corsa/partial/tsconfig.alternate.json new file mode 100644 index 0000000000..f479797400 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/partial/tsconfig.alternate.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noEmit": true, + "strict": true, + "target": "esnext" + }, + "files": ["index.d.ts", "included.ts"] +} diff --git a/packages/dtslint/test/fixtures/corsa/partial/tsconfig.json b/packages/dtslint/test/fixtures/corsa/partial/tsconfig.json new file mode 100644 index 0000000000..32f00dd8e7 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/partial/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noEmit": true, + "strict": true, + "target": "esnext" + }, + "files": ["index.d.ts", "included.ts", "excluded.ts"] +} diff --git a/packages/dtslint/test/fixtures/corsa/pass/index.d.ts b/packages/dtslint/test/fixtures/corsa/pass/index.d.ts new file mode 100644 index 0000000000..4c05c227e7 --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/pass/index.d.ts @@ -0,0 +1 @@ +export declare function literal(): 1; diff --git a/packages/dtslint/test/fixtures/corsa/pass/test.ts b/packages/dtslint/test/fixtures/corsa/pass/test.ts new file mode 100644 index 0000000000..d2c538f68f --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/pass/test.ts @@ -0,0 +1,24 @@ +import { literal } from "./index"; +import type { ExternalType } from "../external"; + +// $ExpectType 1 +literal(); + +declare const external: ExternalType; +external; + +declare const object: { b: string; a: number }; +object; // $ExpectType { a: number; b: string; } + +declare const overloaded: { + (value: string): string; + (value: number): number; +}; +// $ExpectType { (value: string): string; (value: number): number; } || { (value: number): number; (value: string): string; } +overloaded; + +// @ts-expect-error >=7.0 +const expectedError: string = 1; + +// @ts-expect-error <7.0 +const noErrorOutsideRange: string = ""; diff --git a/packages/dtslint/test/fixtures/corsa/pass/tsconfig.json b/packages/dtslint/test/fixtures/corsa/pass/tsconfig.json new file mode 100644 index 0000000000..b918e4146a --- /dev/null +++ b/packages/dtslint/test/fixtures/corsa/pass/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noEmit": true, + "strict": true, + "target": "esnext" + }, + "files": ["index.d.ts", "test.ts"] +} diff --git a/packages/dtslint/test/index.test.ts b/packages/dtslint/test/index.test.ts index af07e11ec7..56b552031e 100644 --- a/packages/dtslint/test/index.test.ts +++ b/packages/dtslint/test/index.test.ts @@ -1,6 +1,33 @@ /// import { CompilerOptionsRaw, checkTsconfig } from "../src/checks"; import { assertPackageIsNotDeprecated } from "../src/index"; +import * as typeScriptPackages from "@definitelytyped/typescript-packages"; +import { execFile } from "child_process"; +import path from "path"; +import { promisify } from "util"; + +const execFileAsync = promisify(execFile); + +async function runBuilt(moduleName: string, exportName: string, args: readonly unknown[]): Promise { + const modulePath = path.resolve(__dirname, `../dist/${moduleName}.js`); + const script = ` +const fn = require(process.argv[1])[process.argv[2]]; +Promise.resolve(fn(...JSON.parse(process.argv[3]))).then( + result => process.stdout.write(JSON.stringify({ result })), + error => { + console.error(error?.stack ?? error); + process.exitCode = 1; + }, +);`; + const { stdout } = await execFileAsync(process.execPath, [ + "-e", + script, + modulePath, + exportName, + JSON.stringify(args), + ]); + return (JSON.parse(stdout) as { result?: T }).result; +} describe("dtslint", () => { const base: CompilerOptionsRaw = { @@ -139,6 +166,135 @@ describe("dtslint", () => { // `"files" list must include at least one ".ts", ".tsx", ".mts" or ".cts" file for testing.`, ]); }); + + describe("Corsa", () => { + const fixtures = path.join(__dirname, "fixtures", "corsa"); + + for (const version of ["7.0", "7.1"] as const) { + it(`checks compiler diagnostics and ExpectType through the TypeScript ${version} IPC API`, async () => { + const result = await runBuilt("lintCorsa", "lintCorsaVersions", [ + path.join(fixtures, "fail"), + ["tsconfig.json"], + [version], + true, + null, + ]); + + expect(result).toContain("compile error TS2322"); + expect(result).toContain("compile error TS2578"); + expect(result?.match(/compile error TS2578/g)).toHaveLength(version === "7.0" ? 1 : 2); + expect(result).toContain("expected type to be:\n 2\ngot:\n 1"); + expect(result).toContain( + "expected type to be:\n { (value: number): number; (value: string): string; }\ngot:", + ); + expect(result).toContain( + "expected type to be:\n { method(value: number): number; method(value: string): string; }\ngot:", + ); + }); + + it(`passes matching TypeScript ${version} ExpectType assertions without invoking ESLint`, async () => { + await expect( + runBuilt("lint", "lint", [ + path.join(fixtures, "pass"), + ["tsconfig.json"], + version, + version, + true, + true, + null, + ]), + ).resolves.toBeUndefined(); + }); + } + + it("reports and deduplicates Corsa failures across tsconfigs", async () => { + const result = await runBuilt("lintCorsa", "lintCorsaVersions", [ + path.join(fixtures, "fail"), + ["tsconfig.json", "tsconfig.alternate.json"], + ["7.0"], + true, + null, + ]); + + expect(result).toContain("TypeScript@7.0 tsconfig.alternate.json, 7.0 tsconfig.json compile error TS2322"); + expect(result).toContain( + "TypeScript@7.0 tsconfig.alternate.json, 7.0 tsconfig.json expected type to be:\n 2\ngot:\n 1", + ); + expect(result?.match(/compile error TS2322/g)).toHaveLength(1); + expect(result?.match(/expected type to be:\n 2\ngot:\n 1/g)).toHaveLength(1); + }); + + it("reports and deduplicates Corsa failures across versions", async () => { + const result = await runBuilt("lint", "lint", [ + path.join(fixtures, "fail"), + ["tsconfig.json"], + "7.0", + "7.1", + true, + true, + null, + ]); + + expect(result).toContain("TypeScript@7.0, 7.1 compile error TS2322"); + expect(result?.match(/compile error TS2322/g)).toHaveLength(1); + }); + + it("reports files excluded from every alternate tsconfig", async () => { + const result = await runBuilt("lint", "lint", [ + path.join(fixtures, "partial"), + ["tsconfig.alternate.json"], + "7.0", + "7.0", + true, + true, + null, + ]); + + expect(result).toContain("excluded.ts:1:1"); + expect(result).toContain("TypeScript@7.0 could not find a tsconfig that includes this file."); + }); + + it("runs ordinary ESLint rules during Corsa-only testing", async () => { + const result = await runBuilt("lint", "lint", [ + path.join(__dirname, "corsa-eslint"), + ["tsconfig.json"], + "7.0", + "7.0", + true, + false, + null, + ]); + + expect(result).toContain("no-var"); + expect(result).toContain("@typescript-eslint/naming-convention"); + }, 30_000); + + it("can use a local Corsa package", async () => { + const packageRoot = path.dirname(typeScriptPackages.resolve("7.0", "package.json")); + + await expect( + runBuilt("lint", "lint", [ + path.join(fixtures, "pass"), + ["tsconfig.json"], + "local", + "local", + true, + true, + packageRoot, + ]), + ).resolves.toBeUndefined(); + + const result = await runBuilt("lintCorsa", "lintCorsaVersions", [ + path.join(fixtures, "fail"), + ["tsconfig.json"], + ["local"], + true, + packageRoot, + ]); + expect(result).toContain("TypeScript@local compile error TS2578"); + expect(result?.match(/compile error TS2578/g)).toHaveLength(1); + }, 30_000); + }); }); describe("assertPackageIsNotDeprecated", () => { it("disallows packages that are in notNeededPackages.json", () => { diff --git a/packages/dtslint/test/tsconfig.json b/packages/dtslint/test/tsconfig.json index 85ba8b7b57..4c4cfada5e 100644 --- a/packages/dtslint/test/tsconfig.json +++ b/packages/dtslint/test/tsconfig.json @@ -9,6 +9,6 @@ { "path": ".." }, { "path": "../../utils" } ], - "exclude": ["expect"] + "exclude": ["expect", "fixtures"] } \ No newline at end of file diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 2461f105f2..738aeb531f 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -23,13 +23,12 @@ }, "dependencies": { "@definitelytyped/utils": "workspace:*", - "@typescript-eslint/types": "^8.56.1", - "@typescript-eslint/utils": "^8.56.1", - "semver": "^7.7.4" + "@typescript-eslint/types": "^8.67.0", + "@typescript-eslint/utils": "^8.67.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^8.54.0", - "@typescript-eslint/parser": "^8.54.0", + "@typescript-eslint/eslint-plugin": "^8.67.0", + "@typescript-eslint/parser": "^8.67.0", "eslint": "^8.57.0", "eslint-plugin-jsdoc": "^44.0.0", "typescript": "<7" @@ -37,10 +36,9 @@ "devDependencies": { "@definitelytyped/eslint-plugin": "link:", "@types/eslint": "^8.56.12", - "@types/semver": "^7.7.1", "glob": "^13.0.6", "jest-file-snapshot": "^0.7.0", - "typescript": "^5.9.3", + "typescript": "^6.0.3", "typescript-5.4": "npm:typescript@~5.4.0-0", "typescript-5.5": "npm:typescript@~5.5.0-0" }, diff --git a/packages/eslint-plugin/src/rules/expect.ts b/packages/eslint-plugin/src/rules/expect.ts index bb323beb13..45dd824e90 100644 --- a/packages/eslint-plugin/src/rules/expect.ts +++ b/packages/eslint-plugin/src/rules/expect.ts @@ -1,9 +1,9 @@ +import { isVersionedExpectErrorOutsideRange } from "@definitelytyped/utils"; import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; import { ReportDescriptorMessageData } from "@typescript-eslint/utils/ts-eslint"; import fs from "fs"; import v8 from "node:v8"; import path from "path"; -import * as semver from "semver"; import type * as ts from "typescript"; import { createRule, findTypesPackage, findUp } from "../util"; @@ -250,10 +250,6 @@ const zeroSourceLocation: Readonly = { const expectTypeToken = "$ExpectType"; -// Based on TypeScript's scanner.ts -const expectErrorSingleLine = /^\/\/\/?\s*@ts-expect-error\s+(.*)/; -const expectErrorMultiLine = /^(?:\/|\*)*\s*@ts-expect-error\s+(.*)/; - function walk( getLocFromIndex: (index: number) => Readonly, report: Reporter, @@ -273,22 +269,9 @@ function walk( const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile); for (const diagnostic of diagnostics) { if (diagnostic.code === 2578) { - // This is a ts-expect-error; parse "// @ts-expect-error " and ignore when the current version is outside that range. const text = sourceFile.text.slice(diagnostic.start!, diagnostic.start! + diagnostic.length!); - const match = text.match(expectErrorSingleLine) || text.match(expectErrorMultiLine); - if (match) { - let range: semver.Range | undefined; - try { - range = new semver.Range(match[1].trim()); - } catch { - // Ignore any parsing errors. - } - - if (range) { - if (!semver.satisfies(versionName, range, { loose: true })) { - continue; - } - } + if (isVersionedExpectErrorOutsideRange(text, ts.versionMajorMinor)) { + continue; } } diff --git a/packages/eslint-plugin/test/__file_snapshots__/types/expect-tsconfigs/expect-dom-tests.ts.lint b/packages/eslint-plugin/test/__file_snapshots__/types/expect-tsconfigs/expect-dom-tests.ts.lint index 1c6cde52db..4651185e20 100644 --- a/packages/eslint-plugin/test/__file_snapshots__/types/expect-tsconfigs/expect-dom-tests.ts.lint +++ b/packages/eslint-plugin/test/__file_snapshots__/types/expect-tsconfigs/expect-dom-tests.ts.lint @@ -1,8 +1,4 @@ -types/expect-tsconfigs/expect-dom-tests.ts - 6:16 error TypeScript@tsconfig.dom.json compile error: -Cannot find name 'WeakSet'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later @definitelytyped/expect - -✖ 1 problem (1 error, 0 warnings) +No errors ==== types/expect-tsconfigs/expect-dom-tests.ts ==== @@ -12,6 +8,3 @@ Cannot find name 'WeakSet'. Do you need to change your target library? Try chang const element: HTMLElement = expect.element; const weakSet: WeakSet<{}> = expect.weakSet; - ~~~~~~~ -!!! @definitelytyped/expect: TypeScript@tsconfig.dom.json compile error: -!!! : Cannot find name 'WeakSet'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later. diff --git a/packages/eslint-plugin/test/__file_snapshots__/types/expect-tsconfigs/index.d.ts.lint b/packages/eslint-plugin/test/__file_snapshots__/types/expect-tsconfigs/index.d.ts.lint index 05dfa5e83a..0589f67864 100644 --- a/packages/eslint-plugin/test/__file_snapshots__/types/expect-tsconfigs/index.d.ts.lint +++ b/packages/eslint-plugin/test/__file_snapshots__/types/expect-tsconfigs/index.d.ts.lint @@ -1,10 +1,8 @@ types/expect-tsconfigs/index.d.ts 1:23 error TypeScript@tsconfig.no-dom.json compile error: -Cannot find name 'HTMLElement' @definitelytyped/expect - 3:23 error TypeScript@tsconfig.dom.json compile error: -Cannot find name 'WeakSet'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later @definitelytyped/expect +Cannot find name 'HTMLElement' @definitelytyped/expect -✖ 2 problems (2 errors, 0 warnings) +✖ 1 problem (1 error, 0 warnings) ==== types/expect-tsconfigs/index.d.ts ==== @@ -14,6 +12,3 @@ Cannot find name 'WeakSet'. Do you need to change your target library? Try chang !!! : Cannot find name 'HTMLElement'. export const weakSet: WeakSet<{}>; - ~~~~~~~ -!!! @definitelytyped/expect: TypeScript@tsconfig.dom.json compile error: -!!! : Cannot find name 'WeakSet'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later. diff --git a/packages/eslint-plugin/test/fixtures/types/expect-error-range/expect-error-range-tests.ts b/packages/eslint-plugin/test/fixtures/types/expect-error-range/expect-error-range-tests.ts index 28f07a2d2c..086cd2fc91 100644 --- a/packages/eslint-plugin/test/fixtures/types/expect-error-range/expect-error-range-tests.ts +++ b/packages/eslint-plugin/test/fixtures/types/expect-error-range/expect-error-range-tests.ts @@ -40,4 +40,3 @@ const elem = ["value", undefined].filter(x => x != null)[0]; // @ts-expect-error >=5.5 const test2: undefined extends typeof elem ? typeof elem : never = elem; } - diff --git a/packages/mergebot/package.json b/packages/mergebot/package.json index 9913784ab2..f944533cfe 100644 --- a/packages/mergebot/package.json +++ b/packages/mergebot/package.json @@ -20,9 +20,9 @@ }, "dependencies": { "@apollo/client": "^4.1.6", + "@azure/functions": "^4.11.2", "@azure/identity": "^4.13.0", "@azure/keyvault-keys": "^4.10.0", - "@azure/functions": "^4.11.2", "@definitelytyped/old-header-parser": "npm:@definitelytyped/header-parser@0.0.178", "@definitelytyped/utils": "workspace:*", "@octokit/webhooks-methods": "^4.1.0", @@ -45,7 +45,7 @@ "jest-file-snapshot": "^0.7.0", "rimraf": "^6.1.3", "seroval": "^1.5.0", - "typescript": "^5.9.3" + "typescript": "^6.0.3" }, "scripts": { "prestart": "pnpm run build", diff --git a/packages/publisher/package.json b/packages/publisher/package.json index ae42950e1d..ff63ba3acc 100644 --- a/packages/publisher/package.json +++ b/packages/publisher/package.json @@ -13,7 +13,7 @@ "longjohn": "^0.2.12", "pacote": "^21.4.0", "semver": "^7.7.4", - "typescript": "^5.9.3", + "typescript": "^6.0.3", "yargs": "^17.7.2" }, "devDependencies": { diff --git a/packages/typescript-packages/package.json b/packages/typescript-packages/package.json index 71542c9c41..93fb475296 100644 --- a/packages/typescript-packages/package.json +++ b/packages/typescript-packages/package.json @@ -26,6 +26,8 @@ "typescript-5.7": "npm:typescript@~5.7.0-0", "typescript-5.8": "npm:typescript@~5.8.0-0", "typescript-5.9": "npm:typescript@~5.9.0-0", - "typescript-6.0": "npm:typescript@~6.0.0-0" + "typescript-6.0": "npm:typescript@~6.0.0-0", + "typescript-7.0": "npm:typescript@~7.0.0-0", + "typescript-7.1": "npm:typescript@~7.1.0-0" } } diff --git a/packages/typescript-packages/src/index.ts b/packages/typescript-packages/src/index.ts index e38f0f8e17..f9b85398b8 100644 --- a/packages/typescript-packages/src/index.ts +++ b/packages/typescript-packages/src/index.ts @@ -1,5 +1,5 @@ import { TypeScriptVersion } from "@definitelytyped/typescript-versions"; -export function resolve(version: TypeScriptVersion) { - return require.resolve(`typescript-${version}`); +export function resolve(version: TypeScriptVersion, subpath?: string) { + return require.resolve(`typescript-${version}${subpath ? `/${subpath}` : ""}`); } diff --git a/packages/typescript-packages/test/index.test.ts b/packages/typescript-packages/test/index.test.ts index 9d67f8d195..e8f8e7c010 100644 --- a/packages/typescript-packages/test/index.test.ts +++ b/packages/typescript-packages/test/index.test.ts @@ -24,7 +24,14 @@ describe("resolve", () => { for (const version of TypeScriptVersion.supported) { const ts = require(resolve(version)); expect(typeof ts.versionMajorMinor).toBe("string"); - expect(ts.versionMajorMinor).toBe(version); + if (version === "7.1") { + expect(ts.version).toMatch(/^7\.1\./); + } else { + expect(ts.versionMajorMinor).toBe(version); + } + if (version.startsWith("7.")) { + expect(resolve(version, "unstable/sync")).toMatch(/api[\\/]sync[\\/]api\.js$/); + } } }); }); diff --git a/packages/typescript-versions/src/index.ts b/packages/typescript-versions/src/index.ts index aa1f1c7b84..2e1c42430a 100644 --- a/packages/typescript-versions/src/index.ts +++ b/packages/typescript-versions/src/index.ts @@ -41,9 +41,9 @@ export type AllTypeScriptVersion = UnsupportedTypeScriptVersion | TypeScriptVers export namespace TypeScriptVersion { /** Add to this list when a version actually ships. */ - export const shipped = ["5.6", "5.7", "5.8", "5.9", "6.0"] as const; + export const shipped = ["5.6", "5.7", "5.8", "5.9", "6.0", "7.0"] as const; /** Add to this list when a version is available as typescript@next */ - export const supported = [...shipped] as const; + export const supported = [...shipped, "7.1"] as const; /** Add to this list when it will no longer be supported on Definitely Typed */ export const unsupported = [ "2.0", diff --git a/packages/typescript-versions/test/index.test.ts b/packages/typescript-versions/test/index.test.ts index 01827a9d1b..61bc4d4ced 100644 --- a/packages/typescript-versions/test/index.test.ts +++ b/packages/typescript-versions/test/index.test.ts @@ -10,7 +10,9 @@ describe("all", () => { it("doesn't have any holes", () => { let prev = TypeScriptVersion.all[0]; for (const version of TypeScriptVersion.all.slice(1)) { - expect(+version * 10 - +prev * 10).toEqual(1); + const [prevMajor, prevMinor] = prev.split(".").map(Number); + const [major, minor] = version.split(".").map(Number); + expect((major === prevMajor && minor === prevMinor + 1) || (major === prevMajor + 1 && minor === 0)).toBeTruthy(); prev = version; } }); @@ -42,7 +44,7 @@ describe("isTypeScriptVersion", () => { describe("range", () => { it("works", () => { - expect(TypeScriptVersion.range("5.6")).toEqual(["5.6", "5.7", "5.8", "5.9", "6.0"]); + expect(TypeScriptVersion.range("5.6")).toEqual(["5.6", "5.7", "5.8", "5.9", "6.0", "7.0", "7.1"]); }); it("includes 5.6 onwards", () => { expect(TypeScriptVersion.range("5.6")).toEqual(TypeScriptVersion.supported); @@ -51,7 +53,16 @@ describe("range", () => { describe("tagsToUpdate", () => { it("works", () => { - expect(TypeScriptVersion.tagsToUpdate("5.6")).toEqual(["ts5.6", "ts5.7", "ts5.8", "ts5.9", "ts6.0", "latest"]); + expect(TypeScriptVersion.tagsToUpdate("5.6")).toEqual([ + "ts5.6", + "ts5.7", + "ts5.8", + "ts5.9", + "ts6.0", + "ts7.0", + "ts7.1", + "latest", + ]); }); it("allows 5.6 onwards", () => { expect(TypeScriptVersion.tagsToUpdate("5.6")).toEqual( diff --git a/packages/utils/package.json b/packages/utils/package.json index a193802d76..e94e2e81ad 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -25,6 +25,7 @@ "libnpmpublish": "^11.1.3", "minimatch": "^10.2.4", "npm-registry-fetch": "^19.1.1", + "semver": "^7.7.4", "tar": "^7.5.9", "tar-stream": "^3.1.8", "which": "^6.0.1" @@ -33,6 +34,7 @@ "@types/charm": "^1.0.6", "@types/libnpmpublish": "^9.0.1", "@types/npm-registry-fetch": "^8.0.9", + "@types/semver": "^7.7.1", "@types/tar-stream": "^3.1.4", "@types/which": "^3.0.4" }, diff --git a/packages/utils/src/expect-error-range.ts b/packages/utils/src/expect-error-range.ts new file mode 100644 index 0000000000..4e8454614f --- /dev/null +++ b/packages/utils/src/expect-error-range.ts @@ -0,0 +1,40 @@ +import * as semver from "semver"; + +const expectErrorToken = "@ts-expect-error"; + +export function isVersionedExpectErrorOutsideRange(text: string, version: string): boolean { + const rangeText = getExpectErrorRange(text); + if (!rangeText) { + return false; + } + + try { + const normalizedVersion = semver.coerce(version); + const range = semver.validRange(rangeText); + return normalizedVersion && range ? !semver.satisfies(normalizedVersion.version, range) : false; + } catch { + return false; + } +} + +function getExpectErrorRange(text: string): string | undefined { + let comment = text.trim(); + let contentStart = 0; + while (comment[contentStart] === "/" || comment[contentStart] === "*") { + contentStart++; + } + comment = comment.slice(contentStart).trimStart(); + if (!comment.startsWith(expectErrorToken)) { + return undefined; + } + + let range = comment.slice(expectErrorToken.length); + if (range.length === range.trimStart().length) { + return undefined; + } + range = range.trim(); + if (range.endsWith("*/")) { + range = range.slice(0, -2).trimEnd(); + } + return range || undefined; +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index e81d162131..13be91a323 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,6 +1,7 @@ export * from "./assertions"; export * from "./async"; export * from "./collections"; +export * from "./expect-error-range"; export * from "./fs"; export * from "./io"; export * from "./logging"; diff --git a/packages/utils/test/expect-error-range.test.ts b/packages/utils/test/expect-error-range.test.ts new file mode 100644 index 0000000000..f641486051 --- /dev/null +++ b/packages/utils/test/expect-error-range.test.ts @@ -0,0 +1,18 @@ +import { isVersionedExpectErrorOutsideRange } from "../src"; + +describe(isVersionedExpectErrorOutsideRange.name, () => { + it("normalizes TypeScript major-minor versions before evaluating ranges", () => { + expect(isVersionedExpectErrorOutsideRange("// @ts-expect-error >=7.0", "7.1")).toBe(false); + expect(isVersionedExpectErrorOutsideRange("// @ts-expect-error >=7.1", "7.0")).toBe(true); + }); + + it("does not suppress diagnostics for invalid ranges", () => { + expect(isVersionedExpectErrorOutsideRange("// @ts-expect-error not a range", "7.1")).toBe(false); + }); + + it("excludes multiline comment delimiters from the range", () => { + expect(isVersionedExpectErrorOutsideRange("/* @ts-expect-error <7.0 */", "7.0")).toBe(true); + expect(isVersionedExpectErrorOutsideRange("/* @ts-expect-error <7.0 */", "6.0")).toBe(false); + expect(isVersionedExpectErrorOutsideRange("/** @ts-expect-error <7.0 */", "7.0")).toBe(true); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b473eb1e40..c751c1babd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,17 +27,17 @@ importers: specifier: ^17.0.35 version: 17.0.35 '@typescript-eslint/eslint-plugin': - specifier: ^8.56.1 - version: 8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3) '@typescript-eslint/parser': - specifier: ^8.56.1 - version: 8.56.1(eslint@8.57.1)(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(eslint@8.57.1)(typescript@6.0.3) eslint: specifier: ^8.57.1 version: 8.57.1 eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + version: 2.32.0(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1) eslint-plugin-jsdoc: specifier: ^48.11.0 version: 48.11.0(eslint@8.57.1) @@ -46,16 +46,16 @@ importers: version: 30.2.0(@types/node@25.3.3) knip: specifier: ^5.85.0 - version: 5.85.0(@types/node@25.3.3)(typescript@5.9.3) + version: 5.85.0(@types/node@25.3.3)(typescript@6.0.3) prettier: specifier: ^3.8.1 version: 3.8.1 ts-jest: - specifier: ^29.4.6 - version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@30.2.0(@types/node@25.3.3))(typescript@5.9.3) + specifier: ^29.4.12 + version: 29.4.12(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@30.2.0(@types/node@25.3.3))(typescript@6.0.3) typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 packages/definitions-parser: dependencies: @@ -85,8 +85,8 @@ importers: specifier: ^11.1.8 version: 11.1.8 typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 packages/dts-critic: dependencies: @@ -94,8 +94,8 @@ importers: specifier: workspace:* version: link:../header-parser typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 yargs: specifier: ^17.7.2 version: 17.7.2 @@ -106,8 +106,8 @@ importers: specifier: ^3.7.0 version: 3.7.0 typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 which: specifier: ^6.0.1 version: 6.0.1 @@ -155,32 +155,35 @@ importers: specifier: workspace:* version: link:../utils '@typescript-eslint/eslint-plugin': - specifier: ^8.56.1 - version: 8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3) '@typescript-eslint/parser': - specifier: ^8.56.1 - version: 8.56.1(eslint@8.57.1)(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(eslint@8.57.1)(typescript@6.0.3) '@typescript-eslint/types': - specifier: ^8.56.1 - version: 8.56.1 + specifier: ^8.67.0 + version: 8.67.0 '@typescript-eslint/typescript-estree': - specifier: ^8.56.1 - version: 8.56.1(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(typescript@6.0.3) '@typescript-eslint/utils': - specifier: ^8.56.1 - version: 8.56.1(eslint@8.57.1)(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(eslint@8.57.1)(typescript@6.0.3) eslint: specifier: ^8.57.1 version: 8.57.1 eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + version: 2.32.0(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1) semver: specifier: ^7.7.4 version: 7.7.4 strip-json-comments: specifier: ^3.1.1 version: 3.1.1 + typescript: + specifier: ^6.0.3 + version: 6.0.3 devDependencies: '@types/eslint': specifier: ^8.56.12 @@ -188,9 +191,9 @@ importers: '@types/semver': specifier: ^7.7.1 version: 7.7.1 - typescript: - specifier: ^5.9.3 - version: 5.9.3 + typescript-7.1: + specifier: npm:typescript@~7.1.0-0 + version: typescript@7.1.0-dev.20260817.1 packages/dtslint-runner: dependencies: @@ -220,26 +223,23 @@ importers: specifier: workspace:* version: link:../utils '@typescript-eslint/eslint-plugin': - specifier: ^8.54.0 - version: 8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3) '@typescript-eslint/parser': - specifier: ^8.54.0 - version: 8.56.1(eslint@8.57.1)(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(eslint@8.57.1)(typescript@6.0.3) '@typescript-eslint/types': - specifier: ^8.56.1 - version: 8.56.1 + specifier: ^8.67.0 + version: 8.67.0 '@typescript-eslint/utils': - specifier: ^8.56.1 - version: 8.56.1(eslint@8.57.1)(typescript@5.9.3) + specifier: ^8.67.0 + version: 8.67.0(eslint@8.57.1)(typescript@6.0.3) eslint: specifier: ^8.57.0 version: 8.57.1 eslint-plugin-jsdoc: specifier: ^44.0.0 version: 44.2.7(eslint@8.57.1) - semver: - specifier: ^7.7.4 - version: 7.7.4 devDependencies: '@definitelytyped/eslint-plugin': specifier: 'link:' @@ -247,9 +247,6 @@ importers: '@types/eslint': specifier: ^8.56.12 version: 8.56.12 - '@types/semver': - specifier: ^7.7.1 - version: 7.7.1 glob: specifier: ^13.0.6 version: 13.0.6 @@ -257,8 +254,8 @@ importers: specifier: ^0.7.0 version: 0.7.0 typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 typescript-5.4: specifier: npm:typescript@~5.4.0-0 version: typescript@5.4.5 @@ -323,7 +320,7 @@ importers: devDependencies: '@graphql-codegen/cli': specifier: ^6.1.2 - version: 6.1.2(@types/node@25.3.3)(graphql@16.13.0)(typescript@5.9.3) + version: 6.1.2(@types/node@25.3.3)(graphql@16.13.0)(typescript@6.0.3) '@graphql-codegen/client-preset': specifier: ^5.2.3 version: 5.2.3(graphql@16.13.0) @@ -358,8 +355,8 @@ importers: specifier: ^1.5.0 version: 1.5.0 typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 packages/publisher: dependencies: @@ -385,8 +382,8 @@ importers: specifier: ^7.7.4 version: 7.7.4 typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 yargs: specifier: ^17.7.2 version: 17.7.2 @@ -455,6 +452,12 @@ importers: typescript-6.0: specifier: npm:typescript@~6.0.0-0 version: typescript@6.0.2 + typescript-7.0: + specifier: npm:typescript@~7.0.0-0 + version: typescript@7.0.2 + typescript-7.1: + specifier: npm:typescript@~7.1.0-0 + version: typescript@7.1.0-dev.20260817.1 packages/typescript-versions: {} @@ -478,6 +481,9 @@ importers: npm-registry-fetch: specifier: ^19.1.1 version: 19.1.1 + semver: + specifier: ^7.7.4 + version: 7.7.4 tar: specifier: ^7.5.9 version: 7.5.9 @@ -497,6 +503,9 @@ importers: '@types/npm-registry-fetch': specifier: ^8.0.9 version: 8.0.9 + '@types/semver': + specifier: ^7.7.1 + version: 7.7.1 '@types/tar-stream': specifier: ^3.1.4 version: 3.1.4 @@ -1050,6 +1059,12 @@ packages: cpu: [x64] os: [win32] + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2032,65 +2047,227 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@typescript-eslint/eslint-plugin@8.56.1': - resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} + '@typescript-eslint/eslint-plugin@8.67.0': + resolution: {integrity: sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.56.1 + '@typescript-eslint/parser': ^8.67.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.56.1': - resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==} + '@typescript-eslint/parser@8.67.0': + resolution: {integrity: sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.56.1': - resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} + '@typescript-eslint/project-service@8.67.0': + resolution: {integrity: sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.56.1': - resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} + '@typescript-eslint/scope-manager@8.67.0': + resolution: {integrity: sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.56.1': - resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} + '@typescript-eslint/tsconfig-utils@8.67.0': + resolution: {integrity: sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.56.1': - resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} + '@typescript-eslint/type-utils@8.67.0': + resolution: {integrity: sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.56.1': - resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} + '@typescript-eslint/types@8.67.0': + resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.56.1': - resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} + '@typescript-eslint/typescript-estree@8.67.0': + resolution: {integrity: sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.56.1': - resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} + '@typescript-eslint/utils@8.67.0': + resolution: {integrity: sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.56.1': - resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} + '@typescript-eslint/visitor-keys@8.67.0': + resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-arm64@7.1.0-dev.20260817.1': + resolution: {integrity: sha512-WtnmAQAdn2nICm0lZOGJSgxSkdz9QaLfETgMKuMpD6Cf5lqzaZ5C2DRxqxl8B2moVqU3kWnK0ijWos1jO/3P0Q==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.1.0-dev.20260817.1': + resolution: {integrity: sha512-wsuj0wwxM0CY8BG+5TQLatleOVe3Dq/DEgwSAm8vhHA8eY0YmgC+iADFQBDcLiwaSj90tKp0B/wRWyxaYySOVQ==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm64@7.1.0-dev.20260817.1': + resolution: {integrity: sha512-jY/0sNMQUeIfML6qR12h7/AgdeIdPTyQmQU6p/f2+0+jgDnOan6gpFCfzNa+ZRu6gEJAmKP2GsQTetoeRtOmCQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-arm@7.1.0-dev.20260817.1': + resolution: {integrity: sha512-0Ggdk5cRMLCZYaKf6BqCT9vH7XXV2iqYv4y6psnt3Ub61AnZjERgaiEfm16wE0DxA/ugEHjsgj6l2KqR+XYXKQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-linux-x64@7.1.0-dev.20260817.1': + resolution: {integrity: sha512-HkYIfyFCjopf/9g7FdABIQUpkAjbVMTkjO9Q+dmNYVvZb89K47ZAPrhVAw5Em3zcCdc3qK9MXVXBfcfqD/YSmg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-arm64@7.1.0-dev.20260817.1': + resolution: {integrity: sha512-jTBf06dI+71vyMeZqnndL9Nf1ViI6MTmPyCvT05ipkKb65CbnQMunCI5pPcuKWLwg4EaJuTSVruvwSJeimkFqw==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@typescript/typescript-win32-x64@7.1.0-dev.20260817.1': + resolution: {integrity: sha512-dU3HQ4kuV0c+gGoGruqHbbIPuyxoxQ2MkNXo+yum5rBfmXEdbgtL9BvyuSa+mHo1ZeC6m2qWj05B0BFILMBsDg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + '@typespec/ts-http-runtime@0.3.6': resolution: {integrity: sha512-jIXhD0eWQ1JA6ln/5Dltyx22UxWNrw0hZmhy2rlv6m6KgF7kplHx3g0fzi09lNmTJQRR91OlemYp3xFnvDK9og==} engines: {node: '>=20.0.0'} @@ -2452,6 +2629,10 @@ packages: resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} engines: {node: 18 || 20 || >=22} + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -3265,8 +3446,8 @@ packages: resolution: {integrity: sha512-uSisMYERbaB9bkA9M4/4dnqyktaEkf1kMHNKq/7DHyxVeWqHQ2mBmVqm5u6/FVHwF3iCNalKcg82Zfl+tffWoA==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} engines: {node: '>=0.4.7'} hasBin: true @@ -3341,8 +3522,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} engines: {node: '>= 4'} immutable@3.7.6: @@ -3989,6 +4170,10 @@ packages: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} @@ -4335,6 +4520,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} @@ -4515,6 +4704,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} @@ -4804,6 +4998,10 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + title-case@3.0.3: resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} @@ -4821,14 +5019,14 @@ packages: resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==} engines: {node: '>=0.10.0'} - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' - ts-jest@29.4.6: - resolution: {integrity: sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==} + ts-jest@29.4.12: + resolution: {integrity: sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -4839,7 +5037,7 @@ packages: esbuild: '*' jest: ^29.0.0 || ^30.0.0 jest-util: ^29.0.0 || ^30.0.0 - typescript: '>=4.3 <6' + typescript: '>=4.3 <7' peerDependenciesMeta: '@babel/core': optional: true @@ -4946,6 +5144,21 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + + typescript@7.1.0-dev.20260817.1: + resolution: {integrity: sha512-PkDN/j5CrorUpue1dmiFluIYgKv10SeVUTLlzgpRsN2qYUNHi3mD7hDuo9s8mcBS2ZMui19yqvK+0gl00zNrmQ==} + engines: {node: '>=16.20.0'} + hasBin: true + ua-parser-js@1.0.41: resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} hasBin: true @@ -5842,6 +6055,11 @@ snapshots: '@esbuild/win32-x64@0.27.3': optional: true + '@eslint-community/eslint-utils@4.10.1(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': dependencies: eslint: 8.57.1 @@ -5877,7 +6095,7 @@ snapshots: graphql: 16.13.0 tslib: 2.6.3 - '@graphql-codegen/cli@6.1.2(@types/node@25.3.3)(graphql@16.13.0)(typescript@5.9.3)': + '@graphql-codegen/cli@6.1.2(@types/node@25.3.3)(graphql@16.13.0)(typescript@6.0.3)': dependencies: '@babel/generator': 7.29.1 '@babel/template': 7.28.6 @@ -5897,11 +6115,11 @@ snapshots: '@inquirer/prompts': 7.10.1(@types/node@25.3.3) '@whatwg-node/fetch': 0.10.13 chalk: 4.1.2 - cosmiconfig: 9.0.1(typescript@5.9.3) + cosmiconfig: 9.0.1(typescript@6.0.3) debounce: 2.2.0 detect-indent: 6.1.0 graphql: 16.13.0 - graphql-config: 5.1.5(@types/node@25.3.3)(graphql@16.13.0)(typescript@5.9.3) + graphql-config: 5.1.5(@types/node@25.3.3)(graphql@16.13.0)(typescript@6.0.3) is-glob: 4.0.3 jiti: 2.6.1 json-to-pretty-yaml: 1.2.2 @@ -7183,97 +7401,178 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/type-utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/parser': 8.67.0(eslint@8.57.1)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/type-utils': 8.67.0(eslint@8.57.1)(typescript@6.0.3) + '@typescript-eslint/utils': 8.67.0(eslint@8.57.1)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.67.0 eslint: 8.57.1 - ignore: 7.0.5 + ignore: 7.0.6 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.67.0 debug: 4.4.3 eslint: 8.57.1 - typescript: 5.9.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.67.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@6.0.3) + '@typescript-eslint/types': 8.67.0 debug: 4.4.3 - typescript: 5.9.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.56.1': + '@typescript-eslint/scope-manager@8.67.0': dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 - '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.67.0(typescript@6.0.3)': dependencies: - typescript: 5.9.3 + typescript: 6.0.3 - '@typescript-eslint/type-utils@8.56.1(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.67.0(eslint@8.57.1)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.67.0(eslint@8.57.1)(typescript@6.0.3) debug: 4.4.3 eslint: 8.57.1 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.56.1': {} + '@typescript-eslint/types@8.67.0': {} - '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.67.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/project-service': 8.67.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@6.0.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 debug: 4.4.3 - minimatch: 10.2.4 + minimatch: 10.2.6 semver: 7.7.4 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.56.1(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/utils@8.67.0(eslint@8.57.1)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@eslint-community/eslint-utils': 4.10.1(eslint@8.57.1) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@6.0.3) eslint: 8.57.1 - typescript: 5.9.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.56.1': + '@typescript-eslint/visitor-keys@8.67.0': dependencies: - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/types': 8.67.0 eslint-visitor-keys: 5.0.1 + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.1.0-dev.20260817.1': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.1.0-dev.20260817.1': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.1.0-dev.20260817.1': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.1.0-dev.20260817.1': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.1.0-dev.20260817.1': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.1.0-dev.20260817.1': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.1.0-dev.20260817.1': + optional: true + '@typespec/ts-http-runtime@0.3.6': dependencies: http-proxy-agent: 7.0.2 @@ -7612,6 +7911,10 @@ snapshots: dependencies: balanced-match: 4.0.4 + brace-expansion@5.0.9: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -7821,23 +8124,23 @@ snapshots: cookie@0.7.2: {} - cosmiconfig@8.3.6(typescript@5.9.3): + cosmiconfig@8.3.6(typescript@6.0.3): dependencies: import-fresh: 3.3.1 js-yaml: 4.1.1 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.9.3 + typescript: 6.0.3 - cosmiconfig@9.0.1(typescript@5.9.3): + cosmiconfig@9.0.1(typescript@6.0.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.1.1 parse-json: 5.2.0 optionalDependencies: - typescript: 5.9.3 + typescript: 6.0.3 cross-fetch@3.2.0: dependencies: @@ -8122,17 +8425,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.67.0(eslint@8.57.1)(typescript@6.0.3) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -8143,7 +8446,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.67.0(eslint@8.57.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -8155,7 +8458,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.67.0(eslint@8.57.1)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -8355,6 +8658,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 @@ -8547,7 +8854,7 @@ snapshots: graphemer@1.4.0: {} - graphql-config@5.1.5(@types/node@25.3.3)(graphql@16.13.0)(typescript@5.9.3): + graphql-config@5.1.5(@types/node@25.3.3)(graphql@16.13.0)(typescript@6.0.3): dependencies: '@graphql-tools/graphql-file-loader': 8.1.9(graphql@16.13.0) '@graphql-tools/json-file-loader': 8.0.26(graphql@16.13.0) @@ -8555,7 +8862,7 @@ snapshots: '@graphql-tools/merge': 9.1.7(graphql@16.13.0) '@graphql-tools/url-loader': 8.0.33(@types/node@25.3.3)(graphql@16.13.0) '@graphql-tools/utils': 10.11.0(graphql@16.13.0) - cosmiconfig: 8.3.6(typescript@5.9.3) + cosmiconfig: 8.3.6(typescript@6.0.3) graphql: 16.13.0 jiti: 2.6.1 minimatch: 9.0.9 @@ -8583,7 +8890,7 @@ snapshots: graphql@16.13.0: {} - handlebars@4.7.8: + handlebars@4.7.9: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -8657,7 +8964,7 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.5: {} + ignore@7.0.6: {} immutable@3.7.6: {} @@ -9309,7 +9616,7 @@ snapshots: dependencies: json-buffer: 3.0.1 - knip@5.85.0(@types/node@25.3.3)(typescript@5.9.3): + knip@5.85.0(@types/node@25.3.3)(typescript@6.0.3): dependencies: '@nodelib/fs.walk': 1.2.8 '@types/node': 25.3.3 @@ -9323,7 +9630,7 @@ snapshots: picomatch: 4.0.3 smol-toml: 1.6.0 strip-json-comments: 5.0.3 - typescript: 5.9.3 + typescript: 6.0.3 zod: 4.3.6 leven@3.1.0: {} @@ -9496,6 +9803,10 @@ snapshots: dependencies: brace-expansion: 5.0.4 + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.9 + minimatch@3.1.5: dependencies: brace-expansion: 1.1.12 @@ -9897,6 +10208,8 @@ snapshots: picomatch@4.0.3: {} + picomatch@4.0.5: {} + pify@4.0.1: {} pirates@4.0.7: {} @@ -10067,6 +10380,8 @@ snapshots: semver@7.7.4: {} + semver@7.8.5: {} + sentence-case@3.0.4: dependencies: no-case: 3.0.4 @@ -10423,6 +10738,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + title-case@3.0.3: dependencies: tslib: 2.6.3 @@ -10439,22 +10759,22 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@6.0.3): dependencies: - typescript: 5.9.3 + typescript: 6.0.3 - ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@30.2.0(@types/node@25.3.3))(typescript@5.9.3): + ts-jest@29.4.12(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@30.2.0(@types/node@25.3.3))(typescript@6.0.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 + handlebars: 4.7.9 jest: 30.2.0(@types/node@25.3.3) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.7.4 + semver: 7.8.5 type-fest: 4.41.0 - typescript: 5.9.3 + typescript: 6.0.3 yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.29.0 @@ -10545,6 +10865,41 @@ snapshots: typescript@6.0.2: {} + typescript@6.0.3: {} + + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + typescript@7.1.0-dev.20260817.1: + optionalDependencies: + '@typescript/typescript-darwin-arm64': 7.1.0-dev.20260817.1 + '@typescript/typescript-darwin-x64': 7.1.0-dev.20260817.1 + '@typescript/typescript-linux-arm': 7.1.0-dev.20260817.1 + '@typescript/typescript-linux-arm64': 7.1.0-dev.20260817.1 + '@typescript/typescript-linux-x64': 7.1.0-dev.20260817.1 + '@typescript/typescript-win32-arm64': 7.1.0-dev.20260817.1 + '@typescript/typescript-win32-x64': 7.1.0-dev.20260817.1 + ua-parser-js@1.0.41: {} uglify-js@3.19.3: