Files
vscode/build/lib/tsgo.ts
T
Dirk BäumerandGitHub 7e4e91cab4 Adapt to TypeScript 7 (#325757)
* Adapt TypeScript 7

* Ensure that we always call TS7 from spawnTsgo

* Fix package lock file

* tsc - tsc6

* More tsc -> tsc6

* More TSGO conversion

* More moves from tsgo -> tsc

* Fix tsgo resolving in extension folder

* Call TS7 compiler directly

* Update package-lock.json

* Remove tsc:version again
2026-07-14 12:34:04 +02:00

94 lines
3.3 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import ansiColors from 'ansi-colors';
import * as cp from 'child_process';
import es from 'event-stream';
import fancyLog from 'fancy-log';
import { createRequire } from 'module';
import * as path from 'path';
const root = path.dirname(path.dirname(import.meta.dirname));
const ansiRegex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
const timestampRegex = /^\[\d{2}:\d{2}:\d{2}\]\s*/;
/**
* Absolute path to the TypeScript 7 (native) compiler entrypoint. TS7 is
* installed under the `@typescript/native` alias, a package name that only
* exists at the repository root and never collides with the `typescript`
* (<= 6.x) that individual extensions install locally. Resolving it explicitly
* and invoking it via `node` guarantees we always run TS7, regardless of the
* node_modules layout of the project being compiled.
*/
const ts7TscPath = path.join(path.dirname(createRequire(import.meta.url).resolve('@typescript/native/package.json')), 'bin', 'tsc');
export function spawnTsgo(projectPath: string, config: { taskName: string; noEmit?: boolean }, onComplete?: () => Promise<void> | void): Promise<void> {
function runReporter(output: string) {
const lines = (output || '').split('\n');
const errorLines = lines.filter(line => /error \w+:/.test(line));
fancyLog(`Finished ${ansiColors.green(config.taskName)} ${projectPath} with ${errorLines.length} errors.`);
for (const line of errorLines) {
fancyLog(line);
}
}
const args = [ts7TscPath, '--project', projectPath, '--pretty', 'false', '--incremental'];
if (config.noEmit) {
args.push('--noEmit');
} else {
args.push('--sourceMap', '--inlineSources');
}
const child = cp.spawn(process.execPath, args, {
cwd: root,
stdio: ['ignore', 'pipe', 'pipe']
});
let stdoutData = '';
let stderrData = '';
child.stdout?.on('data', (data: Buffer) => {
stdoutData += data.toString();
});
child.stderr?.on('data', (data: Buffer) => {
stderrData += data.toString();
});
return new Promise<void>((resolve, reject) => {
child.on('exit', code => {
const allOutput = stdoutData + '\n' + stderrData;
const lines = allOutput
.split(/\r?\n/)
.map(line => line.replace(ansiRegex, '').trim())
.map(line => line.replace(timestampRegex, ''))
.filter(line => line.length > 0)
.filter(line => !/Starting compilation|File change detected|Compilation complete/i.test(line));
runReporter(lines.join('\n'));
if (code === 0) {
Promise.resolve(onComplete?.()).then(() => resolve(), reject);
} else {
reject(new Error(`tsgo exited with code ${code ?? 'unknown'}`));
}
});
child.on('error', err => {
reject(err);
});
});
}
export function createTsgoStream(projectPath: string, config: { taskName: string; noEmit?: boolean }, onComplete?: () => Promise<void> | void): NodeJS.ReadWriteStream {
const stream = es.through();
spawnTsgo(projectPath, config, onComplete).then(() => {
stream.emit('end');
}).catch(err => {
stream.emit('error', err);
});
return stream;
}