From 1caa47e04debc6c355eda9c24ee7429f025ef854 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 9 Jul 2026 09:09:13 -0600 Subject: [PATCH 1/6] Add tsgo as an opt-in fast type-checker Wires TypeScript 7's native compiler preview (tsgo, via @typescript/native-preview) in as a parallel `npm run typecheck:fast` script -- ~6-7x faster than tsc on this codebase, verified on the current tree. Purely additive: the committed build (tsconfig.build.json) and ESLint (@typescript-eslint/parser, still needs typescript 5.x since TS7 ships no compiler API) are untouched. Also pins `"strict": false` explicitly in tsconfig.json, documenting the current implicit default so TypeScript 7's flip of that default to true doesn't silently change type-check results on a future compiler bump. Verified byte-identical `tsc --noEmit` output before/after this pin. Co-Authored-By: Claude --- dependencies.md | 11 ++++ package-lock.json | 142 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + tsconfig.json | 4 ++ 4 files changed, 159 insertions(+) diff --git a/dependencies.md b/dependencies.md index c044d84f3a..b28fd68a1f 100644 --- a/dependencies.md +++ b/dependencies.md @@ -184,3 +184,14 @@ Generally, dependencies are added by simply adding them to the dependencies list - Binary compilation: No. - Can be deferred: The require happens only when `server/serverHelpers/multipartParser.ts` is imported, which is loaded by `registerContentHandlers` at operations-server boot. Realistically always loaded. - Eventual removal: Could be replaced by writing our own streaming multipart parser (a few hundred lines plus tests for edge cases) if maintenance ever lapses, or by Node.js's `request.formData()` once that API supports streaming file parts without buffering (currently it doesn't on the standard Node http server interface used by Fastify). + +## @typescript/native-preview (devDependency) + +- Need for usage: Ships `tsgo`, the native (Go-ported) TypeScript compiler preview that will become TypeScript 7's `tsc`. Wired as an opt-in `npm run typecheck:fast` script — a faster local/CI type-check loop alongside the existing `tsc`-based `build`, not a replacement for either. +- Size/memory cost: Dev-only; not shipped in `files`, never loads in production. +- Security: Microsoft-maintained preview of the upcoming TypeScript 7 toolchain. +- Overlap: Complements, does not replace, the `typescript` devDependency — `tsgo` currently has no declaration-emit parity for one file (`resources/Table.ts`'s anonymous `#private`-field class) and TS 7.0 ships no compiler API, so `@typescript-eslint/parser` still needs `typescript` 5.x. +- Can be deferred: Yes, opt-in script only. +- Binary compilation: No local compilation, but it installs one of several platform-gated `optionalDependencies` that ships a prebuilt native (Go-compiled) `tsgo` binary. +- Eventual removal: Once TypeScript 7 stabilizes as the primary `typescript` devDependency (post-7.1's compiler API), this becomes redundant and `typecheck:fast` can be dropped. +- Note: pinned to an exact nightly `-dev` build rather than a caret range; nightly tags on the npm registry aren't guaranteed to persist indefinitely, so a future bump (or removal if the tarball is ever pruned) may be needed. diff --git a/package-lock.json b/package-lock.json index 44ed170d90..0915525178 100644 --- a/package-lock.json +++ b/package-lock.json @@ -109,6 +109,7 @@ "@types/sinon": "^21.0.0", "@types/tar-fs": "^2.0.4", "@typescript-eslint/parser": "^8.48.1", + "@typescript/native-preview": "7.0.0-dev.20260707.2", "axios": "1.18.1", "chai": "^6.2.0", "chai-as-promised": "^8.0.2", @@ -5404,6 +5405,147 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript/native-preview": { + "version": "7.0.0-dev.20260707.2", + "resolved": "https://registry.npmjs.org/@typescript/native-preview/-/native-preview-7.0.0-dev.20260707.2.tgz", + "integrity": "sha512-oUGp+Rep/hqMhPunyinsALUwSlzHINSxitifPiSaeqoKOKD2OlR9NE3TaPqwsl4NlGslsOSUXI1JotWQzpYCPg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsgo": "bin/tsgo" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260707.2", + "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260707.2", + "@typescript/native-preview-linux-arm": "7.0.0-dev.20260707.2", + "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260707.2", + "@typescript/native-preview-linux-x64": "7.0.0-dev.20260707.2", + "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260707.2", + "@typescript/native-preview-win32-x64": "7.0.0-dev.20260707.2" + } + }, + "node_modules/@typescript/native-preview-darwin-arm64": { + "version": "7.0.0-dev.20260707.2", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-arm64/-/native-preview-darwin-arm64-7.0.0-dev.20260707.2.tgz", + "integrity": "sha512-wny2pgKjGbiZtnOIHVa3tXC1UfDqxNEFzyPGmiqybedG8hipG2Nfp0l5UxbaKCjkLacUpH/W5bP2hBOMVhCOzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/native-preview-darwin-x64": { + "version": "7.0.0-dev.20260707.2", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-x64/-/native-preview-darwin-x64-7.0.0-dev.20260707.2.tgz", + "integrity": "sha512-Afc7M5zOwo+GpfcYwz5Z8HMB2tPVsui7nNIqEuuFB73MPdVqNn/Wmpe4tP4MRri0AtJnJknoHBaTJ/VDAp/Jhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/native-preview-linux-arm": { + "version": "7.0.0-dev.20260707.2", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm/-/native-preview-linux-arm-7.0.0-dev.20260707.2.tgz", + "integrity": "sha512-hJm/UOqZTr9FHmR7uNm8VGX4oKtfWk0Jem0zPeJFNC8ckGUfSBueyiEYMZB+XmRc1aG4x1E46y3CplP4CLHvGQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/native-preview-linux-arm64": { + "version": "7.0.0-dev.20260707.2", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm64/-/native-preview-linux-arm64-7.0.0-dev.20260707.2.tgz", + "integrity": "sha512-iITBa2WjjTI5N9t5l7Z4KoOSI+2zBlhbvFzsD/f8qX8QoKjz/Y4DPyBDgezYi8nkqjjksbgSOJ3/ykzhwrB9cg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/native-preview-linux-x64": { + "version": "7.0.0-dev.20260707.2", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-x64/-/native-preview-linux-x64-7.0.0-dev.20260707.2.tgz", + "integrity": "sha512-du0dzi6y97Po5vDNdPJTyyijHCpaS22JLRnKZEJXBDaO9gCIymOv/5QQokFRuOlQm0bWl3i9PF4OVdGP6uAOQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/native-preview-win32-arm64": { + "version": "7.0.0-dev.20260707.2", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-arm64/-/native-preview-win32-arm64-7.0.0-dev.20260707.2.tgz", + "integrity": "sha512-SsAwfhyHJ1akgBc+99z4+hwdbHsdWaKB8EwCNIMA6JfSLMeUjffrYvxu+vfMyxVtOVOz7RrRXRoiDiu4a2sCtg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/native-preview-win32-x64": { + "version": "7.0.0-dev.20260707.2", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-x64/-/native-preview-win32-x64-7.0.0-dev.20260707.2.tgz", + "integrity": "sha512-DL4u27stv0fo71sVhOzHSwE+YMZsbBijVI+kg5dLDLilSH79WFTJ8RSQ46vJrCMt+Gjlv/JOZP1PuLJDfioYeQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "license": "MIT", diff --git a/package.json b/package.json index 201e7562fb..a84c9e445a 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "scripts": { "build": "tsc --project tsconfig.build.json", "build:watch": "npm run build -- --watch --incremental", + "typecheck:fast": "tsgo --noEmit --project tsconfig.json", "package": "./build-tools/build.sh", "lint": "oxlint --format stylish --deny-warnings .", "lint:required": "oxlint --format stylish --quiet .", @@ -138,6 +139,7 @@ "@types/sinon": "^21.0.0", "@types/tar-fs": "^2.0.4", "@typescript-eslint/parser": "^8.48.1", + "@typescript/native-preview": "7.0.0-dev.20260707.2", "axios": "1.18.1", "chai": "^6.2.0", "chai-as-promised": "^8.0.2", diff --git a/tsconfig.json b/tsconfig.json index a41dc0e8c9..06d1f234be 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -37,6 +37,10 @@ // Allow .ts extensions in imports (will be transpiled to .js by esbuild) "allowImportingTsExtensions": true, + // Codebase is not strict-clean yet; pin explicitly so a compiler upgrade + // that flips this default (e.g. TypeScript 7) doesn't silently change results + "strict": false, + // Enforce erasable syntax only so we can use Node.js type-stripping "erasableSyntaxOnly": true, // Required: third-party type declarations (alasql, mathjs, msgpackr) have incompatible type errors From 2fad3d618f04048cfe2f7fe81d3e7e28256cf44a Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 9 Jul 2026 09:27:18 -0600 Subject: [PATCH 2/6] Add a plain typecheck script alongside typecheck:fast Gives a standing baseline to compare tsgo against tsc, rather than requiring an ad hoc invocation. Co-Authored-By: Claude --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index a84c9e445a..a71fa82776 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "scripts": { "build": "tsc --project tsconfig.build.json", "build:watch": "npm run build -- --watch --incremental", + "typecheck": "tsc --project tsconfig.json", "typecheck:fast": "tsgo --noEmit --project tsconfig.json", "package": "./build-tools/build.sh", "lint": "oxlint --format stylish --deny-warnings .", From d467b9e37dd769c1701edc04e70216e9c42d5ea2 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 9 Jul 2026 10:10:52 -0600 Subject: [PATCH 3/6] Clarify tsgo dependency doc: install coupling, not just usage, is opt-in Addresses cb1kenobi's review on the companion harper-pro PR (#556): the typecheck:fast *script* is opt-in, but @typescript/native-preview as a plain devDependency means npm ci fetches this exact nightly tarball for every CI job, not just the checker. Documents why optionalDependencies isn't the fix (both harper and harper-pro are genuinely public npm packages, so it would leak this dev-only tool into every real end-user install) and formalizes accepting the pruning risk knowingly. Co-Authored-By: Claude --- dependencies.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.md b/dependencies.md index b28fd68a1f..fb20a5c457 100644 --- a/dependencies.md +++ b/dependencies.md @@ -191,7 +191,7 @@ Generally, dependencies are added by simply adding them to the dependencies list - Size/memory cost: Dev-only; not shipped in `files`, never loads in production. - Security: Microsoft-maintained preview of the upcoming TypeScript 7 toolchain. - Overlap: Complements, does not replace, the `typescript` devDependency — `tsgo` currently has no declaration-emit parity for one file (`resources/Table.ts`'s anonymous `#private`-field class) and TS 7.0 ships no compiler API, so `@typescript-eslint/parser` still needs `typescript` 5.x. -- Can be deferred: Yes, opt-in script only. +- Can be deferred: The `typecheck:fast` *usage* is opt-in, but *installation* is not — as a plain `devDependency`, `npm ci` fetches this exact tarball for every job that installs deps (unit, integration, smoke, stress), not just the checker. Accepted knowingly (see Note). - Binary compilation: No local compilation, but it installs one of several platform-gated `optionalDependencies` that ships a prebuilt native (Go-compiled) `tsgo` binary. - Eventual removal: Once TypeScript 7 stabilizes as the primary `typescript` devDependency (post-7.1's compiler API), this becomes redundant and `typecheck:fast` can be dropped. -- Note: pinned to an exact nightly `-dev` build rather than a caret range; nightly tags on the npm registry aren't guaranteed to persist indefinitely, so a future bump (or removal if the tarball is ever pruned) may be needed. +- Note: pinned to an exact nightly `-dev` build rather than a caret range; nightly tags on the npm registry aren't guaranteed to persist indefinitely, so if this exact tarball is ever pruned, `npm ci` fails across all CI jobs (not just `typecheck:fast`) until the pin is bumped. Deliberately accepted as low-probability (npm rarely removes published versions) and cheaply recoverable (one-line version bump), rather than mitigated by moving to `optionalDependencies` — both `harper` and `harper-pro` are genuinely public npm packages (verified against the registry, no `private` field), so `optionalDependencies` would install-attempt this dev-only tool for every real end-user/customer running `npm install`, which is worse than the current CI-only exposure. A looser tag doesn't help either: this package's `beta` dist-tag resolves to an *older* nightly than `latest`, and `latest` itself would just float to a different day's nightly of the same risk class while churning the lockfile on every install. From 581a4a09007435294b4613680503cda259eb902c Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 9 Jul 2026 10:11:02 -0600 Subject: [PATCH 4/6] Fix formatting --- dependencies.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.md b/dependencies.md index fb20a5c457..f6e99d5fca 100644 --- a/dependencies.md +++ b/dependencies.md @@ -191,7 +191,7 @@ Generally, dependencies are added by simply adding them to the dependencies list - Size/memory cost: Dev-only; not shipped in `files`, never loads in production. - Security: Microsoft-maintained preview of the upcoming TypeScript 7 toolchain. - Overlap: Complements, does not replace, the `typescript` devDependency — `tsgo` currently has no declaration-emit parity for one file (`resources/Table.ts`'s anonymous `#private`-field class) and TS 7.0 ships no compiler API, so `@typescript-eslint/parser` still needs `typescript` 5.x. -- Can be deferred: The `typecheck:fast` *usage* is opt-in, but *installation* is not — as a plain `devDependency`, `npm ci` fetches this exact tarball for every job that installs deps (unit, integration, smoke, stress), not just the checker. Accepted knowingly (see Note). +- Can be deferred: The `typecheck:fast` _usage_ is opt-in, but _installation_ is not — as a plain `devDependency`, `npm ci` fetches this exact tarball for every job that installs deps (unit, integration, smoke, stress), not just the checker. Accepted knowingly (see Note). - Binary compilation: No local compilation, but it installs one of several platform-gated `optionalDependencies` that ships a prebuilt native (Go-compiled) `tsgo` binary. - Eventual removal: Once TypeScript 7 stabilizes as the primary `typescript` devDependency (post-7.1's compiler API), this becomes redundant and `typecheck:fast` can be dropped. -- Note: pinned to an exact nightly `-dev` build rather than a caret range; nightly tags on the npm registry aren't guaranteed to persist indefinitely, so if this exact tarball is ever pruned, `npm ci` fails across all CI jobs (not just `typecheck:fast`) until the pin is bumped. Deliberately accepted as low-probability (npm rarely removes published versions) and cheaply recoverable (one-line version bump), rather than mitigated by moving to `optionalDependencies` — both `harper` and `harper-pro` are genuinely public npm packages (verified against the registry, no `private` field), so `optionalDependencies` would install-attempt this dev-only tool for every real end-user/customer running `npm install`, which is worse than the current CI-only exposure. A looser tag doesn't help either: this package's `beta` dist-tag resolves to an *older* nightly than `latest`, and `latest` itself would just float to a different day's nightly of the same risk class while churning the lockfile on every install. +- Note: pinned to an exact nightly `-dev` build rather than a caret range; nightly tags on the npm registry aren't guaranteed to persist indefinitely, so if this exact tarball is ever pruned, `npm ci` fails across all CI jobs (not just `typecheck:fast`) until the pin is bumped. Deliberately accepted as low-probability (npm rarely removes published versions) and cheaply recoverable (one-line version bump), rather than mitigated by moving to `optionalDependencies` — both `harper` and `harper-pro` are genuinely public npm packages (verified against the registry, no `private` field), so `optionalDependencies` would install-attempt this dev-only tool for every real end-user/customer running `npm install`, which is worse than the current CI-only exposure. A looser tag doesn't help either: this package's `beta` dist-tag resolves to an _older_ nightly than `latest`, and `latest` itself would just float to a different day's nightly of the same risk class while churning the lockfile on every install. From 6d799b945f717a9b3de5fb54a296e2e4e9862890 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 9 Jul 2026 10:40:46 -0600 Subject: [PATCH 5/6] Run tsgo via npx instead of as a devDependency Addresses cb1kenobi's review: as a plain devDependency, npm ci fetched this nightly tarball for every CI job (unit, integration, smoke, stress), not just the opt-in typecheck:fast script. Running it via `npx -y -p @typescript/native-preview@ tsgo ...` confines a pruned-tarball failure to typecheck:fast alone, matching its actually-opt-in nature. Trade-off: no package-lock.json integrity-hash pinning for this tool (version is still pinned in the npx invocation itself). Co-Authored-By: Claude --- dependencies.md | 7 +-- package-lock.json | 142 ---------------------------------------------- package.json | 3 +- 3 files changed, 3 insertions(+), 149 deletions(-) diff --git a/dependencies.md b/dependencies.md index f6e99d5fca..5ace308386 100644 --- a/dependencies.md +++ b/dependencies.md @@ -185,13 +185,10 @@ Generally, dependencies are added by simply adding them to the dependencies list - Can be deferred: The require happens only when `server/serverHelpers/multipartParser.ts` is imported, which is loaded by `registerContentHandlers` at operations-server boot. Realistically always loaded. - Eventual removal: Could be replaced by writing our own streaming multipart parser (a few hundred lines plus tests for edge cases) if maintenance ever lapses, or by Node.js's `request.formData()` once that API supports streaming file parts without buffering (currently it doesn't on the standard Node http server interface used by Fastify). -## @typescript/native-preview (devDependency) +## @typescript/native-preview (not a dependency — invoked via npx) - Need for usage: Ships `tsgo`, the native (Go-ported) TypeScript compiler preview that will become TypeScript 7's `tsc`. Wired as an opt-in `npm run typecheck:fast` script — a faster local/CI type-check loop alongside the existing `tsc`-based `build`, not a replacement for either. -- Size/memory cost: Dev-only; not shipped in `files`, never loads in production. +- Not a `package.json` dependency: `typecheck:fast` runs `npx -y -p @typescript/native-preview@ tsgo ...` rather than adding this as a `devDependency`. This is deliberate — an earlier version of this change had it as a plain `devDependency`, which meant `npm ci` fetched this exact nightly tarball for every CI job (unit, integration, smoke, stress), not just the opt-in checker. `optionalDependencies` was considered and rejected: both `harper` and `harper-pro` are genuinely public npm packages (verified against the registry, no `private` field), so that would install-attempt this dev-only tool for every real end-user's `npm install`. Running it via `npx` on-demand confines a pruned-tarball failure to `typecheck:fast` alone, matching its actually-opt-in nature. Trade-off: no `package-lock.json` integrity-hash pinning for this tool (the exact version is still pinned in the npx invocation itself, just not hash-verified against a lockfile entry). - Security: Microsoft-maintained preview of the upcoming TypeScript 7 toolchain. - Overlap: Complements, does not replace, the `typescript` devDependency — `tsgo` currently has no declaration-emit parity for one file (`resources/Table.ts`'s anonymous `#private`-field class) and TS 7.0 ships no compiler API, so `@typescript-eslint/parser` still needs `typescript` 5.x. -- Can be deferred: The `typecheck:fast` _usage_ is opt-in, but _installation_ is not — as a plain `devDependency`, `npm ci` fetches this exact tarball for every job that installs deps (unit, integration, smoke, stress), not just the checker. Accepted knowingly (see Note). -- Binary compilation: No local compilation, but it installs one of several platform-gated `optionalDependencies` that ships a prebuilt native (Go-compiled) `tsgo` binary. - Eventual removal: Once TypeScript 7 stabilizes as the primary `typescript` devDependency (post-7.1's compiler API), this becomes redundant and `typecheck:fast` can be dropped. -- Note: pinned to an exact nightly `-dev` build rather than a caret range; nightly tags on the npm registry aren't guaranteed to persist indefinitely, so if this exact tarball is ever pruned, `npm ci` fails across all CI jobs (not just `typecheck:fast`) until the pin is bumped. Deliberately accepted as low-probability (npm rarely removes published versions) and cheaply recoverable (one-line version bump), rather than mitigated by moving to `optionalDependencies` — both `harper` and `harper-pro` are genuinely public npm packages (verified against the registry, no `private` field), so `optionalDependencies` would install-attempt this dev-only tool for every real end-user/customer running `npm install`, which is worse than the current CI-only exposure. A looser tag doesn't help either: this package's `beta` dist-tag resolves to an _older_ nightly than `latest`, and `latest` itself would just float to a different day's nightly of the same risk class while churning the lockfile on every install. diff --git a/package-lock.json b/package-lock.json index 0915525178..44ed170d90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -109,7 +109,6 @@ "@types/sinon": "^21.0.0", "@types/tar-fs": "^2.0.4", "@typescript-eslint/parser": "^8.48.1", - "@typescript/native-preview": "7.0.0-dev.20260707.2", "axios": "1.18.1", "chai": "^6.2.0", "chai-as-promised": "^8.0.2", @@ -5405,147 +5404,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript/native-preview": { - "version": "7.0.0-dev.20260707.2", - "resolved": "https://registry.npmjs.org/@typescript/native-preview/-/native-preview-7.0.0-dev.20260707.2.tgz", - "integrity": "sha512-oUGp+Rep/hqMhPunyinsALUwSlzHINSxitifPiSaeqoKOKD2OlR9NE3TaPqwsl4NlGslsOSUXI1JotWQzpYCPg==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsgo": "bin/tsgo" - }, - "engines": { - "node": ">=16.20.0" - }, - "optionalDependencies": { - "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260707.2", - "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260707.2", - "@typescript/native-preview-linux-arm": "7.0.0-dev.20260707.2", - "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260707.2", - "@typescript/native-preview-linux-x64": "7.0.0-dev.20260707.2", - "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260707.2", - "@typescript/native-preview-win32-x64": "7.0.0-dev.20260707.2" - } - }, - "node_modules/@typescript/native-preview-darwin-arm64": { - "version": "7.0.0-dev.20260707.2", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-arm64/-/native-preview-darwin-arm64-7.0.0-dev.20260707.2.tgz", - "integrity": "sha512-wny2pgKjGbiZtnOIHVa3tXC1UfDqxNEFzyPGmiqybedG8hipG2Nfp0l5UxbaKCjkLacUpH/W5bP2hBOMVhCOzg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/native-preview-darwin-x64": { - "version": "7.0.0-dev.20260707.2", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-x64/-/native-preview-darwin-x64-7.0.0-dev.20260707.2.tgz", - "integrity": "sha512-Afc7M5zOwo+GpfcYwz5Z8HMB2tPVsui7nNIqEuuFB73MPdVqNn/Wmpe4tP4MRri0AtJnJknoHBaTJ/VDAp/Jhw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/native-preview-linux-arm": { - "version": "7.0.0-dev.20260707.2", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm/-/native-preview-linux-arm-7.0.0-dev.20260707.2.tgz", - "integrity": "sha512-hJm/UOqZTr9FHmR7uNm8VGX4oKtfWk0Jem0zPeJFNC8ckGUfSBueyiEYMZB+XmRc1aG4x1E46y3CplP4CLHvGQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/native-preview-linux-arm64": { - "version": "7.0.0-dev.20260707.2", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm64/-/native-preview-linux-arm64-7.0.0-dev.20260707.2.tgz", - "integrity": "sha512-iITBa2WjjTI5N9t5l7Z4KoOSI+2zBlhbvFzsD/f8qX8QoKjz/Y4DPyBDgezYi8nkqjjksbgSOJ3/ykzhwrB9cg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/native-preview-linux-x64": { - "version": "7.0.0-dev.20260707.2", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-x64/-/native-preview-linux-x64-7.0.0-dev.20260707.2.tgz", - "integrity": "sha512-du0dzi6y97Po5vDNdPJTyyijHCpaS22JLRnKZEJXBDaO9gCIymOv/5QQokFRuOlQm0bWl3i9PF4OVdGP6uAOQA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/native-preview-win32-arm64": { - "version": "7.0.0-dev.20260707.2", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-arm64/-/native-preview-win32-arm64-7.0.0-dev.20260707.2.tgz", - "integrity": "sha512-SsAwfhyHJ1akgBc+99z4+hwdbHsdWaKB8EwCNIMA6JfSLMeUjffrYvxu+vfMyxVtOVOz7RrRXRoiDiu4a2sCtg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/native-preview-win32-x64": { - "version": "7.0.0-dev.20260707.2", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-x64/-/native-preview-win32-x64-7.0.0-dev.20260707.2.tgz", - "integrity": "sha512-DL4u27stv0fo71sVhOzHSwE+YMZsbBijVI+kg5dLDLilSH79WFTJ8RSQ46vJrCMt+Gjlv/JOZP1PuLJDfioYeQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16.20.0" - } - }, "node_modules/abort-controller": { "version": "3.0.0", "license": "MIT", diff --git a/package.json b/package.json index a71fa82776..ea931d414e 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "build": "tsc --project tsconfig.build.json", "build:watch": "npm run build -- --watch --incremental", "typecheck": "tsc --project tsconfig.json", - "typecheck:fast": "tsgo --noEmit --project tsconfig.json", + "typecheck:fast": "npx -y -p @typescript/native-preview@7.0.0-dev.20260707.2 tsgo --noEmit --project tsconfig.json", "package": "./build-tools/build.sh", "lint": "oxlint --format stylish --deny-warnings .", "lint:required": "oxlint --format stylish --quiet .", @@ -140,7 +140,6 @@ "@types/sinon": "^21.0.0", "@types/tar-fs": "^2.0.4", "@typescript-eslint/parser": "^8.48.1", - "@typescript/native-preview": "7.0.0-dev.20260707.2", "axios": "1.18.1", "chai": "^6.2.0", "chai-as-promised": "^8.0.2", From a9739b4fa2201b7ba2f29744df4bc57929ceba04 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 9 Jul 2026 18:34:09 -0600 Subject: [PATCH 6/6] build: use typescript@7.0.2 instead of @typescript/native-preview for tsgo fast-check (#1738) TypeScript 7 merges the native (Go-ported) compiler preview directly into typescript's own tsc binary, so the separate @typescript/native-preview package/tsgo binary is no longer needed once 7.0.2 is out. Still invoked via npx (not a package.json dependency) since typescript is already a 5.x devDependency here and npx resolves/caches the pinned 7.x tarball separately without colliding with it. Co-Authored-By: Claude Sonnet 5 --- dependencies.md | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dependencies.md b/dependencies.md index 5ace308386..79505d7786 100644 --- a/dependencies.md +++ b/dependencies.md @@ -185,10 +185,10 @@ Generally, dependencies are added by simply adding them to the dependencies list - Can be deferred: The require happens only when `server/serverHelpers/multipartParser.ts` is imported, which is loaded by `registerContentHandlers` at operations-server boot. Realistically always loaded. - Eventual removal: Could be replaced by writing our own streaming multipart parser (a few hundred lines plus tests for edge cases) if maintenance ever lapses, or by Node.js's `request.formData()` once that API supports streaming file parts without buffering (currently it doesn't on the standard Node http server interface used by Fastify). -## @typescript/native-preview (not a dependency — invoked via npx) +## typescript@7 (not a dependency — invoked via npx, pinned separately from the `typescript` devDependency) -- Need for usage: Ships `tsgo`, the native (Go-ported) TypeScript compiler preview that will become TypeScript 7's `tsc`. Wired as an opt-in `npm run typecheck:fast` script — a faster local/CI type-check loop alongside the existing `tsc`-based `build`, not a replacement for either. -- Not a `package.json` dependency: `typecheck:fast` runs `npx -y -p @typescript/native-preview@ tsgo ...` rather than adding this as a `devDependency`. This is deliberate — an earlier version of this change had it as a plain `devDependency`, which meant `npm ci` fetched this exact nightly tarball for every CI job (unit, integration, smoke, stress), not just the opt-in checker. `optionalDependencies` was considered and rejected: both `harper` and `harper-pro` are genuinely public npm packages (verified against the registry, no `private` field), so that would install-attempt this dev-only tool for every real end-user's `npm install`. Running it via `npx` on-demand confines a pruned-tarball failure to `typecheck:fast` alone, matching its actually-opt-in nature. Trade-off: no `package-lock.json` integrity-hash pinning for this tool (the exact version is still pinned in the npx invocation itself, just not hash-verified against a lockfile entry). -- Security: Microsoft-maintained preview of the upcoming TypeScript 7 toolchain. -- Overlap: Complements, does not replace, the `typescript` devDependency — `tsgo` currently has no declaration-emit parity for one file (`resources/Table.ts`'s anonymous `#private`-field class) and TS 7.0 ships no compiler API, so `@typescript-eslint/parser` still needs `typescript` 5.x. +- Need for usage: TypeScript 7 merges the native (Go-ported) compiler preview directly into the `typescript` package's `tsc` binary — there is no separate `tsgo` binary or `@typescript/native-preview` package at 7.0.2+. Wired as an opt-in `npm run typecheck:fast` script — a faster local/CI type-check loop alongside the existing `tsc`-based `build`, not a replacement for either. +- Not a `package.json` dependency: `typecheck:fast` runs `npx -y -p typescript@ tsc ...` rather than adding this as a `devDependency`. This is deliberate, and for the same reason as before: an earlier version of this change had the equivalent tool (`@typescript/native-preview`) as a plain `devDependency`, which meant `npm ci` fetched it for every CI job (unit, integration, smoke, stress), not just the opt-in checker. Since the package name here is `typescript` — the same name as our existing 5.x devDependency — it also could not be added as a second `package.json` entry at a different version without colliding; `npx -p typescript@7.0.2` sidesteps this too, resolving and running the pinned 7.x tarball from npm's npx cache without touching the project's installed 5.x `typescript`. Running it via `npx` on-demand confines a pruned-tarball failure to `typecheck:fast` alone, matching its actually-opt-in nature. Trade-off: no `package-lock.json` integrity-hash pinning for this tool (the exact version is still pinned in the npx invocation itself, just not hash-verified against a lockfile entry). +- Security: Microsoft-maintained TypeScript compiler, same publisher/package as the 5.x devDependency. +- Overlap: Complements, does not replace, the `typescript` devDependency — TypeScript 7.0 ships no compiler API yet (planned for 7.1), so `@typescript-eslint/parser` still needs `typescript` 5.x. The 5.x and 7.x versions never coexist in `node_modules` at once: 5.x is the installed devDependency, 7.x is fetched on-demand by `npx` purely for `typecheck:fast`. - Eventual removal: Once TypeScript 7 stabilizes as the primary `typescript` devDependency (post-7.1's compiler API), this becomes redundant and `typecheck:fast` can be dropped. diff --git a/package.json b/package.json index ea931d414e..35c3d17363 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "build": "tsc --project tsconfig.build.json", "build:watch": "npm run build -- --watch --incremental", "typecheck": "tsc --project tsconfig.json", - "typecheck:fast": "npx -y -p @typescript/native-preview@7.0.0-dev.20260707.2 tsgo --noEmit --project tsconfig.json", + "typecheck:fast": "npx -y -p typescript@7.0.2 tsc --noEmit --project tsconfig.json", "package": "./build-tools/build.sh", "lint": "oxlint --format stylish --deny-warnings .", "lint:required": "oxlint --format stylish --quiet .",